changeset 98:5528147076d0

Implement and test seek_to_last for BlockIter
author Lewin Bormann <lbo@spheniscida.de>
date Sun, 25 Sep 2016 16:24:19 +0200
parents 4754dd356f5e
children 9cc9cdc1e8d5
files src/block.rs src/table_reader.rs
diffstat 2 files changed, 59 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/block.rs	Sun Sep 25 12:32:45 2016 +0200
+++ b/src/block.rs	Sun Sep 25 16:24:19 2016 +0200
@@ -35,7 +35,6 @@
     offset: usize,
     // offset of restarts area
     restarts_off: usize,
-    // start of current entry
     current_entry_offset: usize,
     // tracks the last restart we encountered
     current_restart_ix: usize,
@@ -117,6 +116,23 @@
         self.key.resize(shared, 0);
         self.key.extend_from_slice(&self.block[self.offset..self.offset + non_shared]);
     }
+
+    pub fn seek_to_last(&mut self) {
+        if self.number_restarts() > 0 {
+            let restart = self.get_restart_point(self.number_restarts() - 1);
+
+            self.offset = restart;
+            self.current_entry_offset = restart;
+            self.current_restart_ix = self.number_restarts() - 1;
+        } else {
+            self.reset();
+        }
+
+        while let Some((_, _)) = self.next() {
+        }
+
+        self.prev();
+    }
 }
 
 impl<C: Comparator> Iterator for BlockIter<C> {
@@ -177,8 +193,8 @@
             }
         }
         result
+    }
 
-    }
     fn seek(&mut self, to: &[u8]) {
         self.reset();
 
@@ -468,4 +484,30 @@
         assert_eq!(block.current(),
                    Some(("key1".as_bytes().to_vec(), "value1".as_bytes().to_vec())));
     }
+
+    #[test]
+    fn test_block_seek_to_last() {
+        let mut o = Options::default();
+
+        // Test with different number of restarts
+        for block_restart_interval in vec![2, 6, 10] {
+            o.block_restart_interval = block_restart_interval;
+
+            let data = get_data();
+            let mut builder = BlockBuilder::new(o, StandardComparator);
+
+            for &(k, v) in data.iter() {
+                builder.add(k, v);
+            }
+
+            let block_contents = builder.finish();
+
+            let mut block = BlockIter::new(block_contents, StandardComparator);
+
+            block.seek_to_last();
+            assert!(block.valid());
+            assert_eq!(block.current(),
+                       Some(("prefix_key3".as_bytes().to_vec(), "value".as_bytes().to_vec())));
+        }
+    }
 }
--- a/src/table_reader.rs	Sun Sep 25 12:32:45 2016 +0200
+++ b/src/table_reader.rs	Sun Sep 25 16:24:19 2016 +0200
@@ -153,6 +153,21 @@
     }
 }
 
+impl<'a, C: Comparator, R: Read + Seek, FP: FilterPolicy> LdbIterator for TableIterator<'a,
+                                                                                        R,
+                                                                                        C,
+                                                                                        FP> {
+    fn seek(&mut self, key: &[u8]) {
+        // first seek in index block, then set current_block and seek there
+        unimplemented!()
+    }
+
+    fn prev(&mut self) -> Option<Self::Item> {
+        // use BlockIter::seek_to_last
+        unimplemented!()
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use filter::BloomPolicy;