• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

benches/H03-May-2022-934809

src/H03-May-2022-5,2523,639

tests/H03-May-2022-518434

.cargo-checksum.jsonH A D03-May-202289 11

.cargo_vcs_info.jsonH A D01-Jan-197074 65

.gitignoreH A D12-Feb-201818 32

.travis.ymlH A D20-Aug-2019840 3736

Cargo.tomlH A D01-Jan-19701.9 KiB6352

Cargo.toml.orig-cargoH A D20-Aug-20191.3 KiB5846

LICENSE-APACHEH A D12-Feb-201810.6 KiB202169

LICENSE-MITH A D12-Feb-20181 KiB2622

README.rstH A D20-Aug-201910.2 KiB305203

README.rst

1indexmap
2========
3
4|build_status|_ |crates|_ |docs|_ |rustc|_
5
6.. |crates| image:: https://img.shields.io/crates/v/indexmap.svg
7.. _crates: https://crates.io/crates/indexmap
8
9.. |build_status| image:: https://travis-ci.org/bluss/indexmap.svg
10.. _build_status: https://travis-ci.org/bluss/indexmap
11
12.. |docs| image:: https://docs.rs/indexmap/badge.svg
13.. _docs: https://docs.rs/indexmap
14
15.. |rustc| image:: https://img.shields.io/badge/rust-1.18%2B-orange.svg
16.. _rustc: https://img.shields.io/badge/rust-1.18%2B-orange.svg
17
18A safe, pure-Rust hash table which preserves insertion order.
19
20This crate implements compact map and set data-structures,
21where the iteration order of the keys is independent from their hash or
22value. It preserves insertion order (except after removals), and it
23allows lookup of entries by either hash table key or numerical index.
24
25Note: this crate was originally released under the name ``ordermap``,
26but it was renamed to ``indexmap`` to better reflect its features.
27
28Background
29==========
30
31This was inspired by Python 3.6's new dict implementation (which remembers
32the insertion order and is fast to iterate, and is compact in memory).
33
34Some of those features were translated to Rust, and some were not. The result
35was indexmap, a hash table that has following properties:
36
37- Order is **independent of hash function** and hash values of keys.
38- Fast to iterate.
39- Indexed in compact space.
40- Preserves insertion order **as long** as you don't call ``.remove()``.
41- Uses robin hood hashing just like Rust's libstd ``HashMap`` used to do
42  (before std switched to hashbrown).
43
44  - It's the usual backwards shift deletion, but only on the index vector, so
45    it's cheaper because it's moving less memory around.
46
47Does not implement (Yet)
48------------------------
49
50- ``.reserve()`` exists but does not have a complete implementation
51
52Performance
53-----------
54
55``IndexMap`` derives a couple of performance facts directly from how it is constructed,
56which is roughly:
57
58  Two vectors, the first, sparse, with hashes and key-value indices, and the
59  second, dense, the key-value pairs.
60
61- Iteration is very fast since it is on the dense key-values.
62- Removal is fast since it moves memory areas only in the first vector,
63  and uses a single swap in the second vector.
64- Lookup is fast-ish because the hashes and indices are densely stored.
65  Lookup also is slow-ish since hashes and key-value pairs are stored in
66  separate places. (Visible when cpu caches size is limiting.)
67
68- In practice, ``IndexMap`` has been tested out as the hashmap in rustc in PR45282_ and
69  the performance was roughly on par across the whole workload.
70- If you want the properties of ``IndexMap``, or its strongest performance points
71  fits your workload, it might be the best hash table implementation.
72
73.. _PR45282: https://github.com/rust-lang/rust/pull/45282
74
75Interesting Features
76--------------------
77
78- Insertion order is preserved (``.swap_remove()`` perturbs the order, like the method name says).
79- Implements ``.pop() -> Option<(K, V)>`` in O(1) time.
80- ``IndexMap::new()`` is empty and uses no allocation until you insert something.
81- Lookup key-value pairs by index and vice versa.
82- No ``unsafe``.
83- Supports ``IndexMut``.
84
85
86Where to go from here?
87----------------------
88
89- Ideas and PRs for how to implement insertion-order preserving remove (for example tombstones)
90  are welcome. The plan is to split the crate into two hash table implementations
91  a) the current compact index space version and b) the full insertion order version.
92
93
94Ideas that we already did
95-------------------------
96
97- It can be an *indexable* ordered map in the current fashion
98  (This was implemented in 0.2.0, for potential use as a graph datastructure).
99
100- Idea for more cache efficient lookup (This was implemented in 0.1.2).
101
102  Current ``indices: Vec<Pos>``. ``Pos`` is interpreted as ``(u32, u32)`` more
103  or less when ``.raw_capacity()`` fits in 32 bits. ``Pos`` then stores both the lower
104  half of the hash and the entry index.
105  This means that the hash values in ``Bucket`` don't need to be accessed
106  while scanning for an entry.
107
108
109Recent Changes
110==============
111
112- 1.1.0
113
114  - Added optional feature `"rayon"` that adds parallel iterator support
115    to `IndexMap` and `IndexSet` using Rayon. This includes all the regular
116    iterators in parallel versions, and parallel sort.
117
118  - Implemented ``Clone`` for ``map::{Iter, Keys, Values}`` and
119    ``set::{Difference, Intersection, Iter, SymmetricDifference, Union}``
120
121  - Implemented ``Debug`` for ``map::{Entry, IntoIter, Iter, Keys, Values}`` and
122    ``set::{Difference, Intersection, IntoIter, Iter, SymmetricDifference, Union}``
123
124  - Serde trait ``IntoDeserializer`` are implemented for ``IndexMap`` and ``IndexSet``.
125
126  - Minimum Rust version requirement increased to Rust 1.30 for development builds.
127
128- 1.0.2
129
130  - The new methods ``IndexMap::insert_full`` and ``IndexSet::insert_full`` are
131    both like ``insert`` with the index included in the return value.
132
133  - The new method ``Entry::and_modify`` can be used to modify occupied
134    entries, matching the new methods of ``std`` maps in Rust 1.26.
135
136  - The new method ``Entry::or_default`` inserts a default value in unoccupied
137    entries, matching the new methods of ``std`` maps in Rust 1.28.
138
139- 1.0.1
140
141  - Document Rust version policy for the crate (see rustdoc)
142
143- 1.0.0
144
145  - This is the 1.0 release for ``indexmap``! (the crate and datastructure
146    formerly known as “ordermap”)
147  - ``OccupiedEntry::insert`` changed its signature, to use ``&mut self`` for
148    the method receiver, matching the equivalent method for a standard
149    ``HashMap``.  Thanks to @dtolnay for finding this bug.
150  - The deprecated old names from ordermap were removed: ``OrderMap``,
151    ``OrderSet``, ``ordermap!{}``, ``orderset!{}``. Use the new ``IndexMap``
152    etc names instead.
153
154- 0.4.1
155
156  - Renamed crate to ``indexmap``; the ``ordermap`` crate is now deprecated
157    and the types ``OrderMap/Set`` now have a deprecation notice.
158
159- 0.4.0
160
161  - This is the last release series for this ``ordermap`` under that name,
162    because the crate is **going to be renamed** to ``indexmap`` (with types
163    ``IndexMap``, ``IndexSet``) and no change in functionality!
164  - The map and its associated structs moved into the ``map`` submodule of the
165    crate, so that the map and set are symmetric
166
167    + The iterators, ``Entry`` and other structs are now under ``ordermap::map::``
168
169  - Internally refactored ``OrderMap<K, V, S>`` so that all the main algorithms
170    (insertion, lookup, removal etc) that don't use the ``S`` parameter (the
171    hasher) are compiled without depending on ``S``, which reduces generics bloat.
172
173  - ``Entry<K, V>`` no longer has a type parameter ``S``, which is just like
174    the standard ``HashMap``'s entry.
175
176  - Minimum Rust version requirement increased to Rust 1.18
177
178- 0.3.5
179
180  - Documentation improvements
181
182- 0.3.4
183
184  - The ``.retain()`` methods for ``OrderMap`` and ``OrderSet`` now
185    traverse the elements in order, and the retained elements **keep their order**
186  - Added new methods ``.sort_by()``, ``.sort_keys()`` to ``OrderMap`` and
187    ``.sort_by()``, ``.sort()`` to ``OrderSet``. These methods allow you to
188    sort the maps in place efficiently.
189
190- 0.3.3
191
192  - Document insertion behaviour better by @lucab
193  - Updated dependences (no feature changes) by @ignatenkobrain
194
195- 0.3.2
196
197  - Add ``OrderSet`` by @cuviper!
198  - ``OrderMap::drain`` is now (too) a double ended iterator.
199
200- 0.3.1
201
202  - In all ordermap iterators, forward the ``collect`` method to the underlying
203    iterator as well.
204  - Add crates.io categories.
205
206- 0.3.0
207
208  - The methods ``get_pair``, ``get_pair_index`` were both replaced by
209    ``get_full`` (and the same for the mutable case).
210  - Method ``swap_remove_pair`` replaced by ``swap_remove_full``.
211  - Add trait ``MutableKeys`` for opt-in mutable key access. Mutable key access
212    is only possible through the methods of this extension trait.
213  - Add new trait ``Equivalent`` for key equivalence. This extends the
214    ``Borrow`` trait mechanism for ``OrderMap::get`` in a backwards compatible
215    way, just some minor type inference related issues may become apparent.
216    See `#10`__ for more information.
217  - Implement ``Extend<(&K, &V)>`` by @xfix.
218
219__ https://github.com/bluss/ordermap/pull/10
220
221- 0.2.13
222
223  - Fix deserialization to support custom hashers by @Techcable.
224  - Add methods ``.index()`` on the entry types by @garro95.
225
226- 0.2.12
227
228  - Add methods ``.with_hasher()``, ``.hasher()``.
229
230- 0.2.11
231
232  - Support ``ExactSizeIterator`` for the iterators. By @Binero.
233  - Use ``Box<[Pos]>`` internally, saving a word in the ``OrderMap`` struct.
234  - Serde support, with crate feature ``"serde-1"``. By @xfix.
235
236- 0.2.10
237
238  - Add iterator ``.drain(..)`` by @stevej.
239
240- 0.2.9
241
242  - Add method ``.is_empty()`` by @overvenus.
243  - Implement ``PartialEq, Eq`` by @overvenus.
244  - Add method ``.sorted_by()``.
245
246- 0.2.8
247
248  - Add iterators ``.values()`` and ``.values_mut()``.
249  - Fix compatibility with 32-bit platforms.
250
251- 0.2.7
252
253  - Add ``.retain()``.
254
255- 0.2.6
256
257  - Add ``OccupiedEntry::remove_entry`` and other minor entry methods,
258    so that it now has all the features of ``HashMap``'s entries.
259
260- 0.2.5
261
262  - Improved ``.pop()`` slightly.
263
264- 0.2.4
265
266  - Improved performance of ``.insert()`` (`#3`__) by @pczarn.
267
268__ https://github.com/bluss/ordermap/pull/3
269
270- 0.2.3
271
272  - Generalize ``Entry`` for now, so that it works on hashmaps with non-default
273    hasher. However, there's a lingering compat issue since libstd ``HashMap``
274    does not parameterize its entries by the hasher (``S`` typarm).
275  - Special case some iterator methods like ``.nth()``.
276
277- 0.2.2
278
279  - Disable the verbose ``Debug`` impl by default.
280
281- 0.2.1
282
283  - Fix doc links and clarify docs.
284
285- 0.2.0
286
287  - Add more ``HashMap`` methods & compat with its API.
288  - Experimental support for ``.entry()`` (the simplest parts of the API).
289  - Add ``.reserve()`` (placeholder impl).
290  - Add ``.remove()`` as synonym for ``.swap_remove()``.
291  - Changed ``.insert()`` to swap value if the entry already exists, and
292    return ``Option``.
293  - Experimental support as an *indexed* hash map! Added methods
294    ``.get_index()``, ``.get_index_mut()``, ``.swap_remove_index()``,
295    ``.get_pair_index()``, ``.get_pair_index_mut()``.
296
297- 0.1.2
298
299  - Implement the 32/32 split idea for ``Pos`` which improves cache utilization
300    and lookup performance.
301
302- 0.1.1
303
304  - Initial release.
305