types.
-use crate::entry::HasPrefix;
use crate::{SeekableIter, Source};
use std::cmp::Ordering;
+use std::marker::PhantomData;
-pub struct DupsortFunc<S, F>
+pub struct DupsortFunc<'a, S, F>
where
- S: Source,
+ S: Source<'a>,
F: Fn(&S::Item, &S::Item) -> Ordering,
{
source: S,
dupsort_func: F,
+ phantom: PhantomData<&'a char>,
}
-impl<S, F> DupsortFunc<S, F>
+impl<'a, S, F> DupsortFunc<'a, S, F>
where
- S: Source,
+ S: Source<'a>,
F: Fn(&S::Item, &S::Item) -> Ordering,
{
pub fn new(source: S, dupsort_func: F) -> Self {
Self {
source,
dupsort_func,
+ phantom: PhantomData,
}
}
}
-impl<S, F> Source for DupsortFunc<S, F>
+impl<'a, S, F> Source<'a> for DupsortFunc<'a, S, F>
where
- S: Source,
+ S: Source<'a>,
S::Item: PartialEq,
- F: Fn(&S::Item, &S::Item) -> Ordering,
+ F: Fn(&S::Item, &S::Item) -> Ordering + 'a,
{
+ type Iter = DupsortFuncIter<S::Iter, &'a F>;
type Item = S::Item;
- fn iter(&self) -> impl SeekableIter<Item = Self::Item> {
+
+ fn iter(&'a self) -> Self::Iter {
self.source.iter().dupsort_func(&self.dupsort_func)
}
- fn get(&self, key: &[u8]) -> impl SeekableIter<Item = Self::Item>
- where
- S::Item: PartialOrd<[u8]>,
- {
- self.source.get(key).dupsort_func(&self.dupsort_func)
- }
- fn get_prefix(&self, prefix: &[u8]) -> impl SeekableIter<Item = Self::Item>
- where
- S::Item: HasPrefix,
- {
- self.source
- .get_prefix(prefix)
- .dupsort_func(&self.dupsort_func)
- }
- fn get_range(&self, start: &[u8], end: &[u8]) -> impl SeekableIter<Item = Self::Item>
- where
- S::Item: PartialOrd<[u8]>,
- {
- self.source
- .get_range(start, end)
- .dupsort_func(&self.dupsort_func)
- }
}
#[derive(Debug)]
-pub struct DupsortFuncIter<'a, I, F>
+pub struct DupsortFuncIter<I, F>
where
I: SeekableIter,
- F: Fn(&I::Item, &I::Item) -> Ordering,
+ F: FnMut(&I::Item, &I::Item) -> Ordering,
{
run: Vec<I::Item>,
next: Option<I::Item>,
iter: I,
- dupsort_func: &'a F,
+ dupsort_func: F,
}
-impl<'a, I, F> DupsortFuncIter<'a, I, F>
+impl<I, F> DupsortFuncIter<I, F>
where
I: SeekableIter,
- F: Fn(&I::Item, &I::Item) -> Ordering,
+ F: FnMut(&I::Item, &I::Item) -> Ordering,
{
- pub fn new(iter: I, dupsort_func: &'a F) -> Self {
+ pub fn new(iter: I, dupsort_func: F) -> Self {
Self {
run: Vec::new(),
next: None,
}
}
-impl<'a, I, F> Iterator for DupsortFuncIter<'a, I, F>
+impl<I, F> Iterator for DupsortFuncIter<I, F>
where
I: SeekableIter,
I::Item: PartialEq,
}
}
-impl<'a, I, F> SeekableIter for DupsortFuncIter<'a, I, F>
+impl<I, F> SeekableIter for DupsortFuncIter<I, F>
where
I: SeekableIter,
I::Item: PartialEq,
}
}
-impl PartialEq<Entry> for Entry {
- fn eq(&self, other: &Entry) -> bool {
- self.key() == other.key()
+impl AsRef<[u8]> for Entry {
+ fn as_ref(&self) -> &[u8] {
+ self.key()
}
}
-pub trait HasPrefix {
- fn has_prefix(&self, prefix: &[u8]) -> bool;
-}
-
-impl HasPrefix for Entry {
- fn has_prefix(&self, prefix: &[u8]) -> bool {
- self.key().starts_with(prefix)
+impl PartialEq<Entry> for Entry {
+ fn eq(&self, other: &Entry) -> bool {
+ self.key() == other.key()
}
}
-use crate::{entry::HasPrefix, SeekableIter, Source};
+use crate::{SeekableIter, Source};
+use std::marker::PhantomData;
-pub struct FilterIter<'a, I, F> {
+pub struct FilterIter<I, F> {
iter: I,
- filter_func: &'a F,
+ filter: F,
+ seek_key: Vec<u8>,
}
-impl<'a, I, F> FilterIter<'a, I, F>
+impl<I, F> FilterIter<I, F>
where
I: SeekableIter,
- F: Fn(&I::Item, &mut dyn SeekableIter<Item = I::Item>) -> bool,
+ F: FnMut(&I::Item, &mut Vec<u8>) -> bool,
{
- pub fn new(iter: I, filter_func: &'a F) -> Self {
- Self { iter, filter_func }
+ pub fn new(iter: I, filter: F) -> Self {
+ let seek_key = Vec::new();
+ Self {
+ iter,
+ filter,
+ seek_key,
+ }
}
}
-impl<'a, I, F> Iterator for FilterIter<'a, I, F>
+impl<I, F> Iterator for FilterIter<I, F>
where
I: SeekableIter,
- F: Fn(&I::Item, &mut dyn SeekableIter<Item = I::Item>) -> bool,
+ F: FnMut(&I::Item, &mut Vec<u8>) -> bool,
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
- while let Some(e) = self.iter.next() {
- if (self.filter_func)(&e, &mut self.iter) {
- return Some(e);
+ loop {
+ let item = self.iter.next()?;
+ self.seek_key.clear();
+ if (self.filter)(&item, &mut self.seek_key) {
+ return Some(item);
+ }
+ if self.seek_key.len() > 0 {
+ self.iter.seek(self.seek_key.as_slice());
}
}
- None
}
}
-impl<'a, I, F> SeekableIter for FilterIter<'a, I, F>
+impl<I, F> SeekableIter for FilterIter<I, F>
where
I: SeekableIter,
- F: Fn(&I::Item, &mut dyn SeekableIter<Item = I::Item>) -> bool,
+ F: FnMut(&I::Item, &mut Vec<u8>) -> bool,
{
fn seek(&mut self, key: &[u8]) {
self.iter.seek(key);
}
}
-pub struct FilterSource<S, F> {
+pub struct FilterSource<'a, S, F> {
source: S,
filter_func: F,
+ phantom: PhantomData<&'a char>,
}
-impl<S, F> FilterSource<S, F>
+impl<'a, S, F> FilterSource<'a, S, F>
where
- S: Source,
- F: Fn(&S::Item, &mut dyn SeekableIter<Item = S::Item>) -> bool,
+ S: Source<'a>,
+ F: Fn(&S::Item, &mut Vec<u8>) -> bool,
{
pub fn new(source: S, filter_func: F) -> Self {
Self {
source,
filter_func,
+ phantom: PhantomData,
}
}
}
-impl<S, F> Source for FilterSource<S, F>
+impl<'a, S, F> Source<'a> for FilterSource<'a, S, F>
where
- S: Source,
- F: Fn(&S::Item, &mut dyn SeekableIter<Item = S::Item>) -> bool,
+ S: Source<'a>,
+ F: Fn(&S::Item, &mut Vec<u8>) -> bool + 'a,
{
+ type Iter = FilterIter<S::Iter, &'a F>;
type Item = S::Item;
- fn iter(&self) -> impl SeekableIter<Item = Self::Item> {
+ fn iter(&'a self) -> Self::Iter {
self.source.iter().filter_func(&self.filter_func)
}
-
- fn get(&self, key: &[u8]) -> impl SeekableIter<Item = Self::Item>
- where
- Self::Item: PartialOrd<[u8]>,
- {
- self.source.get(key).filter_func(&self.filter_func)
- }
-
- fn get_prefix(&self, prefix: &[u8]) -> impl SeekableIter<Item = Self::Item>
- where
- Self::Item: HasPrefix,
- {
- self.source
- .get_prefix(prefix)
- .filter_func(&self.filter_func)
- }
-
- fn get_range(&self, start: &[u8], end: &[u8]) -> impl SeekableIter<Item = Self::Item>
- where
- Self::Item: PartialOrd<[u8]>,
- {
- self.source
- .get_range(start, end)
- .filter_func(&self.filter_func)
- }
}
#[test]
.map(|n| Entry::new(vec![n], vec![]))
.collect(),
)
- .filter(|e, it| {
+ .filter(|e, sv| {
// pass only even values
if e.key()[0] % 2 != 0 {
return false;
} else if e.key()[0] == 4 {
// at key 4, seek to 8
- it.seek(vec![8].as_slice());
+ sv.push(8);
+ return false;
}
true
});
assert_eq!(
- vec![0, 2, 4, 8],
+ vec![0, 2, 8],
ts.iter().map(|e| e.key()[0]).collect::<Vec<u8>>()
);
}
use crate::dupsort_func::DupsortFuncIter;
-use crate::entry::HasPrefix;
use crate::filter::FilterIter;
use crate::merge_func::MergeFuncIter;
use crate::Entry;
pub trait SeekableIter: Iterator {
fn seek(&mut self, key: &[u8]);
- fn merge_func<'a, F>(self, merge_func: &'a F) -> MergeFuncIter<'a, Self, F>
+ fn merge_func<F>(self, merge_func: F) -> MergeFuncIter<Self, F>
where
- F: Fn(&mut Vec<u8>, &Entry),
+ F: FnMut(&mut Vec<u8>, &Entry),
Self: Sized,
{
MergeFuncIter::new(self, merge_func)
}
- fn dupsort_func<'a, F>(self, dupsort_func: &'a F) -> DupsortFuncIter<'a, Self, F>
+ fn dupsort_func<F>(self, dupsort_func: F) -> DupsortFuncIter<Self, F>
where
- F: Fn(&Self::Item, &Self::Item) -> Ordering,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
Self: Sized,
{
DupsortFuncIter::new(self, dupsort_func)
}
- fn filter_func<'a, F>(self, filter_func: &'a F) -> FilterIter<'a, Self, F>
+ fn filter_func<F>(self, filter_func: F) -> FilterIter<Self, F>
where
- F: Fn(&Self::Item, &mut dyn SeekableIter<Item = Self::Item>) -> bool,
+ F: FnMut(&Self::Item, &mut Vec<u8>) -> bool,
Self: Sized,
{
FilterIter::new(self, filter_func)
}
}
-pub struct PrefixIter<I> {
+pub struct PrefixIter<I>
+where
+ I: SeekableIter,
+ I::Item: AsRef<[u8]>,
+{
iter: I,
prefix: Vec<u8>,
}
-impl<E, I> PrefixIter<I>
+impl<I> PrefixIter<I>
where
- I: SeekableIter<Item = E>,
- E: HasPrefix,
+ I: SeekableIter,
+ I::Item: AsRef<[u8]>,
{
pub fn new(mut iter: I, prefix: impl AsRef<[u8]>) -> Self {
iter.seek(prefix.as_ref());
}
}
-impl<E, I> Iterator for PrefixIter<I>
+impl<I> Iterator for PrefixIter<I>
where
- I: SeekableIter<Item = E>,
- E: HasPrefix,
+ I: SeekableIter,
+ I::Item: AsRef<[u8]>,
{
- type Item = E;
+ type Item = I::Item;
+
fn next(&mut self) -> Option<Self::Item> {
- let item = self.iter.next()?;
- if item.has_prefix(self.prefix.as_slice()) {
- Some(item)
- } else {
- None
- }
+ self.iter
+ .next()
+ .filter(|e| e.as_ref().starts_with(self.prefix.as_slice()))
}
}
-impl<E, I> SeekableIter for PrefixIter<I>
+impl<I> SeekableIter for PrefixIter<I>
where
- I: SeekableIter<Item = E>,
- E: HasPrefix,
+ I: SeekableIter,
+ I::Item: AsRef<[u8]>,
{
fn seek(&mut self, key: &[u8]) {
self.iter.seek(key);
end: Vec<u8>,
}
-impl<I: SeekableIter> RangeIter<I> {
+impl<I> RangeIter<I>
+where
+ I: SeekableIter,
+ I::Item: AsRef<[u8]>,
+{
pub fn new(mut iter: I, start: impl AsRef<[u8]>, end: impl AsRef<[u8]>) -> Self {
iter.seek(start.as_ref());
Self {
}
}
-impl<E, I> Iterator for RangeIter<I>
+impl<I> Iterator for RangeIter<I>
where
- I: SeekableIter<Item = E>,
- E: PartialOrd<[u8]>,
+ I: SeekableIter,
+ I::Item: AsRef<[u8]>,
{
- type Item = E;
+ type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
- let item = self.iter.next()?;
- if item <= *self.end.as_slice() {
- Some(item)
- } else {
- None
- }
+ self.iter
+ .next()
+ .filter(|i| i.as_ref() <= self.end.as_slice())
}
}
-impl<E, I> SeekableIter for RangeIter<I>
+impl<I> SeekableIter for RangeIter<I>
where
- I: SeekableIter<Item = E>,
- E: PartialOrd<[u8]>,
+ I: SeekableIter,
+ I::Item: AsRef<[u8]>,
{
fn seek(&mut self, key: &[u8]) {
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);
}
use crate::{Entry, SeekableIter, Source};
+use std::marker::PhantomData;
-pub struct MergeFunc<S: Source, F: Fn(&mut Vec<u8>, &Entry)> {
+pub struct MergeFunc<'a, S: Source<'a>, F: Fn(&mut Vec<u8>, &Entry)> {
source: S,
merge_func: F,
+ phantom: PhantomData<&'a char>,
}
-impl<S, F> MergeFunc<S, F>
+impl<'a, S, F> MergeFunc<'a, S, F>
where
- S: Source,
+ S: Source<'a>,
F: Fn(&mut Vec<u8>, &Entry),
{
pub fn new(source: S, merge_func: F) -> Self {
- Self { source, merge_func }
+ Self {
+ source,
+ merge_func,
+ phantom: PhantomData,
+ }
}
}
-impl<S, F> Source for MergeFunc<S, F>
+impl<'a, S, F> Source<'a> for MergeFunc<'a, S, F>
where
- S: Source<Item = Entry>,
- F: Fn(&mut Vec<u8>, &Entry),
+ S: Source<'a, Item = Entry>,
+ F: Fn(&mut Vec<u8>, &Entry) + 'a,
{
+ type Iter = MergeFuncIter<S::Iter, &'a F>;
type Item = Entry;
- fn iter(&self) -> impl SeekableIter<Item = Self::Item> {
+ fn iter(&'a self) -> Self::Iter {
self.source.iter().merge_func(&self.merge_func)
}
- fn get(&self, key: &[u8]) -> impl SeekableIter<Item = Self::Item> {
- self.source.get(key).merge_func(&self.merge_func)
- }
- fn get_prefix(&self, prefix: &[u8]) -> impl SeekableIter<Item = Self::Item> {
- self.source.get_prefix(prefix).merge_func(&self.merge_func)
- }
- fn get_range(&self, start: &[u8], end: &[u8]) -> impl SeekableIter<Item = Self::Item> {
- self.source
- .get_range(start, end)
- .merge_func(&self.merge_func)
- }
}
-pub struct MergeFuncIter<'a, I, F: Fn(&mut Vec<u8>, &Entry)> {
+pub struct MergeFuncIter<I, F: FnMut(&mut Vec<u8>, &Entry)> {
prev: Option<Entry>,
iter: I,
- merge_func: &'a F,
+ merge_func: F,
}
-impl<'a, I, F> MergeFuncIter<'a, I, F>
+impl<I, F> MergeFuncIter<I, F>
where
- F: Fn(&mut Vec<u8>, &Entry),
+ F: FnMut(&mut Vec<u8>, &Entry),
{
- pub fn new(iter: I, merge_func: &'a F) -> Self {
+ pub fn new(iter: I, merge_func: F) -> Self {
Self {
prev: None,
iter,
}
}
-impl<'a, I, F> Iterator for MergeFuncIter<'a, I, F>
+impl<I, F> Iterator for MergeFuncIter<I, F>
where
I: Iterator<Item = Entry>,
- F: Fn(&mut Vec<u8>, &Entry),
+ F: FnMut(&mut Vec<u8>, &Entry),
{
type Item = Entry;
fn next(&mut self) -> Option<Self::Item> {
}
}
-impl<'a, I, F> SeekableIter for MergeFuncIter<'a, I, F>
+impl<I, F> SeekableIter for MergeFuncIter<I, F>
where
I: SeekableIter<Item = Entry>,
- F: Fn(&mut Vec<u8>, &Entry),
+ F: FnMut(&mut Vec<u8>, &Entry),
{
fn seek(&mut self, key: &[u8]) {
self.prev.take();
}
}
-impl<S: Source<Item = Entry>> Source for Merger<S> {
+impl<'a, S> Source<'a> for Merger<S>
+where
+ S: Source<'a, Item = Entry>,
+{
type Item = Entry;
- fn iter(&self) -> impl SeekableIter<Item = Self::Item> {
+ type Iter = MergeIter<S::Iter>;
+ fn iter(&'a self) -> Self::Iter {
MergeIter::from(self.sources.iter().map(|s| s.iter()))
}
-
- fn get(&self, key: &[u8]) -> impl SeekableIter<Item = Self::Item> {
- MergeIter::from(self.sources.iter().map(|s| s.get(key)))
- }
-
- fn get_prefix(&self, prefix: &[u8]) -> impl SeekableIter<Item = Self::Item> {
- MergeIter::from(self.sources.iter().map(|s| s.get_prefix(prefix)))
- }
-
- fn get_range(&self, start: &[u8], end: &[u8]) -> impl SeekableIter<Item = Self::Item> {
- MergeIter::from(self.sources.iter().map(|s| s.get_range(start, end)))
- }
}
#[cfg(test)]
}
}
-impl<D: AsRef<[u8]>> Source for Reader<D> {
+impl<'a, D: AsRef<[u8]>> Source<'a> for Reader<D> {
type Item = Entry;
+ type Iter = ReaderIter<D>;
- fn iter(&self) -> impl SeekableIter<Item = Self::Item> {
+ fn iter(&'a self) -> Self::Iter {
ReaderIter {
reader: self.clone(),
next_offset: 0,
self.batch_size += esize;
}
- pub fn source(mut self) -> impl Source<Item = Entry> {
+ pub fn source<'a>(&'a mut self) -> impl Source<'a, Item = Entry> {
if self.batch.get_mut().len() > 0 {
self.write_chunk();
}
- Merger::from(self.readers).merge_func(self.merge_func)
+ Merger::from(self.readers.clone()).merge_func(&self.merge_func)
}
- pub fn write<W: std::io::Write>(self, mut w: Writer<W>) {
- self.source().iter().for_each(|e| {
+ pub fn write<W: std::io::Write>(mut self, mut w: Writer<W>) {
+ if self.batch.get_mut().len() > 0 {
+ self.write_chunk();
+ }
+ let m = Merger::from(self.readers).merge_func(self.merge_func);
+ m.iter().for_each(|e| {
w.add(e).unwrap();
});
}
use crate::dupsort_func::DupsortFunc;
-use crate::entry::HasPrefix;
use crate::filter::FilterSource;
use crate::iter::{PrefixIter, RangeIter};
use crate::merge_func::MergeFunc;
use crate::{Entry, SeekableIter};
-pub trait Source {
- type Item;
+pub trait Source<'a> {
+ type Iter: SeekableIter<Item = Self::Item>;
+ type Item: AsRef<[u8]>;
- fn iter(&self) -> impl SeekableIter<Item = Self::Item>;
- fn get(&self, key: &[u8]) -> impl SeekableIter<Item = Self::Item>
- where
- Self::Item: PartialOrd<[u8]>,
- {
+ fn iter(&'a self) -> Self::Iter;
+ fn get(&'a self, key: &[u8]) -> RangeIter<Self::Iter> {
RangeIter::new(self.iter(), key, key)
}
- fn get_prefix(&self, prefix: &[u8]) -> impl SeekableIter<Item = Self::Item>
- where
- Self::Item: HasPrefix,
- {
+ fn get_prefix(&'a self, prefix: &[u8]) -> PrefixIter<Self::Iter> {
PrefixIter::new(self.iter(), prefix)
}
- fn get_range(&self, start: &[u8], end: &[u8]) -> impl SeekableIter<Item = Self::Item>
- where
- Self::Item: PartialOrd<[u8]>,
- {
+ fn get_range(&'a self, start: &[u8], end: &[u8]) -> RangeIter<Self::Iter> {
RangeIter::new(self.iter(), start, end)
}
- fn merge_func<F>(self, merge_func: F) -> MergeFunc<Self, F>
+ fn merge_func<F>(self, merge_func: F) -> MergeFunc<'a, Self, F>
where
Self: Sized,
F: Fn(&mut Vec<u8>, &Entry),
MergeFunc::new(self, merge_func)
}
- fn dupsort_func<F>(self, dupsort_func: F) -> DupsortFunc<Self, F>
+ fn dupsort_func<F>(self, dupsort_func: F) -> DupsortFunc<'a, Self, F>
where
Self: Sized,
F: Fn(&Self::Item, &Self::Item) -> std::cmp::Ordering,
DupsortFunc::new(self, dupsort_func)
}
- fn filter<F>(self, filter_func: F) -> FilterSource<Self, F>
+ fn filter<F>(self, filter_func: F) -> FilterSource<'a, Self, F>
where
Self: Sized,
- F: Fn(&Self::Item, &mut dyn SeekableIter<Item = Self::Item>) -> bool,
+ F: Fn(&Self::Item, &mut Vec<u8>) -> bool,
{
FilterSource::new(self, filter_func)
}
}
-struct VecIter<'a> {
+pub struct VecIter<'a> {
index: usize,
vec: &'a Vec<Entry>,
}
}
}
-impl Source for Vec<Entry> {
+impl<'a> Source<'a> for Vec<Entry> {
type Item = Entry;
- fn iter(&self) -> impl SeekableIter<Item = Self::Item> {
+ type Iter = VecIter<'a>;
+ fn iter(&'a self) -> Self::Iter {
VecIter {
index: 0,
vec: self,
}
}
-#[cfg(test)]
pub mod test_source {
use crate::Entry;
use crate::SeekableIter;
}
}
- impl Source for TestSource {
+ impl<'a> Source<'a> for TestSource {
type Item = Entry;
- fn iter(&self) -> impl SeekableIter<Item = Self::Item> {
+ type Iter = TestIter<'a>;
+ fn iter(&'a self) -> Self::Iter {
TestIter {
source: self,
off: 0,
}
}
-#[cfg(test)]
pub mod test {
use super::test_source::TestSource;
+ #[allow(unused_imports)]
use super::Source;
use crate::Entry;
+ #[allow(dead_code)]
fn test_source() -> TestSource {
TestSource(vec![
Entry::new(vec![0, 0, 0, 0], vec![0]),