Skip to content

Instantly share code, notes, and snippets.

@leiless
Created October 30, 2023 02:09
Show Gist options
  • Save leiless/e3c3d4d01ebc792e2dc4a386ce95ad17 to your computer and use it in GitHub Desktop.
Save leiless/e3c3d4d01ebc792e2dc4a386ce95ad17 to your computer and use it in GitHub Desktop.
Test LMDB MDB_DUPSORT write with same key-value.
use lmdb::{Cursor, Transaction};
fn test_lmdb_dup_sort_update_in_place() -> anyhow::Result<()> {
let db_dir = "lmdb-dir";
if let Err(err) = std::fs::remove_dir_all(db_dir) {
if err.kind() != std::io::ErrorKind::NotFound {
return Err(err.try_into()?);
}
}
std::fs::create_dir_all(db_dir)?;
let env = {
let mut builder = lmdb::Environment::new();
builder.set_map_size(100 * 1024 * 1024);
builder.open(std::path::Path::new(db_dir)).unwrap()
};
let db = env.create_db(
None,
lmdb::DatabaseFlags::INTEGER_KEY | lmdb::DatabaseFlags::DUP_SORT,
)?;
// Data population #1
let mut txn = env.begin_rw_txn()?;
let start_key = 0x2000_1000_3000_0076_u64;
let key = start_key.to_ne_bytes();
txn.put(db, &key, &"foobar!", lmdb::WriteFlags::empty())?;
txn.commit()?;
let mut txn = env.begin_rw_txn()?;
let start_key = 0x2000_1000_3000_0076_u64;
let key = start_key.to_ne_bytes();
txn.put(db, &key, &"foobar!", lmdb::WriteFlags::empty())?;
txn.commit()?;
// Test MDB_SET_RANGE (>=)
let txn = env.begin_ro_txn()?;
let mut cursor = txn.open_ro_cursor(db)?;
let mut count = 0;
for it in cursor.iter_dup_start() {
for it2 in it {
let (a, b) = it2?;
let key = u64::from_ne_bytes(a.try_into()?);
let val = std::str::from_utf8(b)?;
eprintln!("{:#x} {}", key, val);
count += 1;
}
}
drop(cursor);
txn.abort();
eprintln!("count: {}", count);
let mut txn = env.begin_rw_txn()?;
let start_key = 0x2000_1000_3000_0076_u64;
let key = start_key.to_ne_bytes();
txn.del(db, &key, Some("foobar!".as_ref()))?;
txn.commit()?;
let txn = env.begin_ro_txn()?;
let mut cursor = txn.open_ro_cursor(db)?;
let mut count = 0;
for it in cursor.iter_dup_start() {
for it2 in it {
let (a, b) = it2?;
let key = u64::from_ne_bytes(a.try_into()?);
let val = std::str::from_utf8(b)?;
eprintln!("{:#x} {}", key, val);
count += 1;
}
}
drop(cursor);
txn.abort();
eprintln!("count: {}", count);
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
test_lmdb_dup_sort_update_in_place()?;
eprintln!("Done");
Ok(())
}
@leiless
Copy link
Author

leiless commented Oct 30, 2023

Output

0x2000100030000076 foobar!
count: 1
count: 0
Done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment