1use hashbrown::HashTable;
2use std::borrow::Borrow;
3use std::fmt::Debug;
4use std::hash::Hasher;
5
6pub mod serde;
7
8#[derive(Clone, Debug)]
16pub struct IndexMap<K, V, S = ahash::RandomState> {
17 values: Vec<V>,
18 index_set: IndexSet<K, S>,
19}
20
21impl<K, V, S> IndexMap<K, V, S>
22where
23 K: Eq + std::hash::Hash + Clone,
24 S: std::hash::BuildHasher,
25{
26 pub fn with_hasher(hash_builder: S) -> Self {
27 IndexMap {
28 values: Vec::new(),
29 index_set: IndexSet::with_hasher(hash_builder),
30 }
31 }
32
33 pub fn with_capacity(capacity: usize) -> Self
34 where
35 S: Default,
36 {
37 IndexMap {
38 values: Vec::with_capacity(capacity),
39 index_set: IndexSet::with_capacity(capacity),
40 }
41 }
42
43 pub fn new() -> Self
44 where
45 S: Default,
46 {
47 IndexMap {
48 values: Vec::new(),
49 index_set: IndexSet::new(),
50 }
51 }
52
53 pub fn with_hasher_capacity(hash_builder: S, capacity: usize) -> Self {
54 IndexMap {
55 values: Vec::with_capacity(capacity),
56 index_set: IndexSet::with_hasher_capacity(hash_builder, capacity),
57 }
58 }
59
60 #[inline]
61 pub fn len(&self) -> usize {
62 self.values.len()
63 }
64
65 #[inline]
66 pub fn iter_values(&self) -> std::slice::Iter<'_, V> {
67 self.values.iter()
68 }
69
70 #[inline]
71 pub fn iter_keys(&self) -> std::slice::Iter<'_, K> {
72 self.index_set.keys.iter()
73 }
74
75 #[inline]
76 pub fn iter(&self) -> IndexMapIter<'_, K, V, S> {
77 IndexMapIter {
78 map: self,
79 index: 0,
80 }
81 }
82
83 #[inline]
84 pub fn values(&self) -> &Vec<V> {
85 &self.values
86 }
87
88 #[inline]
89 pub fn keys(&self) -> &Vec<K> {
90 &self.index_set.keys()
91 }
92
93 #[inline]
94 pub fn as_index_set(&self) -> &IndexSet<K, S> {
95 &self.index_set
96 }
97
98 #[inline]
99 pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
100 where
101 K: Borrow<Q>,
102 Q: std::hash::Hash + Eq,
103 {
104 if let Some(idx) = self.index_set.table_get(key) {
105 unsafe {
106 Some(self.values.get_unchecked(idx))
107 }
108 } else {
109 None
110 }
111 }
112
113 #[inline]
114 pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
115 where
116 K: Borrow<Q>,
117 Q: std::hash::Hash + Eq,
118 {
119 if let Some(idx) = self.index_set.table_get(key) {
120 unsafe {
121 Some(self.values.get_unchecked_mut(idx))
122 }
123 } else {
124 None
125 }
126 }
127
128 #[inline]
129 pub fn get_with_index(&self, index: usize) -> Option<&V> {
130 self.values.get(index)
131 }
132
133 #[inline]
134 pub fn get_with_index_mut(&mut self, index: usize) -> Option<&mut V> {
135 self.values.get_mut(index)
136 }
137
138 #[inline]
139 pub fn get_key_with_index(&self, index: usize) -> Option<&K> {
140 self.index_set.get_with_index(index)
141 }
142
143 #[inline]
144 pub fn get_key_value_with_index(&self, index: usize) -> Option<(&K, &V)> {
145 if index < self.len() {
146 unsafe {
147 Some((
148 self.index_set.keys.get_unchecked(index),
149 self.values.get_unchecked(index),
150 ))
151 }
152 } else {
153 None
154 }
155 }
156
157 #[inline]
158 pub fn get_index<Q: ?Sized>(&self, key: &Q) -> Option<usize>
159 where
160 K: Borrow<Q>,
161 Q: std::hash::Hash + Eq,
162 {
163 self.index_set.table_get(key)
164 }
165
166 pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
167 where
168 K: Borrow<Q>,
169 Q: std::hash::Hash + Eq,
170 {
171 self.index_set.contains_key(key)
172 }
173
174 #[inline]
175 pub fn insert(&mut self, key: K, value: V) -> Option<InsertResult<K, V>> {
176 if let Some(idx) = self.index_set.table_get(&key) {
177 unsafe {
179 self.index_set.table_override(&key, &idx);
180 }
181 let old_value = Some(std::mem::replace(&mut self.values[idx], value));
182 let old_key = Some(std::mem::replace(&mut self.index_set.keys[idx], key.clone()));
183 Some(InsertResult {
184 old_value: old_value.unwrap(),
185 old_key: old_key.unwrap(),
186 })
187 } else {
188 let idx = self.values.len();
190 unsafe {
191 self.index_set.table_append(&key, &idx);
192 }
193 self.index_set.keys.push(key.clone());
194 self.values.push(value);
195 None
196 }
197 }
198
199 #[inline]
200 pub fn entry_mut<'a>(&'a mut self, key: K) -> EntryMut<'a, K, V, S> {
201 if let Some(idx) = self.index_set.table_get(&key) {
202 unsafe {
203 EntryMut::Occupied {
204 key: key,
205 value: self.values.get_unchecked_mut(idx),
206 index: idx,
207 }
208 }
209 } else {
210 EntryMut::Vacant { key , map: self }
211 }
212 }
213
214 #[inline]
215 pub fn swap_remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
216 where
217 K: Borrow<Q>,
218 Q: std::hash::Hash + Eq,
219 {
220 if let Some(idx) = self.index_set.table_get(key) {
221 let last_idx = self.values.len() - 1;
222 if idx == last_idx {
223 unsafe {
225 self.index_set.table_swap_remove(key);
226 }
227 self.index_set.keys.pop();
228 return Some(self.values.pop().unwrap());
229 } else {
230 let last_idx_key = self.index_set.keys[last_idx].clone();
231 unsafe {
232 self.index_set.table_swap_remove(key);
235 self.index_set.table_override(last_idx_key.borrow(), &idx);
238 }
239 let value = self.values.swap_remove(idx);
241 self.index_set.keys.swap_remove(idx);
242 Some(value)
243 }
244 } else {
245 None
246 }
247 }
248
249 #[inline]
250 pub fn from_kv_vec(k_vec: Vec<K>, v_vec: Vec<V>) -> Self
251 where
252 S: std::hash::BuildHasher + Default,
253 {
254 let hash_builder = S::default();
255 let mut map = IndexMap::with_hasher(hash_builder);
256 for (k, v) in k_vec.into_iter().zip(v_vec.into_iter()) {
257 let idx = map.values.len();
258 unsafe {
259 map.index_set.table_append(&k, &idx);
260 }
261 map.index_set.keys.push(k);
262 map.values.push(v);
263 }
264 map
265 }
266}
267
268pub struct IndexMapIter<'a, K, V, S> {
269 pub map: &'a IndexMap<K, V, S>,
270 pub index: usize,
271}
272
273impl <'a, K, V, S> Iterator for IndexMapIter<'a, K, V, S>
274where
275 K: Eq + std::hash::Hash + Clone,
276 S: std::hash::BuildHasher,
277{
278 type Item = (&'a K, &'a V);
279
280 #[inline]
281 fn next(&mut self) -> Option<Self::Item> {
282 if self.index < self.map.len() {
283 unsafe {
284 let k = self.map.index_set.keys.get_unchecked(self.index);
285 let v = self.map.values.get_unchecked(self.index);
286 self.index += 1;
287 Some((k, v))
288 }
289 } else {
290 None
291 }
292 }
293
294 #[inline]
295 fn size_hint(&self) -> (usize, Option<usize>) {
296 let remaining = self.map.len() - self.index;
297 (remaining, Some(remaining))
298 }
299
300 #[inline]
301 fn nth(&mut self, n: usize) -> Option<Self::Item> {
302 self.index += n;
303 self.next()
304 }
305}
306
307pub enum EntryMut<'a, K, V, S> {
308 Occupied { key: K, value: &'a mut V, index: usize },
309 Vacant { key: K , map: &'a mut IndexMap<K, V, S> },
310}
311
312impl<'a, K, V, S> EntryMut<'a, K, V, S>
313where
314 K: Eq + std::hash::Hash + Clone,
315 S: std::hash::BuildHasher,
316{
317 #[inline]
318 pub fn is_occupied(&self) -> bool {
319 matches!(self, EntryMut::Occupied { .. })
320 }
321
322 #[inline]
323 pub fn or_insert_with<F>(self, value: F) -> &'a mut V
324 where
325 F: FnOnce() -> V,
326 K: Clone,
327 {
328 match self {
329 EntryMut::Occupied { value: v, .. } => v,
330 EntryMut::Vacant { key, map } => {
331 map.insert(key.clone(), value());
332 map.get_mut(&key).unwrap()
333 }
334 }
335 }
336}
337
338#[derive(Debug, PartialEq)]
339pub struct InsertResult<K, V> {
340 pub old_value: V,
341 pub old_key: K,
342}
343
344#[derive(Clone, Debug)]
345pub struct IndexSet<K, S = ahash::RandomState> {
346 keys: Vec<K>,
347 hashes: Vec<u64>,
348 table: HashTable<usize>,
349 hash_builder: S,
350}
351
352impl<K, S> IndexSet<K, S>
353where
354 K: Eq + std::hash::Hash + Clone,
355 S: std::hash::BuildHasher,
356{
357 pub fn with_hasher(hash_builder: S) -> Self {
358 IndexSet {
359 keys: Vec::new(),
360 hashes: Vec::new(),
361 table: HashTable::new(),
362 hash_builder,
363 }
364 }
365
366 pub fn new() -> Self
367 where
368 S: Default,
369 {
370 IndexSet {
371 keys: Vec::new(),
372 hashes: Vec::new(),
373 table: HashTable::new(),
374 hash_builder: S::default(),
375 }
376 }
377
378 pub fn with_capacity(capacity: usize) -> Self
379 where
380 S: Default,
381 {
382 IndexSet {
383 keys: Vec::with_capacity(capacity),
384 hashes: Vec::with_capacity(capacity),
385 table: HashTable::with_capacity(capacity),
386 hash_builder: S::default(),
387 }
388 }
389
390 pub fn with_hasher_capacity(hash_builder: S, capacity: usize) -> Self {
391 IndexSet {
392 keys: Vec::with_capacity(capacity),
393 hashes: Vec::with_capacity(capacity),
394 table: HashTable::with_capacity(capacity),
395 hash_builder,
396 }
397 }
398
399 #[inline]
401 fn hash_key<Q: ?Sized>(&self, key: &Q) -> u64
402 where
403 K: Borrow<Q>,
404 Q: std::hash::Hash + Eq,
405 {
406 let mut hasher = self.hash_builder.build_hasher();
407 key.hash(&mut hasher);
408 hasher.finish()
409 }
410
411 #[inline]
416 unsafe fn table_override<Q: ?Sized>(&mut self, key: &Q, idx: &usize) -> Option<usize>
417 where
418 K: Borrow<Q>,
419 Q: std::hash::Hash + Eq,
420 {
421 let hash = self.hash_key(key);
422 match self.table.find_entry(hash, |&i| self.keys[i].borrow() == key) {
423 Ok(mut occ) => {
424 *occ.get_mut() = *idx;
426 Some(*idx)
427 }
428 Err(_) => {
429 None
430 }
431 }
432 }
433
434 #[inline]
438 unsafe fn table_append<Q: ?Sized>(&mut self, key: &Q, idx: &usize)
439 where
440 K: Borrow<Q>,
441 Q: std::hash::Hash + Eq,
442 {
443 let hash = self.hash_key(key);
444 self.hashes.push(hash);
445 self.table.insert_unique(
446 hash,
447 *idx,
448 |&i| self.hashes[i]
449 );
450 }
451
452 #[inline]
455 fn table_get<Q: ?Sized>(&self, key: &Q) -> Option<usize>
456 where
457 K: Borrow<Q>,
458 Q: std::hash::Hash + Eq,
459 {
460 let hash = self.hash_key(key);
461 self.table.find(
462 hash,
463 |&i| self.keys[i].borrow() == key
464 ).copied()
465 }
466
467 #[inline]
471 unsafe fn table_swap_remove<Q: ?Sized>(&mut self, key: &Q) -> Option<usize>
472 where
473 K: Borrow<Q>,
474 Q: std::hash::Hash + Eq,
475 {
476 let hash = self.hash_key(key);
477 if let Ok(entry) = self.table.find_entry(
478 hash,
479 |&i| self.keys[i].borrow() == key
480 ) {
481 let (odl_idx, _) = entry.remove();
482 self.hashes.swap_remove(odl_idx);
483 Some(odl_idx)
484 } else {
485 None
486 }
487 }
488
489 #[inline]
490 pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
491 where
492 K: Borrow<Q>,
493 Q: std::hash::Hash + Eq,
494 {
495 self.table_get(key).is_some()
496 }
497
498 #[inline]
499 pub fn len(&self) -> usize {
500 self.keys.len()
501 }
502
503 #[inline]
504 pub fn get_index<Q: ?Sized>(&self, key: &Q) -> Option<usize>
505 where
506 K: Borrow<Q>,
507 Q: std::hash::Hash + Eq,
508 {
509 self.table_get(key)
510 }
511
512 #[inline]
513 pub fn iter(&self) -> std::slice::Iter<'_, K> {
514 self.keys.iter()
515 }
516
517 #[inline]
518 pub fn keys(&self) -> &Vec<K> {
519 &self.keys
520 }
521
522 #[inline]
523 pub fn get_with_index(&self, index: usize) -> Option<&K> {
524 self.keys.get(index)
525 }
526}
527
528
529
530#[cfg(test)]
531mod tests {
532 use super::*;
533 use std::collections::HashMap;
534
535 type M = IndexMap<u64, i64>;
537
538 fn assert_internal_invariants(map: &M) {
539 assert_eq!(map.values.len(), map.index_set.keys.len(), "values/keys len mismatch");
541 assert_eq!(map.values.len(), map.index_set.hashes.len(), "values/hashes len mismatch");
542
543 for (i, k) in map.index_set.keys.iter().enumerate() {
545 let idx = map.index_set.table_get(k).expect("table_get must find existing key");
546 assert_eq!(idx, i, "table idx mismatch for key");
547 }
548
549 for i in 0..map.len() {
552 let k = &map.index_set.keys[i];
553 assert!(map.contains_key(k), "contains_key false for existing key");
554 let v = map.get(k).expect("get must return for existing key");
555 assert_eq!(*v, map.values[i], "get value mismatch");
556 }
557
558 for i in 0..map.index_set.keys.len() {
561 for j in (i + 1)..map.index_set.keys.len() {
562 assert!(map.index_set.keys[i] != map.index_set.keys[j], "duplicate keys detected");
563 }
564 }
565 }
566
567 fn assert_equals_oracle(map: &M, oracle: &HashMap<u64, i64>) {
568 assert_eq!(map.len(), oracle.len(), "len mismatch");
569
570 for (k, v) in oracle.iter() {
572 let got = map.get(k).copied();
573 assert_eq!(got, Some(*v), "value mismatch for key={k}");
574 }
575
576 for (k, v) in map.iter() {
578 assert_eq!(oracle.get(k).copied(), Some(*v), "extra/mismatch entry key={k}");
579 }
580 }
581
582 #[test]
583 fn basic_insert_get_overwrite() {
584 let mut m = M::new();
585
586 assert_eq!(m.insert(1, 10), None);
587 assert_eq!(m.insert(2, 20), None);
588 assert_eq!(m.get(&1).copied(), Some(10));
589 assert_eq!(m.get(&2).copied(), Some(20));
590
591 let old = m.insert(1, 99).unwrap();
593 assert_eq!(old.old_key, 1);
594 assert_eq!(old.old_value, 10);
595 assert_eq!(m.get(&1).copied(), Some(99));
596
597 assert_internal_invariants(&m);
598 }
599
600 #[test]
601 fn swap_remove_last_and_middle() {
602 let mut m = M::new();
603 for i in 0..10 {
604 m.insert(i, (i as i64) * 10);
605 }
606
607 let v = m.swap_remove(&9);
609 assert_eq!(v, Some(90));
610 assert!(m.get(&9).is_none());
611
612 let v = m.swap_remove(&3);
614 assert_eq!(v, Some(30));
615 assert!(m.get(&3).is_none());
616
617 assert_internal_invariants(&m);
618 }
619
620 #[test]
621 fn entry_or_insert_with_works() {
622 let mut m = M::new();
623
624 let v = m.entry_mut(7).or_insert_with(|| 123);
625 assert_eq!(*v, 123);
626
627 let v2 = m.entry_mut(7).or_insert_with(|| 999);
629 assert_eq!(*v2, 123);
630
631 assert_internal_invariants(&m);
632 }
633
634 #[test]
635 fn compare_with_std_hashmap_small_scripted() {
636 let mut m = M::new();
637 let mut o = HashMap::<u64, i64>::new();
638
639 for i in 0..50u64 {
641 m.insert(i, i as i64);
642 o.insert(i, i as i64);
643 }
644
645 for i in 0..50u64 {
646 if i % 3 == 0 {
647 let a = m.swap_remove(&i);
648 let b = o.remove(&i);
649 assert_eq!(a, b);
650 }
651 }
652
653 for i in 0..50u64 {
654 if i % 5 == 0 {
655 m.insert(i, (i as i64) * 100);
656 o.insert(i, (i as i64) * 100);
657 }
658 }
659
660 assert_internal_invariants(&m);
661 assert_equals_oracle(&m, &o);
662 }
663
664 #[test]
665 fn randomized_ops_compare_with_oracle() {
666 use rand::{rngs::StdRng, Rng, SeedableRng};
667
668 let mut rng = StdRng::seed_from_u64(0xC0FFEE);
669 let mut m = M::new();
670 let mut o = HashMap::<u64, i64>::new();
671
672 const STEPS: usize = 30_000;
674 const KEY_SPACE: u64 = 2_000;
675
676 for _ in 0..STEPS {
677 let op = rng.gen_range(0..100);
678 let k = rng.gen_range(0..KEY_SPACE);
679 match op {
680 0..=59 => {
682 let v = rng.gen_range(-1_000_000..=1_000_000);
683 let a = m.insert(k, v);
684 let b = o.insert(k, v);
685
686 match (a, b) {
687 (None, None) => {}
688 (Some(ir), Some(old)) => {
689 assert_eq!(ir.old_key, k);
690 assert_eq!(ir.old_value, old);
691 }
692 _ => panic!("insert mismatch"),
693 }
694 }
695 60..=79 => {
697 let a = m.swap_remove(&k);
698 let b = o.remove(&k);
699 assert_eq!(a, b);
700 }
701 80..=94 => {
703 let a = m.get(&k).copied();
704 let b = o.get(&k).copied();
705 assert_eq!(a, b);
706 }
707 _ => {
709 let a = m.contains_key(&k);
710 let b = o.contains_key(&k);
711 assert_eq!(a, b);
712 }
713 }
714
715 if rng.gen_ratio(1, 200) {
717 assert_internal_invariants(&m);
718 assert_equals_oracle(&m, &o);
719 }
720 }
721
722 assert_internal_invariants(&m);
724 assert_equals_oracle(&m, &o);
725 }
726
727 #[test]
728 fn empty_map_basics() {
729 let m = M::new();
730
731 assert_eq!(m.len(), 0);
732 assert!(m.get(&123).is_none());
733 assert!(!m.contains_key(&123));
734 assert_eq!(m.values.len(), 0);
736 assert_eq!(m.index_set.keys.len(), 0);
737 assert_eq!(m.index_set.hashes.len(), 0);
738 }
739
740 #[test]
741 fn swap_remove_single_element_roundtrip() {
742 let mut m = M::new();
743 m.insert(42, -7);
744 assert_internal_invariants(&m);
745
746 let v = m.swap_remove(&42);
747 assert_eq!(v, Some(-7));
748 assert_eq!(m.len(), 0);
749 assert!(m.get(&42).is_none());
750 assert!(!m.contains_key(&42));
751
752 assert_internal_invariants(&m);
753 }
754
755 #[test]
756 fn remove_then_reinsert_same_key() {
757 let mut m = M::new();
758
759 m.insert(1, 10);
760 m.insert(2, 20);
761 m.insert(3, 30);
762 assert_internal_invariants(&m);
763
764 assert_eq!(m.swap_remove(&2), Some(20));
765 assert!(m.get(&2).is_none());
766 assert_internal_invariants(&m);
767
768 assert_eq!(m.insert(2, 200), None);
770 assert_eq!(m.get(&2).copied(), Some(200));
771 assert_internal_invariants(&m);
772 }
773
774 #[test]
775 fn from_kv_vec_builds_valid_map() {
776 let keys = vec![1u64, 2u64, 3u64, 10u64];
777 let values = vec![10i64, 20i64, 30i64, 100i64];
778
779 let m = M::from_kv_vec(keys.clone(), values.clone());
780 assert_eq!(m.len(), 4);
781
782 assert_eq!(m.index_set.keys, keys);
784 assert_eq!(m.values, values);
785
786 assert_internal_invariants(&m);
787 }
788
789 #[test]
790 fn iter_order_matches_internal_storage_even_after_removes() {
791 let mut m = M::new();
792 for i in 0..8u64 {
793 m.insert(i, (i as i64) + 100);
794 }
795 assert_internal_invariants(&m);
796
797 assert_eq!(m.swap_remove(&0), Some(100));
799 assert_eq!(m.swap_remove(&5), Some(105));
800 assert_internal_invariants(&m);
801
802 let collected: Vec<(u64, i64)> = m.iter().map(|(k, v)| (*k, *v)).collect();
803 let expected: Vec<(u64, i64)> = m.index_set.keys.iter().copied().zip(m.values.iter().copied()).collect();
804 assert_eq!(collected, expected);
805 }
806
807 #[test]
808 fn num_23257_issue() {
809 const ITER_NUM: u64 = 223259;
810 let mut map: IndexMap<u64, Vec<u64>> = IndexMap::new();
811 for i in 0..ITER_NUM {
812 map.entry_mut(0).or_insert_with(Vec::new).push(i);
813 }
814 assert_eq!(map.len(), 1);
815 assert_eq!(map.get(&0).unwrap().len() as u64, ITER_NUM);
816 }
817}