-use crate::{Entry, Iter, Source};
+use crate::{source::Ranges, Entry, Iter, Source};
use std::cmp::Ordering;
use std::collections::BinaryHeap;
}
}
-struct MergeIter<I: Iter> {
+pub struct MergeIter<I: Iter> {
heap: BinaryHeap<MergeEntry<I>>,
finished: Vec<I>,
last_key: Vec<u8>,
}
impl<S: Source> Source for Merger<S> {
- fn iter(&self) -> impl Iter {
+ type It = MergeIter<S::It>;
+ fn iter(&self) -> Self::It {
MergeIter::from(self.sources.iter().map(|s| s.iter()))
}
+}
+
+impl<S: Source + Ranges> Ranges for Merger<S> {
+ type Get = MergeIter<<S as Ranges>::Get>;
+ type Prefix = MergeIter<<S as Ranges>::Prefix>;
+ type Range = MergeIter<<S as Ranges>::Range>;
- fn get(&self, key: &[u8]) -> impl Iter {
+ fn get(&self, key: &[u8]) -> Self::Get {
MergeIter::from(self.sources.iter().map(|s| s.get(key)))
}
- fn get_prefix(&self, prefix: &[u8]) -> impl Iter {
+ fn get_prefix(&self, prefix: &[u8]) -> Self::Prefix {
MergeIter::from(self.sources.iter().map(|s| s.get_prefix(prefix)))
}
- fn get_range(&self, start: &[u8], end: &[u8]) -> impl Iter {
+ fn get_range(&self, start: &[u8], end: &[u8]) -> Self::Range {
MergeIter::from(self.sources.iter().map(|s| s.get_range(start, end)))
}
}
use super::Merger;
use crate::source::test::TestSource;
use crate::{Entry, Source};
+ use std::marker::PhantomData;
fn tnum(m: u8) -> Vec<u8> {
Vec::from_iter((1u8..255).into_iter().filter(|i| i % m == 0))
}
- fn test_source(m: u8) -> TestSource {
- TestSource(Vec::from_iter(
- tnum(m).into_iter().map(|n| Entry::new(vec![n], vec![0])),
- ))
+ fn test_source<'a>(m: u8) -> TestSource<'a> {
+ TestSource(
+ Vec::from_iter(tnum(m).into_iter().map(|n| Entry::new(vec![n], vec![0]))),
+ PhantomData,
+ )
}
#[test]
fn seek(&mut self, key: &[u8]);
}
-impl<'a> Iter for Box<dyn Iter + 'a> {
+impl Iter for Box<dyn Iter> {
fn seek(&mut self, key: &[u8]) {
self.as_mut().seek(key);
}
}
pub trait Source {
- fn iter(&self) -> impl Iter;
+ type It: Iter;
+ fn iter(&self) -> <Self as Source>::It;
+}
+pub trait DefaultRanges {}
+pub trait Ranges {
+ type Get: Iter;
+ type Prefix: Iter;
+ type Range: Iter;
+
+ fn get(&self, key: &[u8]) -> Self::Get;
+ fn get_prefix(&self, prefix: &[u8]) -> Self::Prefix;
+ fn get_range(&self, start: &[u8], end: &[u8]) -> Self::Range;
+}
- fn get(&self, key: &[u8]) -> impl Iter {
+impl<S: Source + DefaultRanges> Ranges for S {
+ type Get = RangeIter<<S as Source>::It>;
+ type Prefix = PrefixIter<<S as Source>::It>;
+ type Range = RangeIter<<S as Source>::It>;
+
+ fn get(&self, key: &[u8]) -> Self::Get {
let mut res = RangeIter {
iter: self.iter(),
+ start: Vec::from(key),
end: Vec::from(key),
};
res.seek(key);
res
}
- fn get_prefix(&self, prefix: &[u8]) -> impl Iter {
+ fn get_prefix(&self, prefix: &[u8]) -> Self::Prefix {
let mut res = PrefixIter {
iter: self.iter(),
prefix: Vec::from(prefix),
res
}
- fn get_range(&self, start: &[u8], end: &[u8]) -> impl Iter {
+ fn get_range(&self, start: &[u8], end: &[u8]) -> Self::Range {
let mut res = RangeIter {
iter: self.iter(),
+ start: Vec::from(start),
end: Vec::from(end),
};
res.seek(start);
}
}
-struct PrefixIter<I: Iter> {
+pub struct PrefixIter<I: Iter> {
iter: I,
prefix: Vec<u8>,
}
}
}
-struct RangeIter<I: Iter> {
+pub struct RangeIter<I: Iter> {
iter: I,
+ start: Vec<u8>,
end: Vec<u8>,
}
impl<I: Iter> Iter for RangeIter<I> {
fn seek(&mut self, key: &[u8]) {
- self.iter.seek(key);
+ if key <= self.start.as_slice() {
+ self.iter.seek(self.start.as_slice());
+ } else if key > self.end.as_slice() {
+ self.iter.seek(self.end.as_slice());
+ self.iter.next();
+ } else {
+ self.iter.seek(key);
+ }
}
}
#[cfg(test)]
pub mod test {
- use super::{Entry, Iter, Source};
+ use super::{DefaultRanges, Entry, Iter, Ranges, Source};
+ use std::marker::PhantomData;
- pub struct TestSource(pub Vec<Entry>);
+ pub struct TestSource<'a>(pub Vec<Entry>, pub PhantomData<&'a u8>);
struct TestIter<'a> {
- source: &'a TestSource,
+ source: &'a TestSource<'a>,
off: usize,
}
}
}
- impl Source for TestSource {
- fn iter(&self) -> impl Iter {
+ impl<'a> Source for TestSource<'a> {
+ type It = TestIter<'a>;
+
+ fn iter(&self) -> TestIter<'a> {
TestIter {
source: self,
off: 0,
}
}
}
-
- fn test_source() -> TestSource {
- TestSource(vec![
- Entry::new(vec![0, 0, 0, 0], vec![0]),
- Entry::new(vec![0, 0, 0, 1], vec![1]),
- Entry::new(vec![0, 0, 1, 0], vec![2]),
- Entry::new(vec![0, 1, 0, 0], vec![3]),
- Entry::new(vec![1, 0, 0, 0], vec![4]),
- ])
+ impl<'a> DefaultRanges for TestSource<'a> {}
+
+ fn test_source<'a>() -> TestSource<'a> {
+ TestSource(
+ vec![
+ Entry::new(vec![0, 0, 0, 0], vec![0]),
+ Entry::new(vec![0, 0, 0, 1], vec![1]),
+ Entry::new(vec![0, 0, 1, 0], vec![2]),
+ Entry::new(vec![0, 1, 0, 0], vec![3]),
+ Entry::new(vec![1, 0, 0, 0], vec![4]),
+ ],
+ PhantomData,
+ )
}
#[test]