From: Chris Mikkelson Date: Fri, 19 Jul 2024 03:28:00 +0000 (-0500) Subject: merger: Remove all internal use of Box X-Git-Url: https://git.mikk.net/?a=commitdiff_plain;h=c5de4a88be7cefd72620817ab6cb8dc251e7aaf9;p=mtbl-rs merger: Remove all internal use of Box Adding Iter implementation for Box allows it to be used as a concrete type in case of a mixed merger. --- diff --git a/src/merger.rs b/src/merger.rs index cf11cf6..a7d671e 100644 --- a/src/merger.rs +++ b/src/merger.rs @@ -1,14 +1,12 @@ use crate::{Entry, Iter, Source}; use std::cmp::Ordering; use std::collections::BinaryHeap; -use std::marker::PhantomData; -pub struct Merger<'a, S: Source> { +pub struct Merger { sources: Vec, - _p: PhantomData<&'a u8>, } -impl<'a, S, I> From for Merger<'a, S> +impl From for Merger where S: Source, I: IntoIterator, @@ -16,42 +14,72 @@ where fn from(i: I) -> Self { Merger { sources: Vec::from_iter(i), - _p: PhantomData, } } } -struct MergeEntry<'a> { +struct MergeEntry { e: Entry, - it: Box, + it: I, } -impl<'a> PartialEq for MergeEntry<'a> { +impl PartialEq for MergeEntry { fn eq(&self, other: &Self) -> bool { self.e.key == other.e.key } } -impl<'a> Eq for MergeEntry<'a> {} +impl Eq for MergeEntry {} -impl<'a> PartialOrd for MergeEntry<'a> { +impl PartialOrd for MergeEntry { fn partial_cmp(&self, other: &Self) -> Option { Some(other.e.key.cmp(&self.e.key)) } } -impl<'a> Ord for MergeEntry<'a> { +impl Ord for MergeEntry { fn cmp(&self, other: &Self) -> Ordering { other.e.key.cmp(&self.e.key) } } -struct MergeIter<'a> { - heap: BinaryHeap>, - finished: Vec>, +struct MergeIter { + heap: BinaryHeap>, + finished: Vec, last_key: Vec, } -impl<'a> Iterator for MergeIter<'a> { +impl MergeIter { + fn add(&mut self, mut it: I) { + match it.next() { + Some(e) => self.heap.push(MergeEntry { e, it }), + None => self.finished.push(it), + } + } +} + +impl From for MergeIter +where + I: Iterator, + I::Item: Iter, +{ + fn from(iters: I) -> Self { + let mut v: Vec = Vec::new(); + let h = BinaryHeap::from_iter(iters.filter_map(|mut it| match it.next() { + Some(e) => Some(MergeEntry { e, it }), + None => { + v.push(it); + None + } + })); + MergeIter { + finished: v, + heap: h, + last_key: Vec::new(), + } + } +} + +impl Iterator for MergeIter { type Item = Entry; fn next(&mut self) -> Option { @@ -71,7 +99,7 @@ impl<'a> Iterator for MergeIter<'a> { } } -impl<'a> Iter for MergeIter<'a> { +impl Iter for MergeIter { fn seek(&mut self, key: &[u8]) { if key > self.last_key.as_slice() { loop { @@ -95,8 +123,8 @@ impl<'a> Iter for MergeIter<'a> { } // backwards seek; reset heap - let mut finished: Vec> = Vec::new(); - let mut heap_entries: Vec> = Vec::new(); + let mut finished: Vec = Vec::new(); + let mut heap_entries: Vec> = Vec::new(); for mut it in self .heap .drain() @@ -116,27 +144,21 @@ impl<'a> Iter for MergeIter<'a> { } } -impl<'a, S: Source> Source for Merger<'a, S> { +impl Source for Merger { fn iter(&self) -> impl Iter { - let mut v: Vec> = Vec::new(); - let h = BinaryHeap::from_iter(self.sources.iter().filter_map(|s| { - let mut it = s.iter(); - match it.next() { - Some(e) => Some(MergeEntry { - e, - it: Box::new(it), - }), - None => { - v.push(Box::new(it)); - None - } - } - })); - MergeIter { - finished: v, - heap: h, - last_key: Vec::new(), - } + MergeIter::from(self.sources.iter().map(|s| s.iter())) + } + + fn get(&self, key: &[u8]) -> impl Iter { + MergeIter::from(self.sources.iter().map(|s| s.get(key))) + } + + fn get_prefix(&self, prefix: &[u8]) -> impl Iter { + MergeIter::from(self.sources.iter().map(|s| s.get_prefix(prefix))) + } + + fn get_range(&self, start: &[u8], end: &[u8]) -> impl Iter { + MergeIter::from(self.sources.iter().map(|s| s.get_range(start, end))) } }