Skip to content

Commit

Permalink
Remove need for &mut self in create_cf and drop_cf (v2) (#506)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryoqun committed Apr 6, 2021
1 parent bc59596 commit 0b700fe
Show file tree
Hide file tree
Showing 14 changed files with 589 additions and 229 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/rust.yml
Expand Up @@ -88,7 +88,14 @@ jobs:
with:
command: test
args: --manifest-path=librocksdb-sys/Cargo.toml
- name: Run rocksdb tests
- name: Run rocksdb tests (single-threaded cf)
uses: actions-rs/cargo@v1
with:
command: test
- name: Run rocksdb tests (multi-threaded cf)
uses: actions-rs/cargo@v1
env:
RUSTFLAGS: -Awarnings # Suppress "variable does not need to be mutable" warnings
with:
command: test
args: --features multi-threaded-cf
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -24,6 +24,7 @@ lz4 = ["librocksdb-sys/lz4"]
zstd = ["librocksdb-sys/zstd"]
zlib = ["librocksdb-sys/zlib"]
bzip2 = ["librocksdb-sys/bzip2"]
multi-threaded-cf = []

[dependencies]
libc = "0.2"
Expand Down
9 changes: 9 additions & 0 deletions README.md
Expand Up @@ -42,3 +42,12 @@ compression support, make these changes to your Cargo.toml:
default-features = false
features = ["lz4"]
```

## Multi-threaded ColumnFamily alternation

The underlying RocksDB does allow column families to be created and dropped
from multiple threads concurrently. But this crate doesn't allow it by default
for compatibility. If you need to modify column families concurrently, enable
crate feature called `multi-threaded-cf`, which makes this binding's
data structures to use RwLock by default. Alternatively, you can directly create
`DBWithThreadMode<MultiThreaded>` without enabling the crate feature.
4 changes: 2 additions & 2 deletions src/backup.rs
Expand Up @@ -235,7 +235,7 @@ impl Default for BackupEngineOptions {
unsafe {
let opts = ffi::rocksdb_options_create();
if opts.is_null() {
panic!("Could not create RocksDB backup options".to_owned());
panic!("Could not create RocksDB backup options");
}
BackupEngineOptions { inner: opts }
}
Expand All @@ -247,7 +247,7 @@ impl Default for RestoreOptions {
unsafe {
let opts = ffi::rocksdb_restore_options_create();
if opts.is_null() {
panic!("Could not create RocksDB restore options".to_owned());
panic!("Could not create RocksDB restore options");
}
RestoreOptions { inner: opts }
}
Expand Down
40 changes: 39 additions & 1 deletion src/column_family.rs
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::{ffi, Options};
use crate::{db::MultiThreaded, ffi, Options};

/// The name of the default column family.
///
Expand Down Expand Up @@ -47,4 +47,42 @@ pub struct ColumnFamily {
pub(crate) inner: *mut ffi::rocksdb_column_family_handle_t,
}

/// A specialized opaque type used to represent a column family by the [`MultiThreaded`]
/// mode. Clone (and Copy) is derived to behave like `&ColumnFamily` (this is used for
/// single-threaded mode). `Clone`/`Copy` is safe because this lifetime is bound to DB like
/// iterators/snapshots. On top of it, this is as cheap and small as `&ColumnFamily` because
/// this only has a single pointer-wide field.
#[derive(Clone, Copy)]
pub struct BoundColumnFamily<'a> {
pub(crate) inner: *mut ffi::rocksdb_column_family_handle_t,
pub(crate) multi_threaded_cfs: std::marker::PhantomData<&'a MultiThreaded>,
}

/// Handy type alias to hide actual type difference to reference [`ColumnFamily`]
/// depending on the `multi-threaded-cf` crate feature.
#[cfg(not(feature = "multi-threaded-cf"))]
pub type ColumnFamilyRef<'a> = &'a ColumnFamily;

#[cfg(feature = "multi-threaded-cf")]
pub type ColumnFamilyRef<'a> = BoundColumnFamily<'a>;

/// Utility trait to accept both supported references to `ColumnFamily`
/// (`&ColumnFamily` and `BoundColumnFamily`)
pub trait AsColumnFamilyRef {
fn inner(&self) -> *mut ffi::rocksdb_column_family_handle_t;
}

impl<'a> AsColumnFamilyRef for &'a ColumnFamily {
fn inner(&self) -> *mut ffi::rocksdb_column_family_handle_t {
self.inner
}
}

impl<'a> AsColumnFamilyRef for BoundColumnFamily<'a> {
fn inner(&self) -> *mut ffi::rocksdb_column_family_handle_t {
self.inner
}
}

unsafe impl Send for ColumnFamily {}
unsafe impl<'a> Send for BoundColumnFamily<'a> {}

0 comments on commit 0b700fe

Please sign in to comment.