|
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