Skip to main content

commonware_storage/index/
mod.rs

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