Skip to main content

fxfs/lsm_tree/
merge.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::log::*;
6use crate::lsm_tree::TreeCounters;
7use crate::lsm_tree::types::{
8    BoxedItem, Item, ItemRef, Key, Layer, LayerIterator, LayerIteratorMut, LayerKey,
9    MaybeContainsKey, MergeType, OrdLowerBound, Value,
10};
11use anyhow::Error;
12use futures::future::BoxFuture;
13use futures::try_join;
14use std::cmp::Ordering;
15use std::collections::BinaryHeap;
16use std::fmt::{Debug, Write};
17use std::ops::{Bound, Deref, DerefMut};
18use std::sync::{Arc, atomic};
19
20#[derive(Debug, Eq, PartialEq)]
21pub enum ItemOp<K, V> {
22    /// Keeps the item to be presented to the merger subsequently with a new merge pair.
23    Keep,
24
25    /// Discards the item and moves on to the next item in the respective layer.
26    Discard,
27
28    /// Replaces the item with something new which will be presented to the merger subsequently with
29    /// a new pair.
30    Replace(BoxedItem<K, V>),
31}
32
33#[derive(Debug, Eq, PartialEq)]
34pub enum MergeResult<K, V> {
35    /// Emits the left item unchanged. Keeps the right item. This is the common case. Once an item
36    /// has been emitted, it will never be seen again by the merge function.
37    EmitLeft,
38
39    /// All other merge results are covered by the following. Take care when replacing items
40    /// that you replace the correct item. The merger will never merge two items together from
41    /// the same layer. Consider the following scenario:
42    ///
43    ///        +-----------+              +-----------+
44    /// 0:     |    A      |              |    C      |
45    ///        +-----------+--------------+-----------+
46    /// 1:                 |      B       |
47    ///                    +--------------+
48    ///
49    /// Let's say that all three items can be merged together. The merge function will first be
50    /// presented with items A and B, at which point it has the option of replacing the left item
51    /// (i.e. A, in layer 0) or the right item (i.e. B in layer 1). However, if you replace the left
52    /// item, the merge function will not then be given the opportunity to merge it with C, so the
53    /// correct thing to do in this case is to replace the right item B in layer 1, and discard the
54    /// left item. A rule you can use is that you should avoid replacing an item with another item
55    /// whose upper bound exceeds that of the item you are replacing.
56    ///
57    /// There are some combinations that might lead to infinite loops (e.g. None, Keep, Keep) and
58    /// should obviously be avoided.
59    Other { emit: Option<BoxedItem<K, V>>, left: ItemOp<K, V>, right: ItemOp<K, V> },
60}
61
62/// Users must provide a merge function which will take pairs of items, left and right, and return a
63/// merge result. The left item's key will either be less than the right item's key, or if they are
64/// the same, then the left item will be in a lower layer index (lower layer indexes indicate more
65/// recent entries). The last remaining item is always emitted.
66pub type MergeFn<K, V> =
67    fn(&MergeLayerIterator<'_, K, V>, &MergeLayerIterator<'_, K, V>) -> MergeResult<K, V>;
68
69pub enum MergeItem<K, V> {
70    None,
71    Item(BoxedItem<K, V>),
72    Iter,
73}
74
75enum RawIterator<'a, K, V> {
76    None,
77    Const(Box<dyn LayerIterator<K, V> + 'a>),
78    Mut(Box<dyn LayerIteratorMut<K, V> + 'a>),
79}
80
81// SAFETY: LayerIteratorMut is not Sync or Send, but it's only used by merge_into, which doesn't
82// send across threads (and is sync, not async).
83unsafe impl<K, V> Send for RawIterator<'_, K, V> {}
84
85// An iterator that keeps track of where we are for each of the layers. We push these onto a
86// min-heap.
87pub struct MergeLayerIterator<'a, K, V> {
88    layer: Option<&'a dyn Layer<K, V>>,
89
90    // The underlying iterator.
91    iter: RawIterator<'a, K, V>,
92
93    // The index of the layer this is for.
94    pub layer_index: u16,
95
96    // The item we are currently pointing at.
97    item: MergeItem<K, V>,
98}
99
100impl<'a, K, V> MergeLayerIterator<'a, K, V> {
101    pub fn key(&self) -> &K {
102        self.item().key
103    }
104
105    pub fn value(&self) -> &V {
106        self.item().value
107    }
108
109    fn new(layer_index: u16, layer: &'a dyn Layer<K, V>) -> Self {
110        MergeLayerIterator {
111            layer: Some(layer),
112            iter: RawIterator::None,
113            layer_index,
114            item: MergeItem::None,
115        }
116    }
117
118    fn new_with_item(layer_index: u16, item: MergeItem<K, V>) -> Self {
119        MergeLayerIterator { layer: None, iter: RawIterator::None, layer_index, item }
120    }
121
122    fn item(&self) -> ItemRef<'_, K, V> {
123        match &self.item {
124            MergeItem::None => panic!("No item!"),
125            MergeItem::Item(item) => item.as_item_ref(),
126            MergeItem::Iter => self.get().unwrap(),
127        }
128    }
129
130    fn get(&self) -> Option<ItemRef<'_, K, V>> {
131        match &self.iter {
132            RawIterator::None => panic!("No iterator!"),
133            RawIterator::Const(iter) => iter.get(),
134            RawIterator::Mut(iter) => iter.get(),
135        }
136    }
137
138    fn set_item_from_iter(&mut self) {
139        self.item = if match &self.iter {
140            RawIterator::None => unreachable!(),
141            RawIterator::Const(iter) => iter.get(),
142            RawIterator::Mut(iter) => iter.get(),
143        }
144        .is_some()
145        {
146            MergeItem::Iter
147        } else {
148            MergeItem::None
149        };
150    }
151
152    fn take_item(&mut self) -> Option<BoxedItem<K, V>> {
153        if matches!(self.item, MergeItem::Item(_)) {
154            if let MergeItem::Item(item) = std::mem::replace(&mut self.item, MergeItem::None) {
155                return Some(item);
156            }
157        }
158        None
159    }
160
161    async fn advance(&mut self) -> Result<(), Error> {
162        if let MergeItem::Iter = self.item {
163            if let RawIterator::Const(iter) = &mut self.iter {
164                iter.advance().await?;
165            } else {
166                // This will never get called in the RawIterator::Mut case.
167                unreachable!();
168            }
169        }
170        self.set_item_from_iter();
171        Ok(())
172    }
173
174    fn replace(&mut self, item: BoxedItem<K, V>) {
175        self.item = MergeItem::Item(item);
176    }
177
178    fn is_some(&self) -> bool {
179        !matches!(self.item, MergeItem::None)
180    }
181
182    // This function exists so that we can advance multiple iterators concurrently using, say,
183    // try_join!.
184    async fn maybe_advance(&mut self, op: &ItemOp<K, V>) -> Result<(), Error> {
185        if let ItemOp::Keep = op { Ok(()) } else { self.advance().await }
186    }
187}
188
189// -- Ord and friends --
190impl<K: OrdLowerBound, V> Ord for MergeLayerIterator<'_, K, V> {
191    fn cmp(&self, other: &Self) -> Ordering {
192        // Reverse ordering because we want min-heap not max-heap.
193        other.key().cmp_lower_bound(self.key()).then(other.layer_index.cmp(&self.layer_index))
194    }
195}
196impl<K: OrdLowerBound, V> PartialOrd for MergeLayerIterator<'_, K, V> {
197    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
198        Some(self.cmp(other))
199    }
200}
201impl<K: OrdLowerBound, V> PartialEq for MergeLayerIterator<'_, K, V> {
202    fn eq(&self, other: &Self) -> bool {
203        self.cmp(other) == Ordering::Equal
204    }
205}
206impl<K: OrdLowerBound, V> Eq for MergeLayerIterator<'_, K, V> {}
207
208// As we merge items, the current item can be an item that has been replaced (and later emitted) by
209// the merge function, or an item referenced by an iterator, or nothing.
210enum CurrentItem<'a, 'b, K, V> {
211    None,
212    Item(BoxedItem<K, V>),
213    Iterator(&'a mut MergeLayerIterator<'b, K, V>),
214}
215
216impl<'a, 'b, K, V> CurrentItem<'a, 'b, K, V> {
217    fn take_iterator(&mut self) -> Option<&'a mut MergeLayerIterator<'b, K, V>> {
218        if matches!(self, CurrentItem::Iterator(_)) {
219            if let CurrentItem::Iterator(iter) = std::mem::replace(self, CurrentItem::None) {
220                return Some(iter);
221            }
222        }
223        None
224    }
225}
226
227impl<'a, K, V> From<&'a CurrentItem<'_, '_, K, V>> for Option<ItemRef<'a, K, V>> {
228    fn from(iter: &'a CurrentItem<'_, '_, K, V>) -> Option<ItemRef<'a, K, V>> {
229        match iter {
230            CurrentItem::None => None,
231            CurrentItem::Iterator(iterator) => Some(iterator.item()),
232            CurrentItem::Item(item) => Some(item.as_item_ref()),
233        }
234    }
235}
236
237/// Merger is the main entry point to merging.
238pub struct Merger<'a, K, V> {
239    // A buffer containing all the MergeLayerIterator objects.
240    iterators: Vec<MergeLayerIterator<'a, K, V>>,
241
242    // The function to be used for merging items.
243    merge_fn: MergeFn<K, V>,
244
245    // If true, additional logging is enabled.
246    trace: bool,
247
248    // Tracks statistics related to the LSM tree.
249    counters: Arc<TreeCounters>,
250}
251
252/// Query describes the goal of a search in the LSM tree.  The caller specifies this to guide the
253/// merger on which layer files it must consult.
254/// Layers might be skipped during a query for a few reasons:
255///   * Existence filters might allow layer files to be skipped.
256///   * For bounded queries (i.e. any except FullScan), if the search key has
257///     MergeType::OptimizedMerge, we can use that to omit older layers once we find a match.
258#[derive(Debug, Clone)]
259pub enum Query<'a, K: Key + LayerKey + OrdLowerBound> {
260    /// Point queries look for a specific key in the LSM tree.  In this case, the existence filters
261    /// for each layer file can be used to decide if the layer file needs to be consulted.
262    /// Note that it is an error to use `Point` for range-like keys.  Either `LimitedRange` or
263    /// `FullRange` must be used instead.
264    Point(&'a K),
265
266    /// LimitedRange queries allow for iteration over a range of keys.  The returned iterator will
267    /// not necessarily terminate at the end of the range; the caller should stop iterating when the
268    /// iterator passes the end of the range: the records returned cannot be relied upon as
269    /// accurate.  For a LimitedRange query, the existence filters for each layer file can be used,
270    /// but we have to check for all possible keys in the range we wish to search.  Obviously, that
271    /// means that the range should be, well, limited.  Fuzzy hashes permit this for extent-like
272    /// keys, but these queries are not the right choice for things like searching a directory.
273    LimitedRange(&'a K),
274
275    /// FullRange queries position the iterator to a starting key, and scans forward to the first
276    /// key of a different type.  In this case, the existence filters are not used.  The key should
277    /// be a search key (see `LayerKey::search_key`) (which, for extent based keys, would normally
278    /// be `start..start + 1`).  This kind of query will still use optimized merges if the keys
279    /// found support it.
280    FullRange(&'a K),
281
282    /// FullScan queries are intended to yield every record in the tree.  In this case, the
283    /// existence filters are not used.
284    FullScan,
285}
286
287impl<'a, K: Key + LayerKey + OrdLowerBound> Query<'a, K> {
288    fn check_layer<V>(&self, layer: &dyn Layer<K, V>) -> MaybeContainsKey {
289        match self {
290            Self::Point(key) => layer.maybe_contains_key(key),
291            Self::LimitedRange(key) => layer.maybe_contains_key(key),
292            Self::FullRange(_) => MaybeContainsKey::Maybe,
293            Self::FullScan => MaybeContainsKey::Maybe,
294        }
295    }
296}
297
298#[fxfs_trace::trace]
299impl<'a, K: Key + LayerKey + OrdLowerBound, V: Value> Merger<'a, K, V> {
300    pub(super) fn new<I: Iterator<Item = &'a dyn Layer<K, V>>>(
301        layers: I,
302        merge_fn: MergeFn<K, V>,
303        counters: Arc<TreeCounters>,
304    ) -> Merger<'a, K, V> {
305        Merger {
306            iterators: layers
307                .enumerate()
308                .map(|(index, layer)| MergeLayerIterator::new(index as u16, layer))
309                .collect(),
310            merge_fn: merge_fn,
311            trace: false,
312            counters,
313        }
314    }
315
316    /// Executes `query`, positioning the iterator to the first matching item.  See `Query` for
317    /// details.
318    #[trace]
319    pub async fn query(
320        &mut self,
321        query: Query<'_, K>,
322    ) -> Result<MergerIterator<'_, 'a, K, V>, Error> {
323        if let Query::Point(key) = query {
324            // NB: It is almost certainly an error to provide a range-like key to a Point query,
325            // hence this debug assertion.  This will most likely result in the wrong result, since
326            // the starting bound would be the original range key and therefore we might miss
327            // records that start earlier but overlap with the key.
328            // For example, if there is a layer which contains 0..100 and 100..200, and we search
329            // for 50..150, we should get both extents, which requires a different starting bound
330            // than 50..150 (particularly it would require the `K::search_key`).
331            debug_assert!(!key.is_range_key())
332        };
333        let len = self.iterators.len();
334        let mut excessive_partitions = false;
335        let pending_iterators = {
336            fxfs_trace::duration!("Merger::filter_layer_files", "len" => len);
337            self.iterators
338                .iter_mut()
339                .rev()
340                .filter(|l| match query.check_layer(l.layer.unwrap()) {
341                    MaybeContainsKey::False => {
342                        // Range-based queries are not able to properly measure false positives
343                        // since it is possible for them to find a key different than the one that
344                        // hit in the Bloom filter, which would skew the false positive rate.
345                        // Therefore, we only record negatives for point queries.
346                        if matches!(query, Query::Point(_)) {
347                            self.counters
348                                .bloom_filter_negatives
349                                .fetch_add(1, atomic::Ordering::Relaxed);
350                        }
351                        false
352                    }
353                    MaybeContainsKey::Maybe => true,
354                    MaybeContainsKey::RangeKeyTooLarge => {
355                        excessive_partitions = true;
356                        true
357                    }
358                })
359                .collect::<Vec<&mut MergeLayerIterator<'a, K, V>>>()
360        };
361        let layer_count = pending_iterators.len();
362        {
363            self.counters.num_seeks.fetch_add(1, atomic::Ordering::Relaxed);
364            self.counters.layer_files_total.fetch_add(len, atomic::Ordering::Relaxed);
365            self.counters
366                .layer_files_skipped
367                .fetch_add(len - layer_count, atomic::Ordering::Relaxed);
368            if excessive_partitions {
369                self.counters.excessive_hash_partitions.fetch_add(1, atomic::Ordering::Relaxed);
370            }
371        }
372        log::debug!(query:?; "Consulting {}/{} layers", layer_count, len);
373        let mut merger_iter = MergerIterator {
374            merge_fn: self.merge_fn,
375            pending_iterators,
376            heap: BinaryHeap::with_capacity(layer_count),
377            item: CurrentItem::None,
378            trace: self.trace,
379            history: String::new(),
380        };
381        let owned_key;
382        let search_key = match query {
383            Query::Point(key) => Bound::Included(key),
384            Query::LimitedRange(key) => match key.search_key() {
385                Some(k) => {
386                    owned_key = k;
387                    Bound::Included(&owned_key)
388                }
389                None => Bound::Included(key),
390            },
391            Query::FullRange(key) => {
392                assert!(key.is_search_key());
393                Bound::Included(key)
394            }
395            Query::FullScan => Bound::Unbounded,
396        };
397        // Range-based queries are not able to properly measure false positives since it is
398        // possible for them to find a key different than the one that hit in the Bloom filter,
399        // which would skew the values. Therefore, we only pass bloom counters for point queries.
400        let bloom_counters = matches!(query, Query::Point(_)).then_some(&*self.counters);
401        merger_iter.seek(search_key, bloom_counters).await?;
402        Ok(merger_iter)
403    }
404
405    pub fn set_trace(&mut self, v: bool) {
406        self.trace = v;
407    }
408}
409
410/// This is an iterator that will allow iteration over merged layers.  The primary interface is via
411/// the LayerIterator trait.
412pub struct MergerIterator<'a, 'b, K, V> {
413    merge_fn: MergeFn<K, V>,
414
415    // Iterators that we have not yet pushed onto the heap.
416    pending_iterators: Vec<&'a mut MergeLayerIterator<'b, K, V>>,
417
418    // A heap with the merge iterators.
419    heap: BinaryHeap<&'a mut MergeLayerIterator<'b, K, V>>,
420
421    // The current item.
422    item: CurrentItem<'a, 'b, K, V>,
423
424    // If true, logs regarding merger behaviour are appended to history.
425    trace: bool,
426
427    // Holds trace information if trace is true.
428    history: String,
429}
430
431impl<'a, 'b, K: Key + LayerKey + OrdLowerBound, V: Value> MergerIterator<'a, 'b, K, V> {
432    pub fn pending_iterators_len(&self) -> usize {
433        self.pending_iterators.len()
434    }
435
436    /// Positions the iterator using `search_key`.
437    async fn seek(
438        &mut self,
439        search_key: Bound<&K>,
440        bloom_counters: Option<&TreeCounters>,
441    ) -> Result<(), Error> {
442        self.push_iterators(search_key, bloom_counters).await?;
443        self.advance_impl(search_key).await
444    }
445
446    // Merges items from an array of layers using the provided merge function. The merge function is
447    // repeatedly provided the lowest and the second lowest element, if one exists. In cases where
448    // the two lowest elements compare equal, the element with the lowest layer (i.e. whichever
449    // comes first in the layers array) will come first.  `search_key` is a bound for the next
450    // key we expect.
451    async fn advance_impl(&mut self, search_key: Bound<&K>) -> Result<(), Error> {
452        loop {
453            loop {
454                if self.heap.is_empty() {
455                    self.item = CurrentItem::None;
456                    return Ok(());
457                }
458                let lowest = self.heap.pop().unwrap();
459                let maybe_second_lowest = self.heap.pop();
460                if let Some(second_lowest) = maybe_second_lowest {
461                    let result = (self.merge_fn)(&lowest, &second_lowest);
462                    if self.trace {
463                        writeln!(
464                            self.history,
465                            "merge {:?}, {:?} -> {:?}",
466                            lowest.item(),
467                            second_lowest.item(),
468                            result
469                        )
470                        .unwrap();
471                    }
472                    match result {
473                        MergeResult::EmitLeft => {
474                            self.heap.push(second_lowest);
475                            self.item = CurrentItem::Iterator(lowest);
476                            break;
477                        }
478                        MergeResult::Other { emit, left, right } => {
479                            try_join!(
480                                lowest.maybe_advance(&left),
481                                second_lowest.maybe_advance(&right)
482                            )?;
483                            self.update_item(lowest, left);
484                            self.update_item(second_lowest, right);
485                            if let Some(emit) = emit {
486                                self.item = CurrentItem::Item(emit);
487                                break;
488                            }
489                        }
490                    }
491                } else {
492                    self.item = CurrentItem::Iterator(lowest);
493                    break;
494                }
495            }
496
497            // If the item we're about to yield isn't within `search_key`, ignore it and
498            // continue.  To see how this would happen, imagine the following scenario:
499            //
500            //       0          10          20            30
501            //       +----------+
502            //   0   |          |
503            //       +----------+-----------+
504            //   1   |                      |
505            //       +----------------------+-------------+
506            //   2   |                                    |
507            //       +------------------------------------+
508            //
509            // If we are to seek for 0..1 and then iterate over what we find, we expect the sequence
510            // 0..10, 10..20, 20..30.  After the first seek, we should only consult iterator 0.  For
511            // the first advance, we will consult iterator 1 but we need to merge the 0..20 element
512            // with the 0..10 element which we already emitted.  To make this work, we push the
513            // 0..10 item back on the heap (see advance) and then merge, but that will yield the
514            // 0..10 entry again, so here we need to skip over it, and then merge again, at which
515            // point we should see the 10..20 entry as expected.
516            match search_key {
517                Bound::Included(key)
518                    if self.get().unwrap().key.cmp_upper_bound(key) == Ordering::Less => {}
519                Bound::Excluded(key)
520                    if self.get().unwrap().key.cmp_upper_bound(key) != Ordering::Greater => {}
521                _ => return Ok(()),
522            }
523            if let Some(iterator) = self.item.take_iterator() {
524                iterator.advance().await?;
525                if iterator.is_some() {
526                    self.heap.push(iterator);
527                }
528            }
529        }
530    }
531
532    // Returns whether more iterators are required for the given `search_key`.  See push_iterators.
533    fn needs_more_iterators(&self, search_key: Bound<&K>) -> bool {
534        if self.pending_iterators.is_empty() {
535            return false;
536        }
537        if self.heap.is_empty() {
538            return true;
539        }
540        let Bound::Included(target) = search_key else { return true };
541        match target.merge_type() {
542            MergeType::FullMerge => true,
543            MergeType::OptimizedMerge => !self.heap.peek().unwrap().key().overlaps(target),
544        }
545    }
546
547    // Pushes additional iterators onto the heap until we are confident that the top element will
548    // yield what we are looking for.
549    async fn push_iterators(
550        &mut self,
551        search_key: Bound<&K>,
552        bloom_counters: Option<&TreeCounters>,
553    ) -> Result<(), Error> {
554        while self.needs_more_iterators(search_key) {
555            let iter = self.pending_iterators.pop().unwrap();
556            let layer = iter.layer.as_ref().unwrap();
557            let sub_iter = layer.seek(search_key).await?;
558            if let (Some(counters), Bound::Included(target)) = (bloom_counters, search_key)
559                && layer.has_bloom_filter()
560            {
561                let found =
562                    sub_iter.get().is_some_and(|item| item.key.cmp_upper_bound(target).is_eq());
563                if !found {
564                    counters.bloom_filter_false_positives.fetch_add(1, atomic::Ordering::Relaxed);
565                }
566            }
567            if self.trace {
568                writeln!(
569                    self.history,
570                    "merger: search for {:?}, found {:?}",
571                    search_key,
572                    sub_iter.get()
573                )
574                .unwrap();
575            }
576            iter.iter = RawIterator::Const(sub_iter);
577            iter.set_item_from_iter();
578            if iter.is_some() {
579                self.heap.push(iter);
580            }
581        }
582        Ok(())
583    }
584
585    // Updates the merge iterator depending on |op|. If discarding, the iterator should have already
586    // been advanced.
587    fn update_item(&mut self, item: &'a mut MergeLayerIterator<'b, K, V>, op: ItemOp<K, V>) {
588        match op {
589            ItemOp::Keep => self.heap.push(item),
590            ItemOp::Discard => {
591                // The iterator should have already been advanced.
592                if item.is_some() {
593                    self.heap.push(item);
594                }
595            }
596            ItemOp::Replace(replacement) => {
597                item.replace(replacement);
598                self.heap.push(item);
599            }
600        }
601    }
602}
603
604impl<'a, K: Key + LayerKey + OrdLowerBound, V: Value> LayerIterator<K, V>
605    for MergerIterator<'a, '_, K, V>
606{
607    async fn advance(&mut self) -> Result<(), Error> {
608        let owned_key;
609        let mut search_key = Bound::Unbounded;
610        if !self.pending_iterators.is_empty() {
611            if let Some(ItemRef { key, .. }) = self.get() {
612                match key.next_key() {
613                    Some(k) => {
614                        assert!(k.is_search_key());
615                        owned_key = k;
616                        search_key = Bound::Included(&owned_key);
617                    }
618                    None => {
619                        owned_key = key.clone();
620                        search_key = Bound::Excluded(&owned_key);
621                    }
622                }
623            }
624        }
625
626        // Advance the iterator for the current item and push it onto the heap, and also push any
627        // additional iterators onto the heap (by calling push_iterators).
628        if let Some(iterator) = self.item.take_iterator() {
629            if self.needs_more_iterators(search_key) {
630                let existing_item = iterator.item().boxed();
631                iterator.advance().await?;
632                if let Bound::Included(s) = search_key
633                    && iterator.is_some()
634                    && iterator.key().merge_type() == MergeType::OptimizedMerge
635                    && s.overlaps(iterator.key())
636                {
637                    // In this case, the key immediately following is a good candidate, and all
638                    // we need to do is merge it with existing iterators; we shouldn't need to
639                    // consult with any more iterators.
640                } else {
641                    // We are going to need to consult more iterators so we need to go back to
642                    // the previous item so that we can merge with it.  See the comment in
643                    // advance_impl.
644                    iterator.replace(existing_item);
645
646                    // We must push other iterators here before pushing iterator onto the heap
647                    // because we know `iterator` would end up at the top of the heap.
648                    self.push_iterators(search_key, None).await?;
649                }
650            } else {
651                iterator.advance().await?;
652            }
653            if iterator.is_some() {
654                self.heap.push(iterator);
655            }
656        } else {
657            self.push_iterators(search_key, None).await?;
658        }
659
660        self.advance_impl(search_key).await
661    }
662
663    fn advance_dyn<'b>(&'b mut self) -> Result<Option<BoxFuture<'b, Result<(), Error>>>, Error> {
664        Ok(Some(Box::pin(self.advance())))
665    }
666
667    fn get(&self) -> Option<ItemRef<'_, K, V>> {
668        (&self.item).into()
669    }
670}
671
672struct MutMergeLayerIterator<'a, K, V>(MergeLayerIterator<'a, K, V>);
673
674impl<K, V> MutMergeLayerIterator<'_, K, V> {
675    fn advance(&mut self) {
676        if let MergeItem::Iter = self.item {
677            self.as_mut().advance();
678        }
679        self.set_item_from_iter();
680    }
681}
682
683impl<'a, K, V> AsMut<dyn LayerIteratorMut<K, V> + 'a> for MutMergeLayerIterator<'a, K, V> {
684    fn as_mut(&mut self) -> &mut (dyn LayerIteratorMut<K, V> + 'a) {
685        let RawIterator::Mut(iter) = &mut self.0.iter else { unreachable!() };
686        iter.as_mut()
687    }
688}
689
690impl<'a, K, V> Deref for MutMergeLayerIterator<'a, K, V> {
691    type Target = MergeLayerIterator<'a, K, V>;
692
693    fn deref(&self) -> &Self::Target {
694        &self.0
695    }
696}
697
698impl<K, V> DerefMut for MutMergeLayerIterator<'_, K, V> {
699    fn deref_mut(&mut self) -> &mut Self::Target {
700        &mut self.0
701    }
702}
703
704// Merges the given item into a mutable layer.
705pub(super) fn merge_into<K: Debug + OrdLowerBound, V: Debug>(
706    mut_iter: Box<dyn LayerIteratorMut<K, V> + '_>,
707    item: Item<K, V>,
708    merge_fn: MergeFn<K, V>,
709) -> Result<(), Error> {
710    let merge_item = if mut_iter.get().is_some() { MergeItem::Iter } else { MergeItem::None };
711    let mut mut_merge_iter = MutMergeLayerIterator(MergeLayerIterator {
712        layer: None,
713        iter: RawIterator::Mut(mut_iter),
714        layer_index: 1,
715        item: merge_item,
716    });
717    let mut item_merge_iter = MergeLayerIterator::new_with_item(0, MergeItem::Item(item.boxed()));
718    while mut_merge_iter.is_some() && item_merge_iter.is_some() {
719        if mut_merge_iter.0 > item_merge_iter {
720            // In this branch the mutable layer is left and the item we're merging-in is right.
721            let merge_result = merge_fn(&mut_merge_iter, &item_merge_iter);
722            debug!(
723                lhs:? = mut_merge_iter.key(),
724                rhs:? = item_merge_iter.key(),
725                result:? = merge_result;
726                "(1) merge");
727            match merge_result {
728                MergeResult::EmitLeft => {
729                    if let Some(item) = mut_merge_iter.take_item() {
730                        mut_merge_iter.as_mut().insert(*item);
731                        mut_merge_iter.set_item_from_iter();
732                    } else {
733                        mut_merge_iter.advance();
734                    }
735                }
736                MergeResult::Other { emit, left, right } => {
737                    if let Some(emit) = emit {
738                        mut_merge_iter.as_mut().insert(*emit);
739                    }
740                    match left {
741                        ItemOp::Keep => {}
742                        ItemOp::Discard => {
743                            if matches!(mut_merge_iter.item, MergeItem::Iter) {
744                                mut_merge_iter.as_mut().erase();
745                            }
746                            mut_merge_iter.set_item_from_iter();
747                        }
748                        ItemOp::Replace(item) => {
749                            if let MergeItem::Iter = mut_merge_iter.item {
750                                mut_merge_iter.as_mut().erase();
751                            }
752                            mut_merge_iter.item = MergeItem::Item(item)
753                        }
754                    }
755                    match right {
756                        ItemOp::Keep => {}
757                        ItemOp::Discard => item_merge_iter.item = MergeItem::None,
758                        ItemOp::Replace(item) => item_merge_iter.item = MergeItem::Item(item),
759                    }
760                }
761            }
762        } else {
763            // In this branch, the item we're merging-in is left and the mutable layer is right.
764            let merge_result = merge_fn(&item_merge_iter, &mut_merge_iter);
765            debug!(
766                lhs:? = mut_merge_iter.key(),
767                rhs:? = item_merge_iter.key(),
768                result:? = merge_result;
769                "(2) merge");
770            match merge_result {
771                MergeResult::EmitLeft => break, // Item is inserted outside the loop
772                MergeResult::Other { emit, left, right } => {
773                    if let Some(emit) = emit {
774                        mut_merge_iter.as_mut().insert(*emit);
775                    }
776                    match left {
777                        ItemOp::Keep => {}
778                        ItemOp::Discard => item_merge_iter.item = MergeItem::None,
779                        ItemOp::Replace(item) => item_merge_iter.item = MergeItem::Item(item),
780                    }
781                    match right {
782                        ItemOp::Keep => {}
783                        ItemOp::Discard => {
784                            if matches!(mut_merge_iter.item, MergeItem::Iter) {
785                                mut_merge_iter.as_mut().erase();
786                            }
787                            mut_merge_iter.set_item_from_iter();
788                        }
789                        ItemOp::Replace(item) => {
790                            if let MergeItem::Iter = mut_merge_iter.item {
791                                mut_merge_iter.as_mut().erase();
792                            }
793                            mut_merge_iter.item = MergeItem::Item(item)
794                        }
795                    }
796                }
797            }
798        }
799    } // while ...
800
801    // The only way we could get here with both items is via the break above, so we know the correct
802    // order required here.
803    if let MergeItem::Item(item) = item_merge_iter.item {
804        mut_merge_iter.as_mut().insert(*item);
805    }
806    if let Some(item) = mut_merge_iter.take_item() {
807        mut_merge_iter.as_mut().insert(*item);
808    }
809    if let RawIterator::Mut(mut iter) = mut_merge_iter.0.iter {
810        iter.commit();
811    }
812    Ok(())
813}
814
815#[cfg(test)]
816mod tests {
817    use super::ItemOp::{Discard, Keep, Replace};
818    use super::{MergeLayerIterator, MergeResult, Merger};
819    use crate::lsm_tree::persistent_layer::{PersistentLayer, PersistentLayerWriter};
820    use crate::lsm_tree::skip_list_layer::SkipListLayer;
821    use crate::lsm_tree::types::{
822        FuzzyHash, Item, ItemRef, Key, Layer, LayerIterator, LayerKey, LayerWriter,
823        MaybeContainsKey, MergeType, OrdLowerBound, OrdUpperBound, SortByU64,
824    };
825    use crate::lsm_tree::{Query, TreeCounters, Value};
826    use crate::object_store::{self, AttributeId, ObjectKey, ObjectValue, VOLUME_DATA_KEY_ID};
827    use crate::serialized_types::{
828        LATEST_VERSION, Version, Versioned, VersionedLatest, versioned_type,
829    };
830    use crate::testing::fake_object::{FakeObject, FakeObjectHandle};
831    use crate::testing::writer::Writer;
832    use fprint::TypeFingerprint;
833    use fxfs_macros::{FuzzyHash, SerializeKey};
834    use rand::RngExt as _;
835    use std::hash::Hash;
836    use std::ops::{Bound, Range};
837    use std::sync::Arc;
838    use std::sync::atomic::Ordering;
839    use storage_units::BlockSize;
840
841    use crate::lsm_tree::testing::TestKey;
842
843    impl Value for i32 {
844        const DELETED_MARKER: Self = 0;
845    }
846
847    fn layer_ref_iter<K: Key, V: Value>(
848        layers: &[Arc<SkipListLayer<K, V>>],
849    ) -> impl Iterator<Item = &dyn Layer<K, V>> {
850        layers.iter().map(|x| x.as_ref() as &dyn Layer<K, V>)
851    }
852
853    fn dyn_layer_ref_iter<K: Key, V: Value>(
854        layers: &[Arc<dyn Layer<K, V>>],
855    ) -> impl Iterator<Item = &dyn Layer<K, V>> {
856        layers.iter().map(|x| x.as_ref())
857    }
858
859    fn counters() -> Arc<TreeCounters> {
860        Arc::new(TreeCounters::default())
861    }
862
863    #[fuchsia::test]
864    async fn test_emit_left() {
865        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
866        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(2..2), 2)];
867        skip_lists[0].insert(items[1].clone()).expect("insert error");
868        skip_lists[1].insert(items[0].clone()).expect("insert error");
869        let mut merger = Merger::new(
870            layer_ref_iter(&skip_lists),
871            |_left, _right| MergeResult::EmitLeft,
872            counters(),
873        );
874        let mut iter = merger.query(Query::FullScan).await.expect("seek failed");
875        let ItemRef { key, value, .. } = iter.get().expect("missing item");
876        assert_eq!((key, value), (&items[0].key, &items[0].value));
877        iter.advance().await.unwrap();
878        let ItemRef { key, value, .. } = iter.get().expect("missing item");
879        assert_eq!((key, value), (&items[1].key, &items[1].value));
880        iter.advance().await.unwrap();
881        assert!(iter.get().is_none());
882    }
883
884    #[fuchsia::test]
885    async fn test_other_emit() {
886        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
887        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(2..2), 2)];
888        skip_lists[0].insert(items[1].clone()).expect("insert error");
889        skip_lists[1].insert(items[0].clone()).expect("insert error");
890        let mut merger = Merger::new(
891            layer_ref_iter(&skip_lists),
892            |_left, _right| MergeResult::Other {
893                emit: Some(Item::new(TestKey(3..3), 3).boxed()),
894                left: Discard,
895                right: Discard,
896            },
897            counters(),
898        );
899        let mut iter = merger.query(Query::FullScan).await.expect("seek failed");
900
901        let ItemRef { key, value, .. } = iter.get().expect("missing item");
902        assert_eq!((key, value), (&TestKey(3..3), &3));
903        iter.advance().await.unwrap();
904        assert!(iter.get().is_none());
905    }
906
907    #[fuchsia::test]
908    async fn test_replace_left() {
909        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
910        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(2..2), 2)];
911        skip_lists[0].insert(items[1].clone()).expect("insert error");
912        skip_lists[1].insert(items[0].clone()).expect("insert error");
913        let mut merger = Merger::new(
914            layer_ref_iter(&skip_lists),
915            |_left, _right| MergeResult::Other {
916                emit: None,
917                left: Replace(Item::new(TestKey(3..3), 3).boxed()),
918                right: Discard,
919            },
920            counters(),
921        );
922        let mut iter = merger.query(Query::FullScan).await.expect("seek failed");
923
924        // The merger should replace the left item and then after discarding the right item, it
925        // should emit the replacement.
926        let ItemRef { key, value, .. } = iter.get().expect("missing item");
927        assert_eq!((key, value), (&TestKey(3..3), &3));
928        iter.advance().await.unwrap();
929        assert!(iter.get().is_none());
930    }
931
932    #[fuchsia::test]
933    async fn test_replace_right() {
934        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
935        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(2..2), 2)];
936        skip_lists[0].insert(items[1].clone()).expect("insert error");
937        skip_lists[1].insert(items[0].clone()).expect("insert error");
938        let mut merger = Merger::new(
939            layer_ref_iter(&skip_lists),
940            |_left, _right| MergeResult::Other {
941                emit: None,
942                left: Discard,
943                right: Replace(Item::new(TestKey(3..3), 3).boxed()),
944            },
945            counters(),
946        );
947        let mut iter = merger.query(Query::FullScan).await.expect("seek failed");
948
949        // The merger should replace the right item and then after discarding the left item, it
950        // should emit the replacement.
951        let ItemRef { key, value, .. } = iter.get().expect("missing item");
952        assert_eq!((key, value), (&TestKey(3..3), &3));
953        iter.advance().await.unwrap();
954        assert!(iter.get().is_none());
955    }
956
957    #[fuchsia::test]
958    async fn test_left_less_than_right() {
959        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
960        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(2..2), 2)];
961        skip_lists[0].insert(items[1].clone()).expect("insert error");
962        skip_lists[1].insert(items[0].clone()).expect("insert error");
963        let mut merger = Merger::new(
964            layer_ref_iter(&skip_lists),
965            |left, right| {
966                assert_eq!((left.key(), left.value()), (&TestKey(1..1), &1));
967                assert_eq!((right.key(), right.value()), (&TestKey(2..2), &2));
968                MergeResult::EmitLeft
969            },
970            counters(),
971        );
972        merger.query(Query::FullScan).await.expect("seek failed");
973    }
974
975    #[fuchsia::test]
976    async fn test_left_equals_right() {
977        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
978        let item = Item::new(TestKey(1..1), 1);
979        skip_lists[0].insert(item.clone()).expect("insert error");
980        skip_lists[1].insert(item.clone()).expect("insert error");
981        let mut merger = Merger::new(
982            layer_ref_iter(&skip_lists),
983            |left, right| {
984                assert_eq!((left.key(), left.value()), (&TestKey(1..1), &1));
985                assert_eq!((right.key(), right.value()), (&TestKey(1..1), &1));
986                assert_eq!(left.layer_index, 0);
987                assert_eq!(right.layer_index, 1);
988                MergeResult::EmitLeft
989            },
990            counters(),
991        );
992        merger.query(Query::FullScan).await.expect("seek failed");
993    }
994
995    #[fuchsia::test]
996    async fn test_keep() {
997        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
998        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(2..2), 2)];
999        skip_lists[0].insert(items[1].clone()).expect("insert error");
1000        skip_lists[1].insert(items[0].clone()).expect("insert error");
1001        let mut merger = Merger::new(
1002            layer_ref_iter(&skip_lists),
1003            |left, right| {
1004                if left.key() == &TestKey(1..1) {
1005                    MergeResult::Other {
1006                        emit: None,
1007                        left: Replace(Item::new(TestKey(3..3), 3).boxed()),
1008                        right: Keep,
1009                    }
1010                } else {
1011                    assert_eq!(left.key(), &TestKey(2..2));
1012                    assert_eq!(right.key(), &TestKey(3..3));
1013                    MergeResult::Other { emit: None, left: Discard, right: Keep }
1014                }
1015            },
1016            counters(),
1017        );
1018        let mut iter = merger.query(Query::FullScan).await.expect("seek failed");
1019
1020        // The merger should first replace left and then it should call the merger again with 2 & 3
1021        // and end up just keeping 3.
1022        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1023        assert_eq!((key, value), (&TestKey(3..3), &3));
1024        iter.advance().await.unwrap();
1025        assert!(iter.get().is_none());
1026    }
1027
1028    #[fuchsia::test]
1029    async fn test_merge_10_layers() {
1030        let skip_lists: Vec<_> = (0..10).map(|_| SkipListLayer::new(100)).collect();
1031        let mut rng = rand::rng();
1032        for i in 0..100 {
1033            skip_lists[rng.random_range(0..10) as usize]
1034                .insert(Item::new(TestKey(i..i), i))
1035                .expect("insert error");
1036        }
1037        let mut merger = Merger::new(
1038            layer_ref_iter(&skip_lists),
1039            |_left, _right| MergeResult::EmitLeft,
1040            counters(),
1041        );
1042        let mut iter = merger.query(Query::FullScan).await.expect("seek failed");
1043
1044        for i in 0..100 {
1045            let ItemRef { key, value, .. } = iter.get().expect("missing item");
1046            assert_eq!((key, value), (&TestKey(i..i), &i));
1047            iter.advance().await.unwrap();
1048        }
1049        assert!(iter.get().is_none());
1050    }
1051
1052    #[fuchsia::test]
1053    async fn test_merge_uses_cmp_lower_bound() {
1054        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
1055        let items = [Item::new(TestKey(1..10), 1), Item::new(TestKey(2..3), 2)];
1056        skip_lists[0].insert(items[1].clone()).expect("insert error");
1057        skip_lists[1].insert(items[0].clone()).expect("insert error");
1058        let mut merger = Merger::new(
1059            layer_ref_iter(&skip_lists),
1060            |_left, _right| MergeResult::EmitLeft,
1061            counters(),
1062        );
1063        let mut iter = merger.query(Query::FullScan).await.expect("seek failed");
1064
1065        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1066        assert_eq!((key, value), (&items[0].key, &items[0].value));
1067        iter.advance().await.unwrap();
1068        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1069        assert_eq!((key, value), (&items[1].key, &items[1].value));
1070        iter.advance().await.unwrap();
1071        assert!(iter.get().is_none());
1072    }
1073
1074    #[fuchsia::test]
1075    async fn test_merge_into_emit_left() {
1076        let skip_list = SkipListLayer::new(100);
1077        let items =
1078            [Item::new(TestKey(1..1), 1), Item::new(TestKey(2..2), 2), Item::new(TestKey(3..3), 3)];
1079        skip_list.insert(items[0].clone()).expect("insert error");
1080        skip_list.insert(items[2].clone()).expect("insert error");
1081        skip_list
1082            .merge_into(items[1].clone(), &items[0].key, |_left, _right| MergeResult::EmitLeft);
1083
1084        let mut iter = skip_list.seek(Bound::Unbounded);
1085        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1086        assert_eq!((key, value), (&items[0].key, &items[0].value));
1087        iter.advance().await.unwrap();
1088        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1089        assert_eq!((key, value), (&items[1].key, &items[1].value));
1090        iter.advance().await.unwrap();
1091        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1092        assert_eq!((key, value), (&items[2].key, &items[2].value));
1093        iter.advance().await.unwrap();
1094        assert!(iter.get().is_none());
1095    }
1096
1097    #[fuchsia::test]
1098    async fn test_merge_into_emit_last_after_replacing() {
1099        let skip_list = SkipListLayer::new(100);
1100        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(2..2), 2)];
1101        skip_list.insert(items[0].clone()).expect("insert error");
1102
1103        skip_list.merge_into(items[1].clone(), &items[0].key, |left, right| {
1104            if left.key() == &TestKey(1..1) {
1105                assert_eq!(right.key(), &TestKey(2..2));
1106                MergeResult::Other {
1107                    emit: None,
1108                    left: Replace(Item::new(TestKey(3..3), 3).boxed()),
1109                    right: Keep,
1110                }
1111            } else {
1112                assert_eq!(left.key(), &TestKey(2..2));
1113                assert_eq!(right.key(), &TestKey(3..3));
1114                MergeResult::EmitLeft
1115            }
1116        });
1117
1118        let mut iter = skip_list.seek(Bound::Unbounded);
1119        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1120        assert_eq!((key, value), (&items[1].key, &items[1].value));
1121        iter.advance().await.unwrap();
1122        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1123        assert_eq!((key, value), (&TestKey(3..3), &3));
1124        iter.advance().await.unwrap();
1125        assert!(iter.get().is_none());
1126    }
1127
1128    #[fuchsia::test]
1129    async fn test_merge_into_emit_left_after_replacing() {
1130        let skip_list = SkipListLayer::new(100);
1131        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(3..3), 3)];
1132        skip_list.insert(items[0].clone()).expect("insert error");
1133
1134        skip_list.merge_into(items[1].clone(), &items[0].key, |left, right| {
1135            if left.key() == &TestKey(1..1) {
1136                assert_eq!(right.key(), &TestKey(3..3));
1137                MergeResult::Other {
1138                    emit: None,
1139                    left: Replace(Item::new(TestKey(2..2), 2).boxed()),
1140                    right: Keep,
1141                }
1142            } else {
1143                assert_eq!(left.key(), &TestKey(2..2));
1144                assert_eq!(right.key(), &TestKey(3..3));
1145                MergeResult::EmitLeft
1146            }
1147        });
1148
1149        let mut iter = skip_list.seek(Bound::Unbounded);
1150        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1151        assert_eq!((key, value), (&TestKey(2..2), &2));
1152        iter.advance().await.unwrap();
1153        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1154        assert_eq!((key, value), (&items[1].key, &items[1].value));
1155        iter.advance().await.unwrap();
1156        assert!(iter.get().is_none());
1157    }
1158
1159    // This tests emitting in both branches of merge_into, and most of the discard paths.
1160    #[fuchsia::test]
1161    async fn test_merge_into_emit_other_and_discard() {
1162        let skip_list = SkipListLayer::new(100);
1163        let items =
1164            [Item::new(TestKey(1..1), 1), Item::new(TestKey(3..3), 3), Item::new(TestKey(5..5), 3)];
1165        skip_list.insert(items[0].clone()).expect("insert error");
1166        skip_list.insert(items[2].clone()).expect("insert error");
1167
1168        skip_list.merge_into(items[1].clone(), &items[0].key, |left, right| {
1169            if left.key() == &TestKey(1..1) {
1170                // This tests the top branch in merge_into.
1171                assert_eq!(right.key(), &TestKey(3..3));
1172                MergeResult::Other {
1173                    emit: Some(Item::new(TestKey(2..2), 2).boxed()),
1174                    left: Discard,
1175                    right: Keep,
1176                }
1177            } else {
1178                // This tests the bottom branch in merge_into.
1179                assert_eq!(left.key(), &TestKey(3..3));
1180                assert_eq!(right.key(), &TestKey(5..5));
1181                MergeResult::Other {
1182                    emit: Some(Item::new(TestKey(4..4), 4).boxed()),
1183                    left: Discard,
1184                    right: Discard,
1185                }
1186            }
1187        });
1188
1189        let mut iter = skip_list.seek(Bound::Unbounded);
1190        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1191        assert_eq!((key, value), (&TestKey(2..2), &2));
1192        iter.advance().await.unwrap();
1193        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1194        assert_eq!((key, value), (&TestKey(4..4), &4));
1195        iter.advance().await.unwrap();
1196        assert!(iter.get().is_none());
1197    }
1198
1199    // This tests replacing the item and discarding the right item (the one remaining untested
1200    // discard path) in the top branch in merge_into.
1201    #[fuchsia::test]
1202    async fn test_merge_into_replace_and_discard() {
1203        let skip_list = SkipListLayer::new(100);
1204        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(3..3), 3)];
1205        skip_list.insert(items[0].clone()).expect("insert error");
1206
1207        skip_list.merge_into(items[1].clone(), &items[0].key, |_left, _right| MergeResult::Other {
1208            emit: Some(Item::new(TestKey(2..2), 2).boxed()),
1209            left: Replace(Item::new(TestKey(4..4), 4).boxed()),
1210            right: Discard,
1211        });
1212
1213        let mut iter = skip_list.seek(Bound::Unbounded);
1214        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1215        assert_eq!((key, value), (&TestKey(2..2), &2));
1216        iter.advance().await.unwrap();
1217        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1218        assert_eq!((key, value), (&TestKey(4..4), &4));
1219        iter.advance().await.unwrap();
1220        assert!(iter.get().is_none());
1221    }
1222
1223    // This tests replacing the right item in the top branch of merge_into and the left item in the
1224    // bottom branch of merge_into.
1225    #[fuchsia::test]
1226    async fn test_merge_into_replace_merge_item() {
1227        let skip_list = SkipListLayer::new(100);
1228        let items =
1229            [Item::new(TestKey(1..1), 1), Item::new(TestKey(3..3), 3), Item::new(TestKey(5..5), 5)];
1230        skip_list.insert(items[0].clone()).expect("insert error");
1231        skip_list.insert(items[2].clone()).expect("insert error");
1232
1233        skip_list.merge_into(items[1].clone(), &items[0].key, |_left, right| {
1234            if right.key() == &TestKey(3..3) {
1235                MergeResult::Other {
1236                    emit: None,
1237                    left: Discard,
1238                    right: Replace(Item::new(TestKey(2..2), 2).boxed()),
1239                }
1240            } else {
1241                assert_eq!(right.key(), &TestKey(5..5));
1242                MergeResult::Other {
1243                    emit: None,
1244                    left: Replace(Item::new(TestKey(4..4), 4).boxed()),
1245                    right: Discard,
1246                }
1247            }
1248        });
1249
1250        let mut iter = skip_list.seek(Bound::Unbounded);
1251        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1252        assert_eq!((key, value), (&TestKey(4..4), &4));
1253        iter.advance().await.unwrap();
1254        assert!(iter.get().is_none());
1255    }
1256
1257    // This tests replacing the right item in the bottom branch of merge_into.
1258    #[fuchsia::test]
1259    async fn test_merge_into_replace_existing() {
1260        let skip_list = SkipListLayer::new(100);
1261        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(3..3), 3)];
1262        skip_list.insert(items[1].clone()).expect("insert error");
1263
1264        skip_list.merge_into(items[0].clone(), &items[0].key, |_left, right| {
1265            if right.key() == &TestKey(3..3) {
1266                MergeResult::Other {
1267                    emit: None,
1268                    left: Keep,
1269                    right: Replace(Item::new(TestKey(2..2), 2).boxed()),
1270                }
1271            } else {
1272                MergeResult::EmitLeft
1273            }
1274        });
1275
1276        let mut iter = skip_list.seek(Bound::Unbounded);
1277        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1278        assert_eq!((key, value), (&items[0].key, &items[0].value));
1279        iter.advance().await.unwrap();
1280        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1281        assert_eq!((key, value), (&TestKey(2..2), &2));
1282        iter.advance().await.unwrap();
1283        assert!(iter.get().is_none());
1284    }
1285
1286    #[fuchsia::test]
1287    async fn test_merge_into_discard_last() {
1288        let skip_list = SkipListLayer::new(100);
1289        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(2..2), 2)];
1290        skip_list.insert(items[0].clone()).expect("insert error");
1291
1292        skip_list.merge_into(items[1].clone(), &items[0].key, |_left, _right| MergeResult::Other {
1293            emit: None,
1294            left: Discard,
1295            right: Keep,
1296        });
1297
1298        let mut iter = skip_list.seek(Bound::Unbounded);
1299        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1300        assert_eq!((key, value), (&items[1].key, &items[1].value));
1301        iter.advance().await.unwrap();
1302        assert!(iter.get().is_none());
1303    }
1304
1305    #[fuchsia::test]
1306    async fn test_merge_into_empty() {
1307        let skip_list = SkipListLayer::new(100);
1308        let items = [Item::new(TestKey(1..1), 1)];
1309
1310        skip_list.merge_into(items[0].clone(), &items[0].key, |_left, _right| {
1311            panic!("Unexpected merge!");
1312        });
1313
1314        let mut iter = skip_list.seek(Bound::Unbounded);
1315        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1316        assert_eq!((key, value), (&items[0].key, &items[0].value));
1317        iter.advance().await.unwrap();
1318        assert!(iter.get().is_none());
1319    }
1320
1321    #[fuchsia::test]
1322    async fn test_seek_uses_minimum_number_of_iterators() {
1323        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
1324        let items = [Item::new(TestKey(1..2), 1), Item::new(TestKey(1..2), 2)];
1325        skip_lists[0].insert(items[0].clone()).expect("insert error");
1326        skip_lists[1].insert(items[1].clone()).expect("insert error");
1327        let mut merger = Merger::new(
1328            layer_ref_iter(&skip_lists),
1329            |_left, _right| MergeResult::Other { emit: None, left: Discard, right: Keep },
1330            counters(),
1331        );
1332        let iter = merger
1333            .query(Query::FullRange(&items[0].key.search_key().unwrap()))
1334            .await
1335            .expect("seek failed");
1336
1337        // Seek should only search in the first skip list, so no merge should take place, and we'll
1338        // know if it has because we'll see a different value (2 rather than 1).
1339        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1340        assert_eq!((key, value), (&items[0].key, &items[0].value));
1341    }
1342
1343    // Checks that merging the given layers produces |expected| sequence of items starting from
1344    // |start|.
1345    async fn test_advance<K: Eq + Key + LayerKey + OrdLowerBound>(
1346        layers: &[&[(K, i32)]],
1347        query: Query<'_, K>,
1348        expected: &[(K, i32)],
1349    ) {
1350        let mut skip_lists = Vec::new();
1351        for &layer in layers {
1352            let skip_list = SkipListLayer::new(100);
1353            for (k, v) in layer {
1354                skip_list.insert(Item::new(k.clone(), *v)).expect("insert error");
1355            }
1356            skip_lists.push(skip_list);
1357        }
1358        let mut merger = Merger::new(
1359            layer_ref_iter(&skip_lists),
1360            |_left, _right| MergeResult::EmitLeft,
1361            counters(),
1362        );
1363        let mut iter = merger.query(query).await.expect("seek failed");
1364        for (k, v) in expected {
1365            let ItemRef { key, value, .. } = iter.get().expect("get failed");
1366            assert_eq!((key, value), (k, v));
1367            iter.advance().await.expect("advance failed");
1368        }
1369        assert!(iter.get().is_none());
1370    }
1371
1372    #[fuchsia::test]
1373    async fn test_seek_skips_replaced_items() {
1374        // The 1..2 and the 2..3 items are overwritten and merging them should be skipped.
1375        test_advance(
1376            &[
1377                &[(TestKey(1..2), 1), (TestKey(2..3), 2), (TestKey(4..5), 3)],
1378                &[(TestKey(1..2), 4), (TestKey(2..3), 5), (TestKey(3..4), 6)],
1379            ],
1380            Query::FullRange(&TestKey(1..2).search_key().unwrap()),
1381            &[(TestKey(1..2), 1), (TestKey(2..3), 2), (TestKey(3..4), 6), (TestKey(4..5), 3)],
1382        )
1383        .await;
1384    }
1385
1386    #[fuchsia::test]
1387    async fn test_advance_skips_replaced_items_at_end() {
1388        // Like the last test, the 1..2 item is overwritten and seeking for it should skip the merge
1389        // but this time, the keys are at the end.
1390        test_advance(
1391            &[&[(TestKey(1..2), 1)], &[(TestKey(1..2), 2)]],
1392            Query::FullRange(&TestKey(1..2).search_key().unwrap()),
1393            &[(TestKey(1..2), 1)],
1394        )
1395        .await;
1396    }
1397
1398    #[derive(
1399        Clone,
1400        Eq,
1401        Hash,
1402        FuzzyHash,
1403        PartialEq,
1404        Debug,
1405        serde::Serialize,
1406        serde::Deserialize,
1407        TypeFingerprint,
1408        Versioned,
1409        SerializeKey,
1410    )]
1411    struct TestKeyWithFullMerge(Range<u64>);
1412
1413    versioned_type! { 1.. => TestKeyWithFullMerge }
1414
1415    impl LayerKey for TestKeyWithFullMerge {
1416        fn merge_type(&self) -> MergeType {
1417            MergeType::FullMerge
1418        }
1419
1420        fn search_key(&self) -> Option<Self> {
1421            Some(Self(self.0.start..self.0.start + 1))
1422        }
1423
1424        fn is_search_key(&self) -> bool {
1425            self.0.end == self.0.start + 1
1426        }
1427
1428        fn overlaps(&self, other: &Self) -> bool {
1429            self.0.start < other.0.end && self.0.end > other.0.start
1430        }
1431    }
1432
1433    impl SortByU64 for TestKeyWithFullMerge {
1434        fn get_leading_u64(&self) -> u64 {
1435            self.0.end
1436        }
1437    }
1438
1439    impl OrdUpperBound for TestKeyWithFullMerge {
1440        fn cmp_upper_bound(&self, other: &TestKeyWithFullMerge) -> std::cmp::Ordering {
1441            self.0.end.cmp(&other.0.end).then(other.0.start.cmp(&self.0.start))
1442        }
1443    }
1444
1445    impl OrdLowerBound for TestKeyWithFullMerge {
1446        fn cmp_lower_bound(&self, other: &Self) -> std::cmp::Ordering {
1447            self.0.start.cmp(&other.0.start)
1448        }
1449    }
1450
1451    // Same set up as `test_seek_skips_replaced_items` except here nothing should skip. Any seek
1452    // should just place the iterator at a particular spot in the merged layers.
1453    #[fuchsia::test]
1454    async fn test_full_merge_consistent_advance_ordering() {
1455        let layer_set = [
1456            [
1457                (TestKeyWithFullMerge(1..2), 1i32),
1458                (TestKeyWithFullMerge(2..3), 2i32),
1459                (TestKeyWithFullMerge(4..5), 3i32),
1460            ]
1461            .as_slice(),
1462            [
1463                (TestKeyWithFullMerge(1..2), 4i32),
1464                (TestKeyWithFullMerge(2..3), 5i32),
1465                (TestKeyWithFullMerge(3..4), 6i32),
1466            ]
1467            .as_slice(),
1468        ];
1469
1470        let full_merge_result = [
1471            (TestKeyWithFullMerge(1..2), 1),
1472            (TestKeyWithFullMerge(1..2), 4),
1473            (TestKeyWithFullMerge(2..3), 2),
1474            (TestKeyWithFullMerge(2..3), 5),
1475            (TestKeyWithFullMerge(3..4), 6),
1476            (TestKeyWithFullMerge(4..5), 3),
1477        ];
1478
1479        test_advance(layer_set.as_slice(), Query::FullScan, &full_merge_result).await;
1480
1481        test_advance(
1482            layer_set.as_slice(),
1483            Query::FullRange(&TestKeyWithFullMerge(1..2).search_key().unwrap()),
1484            &full_merge_result,
1485        )
1486        .await;
1487
1488        test_advance(
1489            layer_set.as_slice(),
1490            Query::FullRange(&TestKeyWithFullMerge(2..3).search_key().unwrap()),
1491            &full_merge_result[2..],
1492        )
1493        .await;
1494
1495        test_advance(
1496            layer_set.as_slice(),
1497            Query::FullRange(&TestKeyWithFullMerge(3..4).search_key().unwrap()),
1498            &full_merge_result[4..],
1499        )
1500        .await;
1501    }
1502
1503    #[fuchsia::test]
1504    async fn test_full_merge_always_consult_all_layers() {
1505        // | 1 |   |
1506        // |   | 2 |
1507        // | 3 | 4 |
1508        let skip_lists =
1509            [SkipListLayer::new(100), SkipListLayer::new(100), SkipListLayer::new(100)];
1510        let items = [
1511            Item::new(TestKeyWithFullMerge(1..2), 1),
1512            Item::new(TestKeyWithFullMerge(2..3), 2),
1513            Item::new(TestKeyWithFullMerge(1..2), 3),
1514            Item::new(TestKeyWithFullMerge(2..3), 4),
1515        ];
1516        skip_lists[0].insert(items[0].clone()).expect("insert error");
1517        skip_lists[1].insert(items[1].clone()).expect("insert error");
1518        skip_lists[2].insert(items[2].clone()).expect("insert error");
1519        skip_lists[2].insert(items[3].clone()).expect("insert error");
1520        let mut merger = Merger::new(
1521            layer_ref_iter(&skip_lists),
1522            |left, right| {
1523                // Sum matching keys.
1524                if left.key() == right.key() {
1525                    MergeResult::Other {
1526                        emit: None,
1527                        left: Discard,
1528                        right: Replace(
1529                            Item::new(left.key().clone(), left.value() + right.value()).boxed(),
1530                        ),
1531                    }
1532                } else {
1533                    MergeResult::EmitLeft
1534                }
1535            },
1536            counters(),
1537        );
1538        let mut iter = merger
1539            .query(Query::FullRange(&items[0].key.search_key().unwrap()))
1540            .await
1541            .expect("seek failed");
1542
1543        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1544        assert_eq!((key, *value), (&items[0].key, items[0].value + items[2].value));
1545        iter.advance().await.expect("advance");
1546        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1547        assert_eq!((key, *value), (&items[1].key, items[1].value + items[3].value));
1548        iter.advance().await.expect("advance");
1549        assert!(iter.get().is_none());
1550    }
1551
1552    #[derive(
1553        Clone,
1554        Eq,
1555        Hash,
1556        FuzzyHash,
1557        PartialEq,
1558        Debug,
1559        serde::Serialize,
1560        serde::Deserialize,
1561        TypeFingerprint,
1562        Versioned,
1563        SerializeKey,
1564    )]
1565    struct TestKeyWithDefaultLayerKey(Range<u64>);
1566
1567    versioned_type! { 1.. => TestKeyWithDefaultLayerKey }
1568
1569    // Default layer key is using `MergeType::FullMerge` and returns None for `next_key()`.
1570    impl LayerKey for TestKeyWithDefaultLayerKey {
1571        fn search_key(&self) -> Option<Self> {
1572            Some(Self(self.0.start..self.0.start + 1))
1573        }
1574
1575        fn is_search_key(&self) -> bool {
1576            self.0.end == self.0.start + 1
1577        }
1578
1579        fn overlaps(&self, other: &Self) -> bool {
1580            self.0.start < other.0.end && self.0.end > other.0.start
1581        }
1582    }
1583
1584    impl SortByU64 for TestKeyWithDefaultLayerKey {
1585        fn get_leading_u64(&self) -> u64 {
1586            self.0.end
1587        }
1588    }
1589
1590    impl OrdUpperBound for TestKeyWithDefaultLayerKey {
1591        fn cmp_upper_bound(&self, other: &TestKeyWithDefaultLayerKey) -> std::cmp::Ordering {
1592            self.0.end.cmp(&other.0.end).then(other.0.start.cmp(&self.0.start))
1593        }
1594    }
1595
1596    impl OrdLowerBound for TestKeyWithDefaultLayerKey {
1597        fn cmp_lower_bound(&self, other: &Self) -> std::cmp::Ordering {
1598            self.0.start.cmp(&other.0.start)
1599        }
1600    }
1601
1602    #[fuchsia::test]
1603    async fn test_no_merge_unbounded_include_all_layers() {
1604        test_advance(
1605            &[
1606                &[
1607                    (TestKeyWithDefaultLayerKey(1..2), 1),
1608                    (TestKeyWithDefaultLayerKey(2..3), 2),
1609                    (TestKeyWithDefaultLayerKey(4..5), 3),
1610                ],
1611                &[
1612                    (TestKeyWithDefaultLayerKey(1..2), 4),
1613                    (TestKeyWithDefaultLayerKey(2..3), 5),
1614                    (TestKeyWithDefaultLayerKey(3..4), 6),
1615                ],
1616            ],
1617            Query::FullScan,
1618            &[
1619                (TestKeyWithDefaultLayerKey(1..2), 1),
1620                (TestKeyWithDefaultLayerKey(1..2), 4),
1621                (TestKeyWithDefaultLayerKey(2..3), 2),
1622                (TestKeyWithDefaultLayerKey(2..3), 5),
1623                (TestKeyWithDefaultLayerKey(3..4), 6),
1624                (TestKeyWithDefaultLayerKey(4..5), 3),
1625            ],
1626        )
1627        .await;
1628    }
1629
1630    #[fuchsia::test]
1631    async fn test_no_merge_proceeds_comprehensively_after_seek() {
1632        test_advance(
1633            &[
1634                &[
1635                    (TestKeyWithDefaultLayerKey(1..2), 1),
1636                    (TestKeyWithDefaultLayerKey(2..3), 2),
1637                    (TestKeyWithDefaultLayerKey(4..5), 3),
1638                ],
1639                &[
1640                    (TestKeyWithDefaultLayerKey(1..2), 4),
1641                    (TestKeyWithDefaultLayerKey(2..3), 5),
1642                    (TestKeyWithDefaultLayerKey(3..4), 6),
1643                ],
1644            ],
1645            Query::FullRange(&TestKeyWithDefaultLayerKey(1..2).search_key().unwrap()),
1646            &[
1647                (TestKeyWithDefaultLayerKey(1..2), 1),
1648                (TestKeyWithDefaultLayerKey(1..2), 4),
1649                (TestKeyWithDefaultLayerKey(2..3), 2),
1650                (TestKeyWithDefaultLayerKey(2..3), 5),
1651                (TestKeyWithDefaultLayerKey(3..4), 6),
1652                (TestKeyWithDefaultLayerKey(4..5), 3),
1653            ],
1654        )
1655        .await;
1656    }
1657
1658    #[fuchsia::test]
1659    async fn test_no_merge_seek_finds_lower_layer() {
1660        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
1661        let items = [
1662            Item::new(TestKeyWithDefaultLayerKey(2..3), 1),
1663            Item::new(TestKeyWithDefaultLayerKey(0..1), 2),
1664        ];
1665        skip_lists[0].insert(items[0].clone()).expect("insert error");
1666        skip_lists[1].insert(items[1].clone()).expect("insert error");
1667        let mut merger = Merger::new(
1668            layer_ref_iter(&skip_lists),
1669            |_left, _right| MergeResult::EmitLeft,
1670            counters(),
1671        );
1672        let iter = merger
1673            .query(Query::FullRange(&items[1].key.search_key().unwrap()))
1674            .await
1675            .expect("seek failed");
1676
1677        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1678        assert_eq!((key, value), (&items[1].key, &items[1].value));
1679    }
1680
1681    #[fuchsia::test]
1682    async fn test_no_merge_seek_stops_at_exact_match() {
1683        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
1684        let items = [
1685            Item::new(TestKeyWithDefaultLayerKey(2..3), 1),
1686            Item::new(TestKeyWithDefaultLayerKey(1..4), 2),
1687        ];
1688        skip_lists[0].insert(items[0].clone()).expect("insert error");
1689        skip_lists[1].insert(items[1].clone()).expect("insert error");
1690        let mut merger = Merger::new(
1691            layer_ref_iter(&skip_lists),
1692            |_left, _right| MergeResult::Other { emit: None, left: Discard, right: Keep },
1693            counters(),
1694        );
1695        let iter = merger
1696            .query(Query::FullRange(&items[0].key.search_key().unwrap()))
1697            .await
1698            .expect("seek failed");
1699
1700        // Seek should only search in the first skip list, so no merge should take place, and we'll
1701        // know if it has because we'll see a different value (2 rather than 1).
1702        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1703        assert_eq!((key, value), (&items[0].key, &items[0].value));
1704    }
1705
1706    #[fuchsia::test]
1707    async fn test_seek_less_than() {
1708        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
1709        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(2..2), 2)];
1710        skip_lists[0].insert(items[0].clone()).expect("insert error");
1711        skip_lists[1].insert(items[1].clone()).expect("insert error");
1712        // Search for a key before 1..1.
1713        let mut merger = Merger::new(
1714            layer_ref_iter(&skip_lists),
1715            |_left, _right| MergeResult::Other { emit: None, left: Discard, right: Keep },
1716            counters(),
1717        );
1718        let iter = merger
1719            .query(Query::FullRange(&TestKey(0..0).search_key().unwrap()))
1720            .await
1721            .expect("seek failed");
1722
1723        // This should find the 2..2 key because of our merge function.
1724        let ItemRef { key, value, .. } = iter.get().expect("missing item");
1725        assert_eq!((key, value), (&items[1].key, &items[1].value));
1726    }
1727
1728    #[fuchsia::test]
1729    async fn test_seek_to_end() {
1730        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
1731        let items = [Item::new(TestKey(1..1), 1), Item::new(TestKey(2..2), 2)];
1732        skip_lists[0].insert(items[0].clone()).expect("insert error");
1733        skip_lists[1].insert(items[1].clone()).expect("insert error");
1734        let mut merger = Merger::new(
1735            layer_ref_iter(&skip_lists),
1736            |_left, _right| MergeResult::Other { emit: None, left: Discard, right: Keep },
1737            counters(),
1738        );
1739        let iter = merger
1740            .query(Query::FullRange(&TestKey(3..3).search_key().unwrap()))
1741            .await
1742            .expect("seek failed");
1743
1744        assert!(iter.get().is_none());
1745    }
1746
1747    #[fuchsia::test]
1748    async fn test_merge_all_discarded() {
1749        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
1750        let items = [Item::new(TestKey(1..2), 1), Item::new(TestKey(2..3), 2)];
1751        skip_lists[0].insert(items[1].clone()).expect("insert error");
1752        skip_lists[1].insert(items[0].clone()).expect("insert error");
1753        let mut merger = Merger::new(
1754            layer_ref_iter(&skip_lists),
1755            |_left, _right| MergeResult::Other { emit: None, left: Discard, right: Discard },
1756            counters(),
1757        );
1758        let iter = merger.query(Query::FullScan).await.expect("seek failed");
1759        assert!(iter.get().is_none());
1760    }
1761
1762    #[fuchsia::test]
1763    async fn test_overlapping_keys() {
1764        let skip_lists =
1765            [SkipListLayer::new(100), SkipListLayer::new(100), SkipListLayer::new(100)];
1766        let items = [
1767            Item::new(TestKey(0..10), 1),
1768            Item::new(TestKey(0..20), 2),
1769            Item::new(TestKey(0..30), 3),
1770        ];
1771        skip_lists[0].insert(items[0].clone()).expect("insert error");
1772        skip_lists[1].insert(items[1].clone()).expect("insert error");
1773        skip_lists[2].insert(items[2].clone()).expect("insert error");
1774        let mut merger = Merger::new(
1775            layer_ref_iter(&skip_lists),
1776            |left, right| {
1777                if left.key().0.end <= right.key().0.start {
1778                    MergeResult::EmitLeft
1779                } else {
1780                    // Hardcoded rule for specific test data to test containment split.
1781                    if left.key() == &TestKey(0..30) && right.key() == &TestKey(10..20) {
1782                        MergeResult::Other {
1783                            emit: Some(Item::new(TestKey(0..10), 1).boxed()),
1784                            left: Replace(Item::new(TestKey(10..30), 1).boxed()),
1785                            right: Keep,
1786                        }
1787                    } else {
1788                        MergeResult::Other {
1789                            emit: None,
1790                            left: Keep,
1791                            right: Replace(
1792                                Item::new(TestKey(left.key().0.end..right.key().0.end), 1).boxed(),
1793                            ),
1794                        }
1795                    }
1796                }
1797            },
1798            counters(),
1799        );
1800        let mut iter = merger
1801            .query(Query::FullRange(&TestKey(0..1).search_key().unwrap()))
1802            .await
1803            .expect("seek failed");
1804        assert_eq!(iter.pending_iterators_len(), 2);
1805        let ItemRef { key, .. } = iter.get().expect("missing item");
1806        assert_eq!(key, &TestKey(0..10));
1807        iter.advance().await.expect("advance failed");
1808        assert_eq!(iter.pending_iterators_len(), 1);
1809        let ItemRef { key, .. } = iter.get().expect("missing item");
1810        assert_eq!(key, &TestKey(10..20));
1811        iter.advance().await.expect("advance failed");
1812        assert_eq!(iter.pending_iterators_len(), 0);
1813        let ItemRef { key, .. } = iter.get().expect("missing item");
1814        assert_eq!(key, &TestKey(20..30));
1815        iter.advance().await.expect("advance failed");
1816        assert_eq!(iter.pending_iterators_len(), 0);
1817        assert_eq!(iter.get(), None);
1818    }
1819
1820    async fn write_layer<K: Key, V: Value>(items: Vec<Item<K, V>>) -> Arc<dyn Layer<K, V>> {
1821        let object = Arc::new(FakeObject::new());
1822        let write_handle = FakeObjectHandle::new(object.clone());
1823        let mut writer = PersistentLayerWriter::<_, K, V>::new(
1824            Writer::new(&write_handle).await,
1825            items.len(),
1826            BlockSize::SIZE_512B,
1827        )
1828        .await
1829        .expect("PersistentLayerWriter::new failed");
1830        for item in items {
1831            writer.write(item.as_item_ref()).await.expect("write failed");
1832        }
1833        writer.complete().await.expect("flush failed");
1834        PersistentLayer::open(FakeObjectHandle::new(object))
1835            .await
1836            .expect("open_persistent_layer failed")
1837    }
1838
1839    fn merge_sum(
1840        left: &MergeLayerIterator<'_, i32, i32>,
1841        right: &MergeLayerIterator<'_, i32, i32>,
1842    ) -> MergeResult<i32, i32> {
1843        // Sum matching keys.
1844        if left.key() == right.key() {
1845            MergeResult::Other {
1846                emit: None,
1847                left: Discard,
1848                right: Replace(Item::new(left.key().clone(), left.value() + right.value()).boxed()),
1849            }
1850        } else {
1851            MergeResult::EmitLeft
1852        }
1853    }
1854
1855    #[fuchsia::test]
1856    async fn test_merge_bloom_filters_point_query() {
1857        let mut layer_0_items = vec![Item::new(1, 1), Item::new(2, 1)];
1858        let mut layer_1_items = vec![Item::new(2, 1), Item::new(4, 1)];
1859        for i in 1000..1300 {
1860            layer_0_items.push(Item::new(i, 1));
1861            layer_1_items.push(Item::new(i + 1000, 1));
1862        }
1863        let items = [Item::new(1, 1), Item::new(2, 2), Item::new(4, 1)];
1864        let layers: [Arc<dyn Layer<i32, i32>>; 2] =
1865            [write_layer(layer_0_items).await, write_layer(layer_1_items).await];
1866        assert!(layers[0].has_bloom_filter());
1867        assert!(layers[1].has_bloom_filter());
1868        let counters = counters();
1869        let mut merger = Merger::new(dyn_layer_ref_iter(&layers), merge_sum, counters.clone());
1870
1871        {
1872            // Key that exists in layer 0 only
1873            let iter = merger.query(Query::Point(&1)).await.expect("seek failed");
1874            let ItemRef { key, value, .. } = iter.get().expect("missing item");
1875            assert_eq!((key, *value), (&items[0].key, items[0].value));
1876        }
1877        {
1878            // Key that exists in layer 0 and 1: must not increment false positives.
1879            let fp_before = counters.bloom_filter_false_positives.load(Ordering::Relaxed);
1880            let iter = merger.query(Query::Point(&2)).await.expect("seek failed");
1881            let ItemRef { key, value, .. } = iter.get().expect("missing item");
1882            assert_eq!((key, *value), (&items[1].key, items[1].value));
1883            assert_eq!(
1884                counters.bloom_filter_false_positives.load(Ordering::Relaxed) - fp_before,
1885                0
1886            );
1887        }
1888        {
1889            // Key that exists in layer 1
1890            let iter = merger.query(Query::Point(&4)).await.expect("seek failed");
1891            let ItemRef { key, value, .. } = iter.get().expect("missing item");
1892            assert_eq!((key, *value), (&items[2].key, items[2].value));
1893        }
1894        {
1895            // Key that doesn't exist at all: both layers must either reject (true negative) or
1896            // falsely match (false positive).
1897            let neg_before = counters.bloom_filter_negatives.load(Ordering::Relaxed);
1898            let fp_before = counters.bloom_filter_false_positives.load(Ordering::Relaxed);
1899            let iter = merger.query(Query::Point(&400)).await.expect("seek failed");
1900            assert!(iter.get().is_none());
1901            let delta_neg = counters.bloom_filter_negatives.load(Ordering::Relaxed) - neg_before;
1902            let delta_fp =
1903                counters.bloom_filter_false_positives.load(Ordering::Relaxed) - fp_before;
1904            assert_eq!(delta_neg + delta_fp, 2);
1905        }
1906    }
1907
1908    #[fuchsia::test]
1909    async fn test_merge_bloom_filters_limited_range() {
1910        // NB: This test uses ObjectKey so that we don't have to reimplement the complex merging
1911        // logic for range-like keys.
1912        let layer_0_items = vec![Item::new(
1913            ObjectKey::extent(0, AttributeId::TEST_ID, 0..2048),
1914            ObjectValue::extent(0, VOLUME_DATA_KEY_ID),
1915        )];
1916        let layer_1_items = vec![
1917            Item::new(
1918                ObjectKey::extent(0, AttributeId::TEST_ID, 1024..4096),
1919                ObjectValue::extent(32768, VOLUME_DATA_KEY_ID),
1920            ),
1921            Item::new(
1922                ObjectKey::extent(0, AttributeId::TEST_ID, 16384..17408),
1923                ObjectValue::extent(65536, VOLUME_DATA_KEY_ID),
1924            ),
1925        ];
1926        let items = [
1927            Item::new(
1928                ObjectKey::extent(0, AttributeId::TEST_ID, 0..2048),
1929                ObjectValue::extent(0, VOLUME_DATA_KEY_ID),
1930            ),
1931            Item::new(
1932                ObjectKey::extent(0, AttributeId::TEST_ID, 2048..4096),
1933                ObjectValue::extent(33792, VOLUME_DATA_KEY_ID),
1934            ),
1935            Item::new(
1936                ObjectKey::extent(0, AttributeId::TEST_ID, 16384..17408),
1937                ObjectValue::extent(65536, VOLUME_DATA_KEY_ID),
1938            ),
1939        ];
1940        let layers: [Arc<dyn Layer<ObjectKey, ObjectValue>>; 2] =
1941            [write_layer(layer_0_items).await, write_layer(layer_1_items).await];
1942        let mut merger =
1943            Merger::new(dyn_layer_ref_iter(&layers), object_store::merge::merge, counters());
1944
1945        {
1946            // Range contains just keys in layer 1
1947            let mut iter = merger
1948                .query(Query::LimitedRange(&ObjectKey::extent(
1949                    0,
1950                    AttributeId::TEST_ID,
1951                    16384..16386,
1952                )))
1953                .await
1954                .expect("seek failed");
1955            let ItemRef { key, value, .. } = iter.get().expect("missing item");
1956            assert_eq!(key, &items[2].key);
1957            assert_eq!(value, &items[2].value);
1958            iter.advance().await.expect("advance");
1959            assert!(iter.get().is_none());
1960        }
1961        {
1962            // Range contains keys in layer 0 and 1
1963            let mut iter = merger
1964                .query(Query::LimitedRange(&ObjectKey::extent(0, AttributeId::TEST_ID, 0..4096)))
1965                .await
1966                .expect("seek failed");
1967            let ItemRef { key, value, .. } = iter.get().expect("missing item");
1968            assert_eq!(key, &items[0].key);
1969            assert_eq!(value, &items[0].value);
1970            iter.advance().await.expect("advance");
1971            let ItemRef { key, value, .. } = iter.get().expect("missing item");
1972            assert_eq!(key, &items[1].key);
1973            assert_eq!(value, &items[1].value);
1974            iter.advance().await.expect("advance");
1975        }
1976        {
1977            // Range contains no keys
1978            let mut iter = merger
1979                .query(Query::LimitedRange(&ObjectKey::extent(
1980                    0,
1981                    AttributeId::TEST_ID,
1982                    8192..12288,
1983                )))
1984                .await
1985                .expect("seek failed");
1986            let ItemRef { key, .. } = iter.get().expect("missing item");
1987            assert_eq!(key, &items[2].key);
1988            iter.advance().await.expect("advance");
1989            assert!(iter.get().is_none());
1990        }
1991    }
1992
1993    #[fuchsia::test]
1994    async fn test_merge_bloom_filters_full_range() {
1995        let layer_0_items = vec![Item::new(1, 1), Item::new(2, 1)];
1996        let layer_1_items = vec![Item::new(2, 1), Item::new(4, 1)];
1997        let items = [Item::new(1, 1), Item::new(2, 2), Item::new(4, 1)];
1998        let layers: [Arc<dyn Layer<i32, i32>>; 2] =
1999            [write_layer(layer_0_items).await, write_layer(layer_1_items).await];
2000        let mut merger = Merger::new(dyn_layer_ref_iter(&layers), merge_sum, counters());
2001
2002        let mut iter = merger.query(Query::FullRange(&0)).await.expect("seek failed");
2003        let ItemRef { key, value, .. } = iter.get().expect("missing item");
2004        assert_eq!((key, *value), (&items[0].key, items[0].value));
2005        iter.advance().await.expect("advance");
2006        let ItemRef { key, value, .. } = iter.get().expect("missing item");
2007        assert_eq!((key, *value), (&items[1].key, items[1].value));
2008        iter.advance().await.expect("advance");
2009        let ItemRef { key, value, .. } = iter.get().expect("missing item");
2010        assert_eq!((key, *value), (&items[2].key, items[2].value));
2011        iter.advance().await.expect("advance");
2012        assert!(iter.get().is_none());
2013    }
2014
2015    #[fuchsia::test]
2016    async fn test_merge_bloom_filters_full_scan() {
2017        let layer_0_items = vec![Item::new(1, 1), Item::new(2, 1)];
2018        let layer_1_items = vec![Item::new(2, 1), Item::new(4, 1)];
2019        let items = [Item::new(1, 1), Item::new(2, 2), Item::new(4, 1)];
2020        let layers: [Arc<dyn Layer<i32, i32>>; 2] =
2021            [write_layer(layer_0_items).await, write_layer(layer_1_items).await];
2022        let mut merger = Merger::new(dyn_layer_ref_iter(&layers), merge_sum, counters());
2023
2024        let mut iter = merger.query(Query::FullScan).await.expect("seek failed");
2025        let ItemRef { key, value, .. } = iter.get().expect("missing item");
2026        assert_eq!((key, *value), (&items[0].key, items[0].value));
2027        iter.advance().await.expect("advance");
2028        let ItemRef { key, value, .. } = iter.get().expect("missing item");
2029        assert_eq!((key, *value), (&items[1].key, items[1].value));
2030        iter.advance().await.expect("advance");
2031        let ItemRef { key, value, .. } = iter.get().expect("missing item");
2032        assert_eq!((key, *value), (&items[2].key, items[2].value));
2033        iter.advance().await.expect("advance");
2034        assert!(iter.get().is_none());
2035    }
2036
2037    #[fuchsia::test]
2038    async fn test_optimized_merge_lazy_pull() {
2039        let skip_lists = [SkipListLayer::new(100), SkipListLayer::new(100)];
2040        let items_top = [
2041            Item::new(TestKey(10..20), 1),
2042            Item::new(TestKey(20..30), 2),
2043            Item::new(TestKey(30..40), 3),
2044        ];
2045        let items_bottom = [Item::new(TestKey(40..50), 4)];
2046
2047        for item in &items_top {
2048            skip_lists[0].insert(item.clone()).expect("insert error");
2049        }
2050        for item in &items_bottom {
2051            skip_lists[1].insert(item.clone()).expect("insert error");
2052        }
2053
2054        let mut merger =
2055            Merger::new(layer_ref_iter(&skip_lists), |_, _| MergeResult::EmitLeft, counters());
2056        merger.set_trace(true);
2057
2058        let mut iter =
2059            merger.query(Query::LimitedRange(&TestKey(10..20))).await.expect("seek failed");
2060        assert_eq!(iter.pending_iterators_len(), 1);
2061
2062        let ItemRef { key, .. } = iter.get().expect("missing item");
2063        assert_eq!(key, &TestKey(10..20));
2064
2065        iter.advance().await.expect("advance failed");
2066        assert_eq!(iter.pending_iterators_len(), 1);
2067
2068        let ItemRef { key, .. } = iter.get().expect("missing item");
2069        assert_eq!(key, &TestKey(20..30));
2070
2071        iter.advance().await.expect("advance failed");
2072        assert_eq!(iter.pending_iterators_len(), 1);
2073
2074        let ItemRef { key, .. } = iter.get().expect("missing item");
2075        assert_eq!(key, &TestKey(30..40));
2076
2077        iter.advance().await.expect("advance failed");
2078        assert_eq!(iter.pending_iterators_len(), 0);
2079
2080        let ItemRef { key, .. } = iter.get().expect("missing item");
2081        assert_eq!(key, &TestKey(40..50));
2082
2083        iter.advance().await.expect("advance failed");
2084        assert!(iter.get().is_none());
2085    }
2086
2087    #[fuchsia::test]
2088    async fn test_excessive_hash_partitions_counter() {
2089        use std::sync::atomic::Ordering;
2090
2091        let layer_0_items: Vec<_> = (0..100)
2092            .map(|i| {
2093                Item::new(
2094                    ObjectKey::extent(0, AttributeId::TEST_ID, i * 512..(i + 1) * 512),
2095                    ObjectValue::extent(0, VOLUME_DATA_KEY_ID),
2096                )
2097            })
2098            .collect();
2099        let layers: [Arc<dyn Layer<ObjectKey, ObjectValue>>; 1] =
2100            [write_layer(layer_0_items).await];
2101        let counters = counters();
2102        let mut merger =
2103            Merger::new(dyn_layer_ref_iter(&layers), object_store::merge::merge, counters.clone());
2104
2105        // A query with <= MAX_HASH_PARTITIONS (e.g. 1 partition: 0..4096)
2106        merger
2107            .query(Query::LimitedRange(&ObjectKey::extent(0, AttributeId::TEST_ID, 0..4096)))
2108            .await
2109            .expect("seek failed");
2110        assert_eq!(counters.excessive_hash_partitions.load(Ordering::Relaxed), 0);
2111
2112        let key_large = ObjectKey::extent(0, AttributeId::TEST_ID, 0..10485760);
2113        assert_eq!(layers[0].maybe_contains_key(&key_large), MaybeContainsKey::RangeKeyTooLarge);
2114
2115        // A query with > MAX_HASH_PARTITIONS (e.g. 10MB range: 0..10485760 = 10 partitions)
2116        merger.query(Query::LimitedRange(&key_large)).await.expect("seek failed");
2117        assert_eq!(counters.excessive_hash_partitions.load(Ordering::Relaxed), 1);
2118    }
2119}