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