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<S: Source> {
sources: Vec<S>,
- _p: PhantomData<&'a u8>,
}
-impl<'a, S, I> From<I> for Merger<'a, S>
+impl<S, I> From<I> for Merger<S>
where
S: Source,
I: IntoIterator<Item = S>,
fn from(i: I) -> Self {
Merger {
sources: Vec::from_iter(i),
- _p: PhantomData,
}
}
}
-struct MergeEntry<'a> {
+struct MergeEntry<I: Iter> {
e: Entry,
- it: Box<dyn Iter + 'a>,
+ it: I,
}
-impl<'a> PartialEq for MergeEntry<'a> {
+impl<I: Iter> PartialEq for MergeEntry<I> {
fn eq(&self, other: &Self) -> bool {
self.e.key == other.e.key
}
}
-impl<'a> Eq for MergeEntry<'a> {}
+impl<I: Iter> Eq for MergeEntry<I> {}
-impl<'a> PartialOrd for MergeEntry<'a> {
+impl<I: Iter> PartialOrd for MergeEntry<I> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(other.e.key.cmp(&self.e.key))
}
}
-impl<'a> Ord for MergeEntry<'a> {
+impl<I: Iter> Ord for MergeEntry<I> {
fn cmp(&self, other: &Self) -> Ordering {
other.e.key.cmp(&self.e.key)
}
}
-struct MergeIter<'a> {
- heap: BinaryHeap<MergeEntry<'a>>,
- finished: Vec<Box<dyn Iter + 'a>>,
+struct MergeIter<I: Iter> {
+ heap: BinaryHeap<MergeEntry<I>>,
+ finished: Vec<I>,
last_key: Vec<u8>,
}
-impl<'a> Iterator for MergeIter<'a> {
+impl<I: Iter> MergeIter<I> {
+ fn add(&mut self, mut it: I) {
+ match it.next() {
+ Some(e) => self.heap.push(MergeEntry { e, it }),
+ None => self.finished.push(it),
+ }
+ }
+}
+
+impl<I> From<I> for MergeIter<I::Item>
+where
+ I: Iterator,
+ I::Item: Iter,
+{
+ fn from(iters: I) -> Self {
+ let mut v: Vec<I::Item> = 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<I: Iter> Iterator for MergeIter<I> {
type Item = Entry;
fn next(&mut self) -> Option<Self::Item> {
}
}
-impl<'a> Iter for MergeIter<'a> {
+impl<I: Iter> Iter for MergeIter<I> {
fn seek(&mut self, key: &[u8]) {
if key > self.last_key.as_slice() {
loop {
}
// backwards seek; reset heap
- let mut finished: Vec<Box<dyn Iter + 'a>> = Vec::new();
- let mut heap_entries: Vec<MergeEntry<'a>> = Vec::new();
+ let mut finished: Vec<I> = Vec::new();
+ let mut heap_entries: Vec<MergeEntry<I>> = Vec::new();
for mut it in self
.heap
.drain()
}
}
-impl<'a, S: Source> Source for Merger<'a, S> {
+impl<S: Source> Source for Merger<S> {
fn iter(&self) -> impl Iter {
- let mut v: Vec<Box<dyn Iter>> = 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)))
}
}