changeset 341:5a266a55f459

memtable: General clean-up, improvement in seek code
author Lewin Bormann <lbo@spheniscida.de>
date Wed, 04 Oct 2017 19:59:43 +0200
parents 801af25e9abd
children b9cb08d20191
files src/memtable.rs
diffstat 1 files changed, 39 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/memtable.rs	Wed Oct 04 19:59:10 2017 +0200
+++ b/src/memtable.rs	Wed Oct 04 19:59:43 2017 +0200
@@ -1,7 +1,7 @@
 use key_types::{LookupKey, UserKey};
 use cmp::{Cmp, MemtableKeyCmp};
 use error::{err, StatusCode, Result};
-use key_types::{parse_memtable_key, build_memtable_key, ValueType};
+use key_types::{parse_internal_key, parse_memtable_key, build_memtable_key, ValueType};
 use types::{current_key_val, LdbIterator, SequenceNumber};
 use skipmap::{SkipMap, SkipMapIter};
 use options::Options;
@@ -14,7 +14,6 @@
 /// MemTable uses MemtableKeys internally, that is, it stores key and value in the [Skipmap] key.
 pub struct MemTable {
     map: SkipMap,
-    cmp: Rc<Box<Cmp>>,
 }
 
 impl MemTable {
@@ -26,10 +25,7 @@
 
     /// Doesn't wrap the comparator in a MemtableKeyCmp.
     fn new_raw(cmp: Rc<Box<Cmp>>) -> MemTable {
-        MemTable {
-            map: SkipMap::new(cmp.clone()),
-            cmp: cmp,
-        }
+        MemTable { map: SkipMap::new(cmp) }
     }
 
     pub fn len(&self) -> usize {
@@ -50,7 +46,6 @@
         iter.seek(key.memtable_key());
 
         if let Some((foundkey, _)) = current_key_val(&iter) {
-            // let (lkeylen, lkeyoff, _, _, _) = parse_memtable_key(key.memtable_key());
             let (fkeylen, fkeyoff, tag, vallen, valoff) = parse_memtable_key(&foundkey);
 
             // Compare user key -- if equal, proceed
@@ -72,7 +67,8 @@
 }
 
 /// MemtableIterator is an iterator over a MemTable. It is mostly concerned with converting to and
-/// from the MemtableKey format used in the inner map (from/to InternalKey format).
+/// from the MemtableKey format used in the inner map; all key-taking or -returning methods deal
+/// with InternalKeys.
 pub struct MemtableIterator {
     skipmapiter: SkipMapIter,
 }
@@ -124,6 +120,7 @@
     fn valid(&self) -> bool {
         self.skipmapiter.valid()
     }
+    /// current places the current key (in InternalKey format) and value into the supplied vectors.
     fn current(&self, key: &mut Vec<u8>, val: &mut Vec<u8>) -> bool {
         if !self.valid() {
             return false;
@@ -147,11 +144,11 @@
             panic!("should not happen");
         }
     }
+    /// seek takes an InternalKey.
     fn seek(&mut self, to: &[u8]) {
-        // We need to assemble the correct memtable key from the supplied InternalKey.
-        let seq = u64::decode_fixed(&to[to.len() - 8..]);
-        let key = LookupKey::new(&to[0..to.len() - 8], seq);
-        self.skipmapiter.seek(key.memtable_key());
+        // Assemble the correct memtable key from the supplied InternalKey.
+        let (_, seq, ukey) = parse_internal_key(to);
+        self.skipmapiter.seek(LookupKey::new(ukey, seq).memtable_key());
     }
 }
 
@@ -206,14 +203,16 @@
 
     #[test]
     fn test_memtable_add() {
-        let mut mt = MemTable::new_raw(options::for_test().cmp);
+        let mut mt = MemTable::new(options::for_test().cmp);
         mt.add(123,
                ValueType::TypeValue,
                "abc".as_bytes(),
                "123".as_bytes());
 
         assert_eq!(mt.map.iter().next().unwrap().0,
-                   vec![11, 97, 98, 99, 1, 123, 0, 0, 0, 0, 0, 0, 3, 49, 50, 51].as_slice());
+                   &[11, 97, 98, 99, 1, 123, 0, 0, 0, 0, 0, 0, 3, 49, 50, 51]);
+        assert_eq!(mt.iter().next().unwrap().0,
+                   &[97, 98, 99, 1, 123, 0, 0, 0, 0, 0, 0]);
     }
 
     #[test]
@@ -273,7 +272,30 @@
     }
 
     #[test]
-    fn test_memtable_iterator_fwd_seek() {
+    fn test_memtable_iterator_seek() {
+        let mt = get_memtable();
+        let mut iter = mt.iter();
+
+        assert!(!iter.valid());
+
+        iter.seek(LookupKey::new("abc".as_bytes(), 400).internal_key());
+        let (mut gotkey, gotval) = current_key_val(&iter).unwrap();
+        truncate_to_userkey(&mut gotkey);
+        assert_eq!(("abc".as_bytes(), "123".as_bytes()),
+                   (gotkey.as_slice(), gotval.as_slice()));
+
+        iter.seek(LookupKey::new("xxx".as_bytes(), 400).internal_key());
+        assert!(!iter.valid());
+
+        iter.seek(LookupKey::new("abd".as_bytes(), 400).internal_key());
+        let (mut gotkey, gotval) = current_key_val(&iter).unwrap();
+        truncate_to_userkey(&mut gotkey);
+        assert_eq!(("abd".as_bytes(), "124".as_bytes()),
+                   (gotkey.as_slice(), gotval.as_slice()));
+    }
+
+    #[test]
+    fn test_memtable_iterator_fwd() {
         let mt = get_memtable();
         let mut iter = mt.iter();
 
@@ -341,8 +363,8 @@
     fn test_memtable_iterator_behavior() {
         let mut mt = MemTable::new(options::for_test().cmp);
         let entries = vec![(115, "abc", "122"),
-                           (120, "abc", "123"),
-                           (121, "abd", "124"),
+                           (120, "abd", "123"),
+                           (121, "abe", "124"),
                            (123, "abf", "126")];
 
         for e in entries.iter() {