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