use crate::util::{DBPath, assert_item, assert_no_item};
use rust_rocksdb::{DB, ReadOptions, WriteBatchWithIndex};
mod util;
#[test]
fn test_write_batch_with_index_with_base_iterator() {
let path = DBPath::new("_rust_rocksdb_wbwi_iterator");
{
let db = DB::open_default(&path).expect("DB should open");
db.put(b"k1", b"v1").unwrap();
db.put(b"k2", b"v2").unwrap();
db.put(b"k3", b"v3").unwrap();
db.put(b"k5", b"v5").unwrap();
let mut wbwi = WriteBatchWithIndex::new(0, true);
wbwi.put(b"k0", b"v0");
wbwi.put(b"k4", b"v4");
wbwi.delete(b"k3");
wbwi.put(b"k6", b"v6");
let mut readopts = ReadOptions::default();
readopts.set_iterate_lower_bound(b"k2");
readopts.set_iterate_upper_bound(b"k5");
let base_iterator = db.raw_iterator_opt(readopts);
let mut iterator = wbwi.iterator_with_base(base_iterator);
iterator.seek_to_first();
assert_item(&iterator, b"k2", b"v2");
iterator.next();
assert_item(&iterator, b"k4", b"v4");
iterator.next();
assert_no_item(&iterator);
}
}
#[test]
fn test_get_from_batch_roundtrip_including_empty_values() {
use rust_rocksdb::Options;
let path = DBPath::new("_rust_rocksdb_wbwi_get_from_batch");
{
let db = DB::open_default(&path).expect("DB should open");
let opts = Options::default();
let readopts = ReadOptions::default();
let mut wbwi = WriteBatchWithIndex::new(0, true);
wbwi.put(b"present", b"value");
wbwi.put(b"empty", b"");
assert_eq!(
wbwi.get_from_batch(b"present", &opts).unwrap(),
Some(b"value".to_vec())
);
assert_eq!(
wbwi.get_from_batch(b"empty", &opts).unwrap(),
Some(Vec::new()),
"an empty value must read back as Some(empty), not None"
);
assert_eq!(wbwi.get_from_batch(b"absent", &opts).unwrap(), None);
db.put(b"in_db", b"db_value").unwrap();
db.put(b"in_db_empty", b"").unwrap();
assert_eq!(
wbwi.get_from_batch_and_db(&db, b"present", &readopts)
.unwrap(),
Some(b"value".to_vec())
);
assert_eq!(
wbwi.get_from_batch_and_db(&db, b"in_db", &readopts)
.unwrap(),
Some(b"db_value".to_vec())
);
assert_eq!(
wbwi.get_from_batch_and_db(&db, b"in_db_empty", &readopts)
.unwrap(),
Some(Vec::new())
);
assert_eq!(
wbwi.get_from_batch_and_db(&db, b"absent", &readopts)
.unwrap(),
None
);
let pinned = wbwi
.get_pinned_from_batch_and_db(&db, b"in_db", &readopts)
.unwrap()
.expect("value should be present");
assert_eq!(&*pinned, b"db_value");
let pinned_empty = wbwi
.get_pinned_from_batch_and_db(&db, b"in_db_empty", &readopts)
.unwrap()
.expect("empty value should still be Some");
assert_eq!(&*pinned_empty, b"");
}
}
#[test]
fn test_get_from_batch_repeated_allocations() {
use rust_rocksdb::Options;
let path = DBPath::new("_rust_rocksdb_wbwi_get_from_batch_loop");
{
let db = DB::open_default(&path).expect("DB should open");
let opts = Options::default();
let readopts = ReadOptions::default();
let mut wbwi = WriteBatchWithIndex::new(0, true);
for i in 0..256u32 {
wbwi.put(format!("k{i:04}").as_bytes(), vec![b'x'; i as usize]);
}
for _ in 0..8 {
for i in 0..256u32 {
let key = format!("k{i:04}");
let from_batch = wbwi.get_from_batch(key.as_bytes(), &opts).unwrap();
assert_eq!(from_batch, Some(vec![b'x'; i as usize]));
let from_both = wbwi
.get_from_batch_and_db(&db, key.as_bytes(), &readopts)
.unwrap();
assert_eq!(from_both, Some(vec![b'x'; i as usize]));
}
}
}
}