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