--- /dev/null
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "lender"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39b1f7f753a5da003547d93e9e8f6542e81db06adad15dda47a9cd12559ab2e0"
+dependencies = [
+ "lender-derive",
+]
+
+[[package]]
+name = "lender-derive"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "556faf0c9adb22669a5f9f6b4ed804c8048d205dcd00fadd463affbb02931d26"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "mtbl"
+version = "0.1.0"
+dependencies = [
+ "lender",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
--- /dev/null
+use std::cmp::Ordering;
+pub use std::rc::Rc;
+
+#[derive(Debug, Clone)]
+pub struct Entry {
+ pub key: Rc<Vec<u8>>,
+ pub value: Rc<Vec<u8>>,
+}
+
+impl Entry {
+ pub fn new() -> Entry {
+ Entry {
+ key: Rc::new(Vec::new()),
+ value: Rc::new(Vec::new()),
+ }
+ }
+ pub fn from_key_value<K: AsRef<[u8]>, V: AsRef<[u8]>>(k: K, v: V) -> Entry {
+ let mut key = Vec::<u8>::with_capacity(k.as_ref().len());
+ let mut value = Vec::<u8>::with_capacity(v.as_ref().len());
+
+ key.extend_from_slice(k.as_ref());
+ value.extend_from_slice(v.as_ref());
+
+ Entry {
+ key: Rc::new(key),
+ value: Rc::new(value),
+ }
+ }
+
+ pub fn unpack(&self) -> (&[u8], &[u8]) {
+ (self.key.as_slice(), self.value.as_slice())
+ }
+}
+
+// Entries are ordered and compared by key only
+impl PartialOrd for Entry {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ self.key.partial_cmp(&other.key)
+ }
+}
+
+impl PartialEq for Entry {
+ fn eq(&self, other: &Self) -> bool {
+ self.key == other.key
+ }
+}
+
+#[cfg(test)]
+mod test {
+
+ use crate::*;
+
+ struct TestIter(Entry);
+
+ impl TestIter {
+ fn new() -> TestIter {
+ TestIter(Entry::new())
+ }
+ }
+
+ impl Iterator for TestIter {
+ type Item = Entry;
+
+ fn next(&mut self) -> Option<Entry> {
+ println!("key strong_count = {}", Rc::strong_count(&self.0.key));
+ Rc::make_mut(&mut self.0.key).push(0);
+ Some(self.0.clone())
+ }
+ }
+
+ #[test]
+ fn test_iter() {
+ for e in TestIter::new() {
+ if e.key.len() > 3 {
+ break;
+ }
+ }
+ }
+
+ #[test]
+ fn test_iter_filter() {
+ for e in TestIter::new().filter(|x: &Entry| x.key.len() % 2 == 0) {
+ println!("{:?}", e);
+ if e.key.len() > 6 {
+ break;
+ }
+ }
+ }
+}
--- /dev/null
+use crate::entry::Entry;
+use std::cell::RefCell;
+use std::iter::Iterator;
+use std::rc::Rc;
+
+pub trait Iter: Iterator<Item = Entry> + Sized {
+ fn seek<T: AsRef<[u8]>>(&mut self, key: T);
+
+ fn wrap_iter<F: FnOnce(IterBox<Self>) -> O, O: Iterator<Item=Entry>>(self, f: F) -> impl Iter
+ {
+ let it = IterBox::new(self);
+ WrapIter {
+ inner: it.clone(),
+ outer: f(it),
+ }
+ }
+
+ // provided methods
+ fn filter_seek<F>(&mut self, filter: F) -> impl Iter
+ where
+ F: FnMut(&Entry, &mut Vec<u8>) -> FilterSeekResult,
+ {
+ FilterSeek {
+ inner: self,
+ filter_func: filter,
+ seek_key: Vec::new(),
+ }
+ }
+}
+
+// WrapIter
+
+pub struct IterBox<I: Iter>(Rc<RefCell<I>>);
+
+impl<I: Iter> Clone for IterBox<I> {
+ fn clone(&self) -> Self {
+ IterBox(self.0.clone())
+ }
+}
+
+impl<I: Iter> IterBox<I> {
+ fn new(i: I) -> IterBox<I> {
+ IterBox(Rc::new(RefCell::new(i)))
+ }
+}
+
+impl<I: Iter> Iterator for IterBox<I> {
+ type Item = Entry;
+
+ fn next(&mut self) -> Option<Entry> {
+ self.0.borrow_mut().next()
+ }
+}
+
+impl<I: Iter> Iter for IterBox<I> {
+ fn seek<T: AsRef<[u8]>>(&mut self, key: T) {
+ self.0.borrow_mut().seek(key);
+ }
+}
+
+struct WrapIter<I: Iter, O: Iterator<Item = Entry>> {
+ inner: IterBox<I>,
+ outer: O,
+}
+
+impl<I: Iter, O: Iterator<Item = Entry>> Iterator for WrapIter<I, O> {
+ type Item = Entry;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.outer.next()
+ }
+}
+
+impl<I: Iter, O: Iterator<Item = Entry>> Iter for WrapIter<I, O> {
+ fn seek<T: AsRef<[u8]>>(&mut self, key: T) {
+ self.inner.seek(key)
+ }
+}
+
+// FilterSeek
+
+pub enum FilterSeekResult {
+ Keep,
+ Skip,
+ Seek,
+}
+pub use FilterSeekResult::*;
+
+struct FilterSeek<'i, I: Iterator<Item = Entry>, F: FnMut(&Entry, &mut Vec<u8>) -> FilterSeekResult>
+{
+ inner: &'i mut I,
+ filter_func: F,
+ seek_key: Vec<u8>,
+}
+
+impl<'i, I, F> Iterator for FilterSeek<'i, I, F>
+where
+ F: FnMut(&Entry, &mut Vec<u8>) -> FilterSeekResult,
+ I: Iter<Item = Entry>,
+{
+ type Item = Entry;
+
+ fn next(&mut self) -> Option<Entry> {
+ self.seek_key.clear();
+ while let Some(e) = self.inner.next() {
+ match (self.filter_func)(&e, &mut self.seek_key) {
+ Skip => continue,
+ Keep => return Some(e),
+ Seek => self.inner.seek(self.seek_key.as_slice()),
+ }
+ }
+ None
+ }
+}
+
+impl<'i, I, F> Iter for FilterSeek<'i, I, F>
+where
+ F: FnMut(&Entry, &mut Vec<u8>) -> FilterSeekResult,
+ I: Iter<Item = Entry>,
+{
+ fn seek<T: AsRef<[u8]>>(&mut self, key: T) {
+ self.inner.seek(key.as_ref());
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ struct TestIter(u8);
+
+ impl Iterator for TestIter {
+ type Item = Entry;
+
+ fn next(&mut self) -> Option<Entry> {
+ match self.0 {
+ 255 => None,
+ _ => {
+ let res = Entry::from_key_value(vec![self.0], vec![self.0]);
+ self.0 = self.0 + 1;
+ Some(res)
+ }
+ }
+ }
+ }
+
+ impl Iter for TestIter {
+ fn seek<T: AsRef<[u8]>>(&mut self, kr: T) {
+ self.0 = kr.as_ref()[0];
+ }
+ }
+
+ #[test]
+ fn test_iter_filter() {
+ let mut ti = TestIter(0);
+ let v: Vec<Entry> = ti
+ .filter_seek(|e, k| {
+ let b = e.key[0];
+ if b % 2 > 0 {
+ if b < 60 {
+ k.push((b + 1) * 4);
+ return FilterSeekResult::Seek;
+ }
+ return FilterSeekResult::Skip;
+ }
+ FilterSeekResult::Keep
+ })
+ .filter(|e| e.key[0] % 5 == 0)
+ .collect();
+ println!("length = {}", v.len());
+ assert!(v.into_iter().all(|e| e.key[0] % 2 == 0));
+ }
+
+ #[test]
+ fn test_iter_wrap() {
+ let ti = TestIter(0);
+ let mut mi = ti.wrap_iter(|i| i.filter(|e| e.key[0] % 2 == 0));
+ mi.seek(&[100]);
+ let v: Vec<Entry> = mi.collect();
+ println!("{:?}", v);
+ }
+}