From 248b40b4659c4f300b46a0948b3fc175d321c397 Mon Sep 17 00:00:00 2001 From: Jordan Terrell Date: Sun, 27 Jan 2019 20:28:30 -0600 Subject: [PATCH] Adding lifetime to ColumnFamily... --- src/db.rs | 28 ++++++++++++++++++++-------- src/lib.rs | 8 +++++--- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/db.rs b/src/db.rs index 2a620cd..44701fb 100644 --- a/src/db.rs +++ b/src/db.rs @@ -22,6 +22,7 @@ use std::collections::BTreeMap; use std::ffi::{CStr, CString}; use std::fmt; use std::fs; +use std::marker::PhantomData; use std::ops::Deref; use std::path::Path; use std::ptr; @@ -699,7 +700,7 @@ impl DB { for (n, h) in cfs_v.iter().zip(cfhandles) { cf_map.write() .map_err(|e| Error::new(e.to_string()))? - .insert(n.name.clone(), ColumnFamily { inner: h }); + .insert(n.name.clone(), h); } } @@ -866,15 +867,19 @@ impl DB { } }; let cf = unsafe { - let cf_handler = ffi_try!(ffi::rocksdb_create_column_family( + let cf_handle = ffi_try!(ffi::rocksdb_create_column_family( self.inner, opts.inner, cname.as_ptr(), )); - let cf = ColumnFamily { inner: cf_handler }; + self.cfs.write().map_err(|e| Error::new(e.to_string()))? - .insert(name.to_string(), cf); - cf + .insert(name.to_string(), cf_handle); + + ColumnFamily { + inner: cf_handle, + db: PhantomData, + } }; Ok(cf) } @@ -883,7 +888,7 @@ impl DB { if let Some(cf) = self.cfs.write().map_err(|e| Error::new(e.to_string()))? .remove(name) { unsafe { - ffi_try!(ffi::rocksdb_drop_column_family(self.inner, cf.inner,)); + ffi_try!(ffi::rocksdb_drop_column_family(self.inner, cf,)); } Ok(()) } else { @@ -895,7 +900,14 @@ impl DB { /// Return the underlying column family handle. pub fn cf_handle(&self, name: &str) -> Option { - self.cfs.read().ok()?.get(name).cloned() + self.cfs + .read() + .ok()? + .get(name) + .map(|h| ColumnFamily { + inner: *h, + db: PhantomData + }) } pub fn iterator(&self, mode: IteratorMode) -> DBIterator { @@ -1269,7 +1281,7 @@ impl Drop for DB { unsafe { if let Ok(cfs) = self.cfs.read() { for cf in cfs.values() { - ffi::rocksdb_column_family_handle_destroy(cf.inner); + ffi::rocksdb_column_family_handle_destroy(*cf); } } ffi::rocksdb_close(self.inner); diff --git a/src/lib.rs b/src/lib.rs index a0c1672..666be5b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,6 +73,7 @@ pub use merge_operator::MergeOperands; use std::collections::BTreeMap; use std::error; use std::fmt; +use std::marker::PhantomData; use std::path::PathBuf; use std::sync::{Arc, RwLock}; @@ -81,7 +82,7 @@ use std::sync::{Arc, RwLock}; /// See crate level documentation for a simple usage example. pub struct DB { inner: *mut ffi::rocksdb_t, - cfs: Arc>>, + cfs: Arc>>, path: PathBuf, } @@ -233,8 +234,9 @@ pub struct WriteOptions { /// An opaque type used to represent a column family. Returned from some functions, and used /// in others #[derive(Copy, Clone)] -pub struct ColumnFamily { +pub struct ColumnFamily<'a> { inner: *mut ffi::rocksdb_column_family_handle_t, + db: PhantomData<&'a DB>, } -unsafe impl Send for ColumnFamily {} +unsafe impl<'a> Send for ColumnFamily<'a> {}