|
|
|
@ -71,7 +71,6 @@ pub trait ReadTransaction<'env> : Transaction<'env> { |
|
|
|
|
len: data_val.mv_size as uint |
|
|
|
|
}); |
|
|
|
|
Ok(Some(slice)) |
|
|
|
|
|
|
|
|
|
} else if err_code == ffi::MDB_NOTFOUND { |
|
|
|
|
Ok(None) |
|
|
|
|
} else { |
|
|
|
@ -91,7 +90,6 @@ pub trait ReadTransaction<'env> : Transaction<'env> { |
|
|
|
|
unsafe { |
|
|
|
|
try!(lmdb_result(ffi::mdb_dbi_flags(self.txn(), db.dbi(), &mut flags))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Ok(DatabaseFlags::from_bits_truncate(flags)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -153,7 +151,6 @@ pub trait WriteTransaction<'env> : ReadTransaction<'env> { |
|
|
|
|
data: data_val.mv_data as *const u8, |
|
|
|
|
len: data_val.mv_size as uint |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
Ok(BufWriter::new(slice)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -282,13 +279,17 @@ impl <'env> WriteTransaction<'env> for RwTransaction<'env> { } |
|
|
|
|
#[cfg(test)] |
|
|
|
|
mod test { |
|
|
|
|
|
|
|
|
|
use libc::{c_uint, c_void, size_t}; |
|
|
|
|
use std::io; |
|
|
|
|
use std::ptr; |
|
|
|
|
use std::rand::{Rng, XorShiftRng}; |
|
|
|
|
use std::sync::{Arc, Barrier, Future}; |
|
|
|
|
use test::{Bencher, black_box}; |
|
|
|
|
|
|
|
|
|
use environment::*; |
|
|
|
|
use ffi::*; |
|
|
|
|
use super::*; |
|
|
|
|
|
|
|
|
|
use test_utils::*; |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn test_put_get_del() { |
|
|
|
@ -442,4 +443,112 @@ mod test { |
|
|
|
|
txn.get(db, format!("{}{}", key, i).as_bytes()).unwrap().unwrap()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[bench] |
|
|
|
|
fn bench_get_rand(b: &mut Bencher) { |
|
|
|
|
let n = 100u32; |
|
|
|
|
let (_dir, env) = setup_bench_db(n); |
|
|
|
|
let db = env.open_db(None).unwrap(); |
|
|
|
|
let txn = env.begin_read_txn().unwrap(); |
|
|
|
|
|
|
|
|
|
let mut keys: Vec<String> = range(0, n).map(|n| get_key(n)) |
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
XorShiftRng::new_unseeded().shuffle(keys.as_mut_slice()); |
|
|
|
|
|
|
|
|
|
b.iter(|| { |
|
|
|
|
let mut i = 0u; |
|
|
|
|
for key in keys.iter() { |
|
|
|
|
i = i + txn.get(db, key.as_bytes()).unwrap().unwrap().len(); |
|
|
|
|
} |
|
|
|
|
black_box(i); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[bench] |
|
|
|
|
fn bench_get_rand_raw(b: &mut Bencher) { |
|
|
|
|
let n = 100u32; |
|
|
|
|
let (_dir, env) = setup_bench_db(n); |
|
|
|
|
let db = env.open_db(None).unwrap(); |
|
|
|
|
let _txn = env.begin_read_txn().unwrap(); |
|
|
|
|
|
|
|
|
|
let mut keys: Vec<String> = range(0, n).map(|n| get_key(n)) |
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
XorShiftRng::new_unseeded().shuffle(keys.as_mut_slice()); |
|
|
|
|
|
|
|
|
|
let dbi = db.dbi(); |
|
|
|
|
let txn = _txn.txn(); |
|
|
|
|
|
|
|
|
|
let mut key_val: MDB_val = MDB_val { mv_size: 0, mv_data: ptr::null_mut() }; |
|
|
|
|
let mut data_val: MDB_val = MDB_val { mv_size: 0, mv_data: ptr::null_mut() }; |
|
|
|
|
|
|
|
|
|
b.iter(|| unsafe { |
|
|
|
|
let mut i = 0u64; |
|
|
|
|
for key in keys.iter() { |
|
|
|
|
key_val.mv_size = key.len() as u64; |
|
|
|
|
key_val.mv_data = key.as_bytes().as_ptr() as *mut _; |
|
|
|
|
|
|
|
|
|
mdb_get(txn, dbi, &mut key_val, &mut data_val); |
|
|
|
|
|
|
|
|
|
i = i + key_val.mv_size; |
|
|
|
|
} |
|
|
|
|
black_box(i); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[bench] |
|
|
|
|
fn bench_put_rand(b: &mut Bencher) { |
|
|
|
|
let n = 100u32; |
|
|
|
|
let (_dir, env) = setup_bench_db(0); |
|
|
|
|
let db = env.open_db(None).unwrap(); |
|
|
|
|
|
|
|
|
|
let mut items: Vec<(String, String)> = range(0, n).map(|n| (get_key(n), get_data(n))) |
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
XorShiftRng::new_unseeded().shuffle(items.as_mut_slice()); |
|
|
|
|
|
|
|
|
|
b.iter(|| { |
|
|
|
|
// TODO: change this to just a transaction renew, instead of a new transaction
|
|
|
|
|
let mut txn = env.begin_write_txn().unwrap(); |
|
|
|
|
let mut i = 0u; |
|
|
|
|
for &(ref key, ref data) in items.iter() { |
|
|
|
|
txn.put(db, key.as_bytes(), data.as_bytes(), WriteFlags::empty()).unwrap(); |
|
|
|
|
} |
|
|
|
|
txn.abort(); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[bench] |
|
|
|
|
fn bench_put_rand_raw(b: &mut Bencher) { |
|
|
|
|
let n = 100u32; |
|
|
|
|
let (_dir, _env) = setup_bench_db(0); |
|
|
|
|
let db = _env.open_db(None).unwrap(); |
|
|
|
|
|
|
|
|
|
let mut items: Vec<(String, String)> = range(0, n).map(|n| (get_key(n), get_data(n))) |
|
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
XorShiftRng::new_unseeded().shuffle(items.as_mut_slice()); |
|
|
|
|
|
|
|
|
|
let dbi = db.dbi(); |
|
|
|
|
let env = _env.env(); |
|
|
|
|
|
|
|
|
|
let mut key_val: MDB_val = MDB_val { mv_size: 0, mv_data: ptr::null_mut() }; |
|
|
|
|
let mut data_val: MDB_val = MDB_val { mv_size: 0, mv_data: ptr::null_mut() }; |
|
|
|
|
|
|
|
|
|
b.iter(|| unsafe { |
|
|
|
|
// TODO: change this to just a transaction renew, instead of a new transaction
|
|
|
|
|
let mut txn: *mut MDB_txn = ptr::null_mut(); |
|
|
|
|
mdb_txn_begin(env, ptr::null_mut(), 0, &mut txn); |
|
|
|
|
|
|
|
|
|
let mut i = 0i32; |
|
|
|
|
for &(ref key, ref data) in items.iter() { |
|
|
|
|
|
|
|
|
|
key_val.mv_size = key.len() as u64; |
|
|
|
|
key_val.mv_data = key.as_bytes().as_ptr() as *mut _; |
|
|
|
|
data_val.mv_size = data.len() as u64; |
|
|
|
|
data_val.mv_data = data.as_bytes().as_ptr() as *mut _; |
|
|
|
|
|
|
|
|
|
i += mdb_put(txn, dbi, &mut key_val, &mut data_val, 0); |
|
|
|
|
} |
|
|
|
|
assert_eq!(0, i); |
|
|
|
|
mdb_txn_abort(txn); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|