in common/rusty_leveldb_sgx/src/db_impl.rs [1223:1337]
fn test_db_impl_init() {
// A sanity check for recovery and basic persistence.
let opt = options::for_test();
let env = opt.env.clone();
// Several test cases with different options follow. The printlns can eventually be
// removed.
{
let mut opt = opt.clone();
opt.reuse_manifest = false;
let _ = DB::open("otherdb", opt.clone()).unwrap();
println!(
"children after: {:?}",
env.children(Path::new("otherdb/")).unwrap()
);
assert!(env.exists(Path::new("otherdb/CURRENT")).unwrap());
// Database is initialized and initial manifest reused.
assert!(!env.exists(Path::new("otherdb/MANIFEST-000001")).unwrap());
assert!(env.exists(Path::new("otherdb/MANIFEST-000002")).unwrap());
assert!(env.exists(Path::new("otherdb/000003.log")).unwrap());
}
{
let mut opt = opt.clone();
opt.reuse_manifest = true;
let mut db = DB::open("db", opt.clone()).unwrap();
println!(
"children after: {:?}",
env.children(Path::new("db/")).unwrap()
);
assert!(env.exists(Path::new("db/CURRENT")).unwrap());
// Database is initialized and initial manifest reused.
assert!(env.exists(Path::new("db/MANIFEST-000001")).unwrap());
assert!(env.exists(Path::new("db/LOCK")).unwrap());
assert!(env.exists(Path::new("db/000003.log")).unwrap());
db.put("abc".as_bytes(), "def".as_bytes()).unwrap();
db.put("abd".as_bytes(), "def".as_bytes()).unwrap();
}
{
println!(
"children before: {:?}",
env.children(Path::new("db/")).unwrap()
);
let mut opt = opt.clone();
opt.reuse_manifest = false;
opt.reuse_logs = false;
let mut db = DB::open("db", opt.clone()).unwrap();
println!(
"children after: {:?}",
env.children(Path::new("db/")).unwrap()
);
// Obsolete manifest is deleted.
assert!(!env.exists(Path::new("db/MANIFEST-000001")).unwrap());
// New manifest is created.
assert!(env.exists(Path::new("db/MANIFEST-000002")).unwrap());
// Obsolete log file is deleted.
assert!(!env.exists(Path::new("db/000003.log")).unwrap());
// New L0 table has been added.
assert!(env.exists(Path::new("db/000003.ldb")).unwrap());
assert!(env.exists(Path::new("db/000004.log")).unwrap());
// Check that entry exists and is correct. Phew, long call chain!
let current = db.current();
log!(opt.log, "files: {:?}", current.borrow().files);
assert_eq!(
"def".as_bytes(),
current
.borrow_mut()
.get(LookupKey::new("abc".as_bytes(), 1).internal_key())
.unwrap()
.unwrap()
.0
.as_slice()
);
db.put("abe".as_bytes(), "def".as_bytes()).unwrap();
}
{
println!(
"children before: {:?}",
env.children(Path::new("db/")).unwrap()
);
// reuse_manifest above causes the old manifest to be deleted as obsolete, but no new
// manifest is written. CURRENT becomes stale.
let mut opt = opt.clone();
opt.reuse_logs = true;
let db = DB::open("db", opt).unwrap();
println!(
"children after: {:?}",
env.children(Path::new("db/")).unwrap()
);
assert!(!env.exists(Path::new("db/MANIFEST-000001")).unwrap());
assert!(env.exists(Path::new("db/MANIFEST-000002")).unwrap());
assert!(!env.exists(Path::new("db/MANIFEST-000005")).unwrap());
assert!(env.exists(Path::new("db/000004.log")).unwrap());
// 000004 should be reused, no new log file should be created.
assert!(!env.exists(Path::new("db/000006.log")).unwrap());
// Log is reused, so memtable should contain last written entry from above.
assert_eq!(1, db.mem.len());
assert_eq!(
"def".as_bytes(),
db.mem
.get(&LookupKey::new("abe".as_bytes(), 3))
.0
.unwrap()
.as_slice()
);
}
}