Skip to content

Commit 0b700fe

Browse files
authored
Remove need for &mut self in create_cf and drop_cf (v2) (#506)
1 parent bc59596 commit 0b700fe

14 files changed

Lines changed: 589 additions & 229 deletions

.github/workflows/rust.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,14 @@ jobs:
8888
with:
8989
command: test
9090
args: --manifest-path=librocksdb-sys/Cargo.toml
91-
- name: Run rocksdb tests
91+
- name: Run rocksdb tests (single-threaded cf)
9292
uses: actions-rs/cargo@v1
9393
with:
9494
command: test
95+
- name: Run rocksdb tests (multi-threaded cf)
96+
uses: actions-rs/cargo@v1
97+
env:
98+
RUSTFLAGS: -Awarnings # Suppress "variable does not need to be mutable" warnings
99+
with:
100+
command: test
101+
args: --features multi-threaded-cf

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ lz4 = ["librocksdb-sys/lz4"]
2424
zstd = ["librocksdb-sys/zstd"]
2525
zlib = ["librocksdb-sys/zlib"]
2626
bzip2 = ["librocksdb-sys/bzip2"]
27+
multi-threaded-cf = []
2728

2829
[dependencies]
2930
libc = "0.2"

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,12 @@ compression support, make these changes to your Cargo.toml:
4242
default-features = false
4343
features = ["lz4"]
4444
```
45+
46+
## Multi-threaded ColumnFamily alternation
47+
48+
The underlying RocksDB does allow column families to be created and dropped
49+
from multiple threads concurrently. But this crate doesn't allow it by default
50+
for compatibility. If you need to modify column families concurrently, enable
51+
crate feature called `multi-threaded-cf`, which makes this binding's
52+
data structures to use RwLock by default. Alternatively, you can directly create
53+
`DBWithThreadMode<MultiThreaded>` without enabling the crate feature.

src/backup.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ impl Default for BackupEngineOptions {
235235
unsafe {
236236
let opts = ffi::rocksdb_options_create();
237237
if opts.is_null() {
238-
panic!("Could not create RocksDB backup options".to_owned());
238+
panic!("Could not create RocksDB backup options");
239239
}
240240
BackupEngineOptions { inner: opts }
241241
}
@@ -247,7 +247,7 @@ impl Default for RestoreOptions {
247247
unsafe {
248248
let opts = ffi::rocksdb_restore_options_create();
249249
if opts.is_null() {
250-
panic!("Could not create RocksDB restore options".to_owned());
250+
panic!("Could not create RocksDB restore options");
251251
}
252252
RestoreOptions { inner: opts }
253253
}

src/column_family.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use crate::{ffi, Options};
15+
use crate::{db::MultiThreaded, ffi, Options};
1616

1717
/// The name of the default column family.
1818
///
@@ -47,4 +47,42 @@ pub struct ColumnFamily {
4747
pub(crate) inner: *mut ffi::rocksdb_column_family_handle_t,
4848
}
4949

50+
/// A specialized opaque type used to represent a column family by the [`MultiThreaded`]
51+
/// mode. Clone (and Copy) is derived to behave like `&ColumnFamily` (this is used for
52+
/// single-threaded mode). `Clone`/`Copy` is safe because this lifetime is bound to DB like
53+
/// iterators/snapshots. On top of it, this is as cheap and small as `&ColumnFamily` because
54+
/// this only has a single pointer-wide field.
55+
#[derive(Clone, Copy)]
56+
pub struct BoundColumnFamily<'a> {
57+
pub(crate) inner: *mut ffi::rocksdb_column_family_handle_t,
58+
pub(crate) multi_threaded_cfs: std::marker::PhantomData<&'a MultiThreaded>,
59+
}
60+
61+
/// Handy type alias to hide actual type difference to reference [`ColumnFamily`]
62+
/// depending on the `multi-threaded-cf` crate feature.
63+
#[cfg(not(feature = "multi-threaded-cf"))]
64+
pub type ColumnFamilyRef<'a> = &'a ColumnFamily;
65+
66+
#[cfg(feature = "multi-threaded-cf")]
67+
pub type ColumnFamilyRef<'a> = BoundColumnFamily<'a>;
68+
69+
/// Utility trait to accept both supported references to `ColumnFamily`
70+
/// (`&ColumnFamily` and `BoundColumnFamily`)
71+
pub trait AsColumnFamilyRef {
72+
fn inner(&self) -> *mut ffi::rocksdb_column_family_handle_t;
73+
}
74+
75+
impl<'a> AsColumnFamilyRef for &'a ColumnFamily {
76+
fn inner(&self) -> *mut ffi::rocksdb_column_family_handle_t {
77+
self.inner
78+
}
79+
}
80+
81+
impl<'a> AsColumnFamilyRef for BoundColumnFamily<'a> {
82+
fn inner(&self) -> *mut ffi::rocksdb_column_family_handle_t {
83+
self.inner
84+
}
85+
}
86+
5087
unsafe impl Send for ColumnFamily {}
88+
unsafe impl<'a> Send for BoundColumnFamily<'a> {}

0 commit comments

Comments
 (0)