rust-rocksdb-zaidoon1/tests/test_single_delete.rs
Zaidoon Abd Al Hadi 9521bc4879
sync with upstream & upgrade to Rust edition 2024 and MSRV 1.89.0 (#187)
* ci: use actions/checkout@v5l (#1043)

* feat: allow user to set checkpoint log size for flush (#1055)

* upgrade to Rust edition 2024 and MSRV 1.89.0

---------

Co-authored-by: Coder <161350311+MamunC0der@users.noreply.github.com>
Co-authored-by: QuantumExplorer <quantum@dash.org>
2025-12-29 13:24:47 -05:00

300 lines
9.8 KiB
Rust

use rust_rocksdb::{ColumnFamilyDescriptor, DB, Options, ReadOptions, WriteOptions};
mod util;
use util::DBPath;
#[test]
fn test_single_delete() {
let path = DBPath::new("_rust_rocksdb_test_single_delete");
{
let db = DB::open_default(&path).unwrap();
// Test basic single_delete
db.put(b"k1", b"v1").unwrap();
assert_eq!(db.get(b"k1").unwrap().unwrap(), b"v1");
db.single_delete(b"k1").unwrap();
assert!(db.get(b"k1").unwrap().is_none());
// Test that single_delete doesn't affect non-existent keys
db.single_delete(b"k2").unwrap();
assert!(db.get(b"k2").unwrap().is_none());
}
}
#[test]
fn test_single_delete_opt() {
let path = DBPath::new("_rust_rocksdb_test_single_delete_opt");
{
let db = DB::open_default(&path).unwrap();
let write_opts = WriteOptions::default();
// Test single_delete with write options
db.put(b"k1", b"v1").unwrap();
assert_eq!(db.get(b"k1").unwrap().unwrap(), b"v1");
db.single_delete_opt(b"k1", &write_opts).unwrap();
assert!(db.get(b"k1").unwrap().is_none());
// Test multiple keys
db.put(b"k2", b"v2").unwrap();
db.put(b"k3", b"v3").unwrap();
db.single_delete_opt(b"k2", &write_opts).unwrap();
assert!(db.get(b"k2").unwrap().is_none());
assert_eq!(db.get(b"k3").unwrap().unwrap(), b"v3");
}
}
#[test]
fn test_single_delete_cf() {
let path = DBPath::new("_rust_rocksdb_test_single_delete_cf");
{
let mut opts = Options::default();
opts.create_if_missing(true);
opts.create_missing_column_families(true);
let cf1_descriptor = ColumnFamilyDescriptor::new("cf1", Options::default());
let cf2_descriptor = ColumnFamilyDescriptor::new("cf2", Options::default());
let db =
DB::open_cf_descriptors(&opts, &path, vec![cf1_descriptor, cf2_descriptor]).unwrap();
let cf1 = db.cf_handle("cf1").unwrap();
let cf2 = db.cf_handle("cf2").unwrap();
// Put and single_delete in cf1
db.put_cf(&cf1, b"k1", b"v1").unwrap();
assert_eq!(db.get_cf(&cf1, b"k1").unwrap().unwrap(), b"v1");
db.single_delete_cf(&cf1, b"k1").unwrap();
assert!(db.get_cf(&cf1, b"k1").unwrap().is_none());
// Put and single_delete in cf2
db.put_cf(&cf2, b"k2", b"v2").unwrap();
assert_eq!(db.get_cf(&cf2, b"k2").unwrap().unwrap(), b"v2");
db.single_delete_cf(&cf2, b"k2").unwrap();
assert!(db.get_cf(&cf2, b"k2").unwrap().is_none());
// Verify that single_delete in one cf doesn't affect another
db.put_cf(&cf1, b"k3", b"v3").unwrap();
db.put_cf(&cf2, b"k3", b"v3_cf2").unwrap();
db.single_delete_cf(&cf1, b"k3").unwrap();
assert!(db.get_cf(&cf1, b"k3").unwrap().is_none());
assert_eq!(db.get_cf(&cf2, b"k3").unwrap().unwrap(), b"v3_cf2");
}
}
#[test]
fn test_single_delete_cf_opt() {
let path = DBPath::new("_rust_rocksdb_test_single_delete_cf_opt");
{
let mut opts = Options::default();
opts.create_if_missing(true);
opts.create_missing_column_families(true);
let cf_descriptor = ColumnFamilyDescriptor::new("cf1", Options::default());
let db = DB::open_cf_descriptors(&opts, &path, vec![cf_descriptor]).unwrap();
let cf = db.cf_handle("cf1").unwrap();
let write_opts = WriteOptions::default();
// Test single_delete_cf_opt
db.put_cf(&cf, b"k1", b"v1").unwrap();
assert_eq!(db.get_cf(&cf, b"k1").unwrap().unwrap(), b"v1");
db.single_delete_cf_opt(&cf, b"k1", &write_opts).unwrap();
assert!(db.get_cf(&cf, b"k1").unwrap().is_none());
}
}
#[test]
fn test_single_delete_with_ts() {
let path = DBPath::new("_rust_rocksdb_test_single_delete_with_ts");
{
let mut opts = Options::default();
opts.create_if_missing(true);
// Set up user-defined timestamp
let comparator_name = "test_comparator";
opts.set_comparator_with_ts(
comparator_name,
8, // timestamp size
Box::new(util::U64Comparator::compare),
Box::new(util::U64Comparator::compare_ts),
Box::new(util::U64Comparator::compare_without_ts),
);
let db = DB::open(&opts, &path).unwrap();
let key = b"k1";
let val1 = b"v1";
let val2 = b"v2";
let ts1 = 1_u64.to_le_bytes();
let ts2 = 2_u64.to_le_bytes();
let ts3 = 3_u64.to_le_bytes();
// Put with timestamps
db.put_with_ts(key, ts1, val1).unwrap();
db.put_with_ts(key, ts2, val2).unwrap();
// Read at different timestamps
let mut opts = ReadOptions::default();
opts.set_timestamp(ts2);
let value = db.get_opt(key, &opts).unwrap();
assert_eq!(value.unwrap().as_slice(), val2);
// Single_delete with timestamp
db.single_delete_with_ts(key, ts3).unwrap();
opts.set_timestamp(ts3);
let value = db.get_opt(key, &opts).unwrap();
assert!(value.is_none());
// ts2 should still read data before deletion
opts.set_timestamp(ts2);
let value = db.get_opt(key, &opts).unwrap();
assert_eq!(value.unwrap().as_slice(), val2);
}
}
#[test]
fn test_single_delete_with_ts_opt() {
let path = DBPath::new("_rust_rocksdb_test_single_delete_with_ts_opt");
{
let mut opts = Options::default();
opts.create_if_missing(true);
// Set up user-defined timestamp
let comparator_name = "test_comparator";
opts.set_comparator_with_ts(
comparator_name,
8, // timestamp size
Box::new(util::U64Comparator::compare),
Box::new(util::U64Comparator::compare_ts),
Box::new(util::U64Comparator::compare_without_ts),
);
let db = DB::open(&opts, &path).unwrap();
let write_opts = WriteOptions::default();
let key = b"k1";
let val = b"v1";
let ts1 = 1_u64.to_le_bytes();
let ts2 = 2_u64.to_le_bytes();
// Put with timestamp
db.put_with_ts(key, ts1, val).unwrap();
// Single_delete with timestamp and write options
db.single_delete_with_ts_opt(key, ts2, &write_opts).unwrap();
let mut read_opts = ReadOptions::default();
read_opts.set_timestamp(ts2);
let value = db.get_opt(key, &read_opts).unwrap();
assert!(value.is_none());
}
}
#[test]
fn test_single_delete_cf_with_ts() {
let path = DBPath::new("_rust_rocksdb_test_single_delete_cf_with_ts");
{
let mut opts = Options::default();
opts.create_if_missing(true);
opts.create_missing_column_families(true);
// Set up user-defined timestamp
let comparator_name = "test_comparator";
let mut cf_opts = Options::default();
cf_opts.set_comparator_with_ts(
comparator_name,
8, // timestamp size
Box::new(util::U64Comparator::compare),
Box::new(util::U64Comparator::compare_ts),
Box::new(util::U64Comparator::compare_without_ts),
);
let cf_descriptor = ColumnFamilyDescriptor::new("cf1", cf_opts);
let db = DB::open_cf_descriptors(&opts, &path, vec![cf_descriptor]).unwrap();
let cf = db.cf_handle("cf1").unwrap();
let key = b"k1";
let val1 = b"v1";
let val2 = b"v2";
let ts1 = 1_u64.to_le_bytes();
let ts2 = 2_u64.to_le_bytes();
let ts3 = 3_u64.to_le_bytes();
// Put with timestamps in column family
db.put_cf_with_ts(&cf, key, ts1, val1).unwrap();
db.put_cf_with_ts(&cf, key, ts2, val2).unwrap();
// Read at different timestamps
let mut opts = ReadOptions::default();
opts.set_timestamp(ts2);
let value = db.get_cf_opt(&cf, key, &opts).unwrap();
assert_eq!(value.unwrap().as_slice(), val2);
// Single_delete with timestamp in column family
db.single_delete_cf_with_ts(&cf, key, ts3).unwrap();
opts.set_timestamp(ts3);
let value = db.get_cf_opt(&cf, key, &opts).unwrap();
assert!(value.is_none());
// ts2 should still read data before deletion
opts.set_timestamp(ts2);
let value = db.get_cf_opt(&cf, key, &opts).unwrap();
assert_eq!(value.unwrap().as_slice(), val2);
}
}
#[test]
fn test_single_delete_cf_with_ts_opt() {
let path = DBPath::new("_rust_rocksdb_test_single_delete_cf_with_ts_opt");
{
let mut opts = Options::default();
opts.create_if_missing(true);
opts.create_missing_column_families(true);
// Set up user-defined timestamp
let comparator_name = "test_comparator";
let mut cf_opts = Options::default();
cf_opts.set_comparator_with_ts(
comparator_name,
8, // timestamp size
Box::new(util::U64Comparator::compare),
Box::new(util::U64Comparator::compare_ts),
Box::new(util::U64Comparator::compare_without_ts),
);
let cf_descriptor = ColumnFamilyDescriptor::new("cf1", cf_opts);
let db = DB::open_cf_descriptors(&opts, &path, vec![cf_descriptor]).unwrap();
let cf = db.cf_handle("cf1").unwrap();
let write_opts = WriteOptions::default();
let key = b"k1";
let val = b"v1";
let ts1 = 1_u64.to_le_bytes();
let ts2 = 2_u64.to_le_bytes();
// Put with timestamp in column family
db.put_cf_with_ts(&cf, key, ts1, val).unwrap();
// Single_delete with timestamp and write options in column family
db.single_delete_cf_with_ts_opt(&cf, key, ts2, &write_opts)
.unwrap();
let mut read_opts = ReadOptions::default();
read_opts.set_timestamp(ts2);
let value = db.get_cf_opt(&cf, key, &read_opts).unwrap();
assert!(value.is_none());
}
}