--- /dev/null
+use std::sync::Arc;
+
+#[derive(Debug, Clone)]
+pub struct Entry {
+ pub key: Arc<Vec<u8>>,
+ pub value: Arc<Vec<u8>>,
+}
+
+impl Entry {
+ pub fn new(key: impl AsRef<[u8]>, value: impl AsRef<[u8]>) -> Self {
+ Entry {
+ key: Arc::new(Vec::from(key.as_ref())),
+ value: Arc::new(Vec::from(value.as_ref())),
+ }
+ }
+
+ pub fn replace(&mut self, e: &Entry) {
+ let key = Arc::make_mut(&mut self.key);
+ let value = Arc::make_mut(&mut self.value);
+ key.clear();
+ key.extend_from_slice(e.key.as_slice());
+ value.clear();
+ value.extend_from_slice(e.value.as_slice());
+ }
+}
-pub mod seekable;
-pub use seekable::Seekable;
+pub mod entry;
+use entry::Entry;
+
+pub mod source;
+use source::{Iter, Source};
+
+pub mod merger;
+//use merger::Merger;
--- /dev/null
+use crate::{Entry, Iter, Source};
+use std::cmp::Ordering;
+use std::collections::BinaryHeap;
+use std::marker::PhantomData;
+
+pub struct Merger<'a, S: Source> {
+ sources: Vec<S>,
+ _p: PhantomData<&'a u8>,
+}
+
+impl<'a, S, I> From<I> for Merger<'a, S>
+where
+ S: Source,
+ I: IntoIterator<Item = S>,
+{
+ fn from(i: I) -> Self {
+ Merger {
+ sources: Vec::from_iter(i),
+ _p: PhantomData,
+ }
+ }
+}
+
+struct MergeEntry<'a> {
+ e: Entry,
+ it: Box<dyn Iter + 'a>,
+}
+
+impl<'a> PartialEq for MergeEntry<'a> {
+ fn eq(&self, other: &Self) -> bool {
+ self.e.key == other.e.key
+ }
+}
+impl<'a> Eq for MergeEntry<'a> {}
+
+impl<'a> PartialOrd for MergeEntry<'a> {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ Some(other.e.key.cmp(&self.e.key))
+ }
+}
+
+impl<'a> Ord for MergeEntry<'a> {
+ fn cmp(&self, other: &Self) -> Ordering {
+ other.e.key.cmp(&self.e.key)
+ }
+}
+
+struct MergeIter<'a, S: Source> {
+ sources: &'a [S],
+ heap: BinaryHeap<MergeEntry<'a>>,
+ last_key: Vec<u8>,
+}
+
+impl<'a, S: Source> Iterator for MergeIter<'a, S> {
+ type Item = Entry;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let cur;
+ {
+ let mut next = self.heap.peek_mut()?;
+ cur = next.e.clone();
+ if let Some(e) = next.it.next() {
+ next.e = e;
+ self.last_key.clear();
+ self.last_key.extend(next.e.key.as_slice());
+ return Some(cur);
+ }
+ }
+ self.heap.pop();
+ Some(cur)
+ }
+}
+
+impl<'a, S: Source> Iter for MergeIter<'a, S> {
+ fn seek(&mut self, key: &[u8]) {
+ if key > self.last_key.as_slice() {
+ loop {
+ match self.heap.peek_mut() {
+ None => return,
+ Some(mut head) => {
+ if head.e.key.as_slice() >= key {
+ self.last_key.clear();
+ self.last_key.extend_from_slice(head.e.key.as_slice());
+ return;
+ }
+ head.it.seek(key);
+ if let Some(e) = head.it.next() {
+ head.e = e;
+ continue;
+ }
+ }
+ }
+ self.heap.pop();
+ }
+ }
+ self.heap = BinaryHeap::from_iter(self.sources.iter().filter_map(|s| {
+ let mut it = s.iter();
+ it.seek(key);
+ Some(MergeEntry {
+ e: it.next()?,
+ it: Box::new(it),
+ })
+ }));
+ self.last_key.clear();
+ self.last_key.extend_from_slice(key);
+ }
+}
+
+impl<'a, S: Source> Source for Merger<'a, S> {
+ fn iter(&self) -> impl Iter {
+ MergeIter {
+ last_key: Vec::new(),
+ sources: self.sources.as_slice(),
+ heap: BinaryHeap::from_iter(self.sources.as_slice().iter().filter_map(|s| {
+ let mut it = s.iter();
+ Some(MergeEntry {
+ e: it.next()?,
+ it: Box::new(it),
+ })
+ })),
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::Merger;
+ use crate::source::test::TestSource;
+ use crate::{Entry, Source};
+
+ 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])),
+ ))
+ }
+
+ #[test]
+ fn test_merge() {
+ let range = 1..8;
+ let s = Merger::from(range.clone().into_iter().map(test_source));
+ let mut v = Vec::<u8>::new();
+ for i in range {
+ v.extend(tnum(i))
+ }
+ v.sort();
+ let v2 = Vec::from_iter(s.iter().map(|e| e.key[0]));
+ assert_eq!(v2, v);
+ }
+
+ #[test]
+ fn test_binheap() {
+ use std::collections::BinaryHeap;
+
+ let v: Vec<u8> = vec![1, 8, 2, 9, 4, 7, 3];
+ let vs = v.as_slice();
+ let h = BinaryHeap::from_iter(vs.into_iter().map(|p| *p));
+ assert_ne!(h.into_vec(), v);
+ }
+}
+++ /dev/null
-mod coalesce;
-mod filter_map;
-mod merge;
-mod vec;
-use coalesce::Coalesce;
-use filter_map::FilterMapValue;
-use merge::Merger;
-pub use vec::SeekableVec;
-
-pub trait Seekable: Sized {
- type Key;
- type Value;
-
- fn next(&mut self) -> Option<(Self::Key, Self::Value)>;
- fn seek(&mut self, key: &Self::Key);
-
- fn filter_mapv<F, V>(self, func: F) -> FilterMapValue<Self, F, V>
- where
- F: FnMut(&Self::Key, Self::Value, &mut Self) -> Option<V>,
- {
- FilterMapValue { next: self, func }
- }
-
- fn merge<L>(iter: L) -> Merger<Self>
- where
- L: Iterator<Item = Self>,
- Self::Key: Ord,
- {
- merge::merge(iter)
- }
-
- fn coalesce<F>(self, cf: F) -> Coalesce<Self, F>
- where
- F: FnMut(&Self::Key, Self::Value, Self::Value) -> Self::Value,
- Self::Key: PartialEq,
- {
- coalesce::coalesce(self, cf)
- }
-}
-
-#[derive(Debug)]
-pub struct Iter<T>(T);
-
-impl<T> Iterator for Iter<T>
-where
- T: Seekable,
-{
- type Item = (T::Key, T::Value);
-
- fn next(&mut self) -> Option<Self::Item> {
- self.0.next()
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::{Iter, Seekable};
-
- struct Empty;
- impl IntoIterator for Empty {
- type Item = ((), ());
- type IntoIter = Iter<Empty>;
- fn into_iter(self) -> Iter<Empty> {
- Iter(self)
- }
- }
-
- impl Seekable for Empty {
- type Value = ();
- type Key = ();
-
- fn next(&mut self) -> Option<((), ())> {
- None
- }
- fn seek(&mut self, _key: &Self::Key) {}
- }
-}
+++ /dev/null
-use crate::seekable::{Iter, Seekable};
-use std::cell::RefCell;
-
-pub struct Coalesce<S, F>
-where
- S: Seekable,
- F: FnMut(&S::Key, S::Value, S::Value) -> S::Value,
-{
- cur_item: RefCell<Option<(S::Key, S::Value)>>,
- rest: S,
- cfunc: F,
-}
-
-pub fn coalesce<S, F>(seekable: S, cf: F) -> Coalesce<S, F>
-where
- S: Seekable,
- F: FnMut(&S::Key, S::Value, S::Value) -> S::Value,
-{
- Coalesce {
- cur_item: RefCell::new(None),
- rest: seekable,
- cfunc: cf,
- }
-}
-
-impl<S, F> IntoIterator for Coalesce<S, F>
-where
- S: Seekable,
- S::Key: PartialEq,
- F: FnMut(&S::Key, S::Value, S::Value) -> S::Value,
-{
- type Item = (S::Key, S::Value);
- type IntoIter = Iter<Self>;
- fn into_iter(self) -> Iter<Self> {
- Iter(self)
- }
-}
-
-impl<S, F> Seekable for Coalesce<S, F>
-where
- S: Seekable,
- S::Key: PartialEq,
- F: FnMut(&S::Key, S::Value, S::Value) -> S::Value,
-{
- type Key = S::Key;
- type Value = S::Value;
-
- fn next(&mut self) -> Option<(Self::Key, Self::Value)> {
- if self.cur_item.borrow().is_none() {
- let next = self.rest.next()?;
- self.cur_item.replace(Some(next));
- }
- while let Some((k, v)) = self.rest.next() {
- if let Some((cur_k, cur_v)) = self.cur_item.replace(None) {
- if k != cur_k {
- self.cur_item.replace(Some((k, v)));
- return Some((cur_k, cur_v));
- }
- self.cur_item
- .replace(Some((k, ((self.cfunc)(&cur_k, cur_v, v)))));
- }
- }
- self.cur_item.replace(None)
- }
-
- fn seek(&mut self, key: &Self::Key) {
- self.cur_item.replace(None);
- self.rest.seek(key);
- }
-}
-
-#[cfg(test)]
-mod test {
- use crate::seekable::SeekableVec;
- use crate::Seekable;
- use std::cmp::Ordering;
-
- #[test]
- fn test_coalesce() {
- let v = vec![(1, 2), (1, 3), (2, 1), (2, 4)];
- let vc = vec![(1, 2 + 3), (2, 1 + 4)];
- let v: SeekableVec<i32, i32> = SeekableVec::from(v.clone());
- assert_eq!(
- v.coalesce(|_k, v1, v2| v1 + v2)
- .into_iter()
- .cmp(vc.into_iter()),
- Ordering::Equal
- )
- }
-}
+++ /dev/null
-use crate::seekable::{Iter, Seekable};
-
-pub struct FilterMapValue<S, F, V>
-where
- S: Seekable,
- F: FnMut(&S::Key, S::Value, &mut S) -> Option<V>,
-{
- pub(crate) next: S,
- pub(crate) func: F,
-}
-
-impl<S, F, V> IntoIterator for FilterMapValue<S, F, V>
-where
- S: Seekable,
- F: FnMut(&S::Key, S::Value, &mut S) -> Option<V>,
-{
- type Item = (S::Key, V);
- type IntoIter = Iter<Self>;
- fn into_iter(self) -> Iter<Self> {
- Iter(self)
- }
-}
-
-impl<S, F, V> Seekable for FilterMapValue<S, F, V>
-where
- S: Seekable,
- F: FnMut(&S::Key, S::Value, &mut S) -> Option<V>,
-{
- type Key = S::Key;
- type Value = V;
-
- fn next(&mut self) -> Option<(S::Key, V)> {
- loop {
- match self.next.next() {
- None => return None,
- Some(v) => {
- if let Some(i) = (self.func)(&v.0, v.1, &mut self.next) {
- return Some((v.0, i));
- }
- }
- }
- }
- }
-
- fn seek(&mut self, key: &S::Key) {
- self.next.seek(key)
- }
-}
-
-pub struct FilterMapKey<S, F, FS, K>
-where
- S: Seekable,
- F: FnMut(&S::Key, &S::Value, &mut S) -> Option<K>,
- FS: FnMut(&K, &mut S),
-{
- pub(crate) next: S,
- pub(crate) func: F,
- pub(crate) seekfunc: FS,
-}
-
-impl<S, F, FS, K> IntoIterator for FilterMapKey<S, F, FS, K>
-where
- S: Seekable,
- F: FnMut(&S::Key, &S::Value, &mut S) -> Option<K>,
- FS: FnMut(&K, &mut S),
-{
- type Item = (K, S::Value);
- type IntoIter = Iter<Self>;
- fn into_iter(self) -> Self::IntoIter {
- Iter(self)
- }
-}
-
-impl<S, F, FS, K> Seekable for FilterMapKey<S, F, FS, K>
-where
- S: Seekable,
- F: FnMut(&S::Key, &S::Value, &mut S) -> Option<K>,
- FS: FnMut(&K, &mut S),
-{
- type Key = K;
- type Value = S::Value;
-
- fn next(&mut self) -> Option<(Self::Key, Self::Value)> {
- loop {
- match self.next.next() {
- None => return None,
- Some((k, v)) => {
- if let Some(newk) = (self.func)(&k, &v, &mut self.next) {
- return Some((newk, v));
- }
- }
- }
- }
- }
- fn seek(&mut self, key: &Self::Key) {
- (self.seekfunc)(key, &mut self.next);
- }
-}
-
-#[cfg(test)]
-mod test {
- use crate::seekable::SeekableVec;
- use crate::Seekable;
- use std::cmp::Ordering;
-
- #[test]
- fn test_map() {
- let mut v = vec![3i32, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7];
- let sv = SeekableVec::from(v.clone().into_iter().collect::<Vec<i32>>());
- v.sort();
- assert_eq!(
- sv.filter_mapv(|_k, _v, _s| Some("hello"))
- .into_iter()
- .cmp(v.into_iter().map(|i| (i, "hello"))),
- Ordering::Equal
- );
- }
-
- #[test]
- fn test_map_filter_seek() {
- let v = vec![3i32, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7]
- .into_iter()
- .map(|i| (i, "foo"))
- .collect::<Vec<(i32, &str)>>();
- let mut sv = SeekableVec::from(v.clone()).filter_mapv(|k, _v, s| {
- if k % 5 == 0 {
- return None;
- }
- if *k == 7 {
- s.seek(&8);
- return None;
- }
- Some("bar")
- });
- sv.seek(&3);
- assert_eq!(sv.next(), Some((3, "bar")));
- assert_eq!(sv.next(), Some((3, "bar")));
-
- sv.seek(&5);
- assert_eq!(sv.next(), Some((6, "bar")));
- assert_eq!(sv.next(), Some((8, "bar")))
- }
-}
+++ /dev/null
-use crate::seekable::{Iter, Seekable};
-use std::cell::RefCell;
-use std::cmp::Ordering;
-use std::collections::BinaryHeap;
-
-pub struct Merger<S>
-where
- S: Seekable,
- S::Key: Ord,
-{
- active: BinaryHeap<MergerEnt<S>>,
- ended: Vec<S>,
-}
-
-struct MergerEnt<S: Seekable>
-where
- S::Key: Ord,
-{
- cur_item: RefCell<(S::Key, S::Value)>,
- rest: S,
-}
-
-impl<S: Seekable> Eq for MergerEnt<S> where S::Key: Ord {}
-impl<S: Seekable> PartialEq for MergerEnt<S>
-where
- S::Key: Ord,
-{
- fn eq(&self, other: &Self) -> bool {
- let sent = self.cur_item.borrow();
- let oent = other.cur_item.borrow();
- sent.0.eq(&oent.0)
- }
-}
-
-// Because std::collections::BinaryHeap implements a max
-// heap and we need a min-heap, we reverse the sense of Ord
-// for MergerEnt<S> vs. S::Key. We do this instead of using
-// std::cmp::Reverse to avoid the additional packing/unpacking
-// boilerplate.
-impl<S: Seekable> PartialOrd for MergerEnt<S>
-where
- S::Key: Ord,
-{
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl<S: Seekable> Ord for MergerEnt<S>
-where
- S::Key: Ord,
-{
- fn cmp(&self, other: &Self) -> Ordering {
- let sent = self.cur_item.borrow();
- let oent = other.cur_item.borrow();
- oent.0.cmp(&sent.0)
- }
-}
-
-impl<S: Seekable> MergerEnt<S>
-where
- S::Key: Ord,
-{
- fn new(mut source: S) -> Option<MergerEnt<S>> {
- Some(MergerEnt {
- cur_item: RefCell::new(source.next()?),
- rest: source,
- })
- }
-
- fn replace(&mut self, v: (S::Key, S::Value)) -> (S::Key, S::Value) {
- self.cur_item.replace(v)
- }
-}
-
-pub fn merge<L, S>(sources: L) -> Merger<S>
-where
- L: Iterator<Item = S>,
- S: Seekable,
- S::Key: Ord,
-{
- Merger {
- active: BinaryHeap::from(
- sources
- .into_iter()
- .filter_map(|i| MergerEnt::new(i))
- .collect::<Vec<MergerEnt<S>>>(),
- ),
- ended: Vec::new(),
- }
-}
-
-impl<S: Seekable> IntoIterator for Merger<S>
-where
- S::Key: Ord,
-{
- type Item = (S::Key, S::Value);
- type IntoIter = Iter<Self>;
- fn into_iter(self) -> Self::IntoIter {
- Iter(self)
- }
-}
-
-fn heap_reset<S: Seekable>(m: &mut Merger<S>, key: &S::Key)
-where
- S::Key: Ord,
-{
- let mut active = Vec::<MergerEnt<S>>::new();
- let mut ended = Vec::<S>::new();
- while let Some(e) = m.active.pop() {
- m.ended.push(e.rest);
- }
- while let Some(mut s) = m.ended.pop() {
- s.seek(key);
- if let Some(next_item) = s.next() {
- active.push(MergerEnt {
- cur_item: RefCell::new(next_item),
- rest: s,
- });
- } else {
- ended.push(s)
- }
- }
-
- m.ended = ended;
- m.active = BinaryHeap::from(active);
-}
-
-// forward seek within the heap
-fn heap_seek<S: Seekable>(m: &mut Merger<S>, key: &S::Key) -> Option<()>
-where
- S::Key: Ord,
-{
- loop {
- let mut head = m.active.peek_mut()?;
- if head.cur_item.borrow().0 >= *key {
- break;
- }
- head.rest.seek(key);
- if let Some(next) = head.rest.next() {
- head.replace(next);
- continue;
- }
- drop(head); // release heap for modification
- let head = m.active.pop()?;
- m.ended.push(head.rest);
- }
- None
-}
-
-impl<S: Seekable> Seekable for Merger<S>
-where
- S::Key: Ord,
-{
- type Key = S::Key;
- type Value = S::Value;
-
- fn next(&mut self) -> Option<(Self::Key, Self::Value)> {
- let mut head = self.active.peek_mut()?;
- if let Some(next) = head.rest.next() {
- return Some(head.replace(next));
- }
- drop(head); // release heap for mutation below
- let head = self.active.pop()?;
- self.ended.push(head.rest);
- Some(head.cur_item.into_inner())
- }
-
- fn seek(&mut self, key: &Self::Key) {
- /* seek forward only */
- let head = self.active.peek_mut();
- if head.is_none() {
- return;
- }
- if head.unwrap().cur_item.borrow().0 > *key {
- heap_reset(self, key);
- return;
- }
- heap_seek(self, key);
- }
-}
-
-#[cfg(test)]
-mod test {
- use crate::seekable::SeekableVec;
- use crate::Seekable;
- use std::cmp::Ordering;
-
- #[test]
- fn test_seekablevec() {
- let mut v = vec![3, 1, 4, 1, 5, 9];
- let mut sv = SeekableVec::from(v.clone());
- v.sort();
- sv.seek(&3);
- assert_eq!(
- sv.into_iter()
- .map(|e| e.0)
- .cmp(v.into_iter().filter(|i| *i >= 3)),
- Ordering::Equal
- );
- }
-
- #[test]
- fn test_merge_sv() {
- let vpi = vec![3, 1, 4, 1, 5, 9];
- let mut ve = vec![2, 7, 1, 8, 2, 8];
- let mut mv = Seekable::merge(
- vec![
- SeekableVec::from(vpi.clone()),
- SeekableVec::from(ve.clone()),
- ]
- .into_iter(),
- );
- mv.seek(&5);
- ve.extend(vpi);
- ve.sort();
- assert_eq!(
- mv.into_iter()
- .map(|e| e.0)
- .cmp(ve.into_iter().filter(|i| *i >= 5)),
- Ordering::Equal
- );
- }
-}
+++ /dev/null
-use crate::seekable::Iter;
-use crate::Seekable;
-
-#[derive(Debug)]
-pub struct SeekableVec<K: Ord + Clone, V: Ord + Clone> {
- off: usize,
- v: Vec<(K, V)>,
-}
-impl<K: Ord + Clone, V: Ord + Clone> IntoIterator for SeekableVec<K, V> {
- type Item = (K, V);
- type IntoIter = Iter<Self>;
- fn into_iter(self) -> Iter<Self> {
- Iter(self)
- }
-}
-impl<K: Ord + Clone, V: Ord + Clone> Seekable for SeekableVec<K, V> {
- type Key = K;
- type Value = V;
- fn next(&mut self) -> Option<(K, V)> {
- if self.off >= self.v.len() {
- return None;
- }
- let v = self.v[self.off].clone();
- self.off += 1;
- Some(v)
- }
- fn seek(&mut self, key: &K) {
- self.off = 0;
- while self.off < self.v.len() {
- if self.v[self.off].0 >= *key {
- break;
- }
- self.off += 1;
- }
- }
-}
-impl<K: Ord + Clone, V: Ord + Clone> From<Vec<(K, V)>> for SeekableVec<K, V> {
- fn from(vec: Vec<(K, V)>) -> SeekableVec<K, V> {
- let mut sv = SeekableVec { off: 0, v: vec };
- sv.v.sort();
- sv
- }
-}
-
-impl<K: Ord + Clone> From<Vec<K>> for SeekableVec<K, ()> {
- fn from(vec: Vec<K>) -> SeekableVec<K, ()> {
- let mut pv = vec.into_iter().map(|k| (k, ())).collect::<Vec<(K, ())>>();
- pv.sort();
- SeekableVec { off: 0, v: pv }
- }
-}
--- /dev/null
+use crate::Entry;
+use std::iter::Iterator;
+
+pub trait Iter: Iterator<Item = Entry> {
+ fn seek(&mut self, key: &[u8]);
+}
+
+pub trait Source {
+ fn iter(&self) -> impl Iter;
+
+ fn get(&self, key: &[u8]) -> impl Iter {
+ let mut res = RangeIter {
+ iter: self.iter(),
+ end: Vec::from(key),
+ };
+ res.seek(key);
+ res
+ }
+
+ fn get_prefix(&self, prefix: &[u8]) -> impl Iter {
+ let mut res = PrefixIter {
+ iter: self.iter(),
+ prefix: Vec::from(prefix),
+ };
+ res.seek(prefix);
+ res
+ }
+
+ fn get_range(&self, start: &[u8], end: &[u8]) -> impl Iter {
+ let mut res = RangeIter {
+ iter: self.iter(),
+ end: Vec::from(end),
+ };
+ res.seek(start);
+ res
+ }
+}
+
+struct PrefixIter<I: Iter> {
+ iter: I,
+ prefix: Vec<u8>,
+}
+
+impl<I: Iter> Iterator for PrefixIter<I> {
+ type Item = Entry;
+ fn next(&mut self) -> Option<Self::Item> {
+ let item = self.iter.next()?;
+ if item.key.starts_with(self.prefix.as_slice()) {
+ Some(item)
+ } else {
+ None
+ }
+ }
+}
+impl<I: Iter> Iter for PrefixIter<I> {
+ fn seek(&mut self, key: &[u8]) {
+ self.iter.seek(key);
+ }
+}
+
+struct RangeIter<I: Iter> {
+ iter: I,
+ end: Vec<u8>,
+}
+
+impl<I: Iter> Iterator for RangeIter<I> {
+ type Item = Entry;
+ fn next(&mut self) -> Option<Self::Item> {
+ let item = self.iter.next()?;
+ if item.key.as_slice() <= self.end.as_slice() {
+ Some(item)
+ } else {
+ None
+ }
+ }
+}
+impl<I: Iter> Iter for RangeIter<I> {
+ fn seek(&mut self, key: &[u8]) {
+ self.iter.seek(key);
+ }
+}
+
+#[cfg(test)]
+pub mod test {
+ use super::{Entry, Iter, Source};
+
+ pub struct TestSource(pub Vec<Entry>);
+
+ struct TestIter<'a> {
+ source: &'a TestSource,
+ off: usize,
+ }
+
+ impl<'a> Iterator for TestIter<'a> {
+ type Item = Entry;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let off = self.off;
+ if off >= self.source.0.len() {
+ return None;
+ }
+ let item = &self.source.0[off];
+ self.off += 1;
+ Some(item.clone())
+ }
+ }
+
+ impl<'a> Iter for TestIter<'a> {
+ fn seek(&mut self, key: &[u8]) {
+ self.off = 0;
+ while self.off < self.source.0.len() && self.source.0[self.off].key.as_slice() < key {
+ self.off += 1;
+ }
+ }
+ }
+
+ impl Source for TestSource {
+ fn iter(&self) -> impl Iter {
+ 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]),
+ ])
+ }
+
+ #[test]
+ fn test_source_iter() {
+ let s = test_source();
+ assert_eq!(
+ Vec::from_iter(s.iter().map(|e| e.value[0])),
+ vec![0, 1, 2, 3, 4]
+ );
+ assert_eq!(
+ Vec::from_iter(s.get(vec![0, 0, 1, 0].as_slice()).map(|e| e.value[0])),
+ vec![2]
+ );
+ assert_eq!(
+ Vec::from_iter(s.get_prefix(vec![0, 0].as_slice()).map(|e| e.value[0])),
+ vec![0, 1, 2]
+ );
+ assert_eq!(
+ Vec::from_iter(
+ s.get_range(vec![0, 0, 0, 1].as_slice(), vec![0, 1, 0, 0].as_slice())
+ .map(|e| e.value[0])
+ ),
+ vec![1, 2, 3]
+ );
+ }
+}