]> git.mikk.net Git - mtbl-rs/commitdiff
Refactor to allow for dyn-compatible Source, iteration over arbitrary
authorChris Mikkelson <chris@mikk.net>
Sat, 5 Apr 2025 22:26:47 +0000 (17:26 -0500)
committerChris Mikkelson <chris@mikk.net>
Sat, 5 Apr 2025 22:26:47 +0000 (17:26 -0500)
types.

src/dupsort_func.rs
src/entry.rs
src/filter.rs
src/iter.rs
src/merge_func.rs
src/merger.rs
src/reader/mod.rs
src/sorter.rs
src/source.rs

index a9b8b9284d0fcca25e5a4d3160c0e06cb10890d2..96d0bf1d43d0684d4135549fbe62be620bef9b54 100644 (file)
@@ -1,81 +1,63 @@
-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,
@@ -85,7 +67,7 @@ where
     }
 }
 
-impl<'a, I, F> Iterator for DupsortFuncIter<'a, I, F>
+impl<I, F> Iterator for DupsortFuncIter<I, F>
 where
     I: SeekableIter,
     I::Item: PartialEq,
@@ -115,7 +97,7 @@ where
     }
 }
 
-impl<'a, I, F> SeekableIter for DupsortFuncIter<'a, I, F>
+impl<I, F> SeekableIter for DupsortFuncIter<I, F>
 where
     I: SeekableIter,
     I::Item: PartialEq,
index 9fe4fc67629208c40c6a080de25854726a1f90be..ce1ede2c2a3e1cfdb6506926f3041db9d015dbec 100644 (file)
@@ -58,18 +58,14 @@ impl PartialEq<[u8]> for Entry {
     }
 }
 
-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()
     }
 }
index 459c50f085ed2ff42e661e5e0c4ce23827142f61..2aed71d593bd0a64be91de7eee21fca1489a6cdc 100644 (file)
@@ -1,99 +1,88 @@
-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]
@@ -107,19 +96,20 @@ fn test_filter() {
             .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>>()
     );
 }
index 0a7209c4b7524f0691440374a0568e244a00e00e..b50e3a84d0a66b55df3210f40b4c010ac66a15c8 100644 (file)
@@ -1,5 +1,4 @@
 use crate::dupsort_func::DupsortFuncIter;
-use crate::entry::HasPrefix;
 use crate::filter::FilterIter;
 use crate::merge_func::MergeFuncIter;
 use crate::Entry;
@@ -9,40 +8,44 @@ use std::iter::Iterator;
 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());
@@ -53,26 +56,24 @@ where
     }
 }
 
-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);
@@ -85,7 +86,11 @@ pub struct RangeIter<I> {
     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 {
@@ -96,33 +101,29 @@ impl<I: SeekableIter> RangeIter<I> {
     }
 }
 
-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);
         }
index 7f55bd6c8f2346143c06ae36a2871dee07d7dd95..ef1038058617b801edb67a592791fe3a4622d081 100644 (file)
@@ -1,53 +1,49 @@
 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,
@@ -56,10 +52,10 @@ where
     }
 }
 
-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> {
@@ -76,10 +72,10 @@ where
     }
 }
 
-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();
index 3c99c1a511a97eca881957e9e67b3af4a0869608..a5e2bb3bb84b87157fd1954015aa34bbe71eb785 100644 (file)
@@ -134,23 +134,15 @@ impl<I: SeekableIter<Item = Entry>> SeekableIter for MergeIter<I> {
     }
 }
 
-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)]
index 4ba0d7ebc82b1e7c4f1983ed6dacd1ce14a637e4..e5659a31d3aa9ff0a6a3438e9a726ea8e6de29ec 100644 (file)
@@ -176,10 +176,11 @@ impl<D: AsRef<[u8]>> SeekableIter for ReaderIter<D> {
     }
 }
 
-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,
index 7685530ee9c90f4dc87ed6bb42ada14d7468e692..c8bab83c140eec92a4ca7d736a1adddbfc79f8f2 100644 (file)
@@ -35,15 +35,19 @@ where
         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();
         });
     }
index c7c6c008772529ef56060bb455dfbb007744c4fc..6a8015d944d1d71f0c18191c2e78e29b347b7d69 100644 (file)
@@ -1,34 +1,25 @@
 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),
@@ -36,7 +27,7 @@ pub trait Source {
         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,
@@ -44,16 +35,16 @@ pub trait Source {
         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>,
 }
@@ -87,9 +78,10 @@ impl<'a> SeekableIter for VecIter<'a> {
     }
 }
 
-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,
@@ -97,7 +89,6 @@ impl Source for Vec<Entry> {
     }
 }
 
-#[cfg(test)]
 pub mod test_source {
     use crate::Entry;
     use crate::SeekableIter;
@@ -133,9 +124,10 @@ pub mod test_source {
         }
     }
 
-    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,
@@ -144,12 +136,13 @@ pub mod test_source {
     }
 }
 
-#[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]),