# Index Map A map with automatically generated `usize`s as keys. It supports [_most_](#method-exclusions) of the methods present on the standard library [`HashMap`](https://doc.rust-lang.org/std/collections/struct.HashMap.html). If you need a generic key-value pair, with user defined keys, this is not the crate for you. It is only meant to be used for things that require automatically generated keys. ## Features - It automatically generates (and recycles) unique indices as keys, - Compatible with `#[no_std]` but requires an allocator. - Doesn't allocate until first value is inserted. - Values are stored in contiguous memory locations. - 0 unsafe blocks ## Performance Due to its simplicity nature, it performs better than `HashMap`. | name | IndexMap [ns/iter] | HashMap [ns/iter] | diff [ns/iter] | diff % | speedup | | ------------ | ------------------ | ----------------- | -------------- | ------- | ------- | | insert | 40,057 | 75,381 | -35,324 | -46.86% | 1.88x | | grow_insert | 12,553 | 100,530 | -87,977 | -87.51% | 8.01x | | insert_erase | 9,572 | 12,370 | -2,798 | -22.62% | 1.29x | | lookup | 1,491 | 24,253 | -22,762 | -93.85% | 16.27x | | lookup_fail | 1.289 | 2.092 | -0.8 | -38.38% | 1.62x | | bench_iter | 1,812 | 1,888 | -76 | -4.03% | 1.04x | | clone_small | 120.30 | 163.70 | -43.4 | -26.51% | 1.36x | | clone_large | 9,635 | 13,041 | -34,06 | -26.12% | 1.35x | The benchmarks performed here are the same as present in the hashbrown repo: [bench.rs](https://github.com/rust-lang/hashbrown/blob/master/benches/bench.rs) ## Usage Anything than needs to have some unique generated id associated with it is the perfect use case for this library. An example could be maintaining a process table. ```rust use index_map::IndexMap; let mut process_table = IndexMap::new(); // Create some processes // Unlike HashMap, insert only takes a value, and returns the key. let vim = process_table.insert("vim".to_string()); // ^^^----------------------------------------------------------. let cargo = process_table.insert("cargo".to_string()); // | // ^^^^^--------------------------------------------------------. let rls = process_table.insert("rust-analyser".to_string()); // | // ^^^----------------------------------------------------------| // | // Unique numbers representing each process <------------------' // Check for a specific one. if !process_table.contains_key(6) { println!("Invalid PID 6}"); } // cargo finished running, remove it process_table.remove(cargo); // Look up the values associated with some keys. let to_find = [2, 4]; for &pid in &to_find { match process_table.get(pid) { Some(process) => println!("{}: {}", pid, process), None => println!("{} not found", pid) } } // Look up the value for a key (will panic if the key is not found). println!("PID 0 process name: {}", process_table[0]); // Iterate over everything. for (pid, process) in &process_table { println!("{}: \"{}\"", pid, process); } ``` ## Method Exclusions - nightly only/unstable - hasher based functions - the internal structure is based on a `Vec` and so hashes are not needed. - [`entry()`](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.entry) - Although all the methods for `OccupiedEntry` are possible, fundamentally, keys are automatically generated, and so the methods based on `VacantEntry` are not possible. - [`Extend`](https://doc.rust-lang.org/std/iter/trait.Extend.html) & [`FromIterator`](https://doc.rust-lang.org/std/iter/trait.FromIterator.html) - It can't take key-value pairs like `HashMap` because of the reason mentioned above, and it can't return the keys for values inserted. ## Contribution If you find any bugs or issues, or you want some feature added, feel free to open an [issue](https://github.com/Lutetium-Vanadium/index-map/issues/new) or a [pull request](https://github.com/Lutetium-Vanadium/index-map/compare).