changeset 367:821c6108558f

version/DB: Set test data into correct otder and add iterator test.
author Lewin Bormann <lbo@spheniscida.de>
date Sun, 08 Oct 2017 12:28:12 +0200
parents 8ae87daebe4a
children 1dc6ed532dae
files src/db_impl.rs src/db_iter.rs src/version.rs
diffstat 3 files changed, 86 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/db_impl.rs	Sun Oct 08 11:46:05 2017 +0200
+++ b/src/db_impl.rs	Sun Oct 08 12:28:12 2017 +0200
@@ -95,7 +95,7 @@
     /// Opens or creates* a new or existing database.
     ///
     /// *depending on the options set (create_if_missing, error_if_exists).
-    fn open(name: &str, opt: Options) -> Result<DB> {
+    pub fn open(name: &str, opt: Options) -> Result<DB> {
         let mut db = DB::new(name, opt);
         let mut ve = VersionEdit::new();
         let save_manifest = db.recover(&mut ve)?;
@@ -964,7 +964,7 @@
     use version::testutil::make_version;
 
     /// build_db creates a database filled with the tables created by make_version().
-    pub fn build_db() -> DB {
+    pub fn build_db() -> (DB, Options) {
         let name = "db";
         let (v, opt) = make_version();
         let mut ve = VersionEdit::new();
@@ -988,7 +988,7 @@
         lw.flush().unwrap();
         set_current_file(&opt.env, name, 10).unwrap();
 
-        DB::open(name, opt).unwrap()
+        (DB::open(name, opt.clone()).unwrap(), opt)
     }
 
     /// set_file_to_compact ensures that the specified table file will be compacted next.
@@ -1213,7 +1213,7 @@
     #[allow(unused_variables)]
     #[test]
     fn test_db_impl_build_db_sanity() {
-        let db = build_db();
+        let db = build_db().0;
         let env = &db.opt.env;
         let name = &db.name;
 
@@ -1222,7 +1222,7 @@
 
     #[test]
     fn test_db_impl_get_from_table_with_snapshot() {
-        let mut db = build_db();
+        let mut db = build_db().0;
 
         assert_eq!(28, db.vset.borrow().last_seq);
 
@@ -1254,11 +1254,15 @@
             assert_eq!("val2".as_bytes(),
                        db.get_at(&ss, "eab".as_bytes()).unwrap().unwrap().as_slice());
         }
+
+        // from table.
+        assert_eq!("val2".as_bytes(),
+                   db.get("cab".as_bytes()).unwrap().as_slice());
     }
 
     #[test]
     fn test_db_impl_delete() {
-        let mut db = build_db();
+        let mut db = build_db().0;
 
         db.put(b"xyy", b"123").unwrap();
         db.put(b"xyz", b"123").unwrap();
@@ -1277,7 +1281,7 @@
 
     #[test]
     fn test_db_impl_compact_single_file() {
-        let mut db = build_db();
+        let mut db = build_db().0;
         set_file_to_compact(&mut db, 4);
         db.maybe_do_compaction().unwrap();
 
@@ -1346,7 +1350,7 @@
 
     #[test]
     fn test_db_impl_compaction() {
-        let mut db = build_db();
+        let mut db = build_db().0;
         let v = db.current();
         v.borrow_mut().compaction_score = Some(2.0);
         v.borrow_mut().compaction_level = Some(1);
@@ -1407,7 +1411,7 @@
     fn test_db_impl_open_close_reopen() {
         let opt;
         {
-            let mut db = build_db();
+            let mut db = build_db().0;
             opt = db.opt.clone();
 
             db.put(b"xx1", b"111").unwrap();
--- a/src/db_iter.rs	Sun Oct 08 11:46:05 2017 +0200
+++ b/src/db_iter.rs	Sun Oct 08 12:28:12 2017 +0200
@@ -276,16 +276,21 @@
     use super::*;
     use types::{current_key_val, Direction};
     use test_util::LdbIteratorIter;
+    use db_impl::DB;
     use db_impl::testutil::*;
 
+    use std::collections::HashMap;
+    use std::collections::HashSet;
+    use std::iter::FromIterator;
+
     #[test]
     fn db_iter_basic_test() {
-        let mut db = build_db();
+        let mut db = build_db().0;
         let mut iter = db.new_iter().unwrap();
 
         // keys and values come from make_version(); they are each the latest entry.
         let keys: &[&[u8]] = &[b"aaa", b"aab", b"aax", b"aba", b"bab", b"bba", b"cab", b"cba"];
-        let vals: &[&[u8]] = &[b"val0", b"val2", b"val1", b"val3", b"val2", b"val3", b"val1",
+        let vals: &[&[u8]] = &[b"val1", b"val2", b"val1", b"val3", b"val2", b"val3", b"val2",
                                b"val3"];
 
         for (k, v) in keys.iter().zip(vals.iter()) {
@@ -296,7 +301,7 @@
 
     #[test]
     fn db_iter_reset() {
-        let mut db = build_db();
+        let mut db = build_db().0;
         let mut iter = db.new_iter().unwrap();
 
         assert!(iter.advance());
@@ -309,12 +314,12 @@
 
     #[test]
     fn db_iter_test_fwd_backwd() {
-        let mut db = build_db();
+        let mut db = build_db().0;
         let mut iter = db.new_iter().unwrap();
 
         // keys and values come from make_version(); they are each the latest entry.
         let keys: &[&[u8]] = &[b"aaa", b"aab", b"aax", b"aba", b"bab", b"bba", b"cab", b"cba"];
-        let vals: &[&[u8]] = &[b"val0", b"val2", b"val1", b"val3", b"val2", b"val3", b"val1",
+        let vals: &[&[u8]] = &[b"val1", b"val2", b"val1", b"val3", b"val2", b"val3", b"val2",
                                b"val3"];
 
         // This specifies the direction that the iterator should move to. Based on this, an index
@@ -353,12 +358,12 @@
 
     #[test]
     fn db_iter_test_seek() {
-        let mut db = build_db();
+        let mut db = build_db().0;
         let mut iter = db.new_iter().unwrap();
 
         // gca is the deleted entry.
         let keys: &[&[u8]] = &[b"aab", b"aaa", b"cab", b"eaa", b"aaa", b"iba", b"fba"];
-        let vals: &[&[u8]] = &[b"val2", b"val0", b"val1", b"val1", b"val0", b"val2", b"val3"];
+        let vals: &[&[u8]] = &[b"val2", b"val1", b"val2", b"val1", b"val1", b"val2", b"val3"];
 
         for (k, v) in keys.iter().zip(vals.iter()) {
             println!("{:?}", String::from_utf8(k.to_vec()).unwrap());
@@ -381,7 +386,7 @@
 
     #[test]
     fn db_iter_deleted_entry_not_returned() {
-        let mut db = build_db();
+        let mut db = build_db().0;
         let mut iter = db.new_iter().unwrap();
         let must_not_appear = b"gca";
 
@@ -392,7 +397,7 @@
 
     #[test]
     fn db_iter_deleted_entry_not_returned_memtable() {
-        let mut db = build_db();
+        let mut db = build_db().0;
 
         db.put(b"xyz", b"123").unwrap();
         db.delete(b"xyz", true).unwrap();
@@ -404,4 +409,51 @@
             assert!(k.as_slice() != must_not_appear);
         }
     }
+
+    #[test]
+    fn db_iter_repeated_open_close() {
+        let opt;
+        {
+            let (mut db, opt_) = build_db();
+            opt = opt_;
+
+            db.put(b"xx1", b"111").unwrap();
+            db.put(b"xx2", b"112").unwrap();
+            db.put(b"xx3", b"113").unwrap();
+            db.put(b"xx4", b"114").unwrap();
+            db.delete(b"xx2", false).unwrap();
+        }
+
+        {
+            let mut db = DB::open("db", opt.clone()).unwrap();
+            db.put(b"xx4", b"222").unwrap();
+        }
+
+        {
+            let mut db = DB::open("db", opt).unwrap();
+
+            let ss = db.get_snapshot();
+
+            let expected: HashMap<Vec<u8>, Vec<u8>> = HashMap::from_iter(vec![
+                                                  (b"xx1".to_vec(), b"111".to_vec()),
+                                                  (b"xx4".to_vec(), b"222".to_vec()),
+                                                  (b"aaa".to_vec(), b"val1".to_vec()),
+                                                  (b"cab".to_vec(), b"val2".to_vec()),
+            ]
+                .into_iter());
+            let non_existing: HashSet<Vec<u8>> = HashSet::from_iter(vec![
+                                                      b"gca".to_vec(),
+                                                      b"xx2".to_vec(),
+            ]
+                .into_iter());
+
+            let mut iter = db.new_iter_at(ss.clone()).unwrap();
+            for (k, v) in LdbIteratorIter::wrap(&mut iter) {
+                if let Some(ev) = expected.get(&k) {
+                    assert_eq!(ev, &v);
+                }
+                assert!(!non_existing.contains(&k));
+            }
+        }
+    }
 }
--- a/src/version.rs	Sun Oct 08 11:46:05 2017 +0200
+++ b/src/version.rs	Sun Oct 08 12:28:12 2017 +0200
@@ -596,29 +596,31 @@
 
         // The different levels overlap in a sophisticated manner to be able to test compactions
         // and so on.
+        // The sequence numbers are in "natural order", i.e. highest levels have lowest sequence
+        // numbers.
 
         // Level 0 (overlapping)
         let f1: &[(&[u8], &[u8], ValueType)] =
             &[("aaa".as_bytes(), "val1".as_bytes(), ValueType::TypeValue),
               ("aab".as_bytes(), "val2".as_bytes(), ValueType::TypeValue),
               ("aba".as_bytes(), "val3".as_bytes(), ValueType::TypeValue)];
-        let t1 = write_table(&env, f1, 1, 1);
+        let t1 = write_table(&env, f1, 25, 1);
         let f2: &[(&[u8], &[u8], ValueType)] =
             &[("aax".as_bytes(), "val1".as_bytes(), ValueType::TypeValue),
               ("bab".as_bytes(), "val2".as_bytes(), ValueType::TypeValue),
               ("bba".as_bytes(), "val3".as_bytes(), ValueType::TypeValue)];
-        let t2 = write_table(&env, f2, 4, 2);
+        let t2 = write_table(&env, f2, 22, 2);
         // Level 1
         let f3: &[(&[u8], &[u8], ValueType)] =
             &[("aaa".as_bytes(), "val0".as_bytes(), ValueType::TypeValue),
               ("cab".as_bytes(), "val2".as_bytes(), ValueType::TypeValue),
               ("cba".as_bytes(), "val3".as_bytes(), ValueType::TypeValue)];
-        let t3 = write_table(&env, f3, 7, 3);
+        let t3 = write_table(&env, f3, 19, 3);
         let f4: &[(&[u8], &[u8], ValueType)] =
             &[("daa".as_bytes(), "val1".as_bytes(), ValueType::TypeValue),
               ("dab".as_bytes(), "val2".as_bytes(), ValueType::TypeValue),
               ("dba".as_bytes(), "val3".as_bytes(), ValueType::TypeValue)];
-        let t4 = write_table(&env, f4, 10, 4);
+        let t4 = write_table(&env, f4, 16, 4);
         let f5: &[(&[u8], &[u8], ValueType)] =
             &[("eaa".as_bytes(), "val1".as_bytes(), ValueType::TypeValue),
               ("eab".as_bytes(), "val2".as_bytes(), ValueType::TypeValue),
@@ -629,23 +631,23 @@
             &[("cab".as_bytes(), "val1".as_bytes(), ValueType::TypeValue),
               ("fab".as_bytes(), "val2".as_bytes(), ValueType::TypeValue),
               ("fba".as_bytes(), "val3".as_bytes(), ValueType::TypeValue)];
-        let t6 = write_table(&env, f6, 16, 6);
+        let t6 = write_table(&env, f6, 10, 6);
         let f7: &[(&[u8], &[u8], ValueType)] =
             &[("gaa".as_bytes(), "val1".as_bytes(), ValueType::TypeValue),
               ("gab".as_bytes(), "val2".as_bytes(), ValueType::TypeValue),
               ("gba".as_bytes(), "val3".as_bytes(), ValueType::TypeValue),
               ("gca".as_bytes(), "val4".as_bytes(), ValueType::TypeDeletion),
               ("gda".as_bytes(), "val5".as_bytes(), ValueType::TypeValue)];
-        let t7 = write_table(&env, f7, 21, 7);
+        let t7 = write_table(&env, f7, 5, 7);
         // Level 3 (2 * 2 entries, for iterator behavior).
         let f8: &[(&[u8], &[u8], ValueType)] =
             &[("haa".as_bytes(), "val1".as_bytes(), ValueType::TypeValue),
               ("hba".as_bytes(), "val2".as_bytes(), ValueType::TypeValue)];
-        let t8 = write_table(&env, f8, 23, 8);
+        let t8 = write_table(&env, f8, 3, 8);
         let f9: &[(&[u8], &[u8], ValueType)] =
             &[("iaa".as_bytes(), "val1".as_bytes(), ValueType::TypeValue),
               ("iba".as_bytes(), "val2".as_bytes(), ValueType::TypeValue)];
-        let t9 = write_table(&env, f9, 25, 9);
+        let t9 = write_table(&env, f9, 1, 9);
 
 
         let cache = TableCache::new("db", opts.clone(), 100);
@@ -734,9 +736,9 @@
     fn test_version_get_simple() {
         let v = make_version().0;
         let cases: &[(&[u8], u64, Result<Option<Vec<u8>>>)] =
-            &[("aaa".as_bytes(), 0, Ok(None)),
-              ("aaa".as_bytes(), 1, Ok(Some("val1".as_bytes().to_vec()))),
+            &[("aaa".as_bytes(), 1, Ok(None)),
               ("aaa".as_bytes(), 100, Ok(Some("val1".as_bytes().to_vec()))),
+              ("aaa".as_bytes(), 21, Ok(Some("val0".as_bytes().to_vec()))),
               ("aab".as_bytes(), 0, Ok(None)),
               ("aab".as_bytes(), 100, Ok(Some("val2".as_bytes().to_vec()))),
               ("daa".as_bytes(), 100, Ok(Some("val1".as_bytes().to_vec()))),