HashSlab
HashSlab is a library inspired by IndexMap, designed to provide a key-value data structure that allows efficient access by both key and index. Unlike IndexMap, HashSlabMap guarantees that the index of a key-value pair remains stable and does not change, even when entries are removed.
Key Features
- Stable Indexes: Once a key-value pair is inserted, its
usizeindex is preserved throughout the lifetime of the map, regardless of any removals. - Dual Access: Access values either by key or by their associated index.
- Interface:
HashSlabMapmethods aim to closely resemble those ofIndexMap.
When to Use HashSlab
This crate is ideal for scenarios where:
- You need predictable and stable indexing of entries.
- Entries are frequently added and removed, but their indexes must remain consistent for external references.
Examples
Basic storing and retrieval:
use HashSlabMap;
let mut map = new;
map.insert;
assert_eq!;
let = map.insert_full;
assert_eq!;
assert_eq!;
map = "earth";
assert_eq!;
assert_eq!;
HashSlab preserve value's index:
use HashSlabMap;
let mut map = new;
map.insert;
map.insert;
map.insert;
map.remove;
map.remove_index;
assert_eq!;
Implementation
HashSlab is implemented using a HashMap for keys and a Slab for values. The HashMap stores the keys, while each entry in the Slab contains both the value and the raw hash (u64) of the corresponding key. This design allows efficient retrieval of the associated key entry in the HashMap using the precomputed hash.
Performance
In general, HashSlabMap has comparable performance to HashMap and IndexMap. Below is a summary of its performance characteristics:
-
Creation: Empty created
HashSlabMapperforms worse because internally it creates 2 data structuresHashMapandSlab, taking twice as long asHashMapandIndexMap. With preallocation, performance is similar, as most time is spent on memory allocation. -
Insertion: Performance is identical across all three data structures.
-
Lookup: Searching with
.get()performs the same asHashMapandIndexMap. However,.get_index()is about 10 times slower thanIndexMapbecauseIndexMapstores entries in aVec-like structure, making index lookups as fast as.get()in aVec. InHashSlabMap, the hash value is first located in theSlab, followed by the corresponding key-value pair in theHashMap. -
Removal: Removing by key is on par with
HashMapand faster thanIndexMap.IndexMapprovides two methods:.swap_remove()- performs similarly toHashSlabMap::remove()..shift_remove()- significantly slower, as it shifts elements in theVec. This method is not included in benchmarks due to being 50-100 times slower.
Comprehensive benchmarks, including detailed graphs and comparisons, can be found here.