Skip to main content

commonware_storage/index/
mod.rs

1//! Memory-efficient index structures for mapping translated keys to values.
2//!
3//! # Multiple Values for a Key
4//!
5//! Keys are translated into a compressed, fixed-size representation using a `Translator`. Depending
6//! on the size of the representation, this can lead to a non-negligible number of collisions (even
7//! if the original keys are collision-free). To workaround this issue, `get` returns all values
8//! that map to the same translated key. If the same key is inserted multiple times (and old values
9//! are not `removed`), all values will be returned.
10//!
11//! # Warning
12//!
13//! If the `Translator` maps many keys to the same translated key, the performance of `Index` will
14//! degrade substantially (each conflicting key may contain the desired value).
15
16mod storage;
17
18pub mod ordered;
19pub mod partitioned;
20pub mod unordered;
21
22/// A mutable iterator over the values associated with a translated key, allowing in-place
23/// modifications.
24///
25/// The [Cursor] provides a way to traverse and modify the linked list of values associated with a
26/// translated key by an index while maintaining its structure. It supports:
27///
28/// - Iteration via `next()` to access values.
29/// - Modification via `update()` to change the current value.
30/// - Insertion via `insert()` to add new values.
31/// - Deletion via `delete()` to remove values.
32///
33/// # Safety
34///
35/// - Must call `next()` before `update()`, `insert()`, or `delete()` to establish a valid position.
36/// - Once `next()` returns `None`, only `insert()` can be called.
37/// - Dropping the `Cursor` automatically restores the list structure by reattaching any detached
38///   `next` nodes.
39///
40/// _If you don't need advanced functionality, just use `insert()`, `insert_and_prune()`, or
41/// `remove()` from [Unordered] instead._
42pub trait Cursor: Send + Sync {
43    /// The type of values the cursor iterates over.
44    type Value: Eq + Send + Sync;
45
46    /// Advances the cursor to the next value in the chain, returning a reference to it.
47    ///
48    /// This method must be called before any other operations (`insert()`, `delete()`, etc.). If
49    /// either `insert()` or `delete()` is called, `next()` must be called to set a new active item.
50    /// If after `insert()`, the next active item is the item after the inserted item. If after
51    /// `delete()`, the next active item is the item after the deleted item.
52    ///
53    /// Handles transitions between phases and adjusts for deletions. Returns `None` when the list
54    /// is exhausted. It is safe to call `next()` even after it returns `None`.
55    #[allow(clippy::should_implement_trait)]
56    fn next(&mut self) -> Option<&Self::Value>;
57
58    /// Inserts a new value at the current position.
59    fn insert(&mut self, value: Self::Value);
60
61    /// Deletes the current value, adjusting the list structure.
62    fn delete(&mut self);
63
64    /// Updates the value at the current position in the iteration.
65    ///
66    /// Panics if called before `next()` or after iteration is complete (`Status::Done` phase).
67    fn update(&mut self, value: Self::Value);
68
69    /// Removes anything in the cursor that satisfies the predicate.
70    fn prune(&mut self, predicate: &impl Fn(&Self::Value) -> bool);
71
72    /// Advances the cursor until finding a value matching the predicate.
73    ///
74    /// Returns `true` if a matching value is found, with the cursor positioned at that element.
75    /// Returns `false` if no match is found and the cursor is exhausted.
76    ///
77    /// After a successful find (returning `true`), the cursor is positioned at the found element,
78    /// allowing operations like `update()` or `delete()` to be called on it without requiring
79    /// another call to `next()`.
80    ///
81    /// This method follows similar semantics to `Iterator::find`, consuming items until a match is
82    /// found or the iterator is exhausted.
83    ///
84    /// # Examples
85    ///
86    /// ```ignore
87    /// let mut cursor = index.get_mut(&key)?;
88    /// if cursor.find(|&value| value == 42) {
89    ///     // Cursor is positioned at the element with value 42
90    ///     cursor.update(100); // Update it to 100
91    /// }
92    /// ```
93    fn find(&mut self, predicate: impl Fn(&Self::Value) -> bool) -> bool {
94        loop {
95            match self.next() {
96                Some(value) if predicate(value) => return true,
97                Some(_) => continue,
98                None => return false,
99            }
100        }
101    }
102}
103
104/// A trait defining the operations provided by a memory-efficient index that maps translated keys
105/// to arbitrary values, with no ordering assumed over the key space.
106pub trait Unordered: Send + Sync {
107    /// The type of values the index stores.
108    type Value: Eq + Send + Sync;
109
110    /// The type of cursor returned by this index to iterate over values with conflicting keys.
111    type Cursor<'a>: Cursor<Value = Self::Value>
112    where
113        Self: 'a;
114
115    /// Returns an iterator over all values associated with a translated key.
116    fn get<'a>(&'a self, key: &[u8]) -> impl Iterator<Item = &'a Self::Value> + Send + 'a
117    where
118        Self::Value: 'a;
119
120    /// Provides mutable access to the values associated with a translated key, if the key exists.
121    fn get_mut<'a>(&'a mut self, key: &[u8]) -> Option<Self::Cursor<'a>>;
122
123    /// Provides mutable access to the values associated with a translated key (if the key exists),
124    /// otherwise inserts a new value and returns `None`.
125    fn get_mut_or_insert<'a>(
126        &'a mut self,
127        key: &[u8],
128        value: Self::Value,
129    ) -> Option<Self::Cursor<'a>>;
130
131    /// Inserts a new value at the current position.
132    fn insert(&mut self, key: &[u8], value: Self::Value);
133
134    /// Insert a value at the given translated key, and prune any values that are no longer valid.
135    ///
136    /// If the value is prunable, it will not be inserted.
137    fn insert_and_prune(
138        &mut self,
139        key: &[u8],
140        value: Self::Value,
141        predicate: impl Fn(&Self::Value) -> bool,
142    );
143
144    /// Remove all values associated with a translated key that match `predicate`.
145    fn prune(&mut self, key: &[u8], predicate: impl Fn(&Self::Value) -> bool);
146
147    /// Remove all values associated with a translated key.
148    fn remove(&mut self, key: &[u8]);
149
150    /// Returns the number of translated keys in the index.
151    #[cfg(test)]
152    fn keys(&self) -> usize;
153
154    /// Returns the number of items in the index, for use in testing. The number of items is always
155    /// at least as large as the number of keys, but may be larger in the case of collisions.
156    #[cfg(test)]
157    fn items(&self) -> usize;
158
159    /// Returns the total number of items pruned from the index, for use in testing.
160    #[cfg(test)]
161    fn pruned(&self) -> usize;
162}
163
164/// A trait defining the additional operations provided by a memory-efficient index that allows
165/// ordered traversal of the indexed keys.
166pub trait Ordered: Unordered + Send + Sync {
167    type Iterator<'a>: Iterator<Item = &'a Self::Value> + Send
168    where
169        Self: 'a;
170
171    // Returns an iterator over all values associated with a translated key that lexicographically
172    // precedes the result of translating `key`. The implementation will cycle around to the last
173    // translated key if `key` is less than or equal to the first translated key. The returned
174    // boolean indicates whether the result is from cycling. Returns None if there are no keys in
175    // the index.
176    fn prev_translated_key<'a>(&'a self, key: &[u8]) -> Option<(Self::Iterator<'a>, bool)>
177    where
178        Self::Value: 'a;
179
180    // Returns an iterator over all values associated with a translated key that lexicographically
181    // follows the result of translating `key`. The implementation will cycle around to the first
182    // translated key if `key` is greater than or equal to the last translated key. The returned
183    // boolean indicates whether the result is from cycling. Returns None if there are no keys in
184    // the index.
185    ///
186    /// For example, if the translator is looking only at the first byte of a key, and the index
187    /// contains values for translated keys 0b, 1c, and 2d, then `get_next([0b, 01, 02, ...])` would
188    /// return the values associated with 1c, `get_next([2a, 01, 02, ...])` would return the values
189    /// associated with 2d, and `get_next([2d])` would "cycle around" to the values associated with
190    /// 0b, returning true for the bool. Because values associated with the same translated key can
191    /// appear in any order, keys with the same first byte in this example would need to be ordered
192    /// by the caller if a full ordering over the untranslated keyspace is desired.
193    fn next_translated_key<'a>(&'a self, key: &[u8]) -> Option<(Self::Iterator<'a>, bool)>
194    where
195        Self::Value: 'a;
196
197    // Returns an iterator over all values associated with the lexicographically first translated
198    // key, or None if there are no keys in the index.
199    fn first_translated_key<'a>(&'a self) -> Option<Self::Iterator<'a>>
200    where
201        Self::Value: 'a;
202
203    // Returns an iterator over all values associated with the lexicographically last translated
204    // key, or None if there are no keys in the index.
205    fn last_translated_key<'a>(&'a self) -> Option<Self::Iterator<'a>>
206    where
207        Self::Value: 'a;
208}
209
210#[cfg(test)]
211mod tests {
212    use super::*;
213    use crate::{
214        index::partitioned::{
215            ordered::Index as PartitionedOrdered, unordered::Index as PartitionedUnordered,
216        },
217        translator::{OneCap, TwoCap},
218    };
219    use commonware_macros::test_traced;
220    use commonware_runtime::{deterministic, Metrics, Runner};
221    use rand::Rng;
222    use std::{
223        collections::HashMap,
224        sync::{Arc, Mutex},
225        thread,
226    };
227
228    fn run_index_basic<I: Unordered<Value = u64>>(index: &mut I) {
229        // Generate a collision and check metrics to make sure it's captured
230        let key = b"duplicate".as_slice();
231        index.insert(key, 1);
232        index.insert(key, 2);
233        index.insert(key, 3);
234        assert_eq!(index.keys(), 1);
235
236        // Check that the values are in the correct order
237        assert_eq!(index.get(key).copied().collect::<Vec<_>>(), vec![1, 3, 2]);
238
239        // Ensure cursor terminates
240        {
241            let mut cursor = index.get_mut(key).unwrap();
242            assert_eq!(*cursor.next().unwrap(), 1);
243            assert_eq!(*cursor.next().unwrap(), 3);
244            assert_eq!(*cursor.next().unwrap(), 2);
245            assert!(cursor.next().is_none());
246        }
247
248        // Make sure we can remove keys with a predicate
249        index.insert(key, 3);
250        index.insert(key, 4);
251        index.prune(key, |i| *i == 3);
252        assert_eq!(index.get(key).copied().collect::<Vec<_>>(), vec![1, 4, 2]);
253        index.prune(key, |_| true);
254        // Try removing all of a keys values.
255        assert_eq!(
256            index.get(key).copied().collect::<Vec<_>>(),
257            Vec::<u64>::new()
258        );
259        assert_eq!(index.keys(), 0);
260
261        assert!(index.get_mut(key).is_none());
262
263        // Removing a key that doesn't exist should be a no-op.
264        index.prune(key, |_| true);
265    }
266
267    fn new_unordered(context: deterministic::Context) -> unordered::Index<TwoCap, u64> {
268        unordered::Index::new(context, TwoCap)
269    }
270
271    fn new_ordered(context: deterministic::Context) -> ordered::Index<TwoCap, u64> {
272        ordered::Index::new(context, TwoCap)
273    }
274
275    fn new_partitioned_unordered(
276        context: deterministic::Context,
277    ) -> PartitionedUnordered<OneCap, u64, 1> {
278        // A one byte prefix and a OneCap translator yields behavior that matches TwoCap translator
279        // on an un-partitioned index.
280        PartitionedUnordered::new(context, OneCap)
281    }
282
283    fn new_partitioned_ordered(
284        context: deterministic::Context,
285    ) -> PartitionedOrdered<OneCap, u64, 1> {
286        // Same translator choice as the unordered variant to keep collision behavior consistent.
287        PartitionedOrdered::new(context, OneCap)
288    }
289
290    #[test_traced]
291    fn test_hash_index_basic() {
292        let runner = deterministic::Runner::default();
293        runner.start(|context| async move {
294            let mut index = new_unordered(context);
295            assert_eq!(index.keys(), 0);
296            run_index_basic(&mut index);
297            assert_eq!(index.keys(), 0);
298        });
299    }
300
301    #[test_traced]
302    fn test_ordered_index_basic() {
303        let runner = deterministic::Runner::default();
304        runner.start(|context| async move {
305            let mut index = new_ordered(context);
306            assert_eq!(index.keys(), 0);
307            run_index_basic(&mut index);
308            assert_eq!(index.keys(), 0);
309        });
310    }
311
312    #[test_traced]
313    fn test_partitioned_index_basic() {
314        let runner = deterministic::Runner::default();
315        runner.start(|context| async move {
316            {
317                let mut index = new_partitioned_unordered(context.with_label("unordered"));
318                assert_eq!(index.keys(), 0);
319                run_index_basic(&mut index);
320                assert_eq!(index.keys(), 0);
321            }
322            {
323                let mut index = new_partitioned_ordered(context.with_label("ordered"));
324                assert_eq!(index.keys(), 0);
325                run_index_basic(&mut index);
326                assert_eq!(index.keys(), 0);
327            }
328        });
329    }
330
331    fn run_index_cursor_find<I: Unordered<Value = u64>>(index: &mut I) {
332        let key = b"test_key";
333
334        // Insert multiple values with collisions
335        index.insert(key, 10);
336        index.insert(key, 20);
337        index.insert(key, 30);
338        index.insert(key, 40);
339
340        // Test finding an element that exists
341        {
342            let mut cursor = index.get_mut(key).unwrap();
343            assert!(cursor.find(|&v| v == 30));
344            // Cursor should be positioned at 30, so we can update it
345            cursor.update(35);
346        }
347
348        // Verify the update worked
349        let values: Vec<u64> = index.get(key).copied().collect();
350        assert!(values.contains(&35));
351        assert!(!values.contains(&30));
352
353        // Test finding an element that doesn't exist
354        {
355            let mut cursor = index.get_mut(key).unwrap();
356            assert!(!cursor.find(|&v| v == 100));
357            // Cursor should be exhausted, so next() returns None
358            assert!(cursor.next().is_none());
359        }
360
361        // Test finding and deleting
362        {
363            let mut cursor = index.get_mut(key).unwrap();
364            assert!(cursor.find(|&v| v == 20));
365            cursor.delete();
366        }
367
368        // Verify the delete worked
369        let values: Vec<u64> = index.get(key).copied().collect();
370        assert!(!values.contains(&20));
371        assert_eq!(values.len(), 3); // 10, 35, 40
372    }
373
374    #[test_traced]
375    fn test_unordered_index_cursor_find() {
376        let runner = deterministic::Runner::default();
377        runner.start(|context| async move {
378            let mut index = new_unordered(context);
379            run_index_cursor_find(&mut index);
380        });
381    }
382
383    #[test_traced]
384    fn test_ordered_index_cursor_find() {
385        let runner = deterministic::Runner::default();
386        runner.start(|context| async move {
387            let mut index = new_ordered(context);
388            run_index_cursor_find(&mut index);
389        });
390    }
391
392    #[test_traced]
393    fn test_partitioned_index_cursor_find() {
394        let runner = deterministic::Runner::default();
395        runner.start(|context| async move {
396            {
397                let mut index = new_partitioned_unordered(context.with_label("unordered"));
398                run_index_cursor_find(&mut index);
399            }
400            {
401                let mut index = new_partitioned_ordered(context.with_label("ordered"));
402                run_index_cursor_find(&mut index);
403            }
404        });
405    }
406
407    fn run_index_many_keys<I: Unordered<Value = u64>>(
408        index: &mut I,
409        mut fill: impl FnMut(&mut [u8]),
410    ) {
411        let mut expected = HashMap::new();
412        const NUM_KEYS: usize = 2000;
413        while expected.len() < NUM_KEYS {
414            let mut key_array = [0u8; 32];
415            fill(&mut key_array);
416            let key = key_array.to_vec();
417
418            let loc = expected.len() as u64;
419            index.insert(&key, loc);
420            expected.insert(key, loc);
421        }
422        assert_eq!(index.keys(), 1975);
423        assert_eq!(index.items(), 2000);
424
425        for (key, loc) in expected.iter() {
426            let mut values = index.get(key);
427            let res = values.find(|i| *i == loc);
428            assert!(res.is_some());
429        }
430    }
431
432    #[test_traced]
433    fn test_hash_index_many_keys() {
434        let runner = deterministic::Runner::default();
435        runner.start(|mut context| async move {
436            let mut index = new_unordered(context.clone());
437            run_index_many_keys(&mut index, |bytes| context.fill(bytes));
438        });
439    }
440
441    #[test_traced]
442    fn test_ordered_index_many_keys() {
443        let runner = deterministic::Runner::default();
444        runner.start(|mut context| async move {
445            let mut index = new_ordered(context.clone());
446            run_index_many_keys(&mut index, |bytes| context.fill(bytes));
447        });
448    }
449
450    #[test_traced]
451    fn test_partitioned_index_many_keys() {
452        let runner = deterministic::Runner::default();
453        runner.start(|mut context| async move {
454            {
455                let mut index = new_partitioned_unordered(context.with_label("unordered"));
456                run_index_many_keys(&mut index, |bytes| context.fill(bytes));
457            }
458        });
459
460        // Since we use context's random byte generator we need to run the two variants from the
461        // same initial context state to ensure the expected identical outcome.
462        let runner = deterministic::Runner::default();
463        runner.start(|mut context| async move {
464            let mut index = new_partitioned_ordered(context.clone());
465            run_index_many_keys(&mut index, |bytes| context.fill(bytes));
466        });
467    }
468
469    fn run_index_key_lengths_and_metrics<I: Unordered<Value = u64>>(index: &mut I) {
470        index.insert(b"a", 1);
471        index.insert(b"ab", 2);
472        index.insert(b"abc", 3);
473
474        assert_eq!(index.get(b"ab").copied().collect::<Vec<_>>(), vec![2, 3]);
475        assert_eq!(index.get(b"abc").copied().collect::<Vec<_>>(), vec![2, 3]);
476
477        index.insert(b"ab", 4);
478        assert_eq!(index.get(b"ab").copied().collect::<Vec<_>>(), vec![2, 4, 3]);
479        assert_eq!(index.keys(), 2);
480        assert_eq!(index.items(), 4);
481
482        index.prune(b"ab", |v| *v == 4);
483        assert_eq!(index.get(b"ab").copied().collect::<Vec<_>>(), vec![2, 3]);
484        assert_eq!(index.keys(), 2);
485        assert_eq!(index.items(), 3);
486
487        index.prune(b"ab", |_| true);
488        assert_eq!(
489            index.get(b"ab").copied().collect::<Vec<_>>(),
490            Vec::<u64>::new()
491        );
492        assert_eq!(index.keys(), 1);
493        assert_eq!(index.items(), 1);
494        assert_eq!(index.get(b"a").copied().collect::<Vec<_>>(), vec![1]);
495    }
496
497    #[test_traced]
498    fn test_hash_index_key_lengths_and_key_item_metrics() {
499        let runner = deterministic::Runner::default();
500        runner.start(|context| async move {
501            let mut index = new_unordered(context);
502            run_index_key_lengths_and_metrics(&mut index);
503        });
504    }
505
506    #[test_traced]
507    fn test_ordered_index_key_lengths_and_key_item_metrics() {
508        let runner = deterministic::Runner::default();
509        runner.start(|context| async move {
510            let mut index = new_ordered(context);
511            run_index_key_lengths_and_metrics(&mut index);
512        });
513    }
514
515    #[test_traced]
516    fn test_partitioned_index_key_lengths_and_key_item_metrics() {
517        let runner = deterministic::Runner::default();
518        runner.start(|context| async move {
519            {
520                let mut index = new_partitioned_unordered(context.with_label("unordered"));
521                run_index_key_lengths_and_metrics(&mut index);
522            }
523            {
524                let mut index = new_partitioned_ordered(context.with_label("ordered"));
525                run_index_key_lengths_and_metrics(&mut index);
526            }
527        });
528    }
529
530    fn run_index_value_order<I: Unordered<Value = u64>>(index: &mut I) {
531        index.insert(b"key", 1);
532        index.insert(b"key", 2);
533        index.insert(b"key", 3);
534        assert_eq!(
535            index.get(b"key").copied().collect::<Vec<_>>(),
536            vec![1, 3, 2]
537        );
538    }
539
540    #[test_traced]
541    fn test_hash_index_value_order() {
542        let runner = deterministic::Runner::default();
543        runner.start(|context| async move {
544            let mut index = new_unordered(context);
545            run_index_value_order(&mut index);
546        });
547    }
548
549    #[test_traced]
550    fn test_ordered_index_value_order() {
551        let runner = deterministic::Runner::default();
552        runner.start(|context| async move {
553            let mut index = new_ordered(context);
554            run_index_value_order(&mut index);
555        });
556    }
557
558    #[test_traced]
559    fn test_partitioned_index_value_order() {
560        let runner = deterministic::Runner::default();
561        runner.start(|context| async move {
562            {
563                let mut index = new_partitioned_unordered(context.with_label("unordered"));
564                run_index_value_order(&mut index);
565            }
566            {
567                let mut index = new_partitioned_ordered(context.with_label("ordered"));
568                run_index_value_order(&mut index);
569            }
570        });
571    }
572
573    fn run_index_remove_specific<I: Unordered<Value = u64>>(index: &mut I) {
574        index.insert(b"key", 1);
575        index.insert(b"key", 2);
576        index.insert(b"key", 3);
577        index.prune(b"key", |v| *v == 2);
578        assert_eq!(index.get(b"key").copied().collect::<Vec<_>>(), vec![1, 3]);
579        index.prune(b"key", |v| *v == 1);
580        assert_eq!(index.get(b"key").copied().collect::<Vec<_>>(), vec![3]);
581    }
582
583    #[test_traced]
584    fn test_hash_index_remove_specific() {
585        let runner = deterministic::Runner::default();
586        runner.start(|context| async move {
587            let mut index = new_unordered(context);
588            run_index_remove_specific(&mut index);
589        });
590    }
591
592    #[test_traced]
593    fn test_ordered_index_remove_specific() {
594        let runner = deterministic::Runner::default();
595        runner.start(|context| async move {
596            let mut index = new_ordered(context);
597            run_index_remove_specific(&mut index);
598        });
599    }
600
601    #[test_traced]
602    fn test_partitioned_index_remove_specific() {
603        let runner = deterministic::Runner::default();
604        runner.start(|context| async move {
605            {
606                let mut index = new_partitioned_unordered(context.with_label("unordered"));
607                run_index_remove_specific(&mut index);
608            }
609            {
610                let mut index = new_partitioned_ordered(context.with_label("ordered"));
611                run_index_remove_specific(&mut index);
612            }
613        });
614    }
615
616    fn run_index_empty_key<I: Unordered<Value = u64>>(index: &mut I) {
617        index.insert(b"", 0);
618        index.insert(b"\0", 1);
619        index.insert(b"\0\0", 2);
620
621        let mut values = index.get(b"").copied().collect::<Vec<_>>();
622        values.sort();
623        assert_eq!(values, vec![0, 1, 2]);
624        let mut values = index.get(b"\0").copied().collect::<Vec<_>>();
625        values.sort();
626        assert_eq!(values, vec![0, 1, 2]);
627        let mut values = index.get(b"\0\0").copied().collect::<Vec<_>>();
628        values.sort();
629        assert_eq!(values, vec![0, 1, 2]);
630
631        index.prune(b"", |v| *v == 1);
632        let mut values = index.get(b"").copied().collect::<Vec<_>>();
633        values.sort();
634        assert_eq!(values, vec![0, 2]);
635    }
636
637    #[test_traced]
638    fn test_hash_index_empty_key() {
639        let runner = deterministic::Runner::default();
640        runner.start(|context| async move {
641            let mut index = new_unordered(context);
642            run_index_empty_key(&mut index);
643        });
644    }
645
646    #[test_traced]
647    fn test_ordered_index_empty_key() {
648        let runner = deterministic::Runner::default();
649        runner.start(|context| async move {
650            let mut index = new_ordered(context);
651            run_index_empty_key(&mut index);
652        });
653    }
654
655    #[test_traced]
656    fn test_partitioned_index_empty_key() {
657        let runner = deterministic::Runner::default();
658        runner.start(|context| async move {
659            {
660                let mut index = new_partitioned_unordered(context.with_label("unordered"));
661                run_index_empty_key(&mut index);
662            }
663            {
664                let mut index = new_partitioned_ordered(context.with_label("ordered"));
665                run_index_empty_key(&mut index);
666            }
667        });
668    }
669
670    fn run_index_mutate_through_iterator<I: Unordered<Value = u64>>(index: &mut I) {
671        index.insert(b"key", 1);
672        index.insert(b"key", 2);
673        index.insert(b"key", 3);
674        {
675            let mut cursor = index.get_mut(b"key").unwrap();
676            while let Some(old) = cursor.next().copied() {
677                cursor.update(old + 10);
678            }
679        }
680        assert_eq!(
681            index.get(b"key").copied().collect::<Vec<_>>(),
682            vec![11, 13, 12]
683        );
684    }
685
686    #[test_traced]
687    fn test_hash_index_mutate_through_iterator() {
688        let runner = deterministic::Runner::default();
689        runner.start(|context| async move {
690            let mut index = new_unordered(context);
691            run_index_mutate_through_iterator(&mut index);
692        });
693    }
694
695    #[test_traced]
696    fn test_ordered_index_mutate_through_index() {
697        let runner = deterministic::Runner::default();
698        runner.start(|context| async move {
699            let mut index = new_ordered(context);
700            run_index_mutate_through_iterator(&mut index);
701        });
702    }
703
704    #[test_traced]
705    fn test_partitioned_index_mutate_through_iterator() {
706        let runner = deterministic::Runner::default();
707        runner.start(|context| async move {
708            {
709                let mut index = new_partitioned_unordered(context.with_label("unordered"));
710                run_index_mutate_through_iterator(&mut index);
711            }
712            {
713                let mut index = new_partitioned_ordered(context.with_label("ordered"));
714                run_index_mutate_through_iterator(&mut index);
715            }
716        });
717    }
718
719    fn run_index_mutate_middle_of_four<I: Unordered<Value = u64>>(index: &mut I) {
720        index.insert(b"key", 1);
721        index.insert(b"key", 2);
722        index.insert(b"key", 3);
723        index.insert(b"key", 4);
724        assert_eq!(
725            index.get(b"key").copied().collect::<Vec<_>>(),
726            vec![1, 4, 3, 2]
727        );
728        {
729            let mut cursor = index.get_mut(b"key").unwrap();
730            assert_eq!(*cursor.next().unwrap(), 1);
731            assert_eq!(*cursor.next().unwrap(), 4);
732            let _ = cursor.next().unwrap();
733            cursor.update(99);
734        }
735        assert_eq!(
736            index.get(b"key").copied().collect::<Vec<_>>(),
737            vec![1, 4, 99, 2]
738        );
739    }
740
741    #[test_traced]
742    fn test_hash_index_mutate_middle_of_four() {
743        let runner = deterministic::Runner::default();
744        runner.start(|context| async move {
745            let mut index = new_unordered(context);
746            run_index_mutate_middle_of_four(&mut index);
747        });
748    }
749
750    #[test_traced]
751    fn test_ordered_index_mutate_middle_of_four() {
752        let runner = deterministic::Runner::default();
753        runner.start(|context| async move {
754            let mut index = new_ordered(context);
755            run_index_mutate_middle_of_four(&mut index);
756        });
757    }
758
759    #[test_traced]
760    fn test_partitioned_index_mutate_middle_of_four() {
761        let runner = deterministic::Runner::default();
762        runner.start(|context| async move {
763            {
764                let mut index = new_partitioned_unordered(context.with_label("unordered"));
765                run_index_mutate_middle_of_four(&mut index);
766            }
767            {
768                let mut index = new_partitioned_ordered(context.with_label("ordered"));
769                run_index_mutate_middle_of_four(&mut index);
770            }
771        });
772    }
773
774    fn run_index_remove_through_iterator<I: Unordered<Value = u64>>(index: &mut I) {
775        index.insert(b"key", 1);
776        index.insert(b"key", 2);
777        index.insert(b"key", 3);
778        index.insert(b"key", 4);
779        assert_eq!(
780            index.get(b"key").copied().collect::<Vec<_>>(),
781            vec![1, 4, 3, 2]
782        );
783        assert_eq!(index.pruned(), 0);
784        {
785            let mut cursor = index.get_mut(b"key").unwrap();
786            assert_eq!(*cursor.next().unwrap(), 1);
787            cursor.delete();
788        }
789        assert_eq!(index.pruned(), 1);
790        assert_eq!(
791            index.get(b"key").copied().collect::<Vec<_>>(),
792            vec![4, 3, 2]
793        );
794        index.insert(b"key", 1);
795        assert_eq!(
796            index.get(b"key").copied().collect::<Vec<_>>(),
797            vec![4, 1, 3, 2]
798        );
799        {
800            let mut cursor = index.get_mut(b"key").unwrap();
801            assert_eq!(*cursor.next().unwrap(), 4);
802            assert_eq!(*cursor.next().unwrap(), 1);
803            assert_eq!(*cursor.next().unwrap(), 3);
804            cursor.delete();
805        }
806        assert_eq!(index.pruned(), 2);
807        assert_eq!(
808            index.get(b"key").copied().collect::<Vec<_>>(),
809            vec![4, 1, 2]
810        );
811        index.insert(b"key", 3);
812        assert_eq!(
813            index.get(b"key").copied().collect::<Vec<_>>(),
814            vec![4, 3, 1, 2]
815        );
816        {
817            let mut cursor = index.get_mut(b"key").unwrap();
818            assert_eq!(*cursor.next().unwrap(), 4);
819            assert_eq!(*cursor.next().unwrap(), 3);
820            assert_eq!(*cursor.next().unwrap(), 1);
821            assert_eq!(*cursor.next().unwrap(), 2);
822            cursor.delete();
823        }
824        assert_eq!(index.pruned(), 3);
825        assert_eq!(
826            index.get(b"key").copied().collect::<Vec<_>>(),
827            vec![4, 3, 1]
828        );
829        index.remove(b"key");
830        assert_eq!(index.keys(), 0);
831        assert_eq!(index.items(), 0);
832        assert_eq!(index.pruned(), 6);
833    }
834
835    #[test_traced]
836    fn test_hash_index_remove_through_iterator() {
837        let runner = deterministic::Runner::default();
838        runner.start(|context| async move {
839            let mut index = new_unordered(context);
840            run_index_remove_through_iterator(&mut index);
841        });
842    }
843
844    #[test_traced]
845    fn test_ordered_index_remove_through_iterator() {
846        let runner = deterministic::Runner::default();
847        runner.start(|context| async move {
848            let mut index = new_ordered(context);
849            run_index_remove_through_iterator(&mut index);
850        });
851    }
852
853    #[test_traced]
854    fn test_partitioned_index_remove_through_iterator() {
855        let runner = deterministic::Runner::default();
856        runner.start(|context| async move {
857            {
858                let mut index = new_partitioned_unordered(context.with_label("unordered"));
859                run_index_remove_through_iterator(&mut index);
860            }
861            {
862                let mut index = new_partitioned_ordered(context.with_label("ordered"));
863                run_index_remove_through_iterator(&mut index);
864            }
865        });
866    }
867    fn run_index_insert_through_iterator<I: Unordered<Value = u64>>(index: &mut I)
868    where
869        I::Value: PartialEq<u64> + Eq,
870    {
871        index.insert(b"key", 1);
872        {
873            let mut cursor = index.get_mut(b"key").unwrap();
874            assert_eq!(*cursor.next().unwrap(), 1);
875            cursor.insert(3);
876        }
877        assert_eq!(index.get(b"key").copied().collect::<Vec<_>>(), vec![1, 3]);
878        assert_eq!(index.keys(), 1);
879        assert_eq!(index.items(), 2);
880        {
881            let mut cursor = index.get_mut(b"key").unwrap();
882            assert_eq!(*cursor.next().unwrap(), 1);
883            cursor.insert(42);
884        }
885        assert_eq!(index.keys(), 1);
886        assert_eq!(index.items(), 3);
887        {
888            let mut iter = index.get(b"key");
889            assert_eq!(*iter.next().unwrap(), 1);
890            assert_eq!(*iter.next().unwrap(), 42);
891        }
892        index.insert(b"key", 100);
893        let mut iter = index.get(b"key");
894        assert_eq!(*iter.next().unwrap(), 1);
895        assert_eq!(*iter.next().unwrap(), 100);
896        assert_eq!(*iter.next().unwrap(), 42);
897        assert_eq!(*iter.next().unwrap(), 3);
898        assert!(iter.next().is_none());
899    }
900
901    #[test_traced]
902    fn test_hash_index_insert_through_iterator() {
903        let runner = deterministic::Runner::default();
904        runner.start(|context| async move {
905            let mut index = new_unordered(context);
906            run_index_insert_through_iterator(&mut index);
907        });
908    }
909
910    #[test_traced]
911    fn test_ordered_index_insert_through_iterator() {
912        let runner = deterministic::Runner::default();
913        runner.start(|context| async move {
914            let mut index = new_ordered(context);
915            run_index_insert_through_iterator(&mut index);
916        });
917    }
918
919    #[test_traced]
920    fn test_partitioned_index_insert_through_iterator() {
921        let runner = deterministic::Runner::default();
922        runner.start(|context| async move {
923            {
924                let mut index = new_partitioned_unordered(context.with_label("unordered"));
925                run_index_insert_through_iterator(&mut index);
926            }
927            {
928                let mut index = new_partitioned_ordered(context.with_label("ordered"));
929                run_index_insert_through_iterator(&mut index);
930            }
931        });
932    }
933
934    fn run_index_cursor_insert_after_done_appends<I: Unordered<Value = u64>>(index: &mut I) {
935        index.insert(b"key", 10);
936        {
937            let mut cursor = index.get_mut(b"key").unwrap();
938            assert_eq!(*cursor.next().unwrap(), 10);
939            assert!(cursor.next().is_none());
940            cursor.insert(20);
941        }
942        assert_eq!(index.get(b"key").copied().collect::<Vec<_>>(), vec![10, 20]);
943    }
944
945    #[test_traced]
946    fn test_hash_index_cursor_insert_after_done_appends() {
947        let runner = deterministic::Runner::default();
948        runner.start(|context| async move {
949            let mut index = new_unordered(context);
950            run_index_cursor_insert_after_done_appends(&mut index);
951        });
952    }
953
954    #[test_traced]
955    fn test_ordered_index_cursor_insert_after_done_appends() {
956        let runner = deterministic::Runner::default();
957        runner.start(|context| async move {
958            let mut index = new_ordered(context);
959            run_index_cursor_insert_after_done_appends(&mut index);
960        });
961    }
962
963    #[test_traced]
964    fn test_partitioned_index_cursor_insert_after_done_appends() {
965        let runner = deterministic::Runner::default();
966        runner.start(|context| async move {
967            {
968                let mut index = new_partitioned_unordered(context.with_label("unordered"));
969                run_index_cursor_insert_after_done_appends(&mut index);
970            }
971            {
972                let mut index = new_partitioned_ordered(context.with_label("ordered"));
973                run_index_cursor_insert_after_done_appends(&mut index);
974            }
975        });
976    }
977
978    fn run_index_remove_to_nothing_then_add<I: Unordered<Value = u64>>(index: &mut I) {
979        for i in 0..4 {
980            index.insert(b"key", i);
981        }
982        {
983            let mut cursor = index.get_mut(b"key").unwrap();
984            assert_eq!(*cursor.next().unwrap(), 0);
985            cursor.delete();
986            assert_eq!(*cursor.next().unwrap(), 3);
987            cursor.delete();
988            assert_eq!(*cursor.next().unwrap(), 2);
989            cursor.delete();
990            assert_eq!(*cursor.next().unwrap(), 1);
991            cursor.delete();
992            assert_eq!(cursor.next(), None);
993            cursor.insert(4);
994            assert_eq!(cursor.next(), None);
995            cursor.insert(5);
996        }
997        assert_eq!(index.get(b"key").copied().collect::<Vec<_>>(), vec![4, 5]);
998    }
999
1000    #[test_traced]
1001    fn test_hash_index_remove_to_nothing_then_add() {
1002        let runner = deterministic::Runner::default();
1003        runner.start(|context| async move {
1004            let mut index = new_unordered(context);
1005            run_index_remove_to_nothing_then_add(&mut index);
1006        });
1007    }
1008
1009    #[test_traced]
1010    fn test_ordered_index_remove_to_nothing_then_add() {
1011        let runner = deterministic::Runner::default();
1012        runner.start(|context| async move {
1013            let mut index = new_ordered(context);
1014            run_index_remove_to_nothing_then_add(&mut index);
1015        });
1016    }
1017
1018    #[test_traced]
1019    fn test_partitioned_index_remove_to_nothing_then_add() {
1020        let runner = deterministic::Runner::default();
1021        runner.start(|context| async move {
1022            {
1023                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1024                run_index_remove_to_nothing_then_add(&mut index);
1025            }
1026            {
1027                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1028                run_index_remove_to_nothing_then_add(&mut index);
1029            }
1030        });
1031    }
1032
1033    fn run_index_insert_and_remove_cursor<I: Unordered<Value = u64>>(index: &mut I) {
1034        index.insert(b"key", 0);
1035        {
1036            let mut cursor = index.get_mut(b"key").unwrap();
1037            assert_eq!(*cursor.next().unwrap(), 0);
1038            cursor.delete();
1039        }
1040        index.remove(b"key");
1041        assert!(index.get(b"key").copied().collect::<Vec<_>>().is_empty());
1042    }
1043
1044    #[test_traced]
1045    fn test_hash_index_insert_and_remove_cursor() {
1046        let runner = deterministic::Runner::default();
1047        runner.start(|context| async move {
1048            let mut index = new_unordered(context);
1049            run_index_insert_and_remove_cursor(&mut index);
1050        });
1051    }
1052
1053    #[test_traced]
1054    fn test_ordered_index_insert_and_remove_cursor() {
1055        let runner = deterministic::Runner::default();
1056        runner.start(|context| async move {
1057            let mut index = new_ordered(context);
1058            run_index_insert_and_remove_cursor(&mut index);
1059        });
1060    }
1061
1062    #[test_traced]
1063    fn test_partitioned_index_insert_and_remove_cursor() {
1064        let runner = deterministic::Runner::default();
1065        runner.start(|context| async move {
1066            {
1067                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1068                run_index_insert_and_remove_cursor(&mut index);
1069            }
1070            {
1071                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1072                run_index_insert_and_remove_cursor(&mut index);
1073            }
1074        });
1075    }
1076
1077    fn run_index_insert_and_prune_vacant<I: Unordered<Value = u64>>(index: &mut I) {
1078        index.insert_and_prune(b"key", 1u64, |_| false);
1079        assert_eq!(index.get(b"key").copied().collect::<Vec<_>>(), vec![1]);
1080        assert_eq!(index.items(), 1);
1081        assert_eq!(index.keys(), 1);
1082        assert_eq!(index.pruned(), 0);
1083    }
1084
1085    #[test_traced]
1086    fn test_hash_index_insert_and_prune_vacant() {
1087        let runner = deterministic::Runner::default();
1088        runner.start(|context| async move {
1089            let mut index = new_unordered(context);
1090            run_index_insert_and_prune_vacant(&mut index);
1091        });
1092    }
1093
1094    #[test_traced]
1095    fn test_ordered_index_insert_and_prune_vacant() {
1096        let runner = deterministic::Runner::default();
1097        runner.start(|context| async move {
1098            let mut index = new_ordered(context);
1099            run_index_insert_and_prune_vacant(&mut index);
1100        });
1101    }
1102
1103    #[test_traced]
1104    fn test_partitioned_index_insert_and_prune_vacant() {
1105        let runner = deterministic::Runner::default();
1106        runner.start(|context| async move {
1107            {
1108                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1109                run_index_insert_and_prune_vacant(&mut index);
1110            }
1111            {
1112                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1113                run_index_insert_and_prune_vacant(&mut index);
1114            }
1115        });
1116    }
1117
1118    fn run_index_insert_and_prune_replace_one<I: Unordered<Value = u64>>(index: &mut I) {
1119        index.insert(b"key", 1u64);
1120        index.insert_and_prune(b"key", 2u64, |v| *v == 1);
1121        assert_eq!(index.get(b"key").copied().collect::<Vec<_>>(), vec![2]);
1122        assert_eq!(index.items(), 1);
1123        assert_eq!(index.keys(), 1);
1124        assert_eq!(index.pruned(), 1);
1125    }
1126
1127    #[test_traced]
1128    fn test_hash_index_insert_and_prune_replace_one() {
1129        let runner = deterministic::Runner::default();
1130        runner.start(|context| async move {
1131            let mut index = new_unordered(context);
1132            run_index_insert_and_prune_replace_one(&mut index);
1133        });
1134    }
1135
1136    #[test_traced]
1137    fn test_ordered_index_insert_and_prune_replace_one() {
1138        let runner = deterministic::Runner::default();
1139        runner.start(|context| async move {
1140            let mut index = new_ordered(context);
1141            run_index_insert_and_prune_replace_one(&mut index);
1142        });
1143    }
1144
1145    #[test_traced]
1146    fn test_partitioned_index_insert_and_prune_replace_one() {
1147        let runner = deterministic::Runner::default();
1148        runner.start(|context| async move {
1149            {
1150                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1151                run_index_insert_and_prune_replace_one(&mut index);
1152            }
1153            {
1154                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1155                run_index_insert_and_prune_replace_one(&mut index);
1156            }
1157        });
1158    }
1159
1160    fn run_index_insert_and_prune_dead_insert<I: Unordered<Value = u64>>(index: &mut I) {
1161        index.insert(b"key", 10u64);
1162        index.insert(b"key", 20u64);
1163        index.insert_and_prune(b"key", 30u64, |_| true);
1164        assert_eq!(
1165            index.get(b"key").copied().collect::<Vec<u64>>(),
1166            Vec::<u64>::new()
1167        );
1168        assert_eq!(index.items(), 0);
1169        assert_eq!(index.keys(), 0);
1170        assert_eq!(index.pruned(), 2);
1171    }
1172
1173    #[test_traced]
1174    fn test_hash_index_insert_and_prune_dead_insert() {
1175        let runner = deterministic::Runner::default();
1176        runner.start(|context| async move {
1177            let mut index = new_unordered(context);
1178            run_index_insert_and_prune_dead_insert(&mut index);
1179        });
1180    }
1181
1182    #[test_traced]
1183    fn test_ordered_index_insert_and_prune_dead_insert() {
1184        let runner = deterministic::Runner::default();
1185        runner.start(|context| async move {
1186            let mut index = new_ordered(context);
1187            run_index_insert_and_prune_dead_insert(&mut index);
1188        });
1189    }
1190
1191    #[test_traced]
1192    fn test_partitioned_index_insert_and_prune_dead_insert() {
1193        let runner = deterministic::Runner::default();
1194        runner.start(|context| async move {
1195            {
1196                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1197                run_index_insert_and_prune_dead_insert(&mut index);
1198            }
1199            {
1200                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1201                run_index_insert_and_prune_dead_insert(&mut index);
1202            }
1203        });
1204    }
1205
1206    fn run_index_cursor_across_threads<I>(index: Arc<Mutex<I>>)
1207    where
1208        I: Unordered<Value = u64> + Send + 'static,
1209    {
1210        // Insert some initial data
1211        {
1212            let mut index = index.lock().unwrap();
1213            index.insert(b"test_key1", 100);
1214            index.insert(b"test_key2", 200);
1215        }
1216
1217        // Spawn a thread that will get a cursor and modify values
1218        let index_clone = Arc::clone(&index);
1219        let handle = thread::spawn(move || {
1220            // Limit the lifetime of the lock and the cursor so they drop before returning
1221            let result = {
1222                let mut index = index_clone.lock().unwrap();
1223                let mut updated = false;
1224                if let Some(mut cursor) = index.get_mut(b"test_key2") {
1225                    if cursor.find(|&value| value == 200) {
1226                        cursor.update(250);
1227                        updated = true;
1228                    }
1229                }
1230                updated
1231            };
1232            result
1233        });
1234
1235        // Wait for the thread to complete
1236        let result = handle.join().unwrap();
1237        assert!(result);
1238
1239        // Verify the update was applied (and collision retained)
1240        {
1241            let index = index.lock().unwrap();
1242            let values: Vec<u64> = index.get(b"test_key2").copied().collect();
1243            assert!(values.contains(&100));
1244            assert!(values.contains(&250));
1245            assert!(!values.contains(&200));
1246        }
1247    }
1248
1249    #[test_traced]
1250    fn test_hash_index_cursor_across_threads() {
1251        let runner = deterministic::Runner::default();
1252        runner.start(|context| async move {
1253            let index = Arc::new(Mutex::new(new_unordered(context)));
1254            run_index_cursor_across_threads(index);
1255        });
1256    }
1257
1258    #[test_traced]
1259    fn test_ordered_index_cursor_across_threads() {
1260        let runner = deterministic::Runner::default();
1261        runner.start(|context| async move {
1262            let index = Arc::new(Mutex::new(new_ordered(context)));
1263            run_index_cursor_across_threads(index);
1264        });
1265    }
1266
1267    #[test_traced]
1268    fn test_partitioned_index_cursor_across_threads() {
1269        let runner = deterministic::Runner::default();
1270        runner.start(|context| async move {
1271            {
1272                let index = Arc::new(Mutex::new(new_partitioned_unordered(
1273                    context.with_label("unordered"),
1274                )));
1275                run_index_cursor_across_threads(index);
1276            }
1277            {
1278                let index = Arc::new(Mutex::new(new_partitioned_ordered(
1279                    context.with_label("ordered"),
1280                )));
1281                run_index_cursor_across_threads(index);
1282            }
1283        });
1284    }
1285
1286    fn run_index_remove_middle_then_next<I: Unordered<Value = u64>>(index: &mut I) {
1287        for i in 0..4 {
1288            index.insert(b"key", i);
1289        }
1290        {
1291            let mut cursor = index.get_mut(b"key").unwrap();
1292            assert_eq!(*cursor.next().unwrap(), 0);
1293            assert_eq!(*cursor.next().unwrap(), 3);
1294            cursor.delete();
1295            assert_eq!(*cursor.next().unwrap(), 2);
1296            cursor.delete();
1297        }
1298        assert_eq!(index.get(b"key").copied().collect::<Vec<_>>(), vec![0, 1]);
1299    }
1300
1301    #[test_traced]
1302    fn test_hash_index_remove_middle_then_next() {
1303        let runner = deterministic::Runner::default();
1304        runner.start(|context| async move {
1305            let mut index = new_unordered(context);
1306            run_index_remove_middle_then_next(&mut index);
1307        });
1308    }
1309
1310    #[test_traced]
1311    fn test_ordered_index_remove_middle_then_next() {
1312        let runner = deterministic::Runner::default();
1313        runner.start(|context| async move {
1314            let mut index = new_ordered(context);
1315            run_index_remove_middle_then_next(&mut index);
1316        });
1317    }
1318
1319    #[test_traced]
1320    fn test_partitioned_index_remove_middle_then_next() {
1321        let runner = deterministic::Runner::default();
1322        runner.start(|context| async move {
1323            {
1324                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1325                run_index_remove_middle_then_next(&mut index);
1326            }
1327            {
1328                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1329                run_index_remove_middle_then_next(&mut index);
1330            }
1331        });
1332    }
1333
1334    fn run_index_remove_to_nothing<I: Unordered<Value = u64>>(index: &mut I) {
1335        for i in 0..4 {
1336            index.insert(b"key", i);
1337        }
1338        {
1339            let mut cursor = index.get_mut(b"key").unwrap();
1340            assert_eq!(*cursor.next().unwrap(), 0);
1341            cursor.delete();
1342            assert_eq!(*cursor.next().unwrap(), 3);
1343            cursor.delete();
1344            assert_eq!(*cursor.next().unwrap(), 2);
1345            cursor.delete();
1346            assert_eq!(*cursor.next().unwrap(), 1);
1347            cursor.delete();
1348            assert_eq!(cursor.next(), None);
1349        }
1350        assert_eq!(index.keys(), 0);
1351        assert_eq!(index.items(), 0);
1352    }
1353
1354    #[test_traced]
1355    fn test_hash_index_remove_to_nothing() {
1356        let runner = deterministic::Runner::default();
1357        runner.start(|context| async move {
1358            let mut index = new_unordered(context);
1359            run_index_remove_to_nothing(&mut index);
1360        });
1361    }
1362
1363    #[test_traced]
1364    fn test_ordered_index_remove_to_nothing() {
1365        let runner = deterministic::Runner::default();
1366        runner.start(|context| async move {
1367            let mut index = new_ordered(context);
1368            run_index_remove_to_nothing(&mut index);
1369        });
1370    }
1371
1372    #[test_traced]
1373    fn test_partitioned_index_remove_to_nothing() {
1374        let runner = deterministic::Runner::default();
1375        runner.start(|context| async move {
1376            {
1377                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1378                run_index_remove_to_nothing(&mut index);
1379            }
1380            {
1381                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1382                run_index_remove_to_nothing(&mut index);
1383            }
1384        });
1385    }
1386
1387    fn run_index_cursor_update_before_next_panics<I: Unordered<Value = u64>>(index: &mut I) {
1388        index.insert(b"key", 123);
1389        let mut cursor = index.get_mut(b"key").unwrap();
1390        cursor.update(321);
1391    }
1392
1393    #[test_traced]
1394    #[should_panic(expected = "must call Cursor::next()")]
1395    fn test_hash_index_cursor_update_before_next_panics() {
1396        let runner = deterministic::Runner::default();
1397        runner.start(|context| async move {
1398            let mut index = new_unordered(context);
1399            run_index_cursor_update_before_next_panics(&mut index);
1400        });
1401    }
1402
1403    #[test_traced]
1404    #[should_panic(expected = "must call Cursor::next()")]
1405    fn test_ordered_index_cursor_update_before_next_panics() {
1406        let runner = deterministic::Runner::default();
1407        runner.start(|context| async move {
1408            let mut index = new_ordered(context);
1409            run_index_cursor_update_before_next_panics(&mut index);
1410        });
1411    }
1412
1413    #[test_traced]
1414    #[should_panic(expected = "must call Cursor::next()")]
1415    fn test_partitioned_index_cursor_update_before_next_panics() {
1416        let runner = deterministic::Runner::default();
1417        runner.start(|context| async move {
1418            {
1419                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1420                run_index_cursor_update_before_next_panics(&mut index);
1421            }
1422            {
1423                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1424                run_index_cursor_update_before_next_panics(&mut index);
1425            }
1426        });
1427    }
1428
1429    fn run_index_cursor_delete_before_next_panics<I: Unordered<Value = u64>>(index: &mut I) {
1430        index.insert(b"key", 123);
1431        let mut cursor = index.get_mut(b"key").unwrap();
1432        cursor.delete();
1433    }
1434
1435    #[test_traced]
1436    #[should_panic(expected = "must call Cursor::next()")]
1437    fn test_hash_index_cursor_delete_before_next_panics() {
1438        let runner = deterministic::Runner::default();
1439        runner.start(|context| async move {
1440            let mut index = new_unordered(context);
1441            run_index_cursor_delete_before_next_panics(&mut index);
1442        });
1443    }
1444
1445    #[test_traced]
1446    #[should_panic(expected = "must call Cursor::next()")]
1447    fn test_ordered_index_cursor_delete_before_next_panics() {
1448        let runner = deterministic::Runner::default();
1449        runner.start(|context| async move {
1450            let mut index = new_ordered(context);
1451            run_index_cursor_delete_before_next_panics(&mut index);
1452        });
1453    }
1454
1455    #[test_traced]
1456    #[should_panic(expected = "must call Cursor::next()")]
1457    fn test_partitioned_index_cursor_delete_before_next_panics() {
1458        let runner = deterministic::Runner::default();
1459        runner.start(|context| async move {
1460            {
1461                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1462                run_index_cursor_delete_before_next_panics(&mut index);
1463            }
1464            {
1465                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1466                run_index_cursor_delete_before_next_panics(&mut index);
1467            }
1468        });
1469    }
1470
1471    fn run_index_cursor_update_after_done<I: Unordered<Value = u64>>(index: &mut I) {
1472        index.insert(b"key", 123);
1473        let mut cursor = index.get_mut(b"key").unwrap();
1474        assert_eq!(*cursor.next().unwrap(), 123);
1475        assert!(cursor.next().is_none());
1476        cursor.update(321);
1477    }
1478
1479    #[test_traced]
1480    #[should_panic(expected = "no active item in Cursor")]
1481    fn test_hash_index_cursor_update_after_done() {
1482        let runner = deterministic::Runner::default();
1483        runner.start(|context| async move {
1484            let mut index = new_unordered(context);
1485            run_index_cursor_update_after_done(&mut index);
1486        });
1487    }
1488
1489    #[test_traced]
1490    #[should_panic(expected = "no active item in Cursor")]
1491    fn test_ordered_index_cursor_update_after_done() {
1492        let runner = deterministic::Runner::default();
1493        runner.start(|context| async move {
1494            let mut index = new_ordered(context);
1495            run_index_cursor_update_after_done(&mut index);
1496        });
1497    }
1498
1499    #[test_traced]
1500    #[should_panic(expected = "no active item in Cursor")]
1501    fn test_partitioned_index_cursor_update_after_done() {
1502        let runner = deterministic::Runner::default();
1503        runner.start(|context| async move {
1504            {
1505                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1506                run_index_cursor_update_after_done(&mut index);
1507            }
1508            {
1509                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1510                run_index_cursor_update_after_done(&mut index);
1511            }
1512        });
1513    }
1514
1515    fn run_index_cursor_insert_before_next<I: Unordered<Value = u64>>(index: &mut I) {
1516        index.insert(b"key", 123);
1517        let mut cursor = index.get_mut(b"key").unwrap();
1518        cursor.insert(321);
1519    }
1520
1521    #[test_traced]
1522    #[should_panic(expected = "must call Cursor::next()")]
1523    fn test_hash_index_cursor_insert_before_next() {
1524        let runner = deterministic::Runner::default();
1525        runner.start(|context| async move {
1526            let mut index = new_unordered(context);
1527            run_index_cursor_insert_before_next(&mut index);
1528        });
1529    }
1530
1531    #[test_traced]
1532    #[should_panic(expected = "must call Cursor::next()")]
1533    fn test_ordered_index_cursor_insert_before_next() {
1534        let runner = deterministic::Runner::default();
1535        runner.start(|context| async move {
1536            let mut index = new_ordered(context);
1537            run_index_cursor_insert_before_next(&mut index);
1538        });
1539    }
1540
1541    #[test_traced]
1542    #[should_panic(expected = "must call Cursor::next()")]
1543    fn test_partitioned_index_cursor_insert_before_next() {
1544        let runner = deterministic::Runner::default();
1545        runner.start(|context| async move {
1546            {
1547                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1548                run_index_cursor_insert_before_next(&mut index);
1549            }
1550            {
1551                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1552                run_index_cursor_insert_before_next(&mut index);
1553            }
1554        });
1555    }
1556
1557    fn run_index_cursor_delete_after_done<I: Unordered<Value = u64>>(index: &mut I) {
1558        index.insert(b"key", 123);
1559        let mut cursor = index.get_mut(b"key").unwrap();
1560        assert_eq!(*cursor.next().unwrap(), 123);
1561        assert!(cursor.next().is_none());
1562        cursor.delete();
1563    }
1564
1565    #[test_traced]
1566    #[should_panic(expected = "no active item in Cursor")]
1567    fn test_hash_index_cursor_delete_after_done() {
1568        let runner = deterministic::Runner::default();
1569        runner.start(|context| async move {
1570            let mut index = new_unordered(context);
1571            run_index_cursor_delete_after_done(&mut index);
1572        });
1573    }
1574
1575    #[test_traced]
1576    #[should_panic(expected = "no active item in Cursor")]
1577    fn test_ordered_index_cursor_delete_after_done() {
1578        let runner = deterministic::Runner::default();
1579        runner.start(|context| async move {
1580            let mut index = new_ordered(context);
1581            run_index_cursor_delete_after_done(&mut index);
1582        });
1583    }
1584
1585    #[test_traced]
1586    #[should_panic(expected = "no active item in Cursor")]
1587    fn test_partitioned_index_cursor_delete_after_done() {
1588        let runner = deterministic::Runner::default();
1589        runner.start(|context| async move {
1590            {
1591                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1592                run_index_cursor_delete_after_done(&mut index);
1593            }
1594            {
1595                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1596                run_index_cursor_delete_after_done(&mut index);
1597            }
1598        });
1599    }
1600
1601    fn run_index_cursor_insert_with_next<I: Unordered<Value = u64>>(index: &mut I) {
1602        index.insert(b"key", 123);
1603        index.insert(b"key", 456);
1604        let mut cursor = index.get_mut(b"key").unwrap();
1605        assert_eq!(*cursor.next().unwrap(), 123);
1606        assert_eq!(*cursor.next().unwrap(), 456);
1607        cursor.insert(789);
1608        assert_eq!(cursor.next(), None);
1609        cursor.insert(999);
1610        drop(cursor);
1611        let mut values = index.get(b"key").copied().collect::<Vec<_>>();
1612        values.sort();
1613        assert_eq!(values, vec![123, 456, 789, 999]);
1614    }
1615
1616    #[test_traced]
1617    fn test_hash_index_cursor_insert_with_next() {
1618        let runner = deterministic::Runner::default();
1619        runner.start(|context| async move {
1620            let mut index = new_unordered(context);
1621            run_index_cursor_insert_with_next(&mut index);
1622        });
1623    }
1624
1625    #[test_traced]
1626    fn test_ordered_index_cursor_insert_with_next() {
1627        let runner = deterministic::Runner::default();
1628        runner.start(|context| async move {
1629            let mut index = new_ordered(context);
1630            run_index_cursor_insert_with_next(&mut index);
1631        });
1632    }
1633
1634    #[test_traced]
1635    fn test_partitioned_index_cursor_insert_with_next() {
1636        let runner = deterministic::Runner::default();
1637        runner.start(|context| async move {
1638            {
1639                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1640                run_index_cursor_insert_with_next(&mut index);
1641            }
1642            {
1643                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1644                run_index_cursor_insert_with_next(&mut index);
1645            }
1646        });
1647    }
1648
1649    fn run_index_cursor_double_delete<I: Unordered<Value = u64>>(index: &mut I) {
1650        index.insert(b"key", 123);
1651        index.insert(b"key", 456);
1652        let mut cursor = index.get_mut(b"key").unwrap();
1653        assert_eq!(*cursor.next().unwrap(), 123);
1654        cursor.delete();
1655        cursor.delete();
1656    }
1657
1658    #[test_traced]
1659    #[should_panic(expected = "must call Cursor::next()")]
1660    fn test_hash_index_cursor_double_delete() {
1661        let runner = deterministic::Runner::default();
1662        runner.start(|context| async move {
1663            let mut index = new_unordered(context);
1664            run_index_cursor_double_delete(&mut index);
1665        });
1666    }
1667
1668    #[test_traced]
1669    #[should_panic(expected = "must call Cursor::next()")]
1670    fn test_ordered_index_cursor_double_delete() {
1671        let runner = deterministic::Runner::default();
1672        runner.start(|context| async move {
1673            let mut index = new_ordered(context);
1674            run_index_cursor_double_delete(&mut index);
1675        });
1676    }
1677
1678    fn run_index_cursor_delete_last_then_next<I: Unordered<Value = u64>>(index: &mut I) {
1679        index.insert(b"key", 1);
1680        index.insert(b"key", 2);
1681        {
1682            let mut cursor = index.get_mut(b"key").unwrap();
1683            assert_eq!(*cursor.next().unwrap(), 1);
1684            assert_eq!(*cursor.next().unwrap(), 2);
1685            cursor.delete();
1686            assert!(cursor.next().is_none());
1687            assert!(cursor.next().is_none());
1688        }
1689        assert_eq!(index.keys(), 1);
1690        assert_eq!(index.items(), 1);
1691    }
1692
1693    #[test_traced]
1694    fn test_hash_index_cursor_delete_last_then_next() {
1695        let runner = deterministic::Runner::default();
1696        runner.start(|context| async move {
1697            let mut index = new_unordered(context);
1698            run_index_cursor_delete_last_then_next(&mut index);
1699        });
1700    }
1701
1702    #[test_traced]
1703    fn test_ordered_index_cursor_delete_last_then_next() {
1704        let runner = deterministic::Runner::default();
1705        runner.start(|context| async move {
1706            let mut index = new_ordered(context);
1707            run_index_cursor_delete_last_then_next(&mut index);
1708        });
1709    }
1710
1711    #[test_traced]
1712    fn test_partitioned_index_cursor_delete_last_then_next() {
1713        let runner = deterministic::Runner::default();
1714        runner.start(|context| async move {
1715            {
1716                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1717                run_index_cursor_delete_last_then_next(&mut index);
1718            }
1719            {
1720                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1721                run_index_cursor_delete_last_then_next(&mut index);
1722            }
1723        });
1724    }
1725
1726    fn run_index_delete_in_middle_then_continue<I: Unordered<Value = u64>>(index: &mut I) {
1727        index.insert(b"key", 1);
1728        index.insert(b"key", 2);
1729        index.insert(b"key", 3);
1730        let mut cur = index.get_mut(b"key").unwrap();
1731        assert_eq!(*cur.next().unwrap(), 1);
1732        assert_eq!(*cur.next().unwrap(), 3);
1733        cur.delete();
1734        assert_eq!(*cur.next().unwrap(), 2);
1735        assert!(cur.next().is_none());
1736        assert!(cur.next().is_none());
1737    }
1738
1739    #[test_traced]
1740    fn test_hash_index_delete_in_middle_then_continue() {
1741        let runner = deterministic::Runner::default();
1742        runner.start(|context| async move {
1743            let mut index = new_unordered(context);
1744            run_index_delete_in_middle_then_continue(&mut index);
1745        });
1746    }
1747
1748    #[test_traced]
1749    fn test_ordered_index_delete_in_middle_then_continue() {
1750        let runner = deterministic::Runner::default();
1751        runner.start(|context| async move {
1752            let mut index = new_ordered(context);
1753            run_index_delete_in_middle_then_continue(&mut index);
1754        });
1755    }
1756
1757    fn run_index_delete_first<I: Unordered<Value = u64>>(index: &mut I) {
1758        index.insert(b"key", 1);
1759        index.insert(b"key", 2);
1760        index.insert(b"key", 3);
1761        {
1762            let mut cur = index.get_mut(b"key").unwrap();
1763            assert_eq!(*cur.next().unwrap(), 1);
1764            cur.delete();
1765            assert_eq!(*cur.next().unwrap(), 3);
1766            assert_eq!(*cur.next().unwrap(), 2);
1767            assert!(cur.next().is_none());
1768            assert!(cur.next().is_none());
1769        }
1770        assert_eq!(index.get(b"key").copied().collect::<Vec<_>>(), vec![3, 2]);
1771    }
1772
1773    #[test_traced]
1774    fn test_hash_index_delete_first() {
1775        let runner = deterministic::Runner::default();
1776        runner.start(|context| async move {
1777            let mut index = new_unordered(context);
1778            run_index_delete_first(&mut index);
1779        });
1780    }
1781
1782    #[test_traced]
1783    fn test_ordered_index_delete_first() {
1784        let runner = deterministic::Runner::default();
1785        runner.start(|context| async move {
1786            let mut index = new_ordered(context);
1787            run_index_delete_first(&mut index);
1788        });
1789    }
1790
1791    fn run_index_delete_first_and_insert<I: Unordered<Value = u64>>(index: &mut I) {
1792        index.insert(b"key", 1);
1793        index.insert(b"key", 2);
1794        index.insert(b"key", 3);
1795        assert_eq!(
1796            index.get(b"key").copied().collect::<Vec<_>>(),
1797            vec![1, 3, 2]
1798        );
1799        {
1800            let mut cur = index.get_mut(b"key").unwrap();
1801            assert_eq!(*cur.next().unwrap(), 1);
1802            cur.delete();
1803            assert_eq!(*cur.next().unwrap(), 3);
1804            cur.insert(4);
1805            assert_eq!(*cur.next().unwrap(), 2);
1806            assert!(cur.next().is_none());
1807            assert!(cur.next().is_none());
1808        }
1809        assert_eq!(
1810            index.get(b"key").copied().collect::<Vec<_>>(),
1811            vec![3, 4, 2]
1812        );
1813    }
1814
1815    #[test_traced]
1816    fn test_hash_index_delete_first_and_insert() {
1817        let runner = deterministic::Runner::default();
1818        runner.start(|context| async move {
1819            let mut index = new_unordered(context);
1820            run_index_delete_first_and_insert(&mut index);
1821        });
1822    }
1823
1824    #[test_traced]
1825    fn test_ordered_index_delete_first_and_insert() {
1826        let runner = deterministic::Runner::default();
1827        runner.start(|context| async move {
1828            let mut index = new_ordered(context);
1829            run_index_delete_first_and_insert(&mut index);
1830        });
1831    }
1832
1833    #[test_traced]
1834    fn test_partitioned_index_delete_first_and_insert() {
1835        let runner = deterministic::Runner::default();
1836        runner.start(|context| async move {
1837            {
1838                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1839                run_index_delete_first_and_insert(&mut index);
1840            }
1841            {
1842                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1843                run_index_delete_first_and_insert(&mut index);
1844            }
1845        });
1846    }
1847
1848    fn run_index_insert_at_entry_then_next<I: Unordered<Value = u64>>(index: &mut I) {
1849        index.insert(b"key", 1);
1850        index.insert(b"key", 2);
1851        let mut cur = index.get_mut(b"key").unwrap();
1852        assert_eq!(*cur.next().unwrap(), 1);
1853        cur.insert(99);
1854        assert_eq!(*cur.next().unwrap(), 2);
1855        assert!(cur.next().is_none());
1856    }
1857
1858    #[test_traced]
1859    fn test_hash_index_insert_at_entry_then_next() {
1860        let runner = deterministic::Runner::default();
1861        runner.start(|context| async move {
1862            let mut index = new_unordered(context);
1863            run_index_insert_at_entry_then_next(&mut index);
1864        });
1865    }
1866
1867    #[test_traced]
1868    fn test_ordered_index_insert_at_entry_then_next() {
1869        let runner = deterministic::Runner::default();
1870        runner.start(|context| async move {
1871            let mut index = new_ordered(context);
1872            run_index_insert_at_entry_then_next(&mut index);
1873        });
1874    }
1875
1876    #[test_traced]
1877    fn test_partitioned_index_insert_at_entry_then_next() {
1878        let runner = deterministic::Runner::default();
1879        runner.start(|context| async move {
1880            {
1881                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1882                run_index_insert_at_entry_then_next(&mut index);
1883            }
1884            {
1885                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1886                run_index_insert_at_entry_then_next(&mut index);
1887            }
1888        });
1889    }
1890
1891    fn run_index_insert_at_entry_then_delete_head<I: Unordered<Value = u64>>(index: &mut I) {
1892        index.insert(b"key", 10);
1893        index.insert(b"key", 20);
1894        let mut cur = index.get_mut(b"key").unwrap();
1895        assert_eq!(*cur.next().unwrap(), 10);
1896        cur.insert(15);
1897        cur.delete();
1898    }
1899
1900    #[test_traced]
1901    #[should_panic(expected = "must call Cursor::next()")]
1902    fn test_hash_index_insert_at_entry_then_delete_head() {
1903        let runner = deterministic::Runner::default();
1904        runner.start(|context| async move {
1905            let mut index = new_unordered(context);
1906            run_index_insert_at_entry_then_delete_head(&mut index);
1907        });
1908    }
1909
1910    #[test_traced]
1911    #[should_panic(expected = "must call Cursor::next()")]
1912    fn test_ordered_index_insert_at_entry_then_delete_head() {
1913        let runner = deterministic::Runner::default();
1914        runner.start(|context| async move {
1915            let mut index = new_ordered(context);
1916            run_index_insert_at_entry_then_delete_head(&mut index);
1917        });
1918    }
1919
1920    #[test_traced]
1921    #[should_panic(expected = "must call Cursor::next()")]
1922    fn test_partitioned_index_insert_at_entry_then_delete_head() {
1923        let runner = deterministic::Runner::default();
1924        runner.start(|context| async move {
1925            {
1926                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1927                run_index_insert_at_entry_then_delete_head(&mut index);
1928            }
1929            {
1930                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1931                run_index_insert_at_entry_then_delete_head(&mut index);
1932            }
1933        });
1934    }
1935
1936    fn run_index_delete_then_insert_without_next<I: Unordered<Value = u64>>(index: &mut I) {
1937        index.insert(b"key", 10);
1938        index.insert(b"key", 20);
1939        let mut cur = index.get_mut(b"key").unwrap();
1940        assert_eq!(*cur.next().unwrap(), 10);
1941        assert_eq!(*cur.next().unwrap(), 20);
1942        cur.delete();
1943        cur.insert(15);
1944    }
1945
1946    #[test_traced]
1947    #[should_panic(expected = "must call Cursor::next()")]
1948    fn test_hash_index_delete_then_insert_without_next() {
1949        let runner = deterministic::Runner::default();
1950        runner.start(|context| async move {
1951            let mut index = new_unordered(context);
1952            run_index_delete_then_insert_without_next(&mut index);
1953        });
1954    }
1955
1956    #[test_traced]
1957    #[should_panic(expected = "must call Cursor::next()")]
1958    fn test_ordered_index_delete_then_insert_without_next() {
1959        let runner = deterministic::Runner::default();
1960        runner.start(|context| async move {
1961            let mut index = new_ordered(context);
1962            run_index_delete_then_insert_without_next(&mut index);
1963        });
1964    }
1965
1966    #[test_traced]
1967    #[should_panic(expected = "must call Cursor::next()")]
1968    fn test_partitioned_index_delete_then_insert_without_next() {
1969        let runner = deterministic::Runner::default();
1970        runner.start(|context| async move {
1971            {
1972                let mut index = new_partitioned_unordered(context.with_label("unordered"));
1973                run_index_delete_then_insert_without_next(&mut index);
1974            }
1975            {
1976                let mut index = new_partitioned_ordered(context.with_label("ordered"));
1977                run_index_delete_then_insert_without_next(&mut index);
1978            }
1979        });
1980    }
1981
1982    fn run_index_inserts_without_next<I: Unordered<Value = u64>>(index: &mut I) {
1983        index.insert(b"key", 10);
1984        index.insert(b"key", 20);
1985        let mut cur = index.get_mut(b"key").unwrap();
1986        assert_eq!(*cur.next().unwrap(), 10);
1987        cur.insert(15);
1988        cur.insert(25);
1989    }
1990
1991    #[test_traced]
1992    #[should_panic(expected = "must call Cursor::next()")]
1993    fn test_hash_index_inserts_without_next() {
1994        let runner = deterministic::Runner::default();
1995        runner.start(|context| async move {
1996            let mut index = new_unordered(context);
1997            run_index_inserts_without_next(&mut index);
1998        });
1999    }
2000
2001    #[test_traced]
2002    #[should_panic(expected = "must call Cursor::next()")]
2003    fn test_ordered_index_inserts_without_next() {
2004        let runner = deterministic::Runner::default();
2005        runner.start(|context| async move {
2006            let mut index = new_ordered(context);
2007            run_index_inserts_without_next(&mut index);
2008        });
2009    }
2010
2011    #[test_traced]
2012    #[should_panic(expected = "must call Cursor::next()")]
2013    fn test_partitioned_index_inserts_without_next() {
2014        let runner = deterministic::Runner::default();
2015        runner.start(|context| async move {
2016            {
2017                let mut index = new_partitioned_unordered(context.with_label("unordered"));
2018                run_index_inserts_without_next(&mut index);
2019            }
2020            {
2021                let mut index = new_partitioned_ordered(context.with_label("ordered"));
2022                run_index_inserts_without_next(&mut index);
2023            }
2024        });
2025    }
2026
2027    fn run_index_delete_last_then_insert_while_done<I: Unordered<Value = u64>>(index: &mut I) {
2028        index.insert(b"k", 7);
2029        {
2030            let mut cur = index.get_mut(b"k").unwrap();
2031            assert_eq!(*cur.next().unwrap(), 7);
2032            cur.delete();
2033            assert!(cur.next().is_none());
2034            cur.insert(8);
2035            assert!(cur.next().is_none());
2036            cur.insert(9);
2037            assert!(cur.next().is_none());
2038        }
2039        assert_eq!(index.keys(), 1);
2040        assert_eq!(index.items(), 2);
2041        assert_eq!(index.get(b"k").copied().collect::<Vec<_>>(), vec![8, 9]);
2042    }
2043
2044    #[test_traced]
2045    fn test_hash_index_delete_last_then_insert_while_done() {
2046        let runner = deterministic::Runner::default();
2047        runner.start(|context| async move {
2048            let mut index = new_unordered(context);
2049            run_index_delete_last_then_insert_while_done(&mut index);
2050        });
2051    }
2052
2053    #[test_traced]
2054    fn test_ordered_index_delete_last_then_insert_while_done() {
2055        let runner = deterministic::Runner::default();
2056        runner.start(|context| async move {
2057            let mut index = new_ordered(context);
2058            run_index_delete_last_then_insert_while_done(&mut index);
2059        });
2060    }
2061
2062    #[test_traced]
2063    fn test_partitioned_index_delete_last_then_insert_while_done() {
2064        let runner = deterministic::Runner::default();
2065        runner.start(|context| async move {
2066            {
2067                let mut index = new_partitioned_unordered(context.with_label("unordered"));
2068                run_index_delete_last_then_insert_while_done(&mut index);
2069            }
2070            {
2071                let mut index = new_partitioned_ordered(context.with_label("ordered"));
2072                run_index_delete_last_then_insert_while_done(&mut index);
2073            }
2074        });
2075    }
2076
2077    fn run_index_drop_mid_iteration_relinks<I: Unordered<Value = u64>>(index: &mut I) {
2078        for i in 0..5 {
2079            index.insert(b"z", i);
2080        }
2081        {
2082            let mut cur = index.get_mut(b"z").unwrap();
2083            cur.next();
2084            cur.next();
2085        }
2086        assert_eq!(
2087            index.get(b"z").copied().collect::<Vec<_>>(),
2088            vec![0, 4, 3, 2, 1]
2089        );
2090    }
2091
2092    #[test_traced]
2093    fn test_hash_index_drop_mid_iteration_relinks() {
2094        let runner = deterministic::Runner::default();
2095        runner.start(|context| async move {
2096            let mut index = new_unordered(context);
2097            run_index_drop_mid_iteration_relinks(&mut index);
2098        });
2099    }
2100
2101    #[test_traced]
2102    fn test_ordered_index_drop_mid_iteration_relinks() {
2103        let runner = deterministic::Runner::default();
2104        runner.start(|context| async move {
2105            let mut index = new_ordered(context);
2106            run_index_drop_mid_iteration_relinks(&mut index);
2107        });
2108    }
2109
2110    #[test_traced]
2111    fn test_partitioned_index_drop_mid_iteration_relinks() {
2112        let runner = deterministic::Runner::default();
2113        runner.start(|context| async move {
2114            {
2115                let mut index = new_partitioned_unordered(context.with_label("unordered"));
2116                run_index_drop_mid_iteration_relinks(&mut index);
2117            }
2118            {
2119                let mut index = new_partitioned_ordered(context.with_label("ordered"));
2120                run_index_drop_mid_iteration_relinks(&mut index);
2121            }
2122        });
2123    }
2124
2125    fn run_index_update_before_next_panics<I: Unordered<Value = u64>>(index: &mut I) {
2126        index.insert(b"p", 1);
2127        let mut cur = index.get_mut(b"p").unwrap();
2128        cur.update(2);
2129    }
2130
2131    #[test_traced]
2132    #[should_panic(expected = "must call Cursor::next()")]
2133    fn test_hash_index_update_before_next_panics() {
2134        let runner = deterministic::Runner::default();
2135        runner.start(|context| async move {
2136            let mut index = new_unordered(context);
2137            run_index_update_before_next_panics(&mut index);
2138        });
2139    }
2140
2141    #[test_traced]
2142    #[should_panic(expected = "must call Cursor::next()")]
2143    fn test_ordered_index_update_before_next_panics() {
2144        let runner = deterministic::Runner::default();
2145        runner.start(|context| async move {
2146            let mut index = new_ordered(context);
2147            run_index_update_before_next_panics(&mut index);
2148        });
2149    }
2150
2151    #[test_traced]
2152    #[should_panic(expected = "must call Cursor::next()")]
2153    fn test_partitioned_index_update_before_next_panics() {
2154        let runner = deterministic::Runner::default();
2155        runner.start(|context| async move {
2156            {
2157                let mut index = new_partitioned_unordered(context.with_label("unordered"));
2158                run_index_update_before_next_panics(&mut index);
2159            }
2160            {
2161                let mut index = new_partitioned_ordered(context.with_label("ordered"));
2162                run_index_update_before_next_panics(&mut index);
2163            }
2164        });
2165    }
2166
2167    fn run_index_entry_replacement_not_a_collision<I: Unordered<Value = u64>>(index: &mut I) {
2168        index.insert(b"a", 1);
2169        {
2170            let mut cur = index.get_mut(b"a").unwrap();
2171            cur.next();
2172            cur.delete();
2173            cur.next();
2174            cur.insert(2);
2175        }
2176        assert_eq!(index.keys(), 1);
2177        assert_eq!(index.items(), 1);
2178    }
2179
2180    #[test_traced]
2181    fn test_hash_index_entry_replacement_not_a_collision() {
2182        let runner = deterministic::Runner::default();
2183        runner.start(|context| async move {
2184            let mut index = new_unordered(context);
2185            run_index_entry_replacement_not_a_collision(&mut index);
2186        });
2187    }
2188
2189    #[test_traced]
2190    fn test_ordered_index_entry_replacement_not_a_collision() {
2191        let runner = deterministic::Runner::default();
2192        runner.start(|context| async move {
2193            let mut index = new_ordered(context);
2194            run_index_entry_replacement_not_a_collision(&mut index);
2195        });
2196    }
2197
2198    #[test_traced]
2199    fn test_partitioned_index_entry_replacement_not_a_collision() {
2200        let runner = deterministic::Runner::default();
2201        runner.start(|context| async move {
2202            {
2203                let mut index = new_partitioned_unordered(context.with_label("unordered"));
2204                run_index_entry_replacement_not_a_collision(&mut index);
2205            }
2206            {
2207                let mut index = new_partitioned_ordered(context.with_label("ordered"));
2208                run_index_entry_replacement_not_a_collision(&mut index);
2209            }
2210        });
2211    }
2212
2213    fn run_index_large_collision_chain_stack_overflow<I: Unordered<Value = u64>>(index: &mut I) {
2214        for i in 0..50000 {
2215            index.insert(b"", i as u64);
2216        }
2217    }
2218
2219    #[test_traced]
2220    fn test_hash_index_large_collision_chain_stack_overflow() {
2221        let runner = deterministic::Runner::default();
2222        runner.start(|context| async move {
2223            let mut index = new_unordered(context);
2224            run_index_large_collision_chain_stack_overflow(&mut index);
2225        });
2226    }
2227
2228    #[test_traced]
2229    fn test_ordered_index_large_collision_chain_stack_overflow() {
2230        let runner = deterministic::Runner::default();
2231        runner.start(|context| async move {
2232            let mut index = new_ordered(context);
2233            run_index_large_collision_chain_stack_overflow(&mut index);
2234        });
2235    }
2236
2237    #[test_traced]
2238    fn test_partitioned_index_large_collision_chain_stack_overflow() {
2239        let runner = deterministic::Runner::default();
2240        runner.start(|context| async move {
2241            {
2242                let mut index = new_partitioned_unordered(context.with_label("unordered"));
2243                run_index_large_collision_chain_stack_overflow(&mut index);
2244            }
2245            {
2246                let mut index = new_partitioned_ordered(context.with_label("ordered"));
2247                run_index_large_collision_chain_stack_overflow(&mut index);
2248            }
2249        });
2250    }
2251}