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, 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.clone());
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);
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.clone());
398                run_index_cursor_find(&mut index);
399            }
400            {
401                let mut index = new_partitioned_ordered(context);
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.clone());
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.clone());
521                run_index_key_lengths_and_metrics(&mut index);
522            }
523            {
524                let mut index = new_partitioned_ordered(context);
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.clone());
564                run_index_value_order(&mut index);
565            }
566            {
567                let mut index = new_partitioned_ordered(context);
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.clone());
607                run_index_remove_specific(&mut index);
608            }
609            {
610                let mut index = new_partitioned_ordered(context);
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.clone());
661                run_index_empty_key(&mut index);
662            }
663            {
664                let mut index = new_partitioned_ordered(context);
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.clone());
710                run_index_mutate_through_iterator(&mut index);
711            }
712            {
713                let mut index = new_partitioned_ordered(context);
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.clone());
765                run_index_mutate_middle_of_four(&mut index);
766            }
767            {
768                let mut index = new_partitioned_ordered(context);
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.clone());
859                run_index_remove_through_iterator(&mut index);
860            }
861            {
862                let mut index = new_partitioned_ordered(context);
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.clone());
925                run_index_insert_through_iterator(&mut index);
926            }
927            {
928                let mut index = new_partitioned_ordered(context);
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.clone());
969                run_index_cursor_insert_after_done_appends(&mut index);
970            }
971            {
972                let mut index = new_partitioned_ordered(context);
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.clone());
1024                run_index_remove_to_nothing_then_add(&mut index);
1025            }
1026            {
1027                let mut index = new_partitioned_ordered(context);
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.clone());
1068                run_index_insert_and_remove_cursor(&mut index);
1069            }
1070            {
1071                let mut index = new_partitioned_ordered(context);
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.clone());
1109                run_index_insert_and_prune_vacant(&mut index);
1110            }
1111            {
1112                let mut index = new_partitioned_ordered(context);
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.clone());
1151                run_index_insert_and_prune_replace_one(&mut index);
1152            }
1153            {
1154                let mut index = new_partitioned_ordered(context);
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.clone());
1197                run_index_insert_and_prune_dead_insert(&mut index);
1198            }
1199            {
1200                let mut index = new_partitioned_ordered(context);
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(context.clone())));
1273                run_index_cursor_across_threads(index);
1274            }
1275            {
1276                let index = Arc::new(Mutex::new(new_partitioned_ordered(context)));
1277                run_index_cursor_across_threads(index);
1278            }
1279        });
1280    }
1281
1282    fn run_index_remove_middle_then_next<I: Unordered<Value = u64>>(index: &mut I) {
1283        for i in 0..4 {
1284            index.insert(b"key", i);
1285        }
1286        {
1287            let mut cursor = index.get_mut(b"key").unwrap();
1288            assert_eq!(*cursor.next().unwrap(), 0);
1289            assert_eq!(*cursor.next().unwrap(), 3);
1290            cursor.delete();
1291            assert_eq!(*cursor.next().unwrap(), 2);
1292            cursor.delete();
1293        }
1294        assert_eq!(index.get(b"key").copied().collect::<Vec<_>>(), vec![0, 1]);
1295    }
1296
1297    #[test_traced]
1298    fn test_hash_index_remove_middle_then_next() {
1299        let runner = deterministic::Runner::default();
1300        runner.start(|context| async move {
1301            let mut index = new_unordered(context);
1302            run_index_remove_middle_then_next(&mut index);
1303        });
1304    }
1305
1306    #[test_traced]
1307    fn test_ordered_index_remove_middle_then_next() {
1308        let runner = deterministic::Runner::default();
1309        runner.start(|context| async move {
1310            let mut index = new_ordered(context);
1311            run_index_remove_middle_then_next(&mut index);
1312        });
1313    }
1314
1315    #[test_traced]
1316    fn test_partitioned_index_remove_middle_then_next() {
1317        let runner = deterministic::Runner::default();
1318        runner.start(|context| async move {
1319            {
1320                let mut index = new_partitioned_unordered(context.clone());
1321                run_index_remove_middle_then_next(&mut index);
1322            }
1323            {
1324                let mut index = new_partitioned_ordered(context);
1325                run_index_remove_middle_then_next(&mut index);
1326            }
1327        });
1328    }
1329
1330    fn run_index_remove_to_nothing<I: Unordered<Value = u64>>(index: &mut I) {
1331        for i in 0..4 {
1332            index.insert(b"key", i);
1333        }
1334        {
1335            let mut cursor = index.get_mut(b"key").unwrap();
1336            assert_eq!(*cursor.next().unwrap(), 0);
1337            cursor.delete();
1338            assert_eq!(*cursor.next().unwrap(), 3);
1339            cursor.delete();
1340            assert_eq!(*cursor.next().unwrap(), 2);
1341            cursor.delete();
1342            assert_eq!(*cursor.next().unwrap(), 1);
1343            cursor.delete();
1344            assert_eq!(cursor.next(), None);
1345        }
1346        assert_eq!(index.keys(), 0);
1347        assert_eq!(index.items(), 0);
1348    }
1349
1350    #[test_traced]
1351    fn test_hash_index_remove_to_nothing() {
1352        let runner = deterministic::Runner::default();
1353        runner.start(|context| async move {
1354            let mut index = new_unordered(context);
1355            run_index_remove_to_nothing(&mut index);
1356        });
1357    }
1358
1359    #[test_traced]
1360    fn test_ordered_index_remove_to_nothing() {
1361        let runner = deterministic::Runner::default();
1362        runner.start(|context| async move {
1363            let mut index = new_ordered(context);
1364            run_index_remove_to_nothing(&mut index);
1365        });
1366    }
1367
1368    #[test_traced]
1369    fn test_partitioned_index_remove_to_nothing() {
1370        let runner = deterministic::Runner::default();
1371        runner.start(|context| async move {
1372            {
1373                let mut index = new_partitioned_unordered(context.clone());
1374                run_index_remove_to_nothing(&mut index);
1375            }
1376            {
1377                let mut index = new_partitioned_ordered(context);
1378                run_index_remove_to_nothing(&mut index);
1379            }
1380        });
1381    }
1382
1383    fn run_index_cursor_update_before_next_panics<I: Unordered<Value = u64>>(index: &mut I) {
1384        index.insert(b"key", 123);
1385        let mut cursor = index.get_mut(b"key").unwrap();
1386        cursor.update(321);
1387    }
1388
1389    #[test_traced]
1390    #[should_panic(expected = "must call Cursor::next()")]
1391    fn test_hash_index_cursor_update_before_next_panics() {
1392        let runner = deterministic::Runner::default();
1393        runner.start(|context| async move {
1394            let mut index = new_unordered(context);
1395            run_index_cursor_update_before_next_panics(&mut index);
1396        });
1397    }
1398
1399    #[test_traced]
1400    #[should_panic(expected = "must call Cursor::next()")]
1401    fn test_ordered_index_cursor_update_before_next_panics() {
1402        let runner = deterministic::Runner::default();
1403        runner.start(|context| async move {
1404            let mut index = new_ordered(context);
1405            run_index_cursor_update_before_next_panics(&mut index);
1406        });
1407    }
1408
1409    #[test_traced]
1410    #[should_panic(expected = "must call Cursor::next()")]
1411    fn test_partitioned_index_cursor_update_before_next_panics() {
1412        let runner = deterministic::Runner::default();
1413        runner.start(|context| async move {
1414            {
1415                let mut index = new_partitioned_unordered(context.clone());
1416                run_index_cursor_update_before_next_panics(&mut index);
1417            }
1418            {
1419                let mut index = new_partitioned_ordered(context);
1420                run_index_cursor_update_before_next_panics(&mut index);
1421            }
1422        });
1423    }
1424
1425    fn run_index_cursor_delete_before_next_panics<I: Unordered<Value = u64>>(index: &mut I) {
1426        index.insert(b"key", 123);
1427        let mut cursor = index.get_mut(b"key").unwrap();
1428        cursor.delete();
1429    }
1430
1431    #[test_traced]
1432    #[should_panic(expected = "must call Cursor::next()")]
1433    fn test_hash_index_cursor_delete_before_next_panics() {
1434        let runner = deterministic::Runner::default();
1435        runner.start(|context| async move {
1436            let mut index = new_unordered(context);
1437            run_index_cursor_delete_before_next_panics(&mut index);
1438        });
1439    }
1440
1441    #[test_traced]
1442    #[should_panic(expected = "must call Cursor::next()")]
1443    fn test_ordered_index_cursor_delete_before_next_panics() {
1444        let runner = deterministic::Runner::default();
1445        runner.start(|context| async move {
1446            let mut index = new_ordered(context);
1447            run_index_cursor_delete_before_next_panics(&mut index);
1448        });
1449    }
1450
1451    #[test_traced]
1452    #[should_panic(expected = "must call Cursor::next()")]
1453    fn test_partitioned_index_cursor_delete_before_next_panics() {
1454        let runner = deterministic::Runner::default();
1455        runner.start(|context| async move {
1456            {
1457                let mut index = new_partitioned_unordered(context.clone());
1458                run_index_cursor_delete_before_next_panics(&mut index);
1459            }
1460            {
1461                let mut index = new_partitioned_ordered(context);
1462                run_index_cursor_delete_before_next_panics(&mut index);
1463            }
1464        });
1465    }
1466
1467    fn run_index_cursor_update_after_done<I: Unordered<Value = u64>>(index: &mut I) {
1468        index.insert(b"key", 123);
1469        let mut cursor = index.get_mut(b"key").unwrap();
1470        assert_eq!(*cursor.next().unwrap(), 123);
1471        assert!(cursor.next().is_none());
1472        cursor.update(321);
1473    }
1474
1475    #[test_traced]
1476    #[should_panic(expected = "no active item in Cursor")]
1477    fn test_hash_index_cursor_update_after_done() {
1478        let runner = deterministic::Runner::default();
1479        runner.start(|context| async move {
1480            let mut index = new_unordered(context);
1481            run_index_cursor_update_after_done(&mut index);
1482        });
1483    }
1484
1485    #[test_traced]
1486    #[should_panic(expected = "no active item in Cursor")]
1487    fn test_ordered_index_cursor_update_after_done() {
1488        let runner = deterministic::Runner::default();
1489        runner.start(|context| async move {
1490            let mut index = new_ordered(context);
1491            run_index_cursor_update_after_done(&mut index);
1492        });
1493    }
1494
1495    #[test_traced]
1496    #[should_panic(expected = "no active item in Cursor")]
1497    fn test_partitioned_index_cursor_update_after_done() {
1498        let runner = deterministic::Runner::default();
1499        runner.start(|context| async move {
1500            {
1501                let mut index = new_partitioned_unordered(context.clone());
1502                run_index_cursor_update_after_done(&mut index);
1503            }
1504            {
1505                let mut index = new_partitioned_ordered(context);
1506                run_index_cursor_update_after_done(&mut index);
1507            }
1508        });
1509    }
1510
1511    fn run_index_cursor_insert_before_next<I: Unordered<Value = u64>>(index: &mut I) {
1512        index.insert(b"key", 123);
1513        let mut cursor = index.get_mut(b"key").unwrap();
1514        cursor.insert(321);
1515    }
1516
1517    #[test_traced]
1518    #[should_panic(expected = "must call Cursor::next()")]
1519    fn test_hash_index_cursor_insert_before_next() {
1520        let runner = deterministic::Runner::default();
1521        runner.start(|context| async move {
1522            let mut index = new_unordered(context);
1523            run_index_cursor_insert_before_next(&mut index);
1524        });
1525    }
1526
1527    #[test_traced]
1528    #[should_panic(expected = "must call Cursor::next()")]
1529    fn test_ordered_index_cursor_insert_before_next() {
1530        let runner = deterministic::Runner::default();
1531        runner.start(|context| async move {
1532            let mut index = new_ordered(context);
1533            run_index_cursor_insert_before_next(&mut index);
1534        });
1535    }
1536
1537    #[test_traced]
1538    #[should_panic(expected = "must call Cursor::next()")]
1539    fn test_partitioned_index_cursor_insert_before_next() {
1540        let runner = deterministic::Runner::default();
1541        runner.start(|context| async move {
1542            {
1543                let mut index = new_partitioned_unordered(context.clone());
1544                run_index_cursor_insert_before_next(&mut index);
1545            }
1546            {
1547                let mut index = new_partitioned_ordered(context);
1548                run_index_cursor_insert_before_next(&mut index);
1549            }
1550        });
1551    }
1552
1553    fn run_index_cursor_delete_after_done<I: Unordered<Value = u64>>(index: &mut I) {
1554        index.insert(b"key", 123);
1555        let mut cursor = index.get_mut(b"key").unwrap();
1556        assert_eq!(*cursor.next().unwrap(), 123);
1557        assert!(cursor.next().is_none());
1558        cursor.delete();
1559    }
1560
1561    #[test_traced]
1562    #[should_panic(expected = "no active item in Cursor")]
1563    fn test_hash_index_cursor_delete_after_done() {
1564        let runner = deterministic::Runner::default();
1565        runner.start(|context| async move {
1566            let mut index = new_unordered(context);
1567            run_index_cursor_delete_after_done(&mut index);
1568        });
1569    }
1570
1571    #[test_traced]
1572    #[should_panic(expected = "no active item in Cursor")]
1573    fn test_ordered_index_cursor_delete_after_done() {
1574        let runner = deterministic::Runner::default();
1575        runner.start(|context| async move {
1576            let mut index = new_ordered(context);
1577            run_index_cursor_delete_after_done(&mut index);
1578        });
1579    }
1580
1581    #[test_traced]
1582    #[should_panic(expected = "no active item in Cursor")]
1583    fn test_partitioned_index_cursor_delete_after_done() {
1584        let runner = deterministic::Runner::default();
1585        runner.start(|context| async move {
1586            {
1587                let mut index = new_partitioned_unordered(context.clone());
1588                run_index_cursor_delete_after_done(&mut index);
1589            }
1590            {
1591                let mut index = new_partitioned_ordered(context);
1592                run_index_cursor_delete_after_done(&mut index);
1593            }
1594        });
1595    }
1596
1597    fn run_index_cursor_insert_with_next<I: Unordered<Value = u64>>(index: &mut I) {
1598        index.insert(b"key", 123);
1599        index.insert(b"key", 456);
1600        let mut cursor = index.get_mut(b"key").unwrap();
1601        assert_eq!(*cursor.next().unwrap(), 123);
1602        assert_eq!(*cursor.next().unwrap(), 456);
1603        cursor.insert(789);
1604        assert_eq!(cursor.next(), None);
1605        cursor.insert(999);
1606        drop(cursor);
1607        let mut values = index.get(b"key").copied().collect::<Vec<_>>();
1608        values.sort();
1609        assert_eq!(values, vec![123, 456, 789, 999]);
1610    }
1611
1612    #[test_traced]
1613    fn test_hash_index_cursor_insert_with_next() {
1614        let runner = deterministic::Runner::default();
1615        runner.start(|context| async move {
1616            let mut index = new_unordered(context);
1617            run_index_cursor_insert_with_next(&mut index);
1618        });
1619    }
1620
1621    #[test_traced]
1622    fn test_ordered_index_cursor_insert_with_next() {
1623        let runner = deterministic::Runner::default();
1624        runner.start(|context| async move {
1625            let mut index = new_ordered(context);
1626            run_index_cursor_insert_with_next(&mut index);
1627        });
1628    }
1629
1630    #[test_traced]
1631    fn test_partitioned_index_cursor_insert_with_next() {
1632        let runner = deterministic::Runner::default();
1633        runner.start(|context| async move {
1634            {
1635                let mut index = new_partitioned_unordered(context.clone());
1636                run_index_cursor_insert_with_next(&mut index);
1637            }
1638            {
1639                let mut index = new_partitioned_ordered(context);
1640                run_index_cursor_insert_with_next(&mut index);
1641            }
1642        });
1643    }
1644
1645    fn run_index_cursor_double_delete<I: Unordered<Value = u64>>(index: &mut I) {
1646        index.insert(b"key", 123);
1647        index.insert(b"key", 456);
1648        let mut cursor = index.get_mut(b"key").unwrap();
1649        assert_eq!(*cursor.next().unwrap(), 123);
1650        cursor.delete();
1651        cursor.delete();
1652    }
1653
1654    #[test_traced]
1655    #[should_panic(expected = "must call Cursor::next()")]
1656    fn test_hash_index_cursor_double_delete() {
1657        let runner = deterministic::Runner::default();
1658        runner.start(|context| async move {
1659            let mut index = new_unordered(context);
1660            run_index_cursor_double_delete(&mut index);
1661        });
1662    }
1663
1664    #[test_traced]
1665    #[should_panic(expected = "must call Cursor::next()")]
1666    fn test_ordered_index_cursor_double_delete() {
1667        let runner = deterministic::Runner::default();
1668        runner.start(|context| async move {
1669            let mut index = new_ordered(context);
1670            run_index_cursor_double_delete(&mut index);
1671        });
1672    }
1673
1674    fn run_index_cursor_delete_last_then_next<I: Unordered<Value = u64>>(index: &mut I) {
1675        index.insert(b"key", 1);
1676        index.insert(b"key", 2);
1677        {
1678            let mut cursor = index.get_mut(b"key").unwrap();
1679            assert_eq!(*cursor.next().unwrap(), 1);
1680            assert_eq!(*cursor.next().unwrap(), 2);
1681            cursor.delete();
1682            assert!(cursor.next().is_none());
1683            assert!(cursor.next().is_none());
1684        }
1685        assert_eq!(index.keys(), 1);
1686        assert_eq!(index.items(), 1);
1687    }
1688
1689    #[test_traced]
1690    fn test_hash_index_cursor_delete_last_then_next() {
1691        let runner = deterministic::Runner::default();
1692        runner.start(|context| async move {
1693            let mut index = new_unordered(context);
1694            run_index_cursor_delete_last_then_next(&mut index);
1695        });
1696    }
1697
1698    #[test_traced]
1699    fn test_ordered_index_cursor_delete_last_then_next() {
1700        let runner = deterministic::Runner::default();
1701        runner.start(|context| async move {
1702            let mut index = new_ordered(context);
1703            run_index_cursor_delete_last_then_next(&mut index);
1704        });
1705    }
1706
1707    #[test_traced]
1708    fn test_partitioned_index_cursor_delete_last_then_next() {
1709        let runner = deterministic::Runner::default();
1710        runner.start(|context| async move {
1711            {
1712                let mut index = new_partitioned_unordered(context.clone());
1713                run_index_cursor_delete_last_then_next(&mut index);
1714            }
1715            {
1716                let mut index = new_partitioned_ordered(context);
1717                run_index_cursor_delete_last_then_next(&mut index);
1718            }
1719        });
1720    }
1721
1722    fn run_index_delete_in_middle_then_continue<I: Unordered<Value = u64>>(index: &mut I) {
1723        index.insert(b"key", 1);
1724        index.insert(b"key", 2);
1725        index.insert(b"key", 3);
1726        let mut cur = index.get_mut(b"key").unwrap();
1727        assert_eq!(*cur.next().unwrap(), 1);
1728        assert_eq!(*cur.next().unwrap(), 3);
1729        cur.delete();
1730        assert_eq!(*cur.next().unwrap(), 2);
1731        assert!(cur.next().is_none());
1732        assert!(cur.next().is_none());
1733    }
1734
1735    #[test_traced]
1736    fn test_hash_index_delete_in_middle_then_continue() {
1737        let runner = deterministic::Runner::default();
1738        runner.start(|context| async move {
1739            let mut index = new_unordered(context);
1740            run_index_delete_in_middle_then_continue(&mut index);
1741        });
1742    }
1743
1744    #[test_traced]
1745    fn test_ordered_index_delete_in_middle_then_continue() {
1746        let runner = deterministic::Runner::default();
1747        runner.start(|context| async move {
1748            let mut index = new_ordered(context);
1749            run_index_delete_in_middle_then_continue(&mut index);
1750        });
1751    }
1752
1753    fn run_index_delete_first<I: Unordered<Value = u64>>(index: &mut I) {
1754        index.insert(b"key", 1);
1755        index.insert(b"key", 2);
1756        index.insert(b"key", 3);
1757        {
1758            let mut cur = index.get_mut(b"key").unwrap();
1759            assert_eq!(*cur.next().unwrap(), 1);
1760            cur.delete();
1761            assert_eq!(*cur.next().unwrap(), 3);
1762            assert_eq!(*cur.next().unwrap(), 2);
1763            assert!(cur.next().is_none());
1764            assert!(cur.next().is_none());
1765        }
1766        assert_eq!(index.get(b"key").copied().collect::<Vec<_>>(), vec![3, 2]);
1767    }
1768
1769    #[test_traced]
1770    fn test_hash_index_delete_first() {
1771        let runner = deterministic::Runner::default();
1772        runner.start(|context| async move {
1773            let mut index = new_unordered(context);
1774            run_index_delete_first(&mut index);
1775        });
1776    }
1777
1778    #[test_traced]
1779    fn test_ordered_index_delete_first() {
1780        let runner = deterministic::Runner::default();
1781        runner.start(|context| async move {
1782            let mut index = new_ordered(context);
1783            run_index_delete_first(&mut index);
1784        });
1785    }
1786
1787    fn run_index_delete_first_and_insert<I: Unordered<Value = u64>>(index: &mut I) {
1788        index.insert(b"key", 1);
1789        index.insert(b"key", 2);
1790        index.insert(b"key", 3);
1791        assert_eq!(
1792            index.get(b"key").copied().collect::<Vec<_>>(),
1793            vec![1, 3, 2]
1794        );
1795        {
1796            let mut cur = index.get_mut(b"key").unwrap();
1797            assert_eq!(*cur.next().unwrap(), 1);
1798            cur.delete();
1799            assert_eq!(*cur.next().unwrap(), 3);
1800            cur.insert(4);
1801            assert_eq!(*cur.next().unwrap(), 2);
1802            assert!(cur.next().is_none());
1803            assert!(cur.next().is_none());
1804        }
1805        assert_eq!(
1806            index.get(b"key").copied().collect::<Vec<_>>(),
1807            vec![3, 4, 2]
1808        );
1809    }
1810
1811    #[test_traced]
1812    fn test_hash_index_delete_first_and_insert() {
1813        let runner = deterministic::Runner::default();
1814        runner.start(|context| async move {
1815            let mut index = new_unordered(context);
1816            run_index_delete_first_and_insert(&mut index);
1817        });
1818    }
1819
1820    #[test_traced]
1821    fn test_ordered_index_delete_first_and_insert() {
1822        let runner = deterministic::Runner::default();
1823        runner.start(|context| async move {
1824            let mut index = new_ordered(context);
1825            run_index_delete_first_and_insert(&mut index);
1826        });
1827    }
1828
1829    #[test_traced]
1830    fn test_partitioned_index_delete_first_and_insert() {
1831        let runner = deterministic::Runner::default();
1832        runner.start(|context| async move {
1833            {
1834                let mut index = new_partitioned_unordered(context.clone());
1835                run_index_delete_first_and_insert(&mut index);
1836            }
1837            {
1838                let mut index = new_partitioned_ordered(context);
1839                run_index_delete_first_and_insert(&mut index);
1840            }
1841        });
1842    }
1843
1844    fn run_index_insert_at_entry_then_next<I: Unordered<Value = u64>>(index: &mut I) {
1845        index.insert(b"key", 1);
1846        index.insert(b"key", 2);
1847        let mut cur = index.get_mut(b"key").unwrap();
1848        assert_eq!(*cur.next().unwrap(), 1);
1849        cur.insert(99);
1850        assert_eq!(*cur.next().unwrap(), 2);
1851        assert!(cur.next().is_none());
1852    }
1853
1854    #[test_traced]
1855    fn test_hash_index_insert_at_entry_then_next() {
1856        let runner = deterministic::Runner::default();
1857        runner.start(|context| async move {
1858            let mut index = new_unordered(context);
1859            run_index_insert_at_entry_then_next(&mut index);
1860        });
1861    }
1862
1863    #[test_traced]
1864    fn test_ordered_index_insert_at_entry_then_next() {
1865        let runner = deterministic::Runner::default();
1866        runner.start(|context| async move {
1867            let mut index = new_ordered(context);
1868            run_index_insert_at_entry_then_next(&mut index);
1869        });
1870    }
1871
1872    #[test_traced]
1873    fn test_partitioned_index_insert_at_entry_then_next() {
1874        let runner = deterministic::Runner::default();
1875        runner.start(|context| async move {
1876            {
1877                let mut index = new_partitioned_unordered(context.clone());
1878                run_index_insert_at_entry_then_next(&mut index);
1879            }
1880            {
1881                let mut index = new_partitioned_ordered(context);
1882                run_index_insert_at_entry_then_next(&mut index);
1883            }
1884        });
1885    }
1886
1887    fn run_index_insert_at_entry_then_delete_head<I: Unordered<Value = u64>>(index: &mut I) {
1888        index.insert(b"key", 10);
1889        index.insert(b"key", 20);
1890        let mut cur = index.get_mut(b"key").unwrap();
1891        assert_eq!(*cur.next().unwrap(), 10);
1892        cur.insert(15);
1893        cur.delete();
1894    }
1895
1896    #[test_traced]
1897    #[should_panic(expected = "must call Cursor::next()")]
1898    fn test_hash_index_insert_at_entry_then_delete_head() {
1899        let runner = deterministic::Runner::default();
1900        runner.start(|context| async move {
1901            let mut index = new_unordered(context);
1902            run_index_insert_at_entry_then_delete_head(&mut index);
1903        });
1904    }
1905
1906    #[test_traced]
1907    #[should_panic(expected = "must call Cursor::next()")]
1908    fn test_ordered_index_insert_at_entry_then_delete_head() {
1909        let runner = deterministic::Runner::default();
1910        runner.start(|context| async move {
1911            let mut index = new_ordered(context);
1912            run_index_insert_at_entry_then_delete_head(&mut index);
1913        });
1914    }
1915
1916    #[test_traced]
1917    #[should_panic(expected = "must call Cursor::next()")]
1918    fn test_partitioned_index_insert_at_entry_then_delete_head() {
1919        let runner = deterministic::Runner::default();
1920        runner.start(|context| async move {
1921            {
1922                let mut index = new_partitioned_unordered(context.clone());
1923                run_index_insert_at_entry_then_delete_head(&mut index);
1924            }
1925            {
1926                let mut index = new_partitioned_ordered(context);
1927                run_index_insert_at_entry_then_delete_head(&mut index);
1928            }
1929        });
1930    }
1931
1932    fn run_index_delete_then_insert_without_next<I: Unordered<Value = u64>>(index: &mut I) {
1933        index.insert(b"key", 10);
1934        index.insert(b"key", 20);
1935        let mut cur = index.get_mut(b"key").unwrap();
1936        assert_eq!(*cur.next().unwrap(), 10);
1937        assert_eq!(*cur.next().unwrap(), 20);
1938        cur.delete();
1939        cur.insert(15);
1940    }
1941
1942    #[test_traced]
1943    #[should_panic(expected = "must call Cursor::next()")]
1944    fn test_hash_index_delete_then_insert_without_next() {
1945        let runner = deterministic::Runner::default();
1946        runner.start(|context| async move {
1947            let mut index = new_unordered(context);
1948            run_index_delete_then_insert_without_next(&mut index);
1949        });
1950    }
1951
1952    #[test_traced]
1953    #[should_panic(expected = "must call Cursor::next()")]
1954    fn test_ordered_index_delete_then_insert_without_next() {
1955        let runner = deterministic::Runner::default();
1956        runner.start(|context| async move {
1957            let mut index = new_ordered(context);
1958            run_index_delete_then_insert_without_next(&mut index);
1959        });
1960    }
1961
1962    #[test_traced]
1963    #[should_panic(expected = "must call Cursor::next()")]
1964    fn test_partitioned_index_delete_then_insert_without_next() {
1965        let runner = deterministic::Runner::default();
1966        runner.start(|context| async move {
1967            {
1968                let mut index = new_partitioned_unordered(context.clone());
1969                run_index_delete_then_insert_without_next(&mut index);
1970            }
1971            {
1972                let mut index = new_partitioned_ordered(context);
1973                run_index_delete_then_insert_without_next(&mut index);
1974            }
1975        });
1976    }
1977
1978    fn run_index_inserts_without_next<I: Unordered<Value = u64>>(index: &mut I) {
1979        index.insert(b"key", 10);
1980        index.insert(b"key", 20);
1981        let mut cur = index.get_mut(b"key").unwrap();
1982        assert_eq!(*cur.next().unwrap(), 10);
1983        cur.insert(15);
1984        cur.insert(25);
1985    }
1986
1987    #[test_traced]
1988    #[should_panic(expected = "must call Cursor::next()")]
1989    fn test_hash_index_inserts_without_next() {
1990        let runner = deterministic::Runner::default();
1991        runner.start(|context| async move {
1992            let mut index = new_unordered(context);
1993            run_index_inserts_without_next(&mut index);
1994        });
1995    }
1996
1997    #[test_traced]
1998    #[should_panic(expected = "must call Cursor::next()")]
1999    fn test_ordered_index_inserts_without_next() {
2000        let runner = deterministic::Runner::default();
2001        runner.start(|context| async move {
2002            let mut index = new_ordered(context);
2003            run_index_inserts_without_next(&mut index);
2004        });
2005    }
2006
2007    #[test_traced]
2008    #[should_panic(expected = "must call Cursor::next()")]
2009    fn test_partitioned_index_inserts_without_next() {
2010        let runner = deterministic::Runner::default();
2011        runner.start(|context| async move {
2012            {
2013                let mut index = new_partitioned_unordered(context.clone());
2014                run_index_inserts_without_next(&mut index);
2015            }
2016            {
2017                let mut index = new_partitioned_ordered(context);
2018                run_index_inserts_without_next(&mut index);
2019            }
2020        });
2021    }
2022
2023    fn run_index_delete_last_then_insert_while_done<I: Unordered<Value = u64>>(index: &mut I) {
2024        index.insert(b"k", 7);
2025        {
2026            let mut cur = index.get_mut(b"k").unwrap();
2027            assert_eq!(*cur.next().unwrap(), 7);
2028            cur.delete();
2029            assert!(cur.next().is_none());
2030            cur.insert(8);
2031            assert!(cur.next().is_none());
2032            cur.insert(9);
2033            assert!(cur.next().is_none());
2034        }
2035        assert_eq!(index.keys(), 1);
2036        assert_eq!(index.items(), 2);
2037        assert_eq!(index.get(b"k").copied().collect::<Vec<_>>(), vec![8, 9]);
2038    }
2039
2040    #[test_traced]
2041    fn test_hash_index_delete_last_then_insert_while_done() {
2042        let runner = deterministic::Runner::default();
2043        runner.start(|context| async move {
2044            let mut index = new_unordered(context);
2045            run_index_delete_last_then_insert_while_done(&mut index);
2046        });
2047    }
2048
2049    #[test_traced]
2050    fn test_ordered_index_delete_last_then_insert_while_done() {
2051        let runner = deterministic::Runner::default();
2052        runner.start(|context| async move {
2053            let mut index = new_ordered(context);
2054            run_index_delete_last_then_insert_while_done(&mut index);
2055        });
2056    }
2057
2058    #[test_traced]
2059    fn test_partitioned_index_delete_last_then_insert_while_done() {
2060        let runner = deterministic::Runner::default();
2061        runner.start(|context| async move {
2062            {
2063                let mut index = new_partitioned_unordered(context.clone());
2064                run_index_delete_last_then_insert_while_done(&mut index);
2065            }
2066            {
2067                let mut index = new_partitioned_ordered(context);
2068                run_index_delete_last_then_insert_while_done(&mut index);
2069            }
2070        });
2071    }
2072
2073    fn run_index_drop_mid_iteration_relinks<I: Unordered<Value = u64>>(index: &mut I) {
2074        for i in 0..5 {
2075            index.insert(b"z", i);
2076        }
2077        {
2078            let mut cur = index.get_mut(b"z").unwrap();
2079            cur.next();
2080            cur.next();
2081        }
2082        assert_eq!(
2083            index.get(b"z").copied().collect::<Vec<_>>(),
2084            vec![0, 4, 3, 2, 1]
2085        );
2086    }
2087
2088    #[test_traced]
2089    fn test_hash_index_drop_mid_iteration_relinks() {
2090        let runner = deterministic::Runner::default();
2091        runner.start(|context| async move {
2092            let mut index = new_unordered(context);
2093            run_index_drop_mid_iteration_relinks(&mut index);
2094        });
2095    }
2096
2097    #[test_traced]
2098    fn test_ordered_index_drop_mid_iteration_relinks() {
2099        let runner = deterministic::Runner::default();
2100        runner.start(|context| async move {
2101            let mut index = new_ordered(context);
2102            run_index_drop_mid_iteration_relinks(&mut index);
2103        });
2104    }
2105
2106    #[test_traced]
2107    fn test_partitioned_index_drop_mid_iteration_relinks() {
2108        let runner = deterministic::Runner::default();
2109        runner.start(|context| async move {
2110            {
2111                let mut index = new_partitioned_unordered(context.clone());
2112                run_index_drop_mid_iteration_relinks(&mut index);
2113            }
2114            {
2115                let mut index = new_partitioned_ordered(context);
2116                run_index_drop_mid_iteration_relinks(&mut index);
2117            }
2118        });
2119    }
2120
2121    fn run_index_update_before_next_panics<I: Unordered<Value = u64>>(index: &mut I) {
2122        index.insert(b"p", 1);
2123        let mut cur = index.get_mut(b"p").unwrap();
2124        cur.update(2);
2125    }
2126
2127    #[test_traced]
2128    #[should_panic(expected = "must call Cursor::next()")]
2129    fn test_hash_index_update_before_next_panics() {
2130        let runner = deterministic::Runner::default();
2131        runner.start(|context| async move {
2132            let mut index = new_unordered(context);
2133            run_index_update_before_next_panics(&mut index);
2134        });
2135    }
2136
2137    #[test_traced]
2138    #[should_panic(expected = "must call Cursor::next()")]
2139    fn test_ordered_index_update_before_next_panics() {
2140        let runner = deterministic::Runner::default();
2141        runner.start(|context| async move {
2142            let mut index = new_ordered(context);
2143            run_index_update_before_next_panics(&mut index);
2144        });
2145    }
2146
2147    #[test_traced]
2148    #[should_panic(expected = "must call Cursor::next()")]
2149    fn test_partitioned_index_update_before_next_panics() {
2150        let runner = deterministic::Runner::default();
2151        runner.start(|context| async move {
2152            {
2153                let mut index = new_partitioned_unordered(context.clone());
2154                run_index_update_before_next_panics(&mut index);
2155            }
2156            {
2157                let mut index = new_partitioned_ordered(context);
2158                run_index_update_before_next_panics(&mut index);
2159            }
2160        });
2161    }
2162
2163    fn run_index_entry_replacement_not_a_collision<I: Unordered<Value = u64>>(index: &mut I) {
2164        index.insert(b"a", 1);
2165        {
2166            let mut cur = index.get_mut(b"a").unwrap();
2167            cur.next();
2168            cur.delete();
2169            cur.next();
2170            cur.insert(2);
2171        }
2172        assert_eq!(index.keys(), 1);
2173        assert_eq!(index.items(), 1);
2174    }
2175
2176    #[test_traced]
2177    fn test_hash_index_entry_replacement_not_a_collision() {
2178        let runner = deterministic::Runner::default();
2179        runner.start(|context| async move {
2180            let mut index = new_unordered(context);
2181            run_index_entry_replacement_not_a_collision(&mut index);
2182        });
2183    }
2184
2185    #[test_traced]
2186    fn test_ordered_index_entry_replacement_not_a_collision() {
2187        let runner = deterministic::Runner::default();
2188        runner.start(|context| async move {
2189            let mut index = new_ordered(context);
2190            run_index_entry_replacement_not_a_collision(&mut index);
2191        });
2192    }
2193
2194    #[test_traced]
2195    fn test_partitioned_index_entry_replacement_not_a_collision() {
2196        let runner = deterministic::Runner::default();
2197        runner.start(|context| async move {
2198            {
2199                let mut index = new_partitioned_unordered(context.clone());
2200                run_index_entry_replacement_not_a_collision(&mut index);
2201            }
2202            {
2203                let mut index = new_partitioned_ordered(context);
2204                run_index_entry_replacement_not_a_collision(&mut index);
2205            }
2206        });
2207    }
2208
2209    fn run_index_large_collision_chain_stack_overflow<I: Unordered<Value = u64>>(index: &mut I) {
2210        for i in 0..50000 {
2211            index.insert(b"", i as u64);
2212        }
2213    }
2214
2215    #[test_traced]
2216    fn test_hash_index_large_collision_chain_stack_overflow() {
2217        let runner = deterministic::Runner::default();
2218        runner.start(|context| async move {
2219            let mut index = new_unordered(context);
2220            run_index_large_collision_chain_stack_overflow(&mut index);
2221        });
2222    }
2223
2224    #[test_traced]
2225    fn test_ordered_index_large_collision_chain_stack_overflow() {
2226        let runner = deterministic::Runner::default();
2227        runner.start(|context| async move {
2228            let mut index = new_ordered(context);
2229            run_index_large_collision_chain_stack_overflow(&mut index);
2230        });
2231    }
2232
2233    #[test_traced]
2234    fn test_partitioned_index_large_collision_chain_stack_overflow() {
2235        let runner = deterministic::Runner::default();
2236        runner.start(|context| async move {
2237            {
2238                let mut index = new_partitioned_unordered(context.clone());
2239                run_index_large_collision_chain_stack_overflow(&mut index);
2240            }
2241            {
2242                let mut index = new_partitioned_ordered(context);
2243                run_index_large_collision_chain_stack_overflow(&mut index);
2244            }
2245        });
2246    }
2247}