diff --git a/src/cursor.rs b/src/cursor.rs index b159c5b..fa4b112 100644 --- a/src/cursor.rs +++ b/src/cursor.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> { 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> { let mut cursor: *mut ffi::MDB_cursor = ptr::null_mut(); @@ -126,11 +126,11 @@ 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, - key: &[u8], - data: &[u8], - flags: WriteFlags) - -> LmdbResult<()> { + pub fn put(&mut self, + key: &[u8], + data: &[u8], + flags: WriteFlags) + -> LmdbResult<()> { let mut key_val: ffi::MDB_val = ffi::MDB_val { mv_size: key.len() as size_t, mv_data: key.as_ptr() as *mut c_void }; let mut data_val: ffi::MDB_val = ffi::MDB_val { mv_size: data.len() as size_t, @@ -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::>()); } @@ -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() }; diff --git a/src/database.rs b/src/database.rs index 38722de..37fbb34 100644 --- a/src/database.rs +++ b/src/database.rs @@ -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>, - name: Option<&str>) - -> LmdbResult> { + /// 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 { 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>, - name: Option<&str>, - flags: DatabaseFlags) - -> LmdbResult> { + /// 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 { 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 } } diff --git a/src/environment.rs b/src/environment.rs index f0b6efe..f82205f 100644 --- a/src/environment.rs +++ b/src/environment.rs @@ -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> { + /// 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 { 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> { + -> LmdbResult { 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 { - let txn = try!(self.begin_read_txn()); + pub fn get_db_flags<'env>(&'env self, db: Database) -> LmdbResult { + 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> { + pub fn begin_ro_txn<'env>(&'env self) -> LmdbResult> { 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> { + pub fn begin_rw_txn<'env>(&'env self) -> LmdbResult> { 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()); } } diff --git a/src/lib.rs b/src/lib.rs index fedfd70..b659851 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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(), diff --git a/src/transaction.rs b/src/transaction.rs index d7a71bb..ba1cf37 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -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> { + fn open_ro_cursor<'txn>(&'txn self, db: Database) -> LmdbResult> { 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> { 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> { + /// 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::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 = range(0, n).map(|n| get_key(n)) .collect::>(); @@ -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 = range(0, n).map(|n| get_key(n)) .collect::>(); @@ -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(); }