rename transaction and cursor opening functions; improve docs

without.crypto
Dan Burkert 10 years ago
parent 25f240282e
commit 9facaae124
  1. 50
      src/cursor.rs
  2. 66
      src/database.rs
  3. 42
      src/environment.rs
  4. 2
      src/lib.rs
  5. 56
      src/transaction.rs

@ -20,8 +20,8 @@ pub trait Cursor<'txn> {
/// Cursor extension methods.
pub trait CursorExt<'txn> : Cursor<'txn> {
/// Retrieves a key/data pair from the cursor. Depending on the cursor op, the current key is
/// returned.
/// Retrieves a key/data pair from the cursor. Depending on the cursor op, the current key may
/// be returned.
fn get(&self,
key: Option<&[u8]>,
data: Option<&[u8]>,
@ -49,7 +49,7 @@ pub trait CursorExt<'txn> : Cursor<'txn> {
impl<'txn, T> CursorExt<'txn> for T where T: Cursor<'txn> {}
/// A read-only cursor for navigating items within a database.
/// A read-only cursor for navigating the items within a database.
pub struct RoCursor<'txn> {
cursor: *mut ffi::MDB_cursor,
_no_sync: marker::NoSync,
@ -73,7 +73,7 @@ impl <'txn> Drop for RoCursor<'txn> {
impl <'txn> RoCursor<'txn> {
/// Creates a new read-only cursor in the given database and transaction. Prefer using
/// `Transaction::open_cursor()`.
/// `Transaction::open_cursor`.
#[doc(hidden)]
pub fn new(txn: &'txn Transaction, db: Database) -> LmdbResult<RoCursor<'txn>> {
let mut cursor: *mut ffi::MDB_cursor = ptr::null_mut();
@ -111,7 +111,7 @@ impl <'txn> Drop for RwCursor<'txn> {
impl <'txn> RwCursor<'txn> {
/// Creates a new read-only cursor in the given database and transaction. Prefer using
/// `WriteTransaction::open_write_cursor()`.
/// `RwTransaction::open_rw_cursor`.
#[doc(hidden)]
pub fn new(txn: &'txn Transaction, db: Database) -> LmdbResult<RwCursor<'txn>> {
let mut cursor: *mut ffi::MDB_cursor = ptr::null_mut();
@ -126,7 +126,7 @@ impl <'txn> RwCursor<'txn> {
/// Puts a key/data pair into the database. The cursor will be positioned at the new data item,
/// or on failure usually near it.
pub fn put(&self,
pub fn put(&mut self,
key: &[u8],
data: &[u8],
flags: WriteFlags)
@ -149,10 +149,8 @@ impl <'txn> RwCursor<'txn> {
///
/// `WriteFlags::NO_DUP_DATA` may be used to delete all data items for the current key, if the
/// database was opened with `DatabaseFlags::DUP_SORT`.
pub fn del(&self, flags: WriteFlags) -> LmdbResult<()> {
unsafe {
lmdb_result(ffi::mdb_cursor_del(self.cursor(), flags.bits()))
}
pub fn del(&mut self, flags: WriteFlags) -> LmdbResult<()> {
unsafe { lmdb_result(ffi::mdb_cursor_del(self.cursor(), flags.bits())) }
}
}
@ -237,15 +235,15 @@ mod test {
(b"key3", b"val3"));
{
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
for &(key, data) in items.iter() {
txn.put(db, key, data, WriteFlags::empty()).unwrap();
}
txn.commit().unwrap();
}
let txn = env.begin_read_txn().unwrap();
let mut cursor = txn.open_read_cursor(db).unwrap();
let txn = env.begin_ro_txn().unwrap();
let mut cursor = txn.open_ro_cursor(db).unwrap();
assert_eq!(items, cursor.iter().collect::<Vec<(&[u8], &[u8])>>());
}
@ -255,12 +253,12 @@ mod test {
let env = Environment::new().open(dir.path(), io::USER_RWX).unwrap();
let db = env.open_db(None).unwrap();
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
txn.put(db, b"key1", b"val1", WriteFlags::empty()).unwrap();
txn.put(db, b"key2", b"val2", WriteFlags::empty()).unwrap();
txn.put(db, b"key3", b"val3", WriteFlags::empty()).unwrap();
let cursor = txn.open_read_cursor(db).unwrap();
let cursor = txn.open_ro_cursor(db).unwrap();
assert_eq!((Some(b"key1"), b"val1"),
cursor.get(None, None, MDB_FIRST).unwrap());
assert_eq!((Some(b"key1"), b"val1"),
@ -285,7 +283,7 @@ mod test {
let env = Environment::new().open(dir.path(), io::USER_RWX).unwrap();
let db = env.create_db(None, DUP_SORT).unwrap();
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
txn.put(db, b"key1", b"val1", WriteFlags::empty()).unwrap();
txn.put(db, b"key1", b"val2", WriteFlags::empty()).unwrap();
txn.put(db, b"key1", b"val3", WriteFlags::empty()).unwrap();
@ -293,7 +291,7 @@ mod test {
txn.put(db, b"key2", b"val2", WriteFlags::empty()).unwrap();
txn.put(db, b"key2", b"val3", WriteFlags::empty()).unwrap();
let cursor = txn.open_read_cursor(db).unwrap();
let cursor = txn.open_ro_cursor(db).unwrap();
assert_eq!((Some(b"key1"), b"val1"),
cursor.get(None, None, MDB_FIRST).unwrap());
assert_eq!((None, b"val1"),
@ -331,7 +329,7 @@ mod test {
let env = Environment::new().open(dir.path(), io::USER_RWX).unwrap();
let db = env.create_db(None, DUP_SORT | DUP_FIXED).unwrap();
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
txn.put(db, b"key1", b"val1", WriteFlags::empty()).unwrap();
txn.put(db, b"key1", b"val2", WriteFlags::empty()).unwrap();
txn.put(db, b"key1", b"val3", WriteFlags::empty()).unwrap();
@ -339,7 +337,7 @@ mod test {
txn.put(db, b"key2", b"val5", WriteFlags::empty()).unwrap();
txn.put(db, b"key2", b"val6", WriteFlags::empty()).unwrap();
let cursor = txn.open_read_cursor(db).unwrap();
let cursor = txn.open_ro_cursor(db).unwrap();
assert_eq!((Some(b"key1"), b"val1"),
cursor.get(None, None, MDB_FIRST).unwrap());
assert_eq!((None, b"val1val2val3"),
@ -353,8 +351,8 @@ mod test {
let env = Environment::new().open(dir.path(), io::USER_RWX).unwrap();
let db = env.open_db(None).unwrap();
let mut txn = env.begin_write_txn().unwrap();
let cursor = txn.open_write_cursor(db).unwrap();
let mut txn = env.begin_rw_txn().unwrap();
let mut cursor = txn.open_rw_cursor(db).unwrap();
cursor.put(b"key1", b"val1", WriteFlags::empty()).unwrap();
cursor.put(b"key2", b"val2", WriteFlags::empty()).unwrap();
@ -374,10 +372,10 @@ mod test {
let n = 100;
let (_dir, env) = setup_bench_db(n);
let db = env.open_db(None).unwrap();
let txn = env.begin_read_txn().unwrap();
let txn = env.begin_ro_txn().unwrap();
b.iter(|| {
let mut cursor = txn.open_read_cursor(db).unwrap();
let mut cursor = txn.open_ro_cursor(db).unwrap();
let mut i = 0;
let mut count = 0u32;
@ -397,10 +395,10 @@ mod test {
let n = 100;
let (_dir, env) = setup_bench_db(n);
let db = env.open_db(None).unwrap();
let txn = env.begin_read_txn().unwrap();
let txn = env.begin_ro_txn().unwrap();
b.iter(|| {
let cursor = txn.open_read_cursor(db).unwrap();
let cursor = txn.open_ro_cursor(db).unwrap();
let mut i = 0;
let mut count = 0u32;
@ -422,7 +420,7 @@ mod test {
let db = env.open_db(None).unwrap();
let dbi: MDB_dbi = db.dbi();
let _txn = env.begin_read_txn().unwrap();
let _txn = env.begin_ro_txn().unwrap();
let txn = _txn.txn();
let mut key = MDB_val { mv_size: 0, mv_data: ptr::null_mut() };

@ -1,53 +1,73 @@
use std::kinds::marker;
use std::ptr;
use ffi::*;
use ffi;
use error::{LmdbResult, lmdb_result};
use flags::DatabaseFlags;
use transaction::{RoTransaction, RwTransaction, Transaction};
use transaction::{RwTransaction, Transaction};
/// A handle to an individual database in an environment.
///
/// A database handle denotes the name and parameters of a database in an environment. The database
/// may not exist in the environment (for instance, if the database is opened during a transaction
/// that has not yet committed).
/// A database handle denotes the name and parameters of a database in an environment.
#[deriving(Clone, Copy)]
pub struct Database<'env> {
dbi: MDB_dbi,
_marker: marker::ContravariantLifetime<'env>,
pub struct Database {
dbi: ffi::MDB_dbi,
}
impl <'env> Database<'env> {
impl Database {
pub unsafe fn open<'e>(txn: &RoTransaction<'e>,
/// Opens a database in the provided transaction.
///
/// If `name` is `None`, then the default database will be opened, otherwise a named database
/// will be opened. The database handle will be private to the transaction until the transaction
/// is successfully committed. If the transaction is aborted the returned database handle
/// should no longer be used.
///
/// ## Unsafety
///
/// * This function (as well as `Environment::open_db`, `Environment::create_db`, and
/// `Database::create`) **must not** be called from multiple concurrent transactions in the same
/// environment. A transaction which uses this function must finish (either commit or abort)
/// before any other transaction may use this function.
pub unsafe fn open(txn: &Transaction,
name: Option<&str>)
-> LmdbResult<Database<'e>> {
-> LmdbResult<Database> {
let c_name = name.map(|n| n.to_c_str());
let name_ptr = if let Some(ref c_name) = c_name { c_name.as_ptr() } else { ptr::null() };
let mut dbi: MDB_dbi = 0;
try!(lmdb_result(mdb_dbi_open(txn.txn(), name_ptr, 0, &mut dbi)));
Ok(Database { dbi: dbi,
_marker: marker::ContravariantLifetime::<'e> })
let mut dbi: ffi::MDB_dbi = 0;
try!(lmdb_result(ffi::mdb_dbi_open(txn.txn(), name_ptr, 0, &mut dbi)));
Ok(Database { dbi: dbi })
}
pub unsafe fn create<'e>(txn: &RwTransaction<'e>,
/// Opens a handle in the provided transaction, creating the database if necessary.
///
/// If `name` is `None`, then the default database will be opened, otherwise a named database
/// will be opened. The database handle will be private to the transaction until the transaction
/// is successfully committed. If the transaction is aborted the returned database handle
/// should no longer be used.
///
/// ## Unsafety
///
/// * This function (as well as `Environment::open_db`, `Environment::create_db`, and
/// `Database::open`) **must not** be called from multiple concurrent transactions in the same
/// environment. A transaction which uses this function must finish (either commit or abort)
/// before any other transaction may use this function.
pub unsafe fn create(txn: &RwTransaction,
name: Option<&str>,
flags: DatabaseFlags)
-> LmdbResult<Database<'e>> {
-> LmdbResult<Database> {
let c_name = name.map(|n| n.to_c_str());
let name_ptr = if let Some(ref c_name) = c_name { c_name.as_ptr() } else { ptr::null() };
let mut dbi: MDB_dbi = 0;
try!(lmdb_result(mdb_dbi_open(txn.txn(), name_ptr, flags.bits() | MDB_CREATE, &mut dbi)));
Ok(Database { dbi: dbi,
_marker: marker::ContravariantLifetime::<'e> })
let mut dbi: ffi::MDB_dbi = 0;
try!(lmdb_result(ffi::mdb_dbi_open(txn.txn(), name_ptr, flags.bits() | ffi::MDB_CREATE, &mut dbi)));
Ok(Database { dbi: dbi })
}
/// Returns the underlying LMDB database handle.
///
/// The caller **must** ensure that the handle is not used after the lifetime of the
/// environment, or after the database handle has been closed.
pub fn dbi(&self) -> MDB_dbi {
pub fn dbi(&self) -> ffi::MDB_dbi {
self.dbi
}
}

@ -46,17 +46,20 @@ impl Environment {
/// case the environment must be configured to allow named databases through
/// `EnvironmentBuilder::set_max_dbs`.
///
/// The returned database handle may be shared among transactions.
pub fn open_db<'env>(&'env self, name: Option<&str>) -> LmdbResult<Database<'env>> {
/// The returned database handle may be shared among any transaction in the environment.
///
/// This function will fail with `LmdbError::BadRslot` if called by a thread which has an ongoing
/// transaction.
pub fn open_db<'env>(&'env self, name: Option<&str>) -> LmdbResult<Database> {
let mutex = self.dbi_open_mutex.lock();
let txn = try!(self.begin_read_txn());
let txn = try!(self.begin_ro_txn());
let db = unsafe { try!(Database::open(&txn, name)) };
try!(txn.commit());
drop(mutex);
Ok(db)
}
/// Opens a handle to an LMDB database, opening the database if necessary.
/// Opens a handle to an LMDB database, creating the database if necessary.
///
/// If the database is already created, the given option flags will be added to it.
///
@ -66,21 +69,24 @@ impl Environment {
/// case the environment must be configured to allow named databases through
/// `EnvironmentBuilder::set_max_dbs`.
///
/// The returned database handle may be shared among transactions.
/// The returned database handle may be shared among any transaction in the environment.
///
/// This function will fail with `LmdbError::BadRslot` if called by a thread with an open
/// transaction.
pub fn create_db<'env>(&'env self,
name: Option<&str>,
flags: DatabaseFlags)
-> LmdbResult<Database<'env>> {
-> LmdbResult<Database> {
let mutex = self.dbi_open_mutex.lock();
let txn = try!(self.begin_write_txn());
let txn = try!(self.begin_rw_txn());
let db = unsafe { try!(Database::create(&txn, name, flags)) };
try!(txn.commit());
drop(mutex);
Ok(db)
}
pub fn get_db_flags<'env>(&'env self, db: Database<'env>) -> LmdbResult<DatabaseFlags> {
let txn = try!(self.begin_read_txn());
pub fn get_db_flags<'env>(&'env self, db: Database) -> LmdbResult<DatabaseFlags> {
let txn = try!(self.begin_ro_txn());
let mut flags: c_uint = 0;
unsafe {
try!(lmdb_result(ffi::mdb_dbi_flags(txn.txn(), db.dbi(), &mut flags)));
@ -89,19 +95,19 @@ impl Environment {
}
/// Create a read-only transaction for use with the environment.
pub fn begin_read_txn<'env>(&'env self) -> LmdbResult<RoTransaction<'env>> {
pub fn begin_ro_txn<'env>(&'env self) -> LmdbResult<RoTransaction<'env>> {
RoTransaction::new(self)
}
/// Create a read-write transaction for use with the environment. This method will block while
/// there are any other read-write transactions open on the environment.
pub fn begin_write_txn<'env>(&'env self) -> LmdbResult<RwTransaction<'env>> {
pub fn begin_rw_txn<'env>(&'env self) -> LmdbResult<RwTransaction<'env>> {
RwTransaction::new(self)
}
/// Flush data buffers to disk.
///
/// Data is always written to disk when `Transaction::commit()` is called, but the operating
/// Data is always written to disk when `Transaction::commit` is called, but the operating
/// system may keep it buffered. LMDB always flushes the OS buffers upon commit as well, unless
/// the environment was opened with `MDB_NOSYNC` or in part `MDB_NOMETASYNC`.
pub fn sync(&self, force: bool) -> LmdbResult<()> {
@ -123,13 +129,13 @@ impl Environment {
pub fn clear_db(&mut self, name: Option<&str>) -> LmdbResult<()> {
let db = try!(self.open_db(name));
let txn = try!(self.begin_write_txn());
let txn = try!(self.begin_rw_txn());
unsafe { lmdb_result(ffi::mdb_drop(txn.txn(), db.dbi(), 0)) }
}
pub fn drop_db(&mut self, name: Option<&str>) -> LmdbResult<()> {
let db = try!(self.open_db(name));
let txn = try!(self.begin_write_txn());
let txn = try!(self.begin_rw_txn());
unsafe { lmdb_result(ffi::mdb_drop(txn.txn(), db.dbi(), 1)) }
}
}
@ -262,8 +268,8 @@ mod test {
{ // writable environment
let env = Environment::new().open(dir.path(), io::USER_RWX).unwrap();
assert!(env.begin_write_txn().is_ok());
assert!(env.begin_read_txn().is_ok());
assert!(env.begin_rw_txn().is_ok());
assert!(env.begin_ro_txn().is_ok());
}
{ // read-only environment
@ -271,8 +277,8 @@ mod test {
.open(dir.path(), io::USER_RWX)
.unwrap();
assert!(env.begin_write_txn().is_err());
assert!(env.begin_read_txn().is_ok());
assert!(env.begin_rw_txn().is_err());
assert!(env.begin_ro_txn().is_ok());
}
}

@ -80,7 +80,7 @@ mod test_utils {
{
let db = env.open_db(None).unwrap();
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
for i in range(0, num_rows) {
txn.put(db,
get_key(i).as_bytes(),

@ -70,7 +70,7 @@ pub trait TransactionExt<'env> : Transaction<'env> {
}
/// Open a new read-only cursor on the given database.
fn open_read_cursor<'txn>(&'txn self, db: Database) -> LmdbResult<RoCursor<'txn>> {
fn open_ro_cursor<'txn>(&'txn self, db: Database) -> LmdbResult<RoCursor<'txn>> {
RoCursor::new(self, db)
}
@ -122,6 +122,16 @@ impl <'env> RoTransaction<'env> {
}
}
/// Resets the read-only transaction.
///
/// Abort the transaction like `Transaction::abort`, but keep the transaction handle.
/// `InactiveTransaction::renew` may reuse the handle. This saves allocation overhead if the
/// process will start a new read-only transaction soon, and also locking overhead if
/// `EnvironmentFlags::NO_TLS` is in use. The reader table lock is released, but the table slot
/// stays tied to its thread or transaction. Reader locks generally don't interfere with
/// writers, but they keep old versions of database pages allocated. Thus they prevent the old
/// pages from being reused when writers commit new data, and so under heavy load the database
/// size may grow much more rapidly than otherwise.
pub fn reset(self) -> InactiveTransaction<'env> {
let txn = self.txn;
unsafe {
@ -134,7 +144,6 @@ impl <'env> RoTransaction<'env> {
_no_send: marker::NoSend,
_contravariant: marker::ContravariantLifetime::<'env>,
}
}
}
@ -161,7 +170,10 @@ impl <'env> Drop for InactiveTransaction<'env> {
impl <'env> InactiveTransaction<'env> {
/// Renews the inactive transaction and returns the active read-only transaction.
/// Renews the inactive transaction, returning an active read-only transaction.
///
/// This acquires a new reader lock for a transaction handle that had been released by
/// `RoTransaction::reset`.
pub fn renew(self) -> LmdbResult<RoTransaction<'env>> {
let txn = self.txn;
unsafe {
@ -213,8 +225,8 @@ impl <'env> RwTransaction<'env> {
}
}
/// Open a new read-write cursor on the given database.
pub fn open_write_cursor<'txn>(&'txn mut self, db: Database) -> LmdbResult<RwCursor<'txn>> {
/// Opens a new read-write cursor on the given database and transaction.
pub fn open_rw_cursor<'txn>(&'txn mut self, db: Database) -> LmdbResult<RwCursor<'txn>> {
RwCursor::new(self, db)
}
@ -341,13 +353,13 @@ mod test {
let env = Environment::new().open(dir.path(), io::USER_RWX).unwrap();
let db = env.open_db(None).unwrap();
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
txn.put(db, b"key1", b"val1", WriteFlags::empty()).unwrap();
txn.put(db, b"key2", b"val2", WriteFlags::empty()).unwrap();
txn.put(db, b"key3", b"val3", WriteFlags::empty()).unwrap();
txn.commit().unwrap();
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
assert_eq!(b"val1", txn.get(db, b"key1").unwrap());
assert_eq!(b"val2", txn.get(db, b"key2").unwrap());
assert_eq!(b"val3", txn.get(db, b"key3").unwrap());
@ -363,14 +375,14 @@ mod test {
let env = Environment::new().open(dir.path(), io::USER_RWX).unwrap();
let db = env.open_db(None).unwrap();
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
{
let mut writer = txn.reserve(db, b"key1", 4, WriteFlags::empty()).unwrap();
writer.write(b"val1").unwrap();
}
txn.commit().unwrap();
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
assert_eq!(b"val1", txn.get(db, b"key1").unwrap());
assert_eq!(txn.get(db, b"key"), Err(LmdbError::NotFound));
@ -397,7 +409,7 @@ mod test {
{
let db = env.open_db(None).unwrap();
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
txn.put(db, b"key", b"val", WriteFlags::empty()).unwrap();
txn.commit().unwrap();
}
@ -405,7 +417,7 @@ mod test {
env.clear_db(None).unwrap();
let db = env.open_db(None).unwrap();
let txn = env.begin_read_txn().unwrap();
let txn = env.begin_ro_txn().unwrap();
txn.get(db, b"key").is_err();
}
@ -416,12 +428,12 @@ mod test {
let db = env.open_db(None).unwrap();
{
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
txn.put(db, b"key", b"val", WriteFlags::empty()).unwrap();
txn.commit().unwrap();
}
let txn = env.begin_read_txn().unwrap();
let txn = env.begin_ro_txn().unwrap();
let inactive = txn.reset();
let active = inactive.renew().unwrap();
assert!(active.get(db, b"key").is_ok());
@ -433,7 +445,7 @@ mod test {
let env = Environment::new().open(dir.path(), io::USER_RWX).unwrap();
let db = env.open_db(None).unwrap();
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
txn.put(db, b"key1", b"val1", WriteFlags::empty()).unwrap();
{
@ -466,21 +478,21 @@ mod test {
futures.push(Future::spawn(move|| {
let db = reader_env.open_db(None).unwrap();
{
let txn = reader_env.begin_read_txn().unwrap();
let txn = reader_env.begin_ro_txn().unwrap();
assert_eq!(txn.get(db, key), Err(LmdbError::NotFound));
txn.abort();
}
reader_barrier.wait();
reader_barrier.wait();
{
let txn = reader_env.begin_read_txn().unwrap();
let txn = reader_env.begin_ro_txn().unwrap();
txn.get(db, key).unwrap() == val
}
}));
}
let db = env.open_db(None).unwrap();
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
barrier.wait();
txn.put(db, key, val, WriteFlags::empty()).unwrap();
txn.commit().unwrap();
@ -505,7 +517,7 @@ mod test {
futures.push(Future::spawn(move|| {
let db = writer_env.open_db(None).unwrap();
let mut txn = writer_env.begin_write_txn().unwrap();
let mut txn = writer_env.begin_rw_txn().unwrap();
txn.put(db,
format!("{}{}", key, i).as_bytes(),
format!("{}{}", val, i).as_bytes(),
@ -517,7 +529,7 @@ mod test {
assert!(futures.iter_mut().all(|b| b.get()));
let db = env.open_db(None).unwrap();
let txn = env.begin_read_txn().unwrap();
let txn = env.begin_ro_txn().unwrap();
for i in range(0, n) {
assert_eq!(
@ -531,7 +543,7 @@ mod test {
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 txn = env.begin_ro_txn().unwrap();
let mut keys: Vec<String> = range(0, n).map(|n| get_key(n))
.collect::<Vec<_>>();
@ -551,7 +563,7 @@ mod test {
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 _txn = env.begin_ro_txn().unwrap();
let mut keys: Vec<String> = range(0, n).map(|n| get_key(n))
.collect::<Vec<_>>();
@ -588,7 +600,7 @@ mod test {
XorShiftRng::new_unseeded().shuffle(items.as_mut_slice());
b.iter(|| {
let mut txn = env.begin_write_txn().unwrap();
let mut txn = env.begin_rw_txn().unwrap();
for &(ref key, ref data) in items.iter() {
txn.put(db, key.as_bytes(), data.as_bytes(), WriteFlags::empty()).unwrap();
}

Loading…
Cancel
Save