|
1 | | -# indexmap |
| 1 | +# ringmap |
2 | 2 |
|
3 | | -[](https://github.com/indexmap-rs/indexmap/actions) |
4 | | -[](https://crates.io/crates/indexmap) |
5 | | -[](https://docs.rs/indexmap) |
6 | | -[](https://img.shields.io/badge/rust-1.63%2B-orange.svg) |
| 3 | +[](https://github.com/indexmap-rs/ringmap/actions) |
| 4 | +[](https://crates.io/crates/ringmap) |
| 5 | +[](https://docs.rs/ringmap) |
| 6 | +[](https://img.shields.io/badge/rust-1.68%2B-orange.svg) |
7 | 7 |
|
8 | | -A pure-Rust hash table which preserves (in a limited sense) insertion order. |
| 8 | +A pure-Rust hash table which preserves (in a limited sense) insertion order, |
| 9 | +with efficient deque-like manipulation of both the front and back ends. |
9 | 10 |
|
10 | 11 | This crate implements compact map and set data-structures, |
11 | 12 | where the iteration order of the keys is independent from their hash or |
12 | | -value. It preserves insertion order (except after removals), and it |
| 13 | +value. It preserves insertion order in most mutating operations, and it |
13 | 14 | allows lookup of entries by either hash table key or numerical index. |
14 | 15 |
|
15 | | -Note: this crate was originally released under the name `ordermap`, |
16 | | -but it was renamed to `indexmap` to better reflect its features. |
17 | | -The [`ordermap`](https://crates.io/crates/ordermap) crate now exists |
18 | | -as a wrapper over `indexmap` with stronger ordering properties. |
19 | | - |
20 | 16 | # Background |
21 | 17 |
|
22 | | -This was inspired by Python 3.6's new dict implementation (which remembers |
23 | | -the insertion order and is fast to iterate, and is compact in memory). |
24 | | - |
25 | | -Some of those features were translated to Rust, and some were not. The result |
26 | | -was indexmap, a hash table that has following properties: |
| 18 | +This crate was forked from [`indexmap`](https://crates.io/crates/indexmap), |
| 19 | +with the primary difference being a change from `Vec` to `VecDeque` for the |
| 20 | +primary item storage. As a result, it has many of the same properties, as |
| 21 | +well as a few new ones: |
27 | 22 |
|
28 | 23 | - Order is **independent of hash function** and hash values of keys. |
29 | 24 | - Fast to iterate. |
30 | 25 | - Indexed in compact space. |
31 | | -- Preserves insertion order **as long** as you don't call `.remove()`, |
32 | | - `.swap_remove()`, or other methods that explicitly change order. |
33 | | - The alternate `.shift_remove()` does preserve relative order. |
| 26 | +- Efficient pushing and popping from both the front and back. |
| 27 | +- Preserves insertion order **as long** as you don't call `.swap_remove_back()` |
| 28 | + or other methods that explicitly change order. |
| 29 | + - In `ringmap`, the regular `.remove()` **does** preserve insertion order, |
| 30 | + equivalent to what `indexmap` calls `.shift_remove()`. |
34 | 31 | - Uses hashbrown for the inner table, just like Rust's libstd `HashMap` does. |
35 | 32 |
|
36 | | -## Performance |
37 | | - |
38 | | -`IndexMap` derives a couple of performance facts directly from how it is constructed, |
39 | | -which is roughly: |
40 | | - |
41 | | -> A raw hash table of key-value indices, and a vector of key-value pairs. |
42 | | -
|
43 | | -- Iteration is very fast since it is on the dense key-values. |
44 | | -- Removal is fast since it moves memory areas only in the table, |
45 | | - and uses a single swap in the vector. |
46 | | -- Lookup is fast-ish because the initial 7-bit hash lookup uses SIMD, and indices are |
47 | | - densely stored. Lookup also is slow-ish since the actual key-value pairs are stored |
48 | | - separately. (Visible when cpu caches size is limiting.) |
49 | | - |
50 | | -- In practice, `IndexMap` has been tested out as the hashmap in rustc in [PR45282] and |
51 | | - the performance was roughly on par across the whole workload. |
52 | | -- If you want the properties of `IndexMap`, or its strongest performance points |
53 | | - fits your workload, it might be the best hash table implementation. |
54 | | - |
55 | | -[PR45282]: https://github.com/rust-lang/rust/pull/45282 |
| 33 | +`ringmap` also follows [`ordermap`](https://crates.io/crates/ordermap) in using |
| 34 | +its entry order for `PartialEq` and `Eq`, whereas `indexmap` considers the same |
| 35 | +entries in *any* order to be equal for drop-in compatibility with `HashMap` |
| 36 | +semantics. Using the order is faster, and also allows `ringmap` to implement |
| 37 | +`PartialOrd`, `Ord`, and `Hash`. |
56 | 38 |
|
57 | 39 | # Recent Changes |
58 | 40 |
|
59 | | -See [RELEASES.md](https://github.com/indexmap-rs/indexmap/blob/master/RELEASES.md). |
| 41 | +See [RELEASES.md](https://github.com/indexmap-rs/ringmap/blob/main/RELEASES.md). |
0 commit comments