Skip to content

Commit

Permalink
Drop copy and clone traits requirement on backend databases
Browse files Browse the repository at this point in the history
Signed-off-by: Victor Porof <[email protected]>
  • Loading branch information
victorporof committed Nov 1, 2019
1 parent a4d76eb commit 2bb1436
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 72 deletions.
4 changes: 2 additions & 2 deletions examples/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn main() {
let k = created_arc.read().unwrap();
let store = k.open_single("store", StoreOptions::create()).unwrap();

populate_store(&k, store).unwrap();
populate_store(&k, &store).unwrap();

let reader = k.read().unwrap();

Expand Down Expand Up @@ -64,7 +64,7 @@ fn main() {
}
}

fn populate_store(k: &Rkv<LmdbEnvironment>, store: SingleStore<LmdbDatabase>) -> Result<(), StoreError> {
fn populate_store(k: &Rkv<LmdbEnvironment>, store: &SingleStore<LmdbDatabase>) -> Result<(), StoreError> {
let mut writer = k.write()?;
for (country, city) in vec![
("Canada", Value::Str("Ottawa")),
Expand Down
8 changes: 4 additions & 4 deletions examples/simple-store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use rkv::{
type MultiStore = rkv::MultiStore<LmdbDatabase>;
type Writer<'env> = rkv::Writer<LmdbRwTransaction<'env>>;

fn getput<'env, 's>(store: MultiStore, writer: &'env mut Writer, ids: &'s mut Vec<String>) {
fn getput<'env, 's>(store: &MultiStore, writer: &'env mut Writer, ids: &'s mut Vec<String>) {
let keys = vec!["str1", "str2", "str3"];
// we convert the writer into a cursor so that we can safely read
for k in keys.iter() {
Expand All @@ -46,7 +46,7 @@ fn getput<'env, 's>(store: MultiStore, writer: &'env mut Writer, ids: &'s mut Ve
}
}

fn delete(store: MultiStore, writer: &mut Writer) {
fn delete(store: &MultiStore, writer: &mut Writer) {
let keys = vec!["str1", "str2", "str3"];
let vals = vec!["string uno", "string quatro", "string siete"];
// we convert the writer into a cursor so that we can safely read
Expand Down Expand Up @@ -96,10 +96,10 @@ fn main() {
multistore.put(&mut writer, "str3", &Value::Str("string siete")).unwrap();
multistore.put(&mut writer, "str3", &Value::Str("string ocho")).unwrap();
multistore.put(&mut writer, "str3", &Value::Str("string nueve")).unwrap();
getput(multistore, &mut writer, &mut ids);
getput(&multistore, &mut writer, &mut ids);
writer.commit().unwrap();
let mut writer = k.write().unwrap();
delete(multistore, &mut writer);
delete(&multistore, &mut writer);
writer.commit().unwrap();
}

Expand Down
2 changes: 1 addition & 1 deletion src/backend/impl_lmdb/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

use crate::backend::traits::BackendDatabase;

#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[derive(Debug, Eq, PartialEq)]
pub struct DatabaseImpl(pub(crate) lmdb::Database);

impl BackendDatabase for DatabaseImpl {}
14 changes: 7 additions & 7 deletions src/backend/impl_lmdb/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl<'env> BackendRoTransaction for RoTransactionImpl<'env> {
type Database = DatabaseImpl;
type Flags = WriteFlagsImpl;

fn get(&self, db: Self::Database, key: &[u8]) -> Result<&[u8], Self::Error> {
fn get(&self, db: &Self::Database, key: &[u8]) -> Result<&[u8], Self::Error> {
self.0.get(db.0, &key).map_err(ErrorImpl)
}

Expand All @@ -43,7 +43,7 @@ impl<'env> BackendRoTransaction for RoTransactionImpl<'env> {
impl<'env> BackendRoCursorTransaction<'env> for RoTransactionImpl<'env> {
type RoCursor = RoCursorImpl<'env>;

fn open_ro_cursor(&'env self, db: Self::Database) -> Result<Self::RoCursor, Self::Error> {
fn open_ro_cursor(&'env self, db: &Self::Database) -> Result<Self::RoCursor, Self::Error> {
self.0.open_ro_cursor(db.0).map(RoCursorImpl).map_err(ErrorImpl)
}
}
Expand All @@ -56,19 +56,19 @@ impl<'env> BackendRwTransaction for RwTransactionImpl<'env> {
type Database = DatabaseImpl;
type Flags = WriteFlagsImpl;

fn get(&self, db: Self::Database, key: &[u8]) -> Result<&[u8], Self::Error> {
fn get(&self, db: &Self::Database, key: &[u8]) -> Result<&[u8], Self::Error> {
self.0.get(db.0, &key).map_err(ErrorImpl)
}

fn put(&mut self, db: Self::Database, key: &[u8], value: &[u8], flags: Self::Flags) -> Result<(), Self::Error> {
fn put(&mut self, db: &Self::Database, key: &[u8], value: &[u8], flags: Self::Flags) -> Result<(), Self::Error> {
self.0.put(db.0, &key, &value, flags.0).map_err(ErrorImpl)
}

fn del(&mut self, db: Self::Database, key: &[u8], value: Option<&[u8]>) -> Result<(), Self::Error> {
fn del(&mut self, db: &Self::Database, key: &[u8], value: Option<&[u8]>) -> Result<(), Self::Error> {
self.0.del(db.0, &key, value).map_err(ErrorImpl)
}

fn clear_db(&mut self, db: Self::Database) -> Result<(), Self::Error> {
fn clear_db(&mut self, db: &Self::Database) -> Result<(), Self::Error> {
self.0.clear_db(db.0).map_err(ErrorImpl)
}

Expand All @@ -84,7 +84,7 @@ impl<'env> BackendRwTransaction for RwTransactionImpl<'env> {
impl<'env> BackendRwCursorTransaction<'env> for RwTransactionImpl<'env> {
type RoCursor = RoCursorImpl<'env>;

fn open_ro_cursor(&'env self, db: Self::Database) -> Result<Self::RoCursor, Self::Error> {
fn open_ro_cursor(&'env self, db: &Self::Database) -> Result<Self::RoCursor, Self::Error> {
self.0.open_ro_cursor(db.0).map(RoCursorImpl).map_err(ErrorImpl)
}
}
16 changes: 8 additions & 8 deletions src/backend/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::error::StoreError;

pub trait BackendError: Debug + Display + Into<StoreError> {}

pub trait BackendDatabase: Debug + Eq + PartialEq + Copy + Clone {}
pub trait BackendDatabase: Debug + Eq + PartialEq {}

pub trait BackendFlags: Debug + Eq + PartialEq + Copy + Clone + Default {
fn empty() -> Self;
Expand Down Expand Up @@ -120,7 +120,7 @@ pub trait BackendRoTransaction: Debug {
type Database: BackendDatabase;
type Flags: BackendWriteFlags;

fn get(&self, db: Self::Database, key: &[u8]) -> Result<&[u8], Self::Error>;
fn get(&self, db: &Self::Database, key: &[u8]) -> Result<&[u8], Self::Error>;

fn abort(self);
}
Expand All @@ -130,13 +130,13 @@ pub trait BackendRwTransaction: Debug {
type Database: BackendDatabase;
type Flags: BackendWriteFlags;

fn get(&self, db: Self::Database, key: &[u8]) -> Result<&[u8], Self::Error>;
fn get(&self, db: &Self::Database, key: &[u8]) -> Result<&[u8], Self::Error>;

fn put(&mut self, db: Self::Database, key: &[u8], value: &[u8], flags: Self::Flags) -> Result<(), Self::Error>;
fn put(&mut self, db: &Self::Database, key: &[u8], value: &[u8], flags: Self::Flags) -> Result<(), Self::Error>;

fn del(&mut self, db: Self::Database, key: &[u8], value: Option<&[u8]>) -> Result<(), Self::Error>;
fn del(&mut self, db: &Self::Database, key: &[u8], value: Option<&[u8]>) -> Result<(), Self::Error>;

fn clear_db(&mut self, db: Self::Database) -> Result<(), Self::Error>;
fn clear_db(&mut self, db: &Self::Database) -> Result<(), Self::Error>;

fn commit(self) -> Result<(), Self::Error>;

Expand All @@ -146,13 +146,13 @@ pub trait BackendRwTransaction: Debug {
pub trait BackendRoCursorTransaction<'env>: BackendRoTransaction {
type RoCursor: BackendRoCursor<'env>;

fn open_ro_cursor(&'env self, db: Self::Database) -> Result<Self::RoCursor, Self::Error>;
fn open_ro_cursor(&'env self, db: &Self::Database) -> Result<Self::RoCursor, Self::Error>;
}

pub trait BackendRwCursorTransaction<'env>: BackendRwTransaction {
type RoCursor: BackendRoCursor<'env>;

fn open_ro_cursor(&'env self, db: Self::Database) -> Result<Self::RoCursor, Self::Error>;
fn open_ro_cursor(&'env self, db: &Self::Database) -> Result<Self::RoCursor, Self::Error>;
}

pub trait BackendRoCursor<'env>: Debug {
Expand Down
14 changes: 8 additions & 6 deletions src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,19 +734,19 @@ mod tests {
// as the Value::I64 borrows an immutable reference to the Writer.
// So we extract and copy its primitive value.

fn get_existing_foo(store: SingleStore<LmdbDatabase>, writer: &Writer<LmdbRwTransaction>) -> Option<i64> {
fn get_existing_foo(store: &SingleStore<LmdbDatabase>, writer: &Writer<LmdbRwTransaction>) -> Option<i64> {
match store.get(writer, "foo").expect("read") {
Some(Value::I64(val)) => Some(val),
_ => None,
}
}

let mut writer = k.write().expect("writer");
let mut existing = get_existing_foo(sk, &writer).unwrap_or(99);
let mut existing = get_existing_foo(&sk, &writer).unwrap_or(99);
existing += 1;
sk.put(&mut writer, "foo", &Value::I64(existing)).expect("success");

let updated = get_existing_foo(sk, &writer).unwrap_or(99);
let updated = get_existing_foo(&sk, &writer).unwrap_or(99);
assert_eq!(updated, 100);
writer.commit().expect("commit");
}
Expand Down Expand Up @@ -1246,7 +1246,7 @@ mod tests {
let root = Builder::new().prefix("test_multiple_thread").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let rkv_arc = Arc::new(RwLock::new(Rkv::new::<backend::Lmdb>(root.path()).expect("new succeeded")));
let store = rkv_arc.read().unwrap().open_single("test", StoreOptions::create()).expect("opened");
let store_arc = Arc::new(rkv_arc.read().unwrap().open_single("test", StoreOptions::create()).expect("opened"));

let num_threads = 10;
let mut write_handles = Vec::with_capacity(num_threads as usize);
Expand All @@ -1260,10 +1260,11 @@ mod tests {
// For each KV pair, spawn a thread that writes it to the store.
for i in 0..num_threads {
let rkv_arc = rkv_arc.clone();
let store_arc = store_arc.clone();
write_handles.push(thread::spawn(move || {
let rkv = rkv_arc.write().expect("rkv");
let mut writer = rkv.write().expect("writer");
store.put(&mut writer, i.to_string(), &Value::U64(i)).expect("written");
store_arc.put(&mut writer, i.to_string(), &Value::U64(i)).expect("written");
writer.commit().unwrap();
}));
}
Expand All @@ -1275,10 +1276,11 @@ mod tests {
// and returns its value.
for i in 0..num_threads {
let rkv_arc = rkv_arc.clone();
let store_arc = store_arc.clone();
read_handles.push(thread::spawn(move || {
let rkv = rkv_arc.read().expect("rkv");
let reader = rkv.read().expect("reader");
let value = match store.get(&reader, i.to_string()) {
let value = match store_arc.get(&reader, i.to_string()) {
Ok(Some(Value::U64(value))) => value,
Ok(Some(_)) => panic!("value type unexpected"),
Ok(None) => panic!("value not found"),
Expand Down
18 changes: 9 additions & 9 deletions src/readwrite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ pub trait Readable<'env> {
type Database: BackendDatabase;
type RoCursor: BackendRoCursor<'env>;

fn get<K>(&'env self, db: Self::Database, k: &K) -> Result<Option<Value<'env>>, StoreError>
fn get<K>(&'env self, db: &Self::Database, k: &K) -> Result<Option<Value<'env>>, StoreError>
where
K: AsRef<[u8]>;

fn open_ro_cursor(&'env self, db: Self::Database) -> Result<Self::RoCursor, StoreError>;
fn open_ro_cursor(&'env self, db: &Self::Database) -> Result<Self::RoCursor, StoreError>;
}

impl<'env, T> Readable<'env> for Reader<T>
Expand All @@ -41,15 +41,15 @@ where
type Database = T::Database;
type RoCursor = T::RoCursor;

fn get<K>(&'env self, db: T::Database, k: &K) -> Result<Option<Value<'env>>, StoreError>
fn get<K>(&'env self, db: &T::Database, k: &K) -> Result<Option<Value<'env>>, StoreError>
where
K: AsRef<[u8]>,
{
let bytes = self.0.get(db, k.as_ref()).map_err(|e| e.into());
read_transform(bytes)
}

fn open_ro_cursor(&'env self, db: T::Database) -> Result<T::RoCursor, StoreError> {
fn open_ro_cursor(&'env self, db: &T::Database) -> Result<T::RoCursor, StoreError> {
self.0.open_ro_cursor(db).map_err(|e| e.into())
}
}
Expand All @@ -76,15 +76,15 @@ where
type Database = T::Database;
type RoCursor = T::RoCursor;

fn get<K>(&'env self, db: T::Database, k: &K) -> Result<Option<Value<'env>>, StoreError>
fn get<K>(&'env self, db: &T::Database, k: &K) -> Result<Option<Value<'env>>, StoreError>
where
K: AsRef<[u8]>,
{
let bytes = self.0.get(db, k.as_ref()).map_err(|e| e.into());
read_transform(bytes)
}

fn open_ro_cursor(&'env self, db: T::Database) -> Result<T::RoCursor, StoreError> {
fn open_ro_cursor(&'env self, db: &T::Database) -> Result<T::RoCursor, StoreError> {
self.0.open_ro_cursor(db).map_err(|e| e.into())
}
}
Expand All @@ -107,22 +107,22 @@ where
self.0.abort();
}

pub(crate) fn put<K>(&mut self, db: T::Database, k: &K, v: &Value, flags: T::Flags) -> Result<(), StoreError>
pub(crate) fn put<K>(&mut self, db: &T::Database, k: &K, v: &Value, flags: T::Flags) -> Result<(), StoreError>
where
K: AsRef<[u8]>,
{
// TODO: don't allocate twice.
self.0.put(db, k.as_ref(), &v.to_bytes()?, flags).map_err(|e| e.into())
}

pub(crate) fn delete<K>(&mut self, db: T::Database, k: &K, v: Option<&[u8]>) -> Result<(), StoreError>
pub(crate) fn delete<K>(&mut self, db: &T::Database, k: &K, v: Option<&[u8]>) -> Result<(), StoreError>
where
K: AsRef<[u8]>,
{
self.0.del(db, k.as_ref(), v).map_err(|e| e.into())
}

pub(crate) fn clear(&mut self, db: T::Database) -> Result<(), StoreError> {
pub(crate) fn clear(&mut self, db: &T::Database) -> Result<(), StoreError> {
self.0.clear_db(db).map_err(|e| e.into())
}
}
29 changes: 14 additions & 15 deletions src/store/multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use crate::value::Value;

type EmptyResult = Result<(), StoreError>;

#[derive(Copy, Clone)]
pub struct MultiStore<D> {
db: D,
}
Expand All @@ -49,14 +48,14 @@ where
}

/// Provides a cursor to all of the values for the duplicate entries that match this key
pub fn get<'env, R, I, C, K>(self, reader: &'env R, k: K) -> Result<Iter<'env, I, C>, StoreError>
pub fn get<'env, R, I, C, K>(&self, reader: &'env R, k: K) -> Result<Iter<'env, I, C>, StoreError>
where
R: Readable<'env, Database = D, RoCursor = C>,
I: BackendIter<'env>,
C: BackendRoCursor<'env, Iter = I>,
K: AsRef<[u8]>,
{
let mut cursor = reader.open_ro_cursor(self.db)?;
let mut cursor = reader.open_ro_cursor(&self.db)?;
let iter = cursor.iter_dup_of(k);

Ok(Iter {
Expand All @@ -67,54 +66,54 @@ where
}

/// Provides the first value that matches this key
pub fn get_first<'env, R, K>(self, reader: &'env R, k: K) -> Result<Option<Value<'env>>, StoreError>
pub fn get_first<'env, R, K>(&self, reader: &'env R, k: K) -> Result<Option<Value<'env>>, StoreError>
where
R: Readable<'env, Database = D>,
K: AsRef<[u8]>,
{
reader.get(self.db, &k)
reader.get(&self.db, &k)
}

/// Insert a value at the specified key.
/// This put will allow duplicate entries. If you wish to have duplicate entries
/// rejected, use the `put_with_flags` function and specify NO_DUP_DATA
pub fn put<T, K>(self, writer: &mut Writer<T>, k: K, v: &Value) -> EmptyResult
pub fn put<T, K>(&self, writer: &mut Writer<T>, k: K, v: &Value) -> EmptyResult
where
T: BackendRwTransaction<Database = D>,
K: AsRef<[u8]>,
{
writer.put(self.db, &k, v, T::Flags::empty())
writer.put(&self.db, &k, v, T::Flags::empty())
}

pub fn put_with_flags<T, K>(self, writer: &mut Writer<T>, k: K, v: &Value, flags: T::Flags) -> EmptyResult
pub fn put_with_flags<T, K>(&self, writer: &mut Writer<T>, k: K, v: &Value, flags: T::Flags) -> EmptyResult
where
T: BackendRwTransaction<Database = D>,
K: AsRef<[u8]>,
{
writer.put(self.db, &k, v, flags)
writer.put(&self.db, &k, v, flags)
}

pub fn delete_all<T, K>(self, writer: &mut Writer<T>, k: K) -> EmptyResult
pub fn delete_all<T, K>(&self, writer: &mut Writer<T>, k: K) -> EmptyResult
where
T: BackendRwTransaction<Database = D>,
K: AsRef<[u8]>,
{
writer.delete(self.db, &k, None)
writer.delete(&self.db, &k, None)
}

pub fn delete<T, K>(self, writer: &mut Writer<T>, k: K, v: &Value) -> EmptyResult
pub fn delete<T, K>(&self, writer: &mut Writer<T>, k: K, v: &Value) -> EmptyResult
where
T: BackendRwTransaction<Database = D>,
K: AsRef<[u8]>,
{
writer.delete(self.db, &k, Some(&v.to_bytes()?))
writer.delete(&self.db, &k, Some(&v.to_bytes()?))
}

pub fn clear<T>(self, writer: &mut Writer<T>) -> EmptyResult
pub fn clear<T>(&self, writer: &mut Writer<T>) -> EmptyResult
where
T: BackendRwTransaction<Database = D>,
{
writer.clear(self.db)
writer.clear(&self.db)
}
}

Expand Down
Loading

0 comments on commit 2bb1436

Please sign in to comment.