Crates.io | hashslab |
lib.rs | hashslab |
version | |
source | src |
created_at | 2024-11-20 15:36:21.997085 |
updated_at | 2024-12-12 11:43:42.376154 |
description | A hash table with data accessible by index. |
homepage | |
repository | https://github.com/pepyaka/hashslab |
max_upload_size | |
id | 1454887 |
Cargo.toml error: | TOML parse error at line 17, column 1 | 17 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
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.
usize
index is preserved throughout the lifetime of the map, regardless of any removals.HashSlabMap
methods aim to closely resemble those of IndexMap
.HashSlab
This crate is ideal for scenarios where:
Basic storing and retrieval:
use hashslab::HashSlabMap;
let mut map = HashSlabMap::new();
map.insert('a', "hello");
assert_eq!(map.get(&'a'), Some(&"hello"));
let (idx, _) = map.insert_full('b', "world");
assert_eq!(idx, 1);
assert_eq!(map[&'b'], "world");
map[idx] = "earth";
assert_eq!(map.get_index(0), Some((&'a', &"hello")));
assert_eq!(map[idx], "earth");
HashSlab preserve value's index:
use hashslab::HashSlabMap;
let mut map = HashSlabMap::new();
map.insert('a', "hello");
map.insert('b', "world");
map.insert('c', "!");
map.remove(&'a');
map.remove_index(1);
assert_eq!(map.get_index_of(&'c'), Some(2));
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.
In general, HashSlabMap
has comparable performance to HashMap
and IndexMap
. Below is a summary of its performance characteristics:
Creation: Empty created HashSlabMap
performs worse because internally it creates 2 data structures HashMap
and Slab
, taking twice as long as HashMap
and IndexMap
. 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 as HashMap
and IndexMap
. However, .get_index()
is about 10 times slower than IndexMap
because IndexMap
stores entries in a Vec
-like structure, making index lookups as fast as .get()
in a Vec
. In HashSlabMap
, the hash value is first located in the Slab
, followed by the corresponding key in the HashMap
.
Removal: Removing by key is on par with HashMap
and faster than IndexMap
. IndexMap
provides two methods:
.swap_remove()
- performs similarly to HashSlabMap::remove()
..shift_remove()
- significantly slower, as it shifts elements in the Vec
. 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.
This crate supports being built without std
. This is chosen by disabling the default "std" cargo feature, by adding default-features = false
to your dependency specification.
Creating maps and sets using .new()
and .with_capacity()
is unavailable without std. Use methods .default()
, .with_hasher()
, .with_capacity_and_hasher()
instead. A no-std compatible hasher will be needed as well, for example from the crate twox-hash.