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