Skip to main content

tf_idf_vectorizer/utils/datastruct/map/
index_map.rs

1use hashbrown::HashTable;
2use std::borrow::Borrow;
3use std::fmt::Debug;
4use std::hash::Hasher;
5use std::iter::FusedIterator;
6
7/// IndexMap
8/// 連続領域を保証するHashMap
9/// 
10/// # Safety
11/// table, hashes は table_* メソッドが責任をもつこと 更新とか
12/// 
13/// O(1) operations for:
14/// - key -> value
15/// - key -> index
16/// - index -> key
17/// - index -> value
18/// - insert
19/// - swap_remove
20#[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            // K が Rc の場合を考慮して すべて差し替える
196            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            // New key, insert entry
208            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                // 最後の要素を削除する場合
245                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                    // keyとの整合性があるうちに削除予定のをtableから消す ここでhashesがswap_removeされる
257                    // last_idxの要素がswapで移動してくる
258                    self.index_set.table_swap_remove(key);
259                    // 移動させられた要素のtableを再登録
260                    // 登録されていた前のidxに対するkeyはまだ整合性が取れているので問題ない
261                    self.index_set.table_override(last_idx_key.borrow(), &idx);
262                }
263                // swap_remove ここで実際にtableのidxとvalues, keys, hashesの整合性が回復
264                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, // exclusive
300}
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        // n 個スキップ
333        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    /// hash util
495    #[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    /// override
507    /// 完全な整合性が必要
508    /// keyに対するidxを更新し、更新したidxを返す
509    /// 存在しない場合はNone
510    #[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                // idxの上書きだけ
520                *occ.get_mut() = *idx;
521                Some(*idx)
522            }
523            Err(_) => {
524                None
525            }
526        }
527    }
528
529    /// append
530    /// 完全な整合性が必要
531    /// hashesとtableを更新する
532    #[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    /// get
548    /// とくに注意なし 不可変参照なので
549    #[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    /// remove
563    /// 完全な整合性が必要
564    /// hashesはswap_removeされます
565    #[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    // まずは比較しやすい型でテスト
631    type M = IndexMap<u64, i64>;
632
633    fn assert_internal_invariants(map: &M) {
634        // 長さが揃っていること
635        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        // table_get が返す idx が範囲内で、keys/values と一致すること
639        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        // 逆方向も確認
645        // 重複キー禁止 + contains/get の整合
646        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        // キー重複が無いこと
654        // O(n^2) だけどユニットテストならOK
655        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        // 全キーが一致し、値も一致すること
666        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        // map 側に余計なキーがないこと(oracle で確認)
672        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        // last remove
685        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        // middle remove
694        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        // 2回目は既存参照が返る
713        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        // 混ぜた操作を固定シナリオで
725        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, // index はテストしない
738                });
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        // ある程度衝突や削除を踏む
762        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                // insert (多め)
770                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                // swap_remove
785                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, // index はテストしない
792                    });
793                }
794                // get
795                80..=94 => {
796                    let a = m.get(&k).copied();
797                    let b = o.get(&k).copied();
798                    assert_eq!(a, b);
799                }
800                // contains
801                _ => {
802                    let a = m.contains_key(&k);
803                    let b = o.contains_key(&k);
804                    assert_eq!(a, b);
805                }
806            }
807
808            // たまに内部整合をチェック(重いので間引く)
809            if rng.gen_ratio(1, 200) {
810                assert_internal_invariants(&m);
811                assert_equals_oracle(&m, &o);
812            }
813        }
814
815        // 最後に必ず一致
816        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        // 空でも長さ整合は成立
828        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        // 同じキーを再挿入しても table が壊れないこと
870        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        // 順序と内容が一致
884        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        // いくつか消して、内部順序が変わっても iter が keys/values と整合すること
899        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}