Mercurial > lbo > hg > leveldb-rs
changeset 237:f3626bf3e30f
cmp/merging_iter/types/version: Implement LdbIterator for boxed; add generic concatenating table iterator
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Wed, 13 Sep 2017 20:22:45 +0200 |
parents | 0c747fecd98f |
children | 889436eb7a06 |
files | src/cmp.rs src/merging_iter.rs src/types.rs src/version.rs |
diffstat | 4 files changed, 59 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/src/cmp.rs Tue Sep 12 19:58:44 2017 +0200 +++ b/src/cmp.rs Wed Sep 13 20:22:45 2017 +0200 @@ -4,6 +4,8 @@ use std::cmp::Ordering; use std::rc::Rc; +type WrappedCmp = Rc<Box<Cmp>>; + /// Comparator trait, supporting types that can be nested (i.e., add additional functionality on /// top of an inner comparator) pub trait Cmp {
--- a/src/merging_iter.rs Tue Sep 12 19:58:44 2017 +0200 +++ b/src/merging_iter.rs Wed Sep 13 20:22:45 2017 +0200 @@ -32,12 +32,12 @@ impl MergingIter { /// Construct a new merging iterator. - pub fn new(opt: Options, iters: Vec<Box<LdbIterator>>) -> MergingIter { + pub fn new(cmp: Rc<Box<Cmp>>, iters: Vec<Box<LdbIterator>>) -> MergingIter { let mi = MergingIter { iters: iters, current: None, direction: Direction::Fwd, - cmp: opt.cmp, + cmp: cmp, }; mi } @@ -195,6 +195,7 @@ mod tests { use super::*; + use cmp::DefaultCmp; use options::Options; use test_util::{test_iterator_properties, LdbIteratorIter, TestLdbIter}; use types::{current_key_val, LdbIterator}; @@ -206,7 +207,7 @@ let iter = skm.iter(); let mut iter2 = skm.iter(); - let mut miter = MergingIter::new(Options::default(), vec![Box::new(iter)]); + let mut miter = MergingIter::new(Rc::new(Box::new(DefaultCmp)), vec![Box::new(iter)]); loop { if let Some((k, v)) = miter.next() { @@ -228,7 +229,8 @@ let iter = skm.iter(); let iter2 = skm.iter(); - let mut miter = MergingIter::new(Options::default(), vec![Box::new(iter), Box::new(iter2)]); + let mut miter = MergingIter::new(Rc::new(Box::new(DefaultCmp)), + vec![Box::new(iter), Box::new(iter2)]); loop { if let Some((k, v)) = miter.next() { @@ -249,7 +251,8 @@ let val = "def".as_bytes(); let iter = TestLdbIter::new(vec![(b("aba"), val), (b("abc"), val)]); let iter2 = TestLdbIter::new(vec![(b("abb"), val), (b("abd"), val)]); - let miter = MergingIter::new(Options::default(), vec![Box::new(iter), Box::new(iter2)]); + let miter = MergingIter::new(Rc::new(Box::new(DefaultCmp)), + vec![Box::new(iter), Box::new(iter2)]); test_iterator_properties(miter); } @@ -259,7 +262,8 @@ let iter = TestLdbIter::new(vec![(b("aba"), val), (b("abc"), val), (b("abe"), val)]); let iter2 = TestLdbIter::new(vec![(b("abb"), val), (b("abd"), val)]); - let mut miter = MergingIter::new(Options::default(), vec![Box::new(iter), Box::new(iter2)]); + let mut miter = MergingIter::new(Rc::new(Box::new(DefaultCmp)), + vec![Box::new(iter), Box::new(iter2)]); // miter should return the following sequence: [aba, abb, abc, abd, abe] @@ -302,7 +306,8 @@ let it2 = TestLdbIter::new(vec![(&b("abb"), val), (&b("abd"), val)]); let expected = vec![b("aba"), b("abb"), b("abc"), b("abd"), b("abe")]; - let mut iter = MergingIter::new(Options::default(), vec![Box::new(it1), Box::new(it2)]); + let mut iter = MergingIter::new(Rc::new(Box::new(DefaultCmp)), + vec![Box::new(it1), Box::new(it2)]); let mut i = 0; for (k, _) in LdbIteratorIter::wrap(&mut iter) { @@ -318,7 +323,8 @@ let it1 = TestLdbIter::new(vec![(b("aba"), val), (b("abc"), val), (b("abe"), val)]); let it2 = TestLdbIter::new(vec![(b("abb"), val), (b("abd"), val)]); - let mut iter = MergingIter::new(Options::default(), vec![Box::new(it1), Box::new(it2)]); + let mut iter = MergingIter::new(Rc::new(Box::new(DefaultCmp)), + vec![Box::new(it1), Box::new(it2)]); assert!(!iter.valid()); iter.advance();
--- a/src/types.rs Tue Sep 12 19:58:44 2017 +0200 +++ b/src/types.rs Wed Sep 13 20:22:45 2017 +0200 @@ -91,6 +91,27 @@ } } +impl LdbIterator for Box<LdbIterator> { + fn advance(&mut self) -> bool { + self.as_mut().advance() + } + fn current(&self, key: &mut Vec<u8>, val: &mut Vec<u8>) -> bool { + self.as_ref().current(key, val) + } + fn seek(&mut self, key: &[u8]) { + self.as_mut().seek(key) + } + fn reset(&mut self) { + self.as_mut().reset() + } + fn valid(&self) -> bool { + self.as_ref().valid() + } + fn prev(&mut self) -> bool { + self.as_mut().prev() + } +} + /// The unique (sequential) number of a file. pub type FileNum = u64;
--- a/src/version.rs Tue Sep 12 19:58:44 2017 +0200 +++ b/src/version.rs Wed Sep 13 20:22:45 2017 +0200 @@ -245,13 +245,9 @@ /// new_concat_iter returns an iterator that iterates over the files in a level. Note that this /// only really makes sense for levels > 0. fn new_concat_iter(&self, level: usize) -> VersionIter { - VersionIter { - files: self.files[level].clone(), - cache: self.table_cache.clone(), - cmp: InternalKeyCmp(self.user_cmp.clone()), - current: None, - current_ix: 0, - } + new_version_iter(self.files[level].clone(), + self.table_cache.clone(), + self.user_cmp.clone()) } /// new_iters returns a set of iterators that can be merged to yield all entries in this @@ -272,8 +268,24 @@ } } -/// VersionIter iterates over all files belonging to a certain level. -struct VersionIter { +/// new_version_iter returns an iterator over the entries in the specified ordered list of table +/// files. +pub fn new_version_iter(files: Vec<FileMetaHandle>, + cache: Shared<TableCache>, + ucmp: Rc<Box<Cmp>>) + -> VersionIter { + VersionIter { + files: files, + cache: cache, + cmp: InternalKeyCmp(ucmp), + current: None, + current_ix: 0, + } +} + +/// VersionIter iterates over the entries in an ordered list of table files (specifically, for +/// example, the tables in a level). +pub struct VersionIter { // NOTE: Maybe we need to change this to Rc to support modification of the file set after // creation of the iterator. Versions should be immutable, though. files: Vec<FileMetaHandle>, @@ -583,7 +595,7 @@ let mut opt = Options::default(); opt.set_comparator(Box::new(InternalKeyCmp(Rc::new(Box::new(DefaultCmp))))); - let mut miter = MergingIter::new(opt, iters); + let mut miter = MergingIter::new(opt.cmp.clone(), iters); assert_eq!(LdbIteratorIter::wrap(&mut miter).count(), 25); // Check that all elements are in order.