-use crate::{Entry, Iter, Source};
+use crate::entry::HasPrefix;
+use crate::{Iter, Source};
use std::cmp::Ordering;
pub struct DupsortFunc<S, F>
where
S: Source,
- F: Fn(&Entry, &Entry) -> Ordering,
+ F: Fn(&S::Item, &S::Item) -> Ordering,
{
source: S,
dupsort_func: F,
impl<S, F> DupsortFunc<S, F>
where
S: Source,
- F: Fn(&Entry, &Entry) -> Ordering,
+ F: Fn(&S::Item, &S::Item) -> Ordering,
{
pub fn new(source: S, dupsort_func: F) -> Self {
Self {
impl<S, F> Source for DupsortFunc<S, F>
where
S: Source,
- F: Fn(&Entry, &Entry) -> Ordering,
+ S::Item: PartialEq,
+ F: Fn(&S::Item, &S::Item) -> Ordering,
{
- fn iter(&self) -> impl Iter {
+ type Item = S::Item;
+ fn iter(&self) -> impl Iter<Item = Self::Item> {
self.source.iter().dupsort_func(&self.dupsort_func)
}
- fn get(&self, key: &[u8]) -> impl Iter {
+ fn get(&self, key: &[u8]) -> impl Iter<Item = Self::Item>
+ where
+ S::Item: PartialOrd<[u8]>,
+ {
self.source.get(key).dupsort_func(&self.dupsort_func)
}
- fn get_prefix(&self, prefix: &[u8]) -> impl Iter {
+ fn get_prefix(&self, prefix: &[u8]) -> impl Iter<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 Iter {
+ fn get_range(&self, start: &[u8], end: &[u8]) -> impl Iter<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>
where
- F: Fn(&Entry, &Entry) -> Ordering,
+ I: Iter,
+ F: Fn(&I::Item, &I::Item) -> Ordering,
{
- run: Vec<Entry>,
- next: Option<Entry>,
+ run: Vec<I::Item>,
+ next: Option<I::Item>,
iter: I,
dupsort_func: &'a F,
}
impl<'a, I, F> DupsortFuncIter<'a, I, F>
where
- F: Fn(&Entry, &Entry) -> Ordering,
+ I: Iter,
+ F: Fn(&I::Item, &I::Item) -> Ordering,
{
pub fn new(iter: I, dupsort_func: &'a F) -> Self {
Self {
impl<'a, I, F> Iterator for DupsortFuncIter<'a, I, F>
where
- I: Iterator<Item = Entry>,
- F: Fn(&Entry, &Entry) -> Ordering,
+ I: Iter,
+ I::Item: PartialEq,
+ F: Fn(&I::Item, &I::Item) -> Ordering,
{
- type Item = Entry;
+ type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
self.run.pop().or_else(|| {
// println!("2: {:?} / {:?}", self.next, self.run);
while let Some(e) = self.iter.next() {
- if e.key() == self.run[0].key() {
+ if e == self.run[0] {
self.run.push(e);
continue;
}
impl<'a, I, F> Iter for DupsortFuncIter<'a, I, F>
where
I: Iter,
- F: Fn(&Entry, &Entry) -> Ordering,
+ I::Item: PartialEq,
+ F: Fn(&I::Item, &I::Item) -> Ordering,
{
fn seek(&mut self, key: &[u8]) {
self.run.clear();
#[test]
fn test_dupsort() {
use crate::source::test_source::TestSource;
+ use crate::Entry;
let ts = TestSource(
(1u8..10)
+use std::cmp::Ordering;
use std::sync::Arc;
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, Eq)]
pub struct Entry {
key: Arc<Vec<u8>>,
value: Arc<Vec<u8>>,
Arc::make_mut(&mut self.value)
}
}
+
+impl PartialOrd<[u8]> for Entry {
+ fn partial_cmp(&self, other: &[u8]) -> Option<Ordering> {
+ Some(self.key().cmp(other))
+ }
+}
+
+impl PartialEq<[u8]> for Entry {
+ fn eq(&self, other: &[u8]) -> bool {
+ self.key() == other
+ }
+}
+
+impl PartialEq<Entry> for Entry {
+ fn eq(&self, other: &Entry) -> bool {
+ self.key() == other.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)
+ }
+}
-use crate::{Entry, Iter, Source};
+use crate::{entry::HasPrefix, Iter, Source};
pub struct FilterIter<'a, I, F> {
iter: I,
impl<'a, I, F> FilterIter<'a, I, F>
where
- F: Fn(&Entry, &mut dyn Iter) -> bool,
+ I: Iter,
+ F: Fn(&I::Item, &mut dyn Iter<Item = I::Item>) -> bool,
{
pub fn new(iter: I, filter_func: &'a F) -> Self {
Self { iter, filter_func }
impl<'a, I, F> Iterator for FilterIter<'a, I, F>
where
- F: Fn(&Entry, &mut dyn Iter) -> bool,
I: Iter,
+ F: Fn(&I::Item, &mut dyn Iter<Item = I::Item>) -> bool,
{
- type Item = Entry;
+ type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
while let Some(e) = self.iter.next() {
impl<'a, I, F> Iter for FilterIter<'a, I, F>
where
I: Iter,
- F: Fn(&Entry, &mut dyn Iter) -> bool,
+ F: Fn(&I::Item, &mut dyn Iter<Item = I::Item>) -> bool,
{
fn seek(&mut self, key: &[u8]) {
self.iter.seek(key);
impl<S, F> FilterSource<S, F>
where
S: Source,
- F: Fn(&Entry, &mut dyn Iter) -> bool,
+ F: Fn(&S::Item, &mut dyn Iter<Item = S::Item>) -> bool,
{
pub fn new(source: S, filter_func: F) -> Self {
Self {
impl<S, F> Source for FilterSource<S, F>
where
S: Source,
- F: Fn(&Entry, &mut dyn Iter) -> bool,
+ F: Fn(&S::Item, &mut dyn Iter<Item = S::Item>) -> bool,
{
- fn iter(&self) -> impl Iter {
+ type Item = S::Item;
+ fn iter(&self) -> impl Iter<Item = Self::Item> {
self.source.iter().filter_func(&self.filter_func)
}
- fn get(&self, key: &[u8]) -> impl Iter {
+ fn get(&self, key: &[u8]) -> impl Iter<Item = Self::Item>
+ where
+ Self::Item: PartialOrd<[u8]>,
+ {
self.source.get(key).filter_func(&self.filter_func)
}
- fn get_prefix(&self, prefix: &[u8]) -> impl Iter {
+ fn get_prefix(&self, prefix: &[u8]) -> impl Iter<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 Iter {
+ fn get_range(&self, start: &[u8], end: &[u8]) -> impl Iter<Item = Self::Item>
+ where
+ Self::Item: PartialOrd<[u8]>,
+ {
self.source
.get_range(start, end)
.filter_func(&self.filter_func)
#[test]
fn test_filter() {
use crate::source::test_source::TestSource;
+ use crate::Entry;
let ts = TestSource(
(0u8..10)
use crate::dupsort_func::DupsortFuncIter;
+use crate::entry::HasPrefix;
use crate::filter::FilterIter;
use crate::merge_func::MergeFuncIter;
use crate::Entry;
use std::cmp::Ordering;
use std::iter::Iterator;
-pub trait Iter: Iterator<Item = Entry> {
+pub trait Iter: Iterator {
fn seek(&mut self, key: &[u8]);
fn merge_func<'a, F>(self, merge_func: &'a F) -> MergeFuncIter<'a, Self, F>
fn dupsort_func<'a, F>(self, dupsort_func: &'a F) -> DupsortFuncIter<'a, Self, F>
where
- F: Fn(&Entry, &Entry) -> Ordering,
+ F: Fn(&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>
where
- F: Fn(&Entry, &mut dyn Iter) -> bool,
+ F: Fn(&Self::Item, &mut dyn Iter<Item = Self::Item>) -> bool,
Self: Sized,
{
FilterIter::new(self, filter_func)
}
}
-pub type BoxedIter<'a> = Box<dyn Iter + 'a>;
-
-impl<'a> Iter for BoxedIter<'a> {
- fn seek(&mut self, key: &[u8]) {
- self.as_mut().seek(key);
- }
-}
-
-pub struct PrefixIter<I: Iter> {
+pub struct PrefixIter<I> {
iter: I,
prefix: Vec<u8>,
}
-impl<I: Iter> PrefixIter<I> {
+impl<E, I> PrefixIter<I>
+where
+ I: Iter<Item = E>,
+ E: HasPrefix,
+{
pub fn new(mut iter: I, prefix: impl AsRef<[u8]>) -> Self {
iter.seek(prefix.as_ref());
Self {
}
}
-impl<I: Iter> Iterator for PrefixIter<I> {
- type Item = Entry;
+impl<E, I> Iterator for PrefixIter<I>
+where
+ I: Iter<Item = E>,
+ E: HasPrefix,
+{
+ type Item = E;
fn next(&mut self) -> Option<Self::Item> {
let item = self.iter.next()?;
- if item.key().starts_with(self.prefix.as_slice()) {
+ if item.has_prefix(self.prefix.as_slice()) {
Some(item)
} else {
None
}
}
-impl<I: Iter> Iter for PrefixIter<I> {
+impl<E, I> Iter for PrefixIter<I>
+where
+ I: Iter<Item = E>,
+ E: HasPrefix,
+{
fn seek(&mut self, key: &[u8]) {
self.iter.seek(key);
}
}
-pub struct RangeIter<I: Iter> {
+pub struct RangeIter<I> {
iter: I,
start: Vec<u8>,
end: Vec<u8>,
}
}
-impl<I: Iter> Iterator for RangeIter<I> {
- type Item = Entry;
+impl<E, I> Iterator for RangeIter<I>
+where
+ I: Iter<Item = E>,
+ E: PartialOrd<[u8]>,
+{
+ type Item = E;
fn next(&mut self) -> Option<Self::Item> {
let item = self.iter.next()?;
- if item.key() <= self.end.as_slice() {
+ if item <= *self.end.as_slice() {
Some(item)
} else {
None
}
}
-impl<I: Iter> Iter for RangeIter<I> {
+impl<E, I> Iter for RangeIter<I>
+where
+ I: Iter<Item = E>,
+ E: PartialOrd<[u8]>,
+{
fn seek(&mut self, key: &[u8]) {
if key <= self.start.as_slice() {
self.iter.seek(self.start.as_slice());
impl<S, F> Source for MergeFunc<S, F>
where
- S: Source,
+ S: Source<Item = Entry>,
F: Fn(&mut Vec<u8>, &Entry),
{
- fn iter(&self) -> impl Iter {
+ type Item = Entry;
+ fn iter(&self) -> impl Iter<Item = Self::Item> {
self.source.iter().merge_func(&self.merge_func)
}
- fn get(&self, key: &[u8]) -> impl Iter {
+ fn get(&self, key: &[u8]) -> impl Iter<Item = Self::Item> {
self.source.get(key).merge_func(&self.merge_func)
}
- fn get_prefix(&self, prefix: &[u8]) -> impl Iter {
+ fn get_prefix(&self, prefix: &[u8]) -> impl Iter<Item = Self::Item> {
self.source.get_prefix(prefix).merge_func(&self.merge_func)
}
- fn get_range(&self, start: &[u8], end: &[u8]) -> impl Iter {
+ fn get_range(&self, start: &[u8], end: &[u8]) -> impl Iter<Item = Self::Item> {
self.source
.get_range(start, end)
.merge_func(&self.merge_func)
impl<'a, I, F> Iter for MergeFuncIter<'a, I, F>
where
- I: Iter,
+ I: Iter<Item = Entry>,
F: Fn(&mut Vec<u8>, &Entry),
{
fn seek(&mut self, key: &[u8]) {
use std::cmp::Ordering;
use std::collections::BinaryHeap;
-pub struct Merger<S: Source> {
+pub struct Merger<S> {
sources: Vec<S>,
}
impl<S, I> From<I> for Merger<S>
where
- S: Source,
I: IntoIterator<Item = S>,
{
fn from(i: I) -> Self {
impl<I> From<I> for MergeIter<I::Item>
where
I: Iterator,
- I::Item: Iter,
+ I::Item: Iter<Item = Entry>,
{
fn from(iters: I) -> Self {
let mut v: Vec<I::Item> = Vec::new();
}
}
-impl<I: Iter> Iterator for MergeIter<I> {
+impl<I: Iter<Item = Entry>> Iterator for MergeIter<I> {
type Item = Entry;
fn next(&mut self) -> Option<Self::Item> {
}
}
-impl<I: Iter> Iter for MergeIter<I> {
+impl<I: Iter<Item = Entry>> Iter for MergeIter<I> {
fn seek(&mut self, key: &[u8]) {
if key > self.last_key.as_slice() {
loop {
}
}
-impl<S: Source> Source for Merger<S> {
- fn iter(&self) -> impl Iter {
+impl<S: Source<Item = Entry>> Source for Merger<S> {
+ type Item = Entry;
+ fn iter(&self) -> impl Iter<Item = Self::Item> {
MergeIter::from(self.sources.iter().map(|s| s.iter()))
}
- fn get(&self, key: &[u8]) -> impl Iter {
+ fn get(&self, key: &[u8]) -> impl Iter<Item = Self::Item> {
MergeIter::from(self.sources.iter().map(|s| s.get(key)))
}
- fn get_prefix(&self, prefix: &[u8]) -> impl Iter {
+ fn get_prefix(&self, prefix: &[u8]) -> impl Iter<Item = Self::Item> {
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]) -> impl Iter<Item = Self::Item> {
MergeIter::from(self.sources.iter().map(|s| s.get_range(start, end)))
}
}
}
impl<D: AsRef<[u8]>> Source for Reader<D> {
- fn iter(&self) -> impl Iter {
+ type Item = Entry;
+
+ fn iter(&self) -> impl Iter<Item = Self::Item> {
ReaderIter {
reader: self.clone(),
next_offset: 0,
self.batch_size += esize;
}
- pub fn source(mut self) -> impl Source {
+ pub fn source(mut self) -> impl Source<Item = Entry> {
if self.batch.get_mut().len() > 0 {
self.write_chunk();
}
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, Iter};
pub trait Source {
- fn iter(&self) -> impl Iter;
- fn get(&self, key: &[u8]) -> impl Iter {
+ type Item;
+
+ fn iter(&self) -> impl Iter<Item = Self::Item>;
+ fn get(&self, key: &[u8]) -> impl Iter<Item = Self::Item>
+ where
+ Self::Item: PartialOrd<[u8]>,
+ {
RangeIter::new(self.iter(), key, key)
}
- fn get_prefix(&self, prefix: &[u8]) -> impl Iter {
+ fn get_prefix(&self, prefix: &[u8]) -> impl Iter<Item = Self::Item>
+ where
+ Self::Item: HasPrefix,
+ {
PrefixIter::new(self.iter(), prefix)
}
- fn get_range(&self, start: &[u8], end: &[u8]) -> impl Iter {
+ fn get_range(&self, start: &[u8], end: &[u8]) -> impl Iter<Item = Self::Item>
+ where
+ Self::Item: PartialOrd<[u8]>,
+ {
RangeIter::new(self.iter(), start, end)
}
fn dupsort_func<F>(self, dupsort_func: F) -> DupsortFunc<Self, F>
where
Self: Sized,
- F: Fn(&Entry, &Entry) -> std::cmp::Ordering,
+ F: Fn(&Self::Item, &Self::Item) -> std::cmp::Ordering,
{
DupsortFunc::new(self, dupsort_func)
}
fn filter<F>(self, filter_func: F) -> FilterSource<Self, F>
where
Self: Sized,
- F: Fn(&Entry, &mut dyn Iter) -> bool,
+ F: Fn(&Self::Item, &mut dyn Iter<Item = Self::Item>) -> bool,
{
FilterSource::new(self, filter_func)
}
}
impl Source for Vec<Entry> {
- fn iter(&self) -> impl Iter {
+ type Item = Entry;
+ fn iter(&self) -> impl Iter<Item = Self::Item> {
VecIter {
index: 0,
vec: self,
}
impl Source for TestSource {
- fn iter(&self) -> impl Iter {
+ type Item = Entry;
+ fn iter(&self) -> impl Iter<Item = Self::Item> {
TestIter {
source: self,
off: 0,