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.