1use 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 Keep,
24
25 Discard,
27
28 Replace(BoxedItem<K, V>),
31}
32
33#[derive(Debug, Eq, PartialEq)]
34pub enum MergeResult<K, V> {
35 EmitLeft,
38
39 Other { emit: Option<BoxedItem<K, V>>, left: ItemOp<K, V>, right: ItemOp<K, V> },
60}
61
62pub 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
81unsafe impl<K, V> Send for RawIterator<'_, K, V> {}
84
85pub struct MergeLayerIterator<'a, K, V> {
88 layer: Option<&'a dyn Layer<K, V>>,
89
90 iter: RawIterator<'a, K, V>,
92
93 pub layer_index: u16,
95
96 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 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 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
189impl<K: OrdLowerBound, V> Ord for MergeLayerIterator<'_, K, V> {
191 fn cmp(&self, other: &Self) -> Ordering {
192 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
208enum 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
237pub struct Merger<'a, K, V> {
239 iterators: Vec<MergeLayerIterator<'a, K, V>>,
241
242 merge_fn: MergeFn<K, V>,
244
245 trace: bool,
247
248 counters: Arc<TreeCounters>,
250}
251
252#[derive(Debug, Clone)]
259pub enum Query<'a, K: Key + LayerKey + OrdLowerBound> {
260 Point(&'a K),
265
266 LimitedRange(&'a K),
274
275 FullRange(&'a K),
281
282 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 #[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 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 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 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
410pub struct MergerIterator<'a, 'b, K, V> {
413 merge_fn: MergeFn<K, V>,
414
415 pending_iterators: Vec<&'a mut MergeLayerIterator<'b, K, V>>,
417
418 heap: BinaryHeap<&'a mut MergeLayerIterator<'b, K, V>>,
420
421 item: CurrentItem<'a, 'b, K, V>,
423
424 trace: bool,
426
427 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 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 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 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 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 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 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 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 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 } else {
641 iterator.replace(existing_item);
645
646 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
704pub(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 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 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, 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 } 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 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 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 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 #[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 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 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 #[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 #[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 #[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 let ItemRef { key, value, .. } = iter.get().expect("missing item");
1340 assert_eq!((key, value), (&items[0].key, &items[0].value));
1341 }
1342
1343 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 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 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 #[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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 merger.query(Query::LimitedRange(&key_large)).await.expect("seek failed");
2117 assert_eq!(counters.excessive_hash_partitions.load(Ordering::Relaxed), 1);
2118 }
2119}