summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Nazarewicz <mina86@mina86.com>2023-08-07 17:56:06 +0200
committerGitHub <noreply@github.com>2023-08-07 17:56:06 +0200
commit41512c03c2ad5f745cda08e2079db93cc340282c (patch)
treeb000d37fafedae02496816f2378c3d7e8bc28674
parentf8906c39ac26d51b4f5873370c8e214ff86fa02c (diff)
Wrap prop names into a PropName type offering free conversion to str (#780)
-rw-r--r--.github/workflows/rust.yml2
-rw-r--r--CHANGELOG.md18
-rw-r--r--Cargo.toml2
-rw-r--r--README.md22
-rw-r--r--librocksdb-sys/Cargo.toml2
-rw-r--r--src/lib.rs1
-rw-r--r--src/prop_name.rs324
-rw-r--r--src/properties.rs125
-rw-r--r--tests/test_property.rs4
9 files changed, 402 insertions, 98 deletions
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 25ad816..ac9a3d3 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -2,7 +2,7 @@ name: RocksDB CI
on: [push, pull_request]
env:
- RUST_VERSION: 1.60.0
+ RUST_VERSION: 1.63.0
jobs:
fmt:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6c487d..0d91541 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## [Unreleased]
+* Bump MSRV to 1.63.0 (mina86)
+* Convert properties to `&PropName` which can be converted at no cost to `&CStr`
+ and `&str` (mina86)
+
## 0.21.0 (2023-05-09)
* Add doc-check to CI with fix warnings in docs (YuraKotov)
@@ -109,10 +113,10 @@
* Bump `librocksdb-sys` up to 6.20.3 (olegnn, akrylysov)
* Add `DB::key_may_exist_cf_opt` method (stanislav-tkach)
* Add `Options::set_zstd_max_train_bytes` method (stanislav-tkach)
-* Mark Cache and Env as Send and Sync (akrylysov)
+* Mark Cache and Env as Send and Sync (akrylysov)
* Allow cloning the Cache and Env (duarten)
-* Make SSE inclusion conditional for target features (mbargull)
-* Use Self where possible (adamnemecek)
+* Make SSE inclusion conditional for target features (mbargull)
+* Use Self where possible (adamnemecek)
* Don't leak dropped column families (ryoqun)
## 0.16.0 (2021-04-18)
@@ -169,23 +173,23 @@
* Add `set_max_total_wal_size` to the `Options` (wqfish)
* Simplify conversion on iterator item (zhangsoledad)
* Add `flush_cf` method to the `DB` (wqfish)
-* Fix potential segfault when calling `next` on the `DBIterator` that is at the end of the range (wqfish)
+* Fix potential segfault when calling `next` on the `DBIterator` that is at the end of the range (wqfish)
* Move to Rust 2018 (wqfish)
* Fix doc for `WriteBatch::delete` (wqfish)
* Bump `uuid` and `bindgen` dependencies (jonhoo)
* Change APIs that never return error to not return `Result` (wqfish)
* Fix lifetime parameter for iterators (wqfish)
-* Add a doc for `optimize_level_style_compaction` method (NikVolf)
+* Add a doc for `optimize_level_style_compaction` method (NikVolf)
* Make `DBPath` use `tempfile` (jder)
* Refactor `db.rs` and `lib.rs` into smaller pieces (jder)
* Check if we're on a big endian system and act upon it (knarz)
* Bump internal snappy version up to 1.1.8 (aleksuss)
* Bump rocksdb version up to 6.7.3 (aleksuss)
-* Atomic flush option (mappum)
+* Atomic flush option (mappum)
* Make `set_iterate_upper_bound` method safe (wqfish)
* Add support for data block hash index (dvdplm)
* Add some extra config options (casualjim)
-* Add support for range delete APIs (wqfish)
+* Add support for range delete APIs (wqfish)
* Improve building `librocksdb-sys` with system libraries (basvandijk)
* Add support for `open_for_read_only` APIs (wqfish)
* Fix doc for `DBRawIterator::prev` and `next` methods (wqfish)
diff --git a/Cargo.toml b/Cargo.toml
index bab5dcb..7efbd95 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,7 +3,7 @@ name = "rocksdb"
description = "Rust wrapper for Facebook's RocksDB embeddable database"
version = "0.21.0"
edition = "2018"
-rust-version = "1.60"
+rust-version = "1.63"
authors = ["Tyler Neely <t@jujit.su>", "David Greenberg <dsg123456789@gmail.com>"]
repository = "https://github.com/rust-rocksdb/rust-rocksdb"
license = "Apache-2.0"
diff --git a/README.md b/README.md
index 8b59c94..f18f0f9 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ rust-rocksdb
[![documentation](https://docs.rs/rocksdb/badge.svg)](https://docs.rs/rocksdb)
[![license](https://img.shields.io/crates/l/rocksdb.svg)](https://github.com/rust-rocksdb/rust-rocksdb/blob/master/LICENSE)
[![Gitter chat](https://badges.gitter.im/rust-rocksdb/gitter.png)](https://gitter.im/rust-rocksdb/lobby)
-![rust 1.60.0 required](https://img.shields.io/badge/rust-1.60.0-blue.svg?label=MSRV)
+![rust 1.63.0 required](https://img.shields.io/badge/rust-1.63.0-blue.svg?label=MSRV)
![GitHub commits (since latest release)](https://img.shields.io/github/commits-since/rust-rocksdb/rust-rocksdb/latest.svg)
@@ -16,25 +16,25 @@ rust-rocksdb
## Contributing
-Feedback and pull requests welcome! If a particular feature of RocksDB is
-important to you, please let me know by opening an issue, and I'll
+Feedback and pull requests welcome! If a particular feature of RocksDB is
+important to you, please let me know by opening an issue, and I'll
prioritize it.
## Usage
-This binding is statically linked with a specific version of RocksDB. If you
-want to build it yourself, make sure you've also cloned the RocksDB and
+This binding is statically linked with a specific version of RocksDB. If you
+want to build it yourself, make sure you've also cloned the RocksDB and
compression submodules:
git submodule update --init --recursive
## Compression Support
-By default, support for the [Snappy](https://github.com/google/snappy),
-[LZ4](https://github.com/lz4/lz4), [Zstd](https://github.com/facebook/zstd),
-[Zlib](https://zlib.net), and [Bzip2](http://www.bzip.org) compression
-is enabled through crate features. If support for all of these compression
-algorithms is not needed, default features can be disabled and specific
-compression algorithms can be enabled. For example, to enable only LZ4
+By default, support for the [Snappy](https://github.com/google/snappy),
+[LZ4](https://github.com/lz4/lz4), [Zstd](https://github.com/facebook/zstd),
+[Zlib](https://zlib.net), and [Bzip2](http://www.bzip.org) compression
+is enabled through crate features. If support for all of these compression
+algorithms is not needed, default features can be disabled and specific
+compression algorithms can be enabled. For example, to enable only LZ4
compression support, make these changes to your Cargo.toml:
```
diff --git a/librocksdb-sys/Cargo.toml b/librocksdb-sys/Cargo.toml
index 57f6eb2..5a2bfc9 100644
--- a/librocksdb-sys/Cargo.toml
+++ b/librocksdb-sys/Cargo.toml
@@ -2,7 +2,7 @@
name = "librocksdb-sys"
version = "0.11.0+8.3.2"
edition = "2018"
-rust-version = "1.60"
+rust-version = "1.63"
authors = ["Karl Hobley <karlhobley10@gmail.com>", "Arkadiy Paronyan <arkadiy@ethcore.io>"]
license = "MIT/Apache-2.0/BSD-3-Clause"
description = "Native bindings to librocksdb"
diff --git a/src/lib.rs b/src/lib.rs
index 9de4b86..2e4f17f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -89,6 +89,7 @@ mod env;
mod iter_range;
pub mod merge_operator;
pub mod perf;
+mod prop_name;
pub mod properties;
mod slice_transform;
mod snapshot;
diff --git a/src/prop_name.rs b/src/prop_name.rs
new file mode 100644
index 0000000..0c8f717
--- /dev/null
+++ b/src/prop_name.rs
@@ -0,0 +1,324 @@
+use crate::ffi_util::CStrLike;
+
+use std::ffi::{CStr, CString};
+
+/// A borrowed name of a RocksDB property.
+///
+/// The value is guaranteed to be a nul-terminated UTF-8 string. This means it
+/// can be converted to [`CStr`] and [`str`] at zero cost.
+#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(transparent)]
+pub struct PropName(CStr);
+
+impl PropName {
+ /// Creates a new object from a nul-terminated string with no internal nul
+ /// bytes.
+ ///
+ /// Panics if the `value` isn’t terminated by a nul byte or contains
+ /// interior nul bytes.
+ pub(crate) const fn new_unwrap(value: &str) -> &Self {
+ let bytes = if let Some((&0, bytes)) = value.as_bytes().split_last() {
+ bytes
+ } else {
+ panic!("input was not nul-terminated");
+ };
+
+ let mut idx = 0;
+ while idx < bytes.len() {
+ assert!(bytes[idx] != 0, "input contained interior nul byte");
+ idx += 1;
+ }
+
+ // SAFETY: 1. We’ve just verified `value` is a nul-terminated with no
+ // interior nul bytes and since its `str` it’s also valid UTF-8.
+ // 2. Self and CStr have the same representation so casting is sound.
+ unsafe {
+ let value = CStr::from_bytes_with_nul_unchecked(value.as_bytes());
+ &*(value as *const CStr as *const Self)
+ }
+ }
+
+ /// Converts the value into a C string slice.
+ #[inline]
+ pub fn as_c_str(&self) -> &CStr {
+ &self.0
+ }
+
+ /// Converts the value into a string slice.
+ ///
+ /// Nul byte terminating the underlying C string is not included in the
+ /// returned slice.
+ #[inline]
+ pub fn as_str(&self) -> &str {
+ // SAFETY: self.0 is guaranteed to be valid ASCII string.
+ unsafe { std::str::from_utf8_unchecked(self.0.to_bytes()) }
+ }
+}
+
+impl core::ops::Deref for PropName {
+ type Target = CStr;
+
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ self.as_c_str()
+ }
+}
+
+impl core::convert::AsRef<CStr> for PropName {
+ #[inline]
+ fn as_ref(&self) -> &CStr {
+ self.as_c_str()
+ }
+}
+
+impl core::convert::AsRef<str> for PropName {
+ #[inline]
+ fn as_ref(&self) -> &str {
+ self.as_str()
+ }
+}
+
+impl std::borrow::ToOwned for PropName {
+ type Owned = PropertyName;
+
+ #[inline]
+ fn to_owned(&self) -> Self::Owned {
+ PropertyName(self.0.to_owned())
+ }
+
+ #[inline]
+ fn clone_into(&self, target: &mut Self::Owned) {
+ self.0.clone_into(&mut target.0);
+ }
+}
+
+impl core::fmt::Display for PropName {
+ #[inline]
+ fn fmt(&self, fmtr: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ self.as_str().fmt(fmtr)
+ }
+}
+
+impl core::fmt::Debug for PropName {
+ #[inline]
+ fn fmt(&self, fmtr: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ self.as_str().fmt(fmtr)
+ }
+}
+
+impl core::cmp::PartialEq<CStr> for PropName {
+ #[inline]
+ fn eq(&self, other: &CStr) -> bool {
+ self.as_c_str().eq(other)
+ }
+}
+
+impl core::cmp::PartialEq<str> for PropName {
+ #[inline]
+ fn eq(&self, other: &str) -> bool {
+ self.as_str().eq(other)
+ }
+}
+
+impl core::cmp::PartialEq<PropName> for CStr {
+ #[inline]
+ fn eq(&self, other: &PropName) -> bool {
+ self.eq(other.as_c_str())
+ }
+}
+
+impl core::cmp::PartialEq<PropName> for str {
+ #[inline]
+ fn eq(&self, other: &PropName) -> bool {
+ self.eq(other.as_str())
+ }
+}
+
+impl<'a> CStrLike for &'a PropName {
+ type Baked = &'a CStr;
+ type Error = std::convert::Infallible;
+
+ #[inline]
+ fn bake(self) -> Result<Self::Baked, Self::Error> {
+ Ok(&self.0)
+ }
+
+ #[inline]
+ fn into_c_string(self) -> Result<CString, Self::Error> {
+ Ok(self.0.to_owned())
+ }
+}
+
+/// An owned name of a RocksDB property.
+///
+/// The value is guaranteed to be a nul-terminated UTF-8 string. This means it
+/// can be converted to [`CString`] and [`String`] at zero cost.
+#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(transparent)]
+pub struct PropertyName(CString);
+
+impl PropertyName {
+ /// Creates a new object from valid nul-terminated UTF-8 string. The string
+ /// must not contain interior nul bytes.
+ #[inline]
+ unsafe fn from_vec_with_nul_unchecked(inner: Vec<u8>) -> Self {
+ // SAFETY: Caller promises inner is nul-terminated and valid UTF-8.
+ Self(CString::from_vec_with_nul_unchecked(inner))
+ }
+
+ /// Converts the value into a C string.
+ #[inline]
+ pub fn into_c_string(self) -> CString {
+ self.0
+ }
+
+ /// Converts the property name into a string.
+ ///
+ /// Nul byte terminating the underlying C string is not included in the
+ /// returned value.
+ #[inline]
+ pub fn into_string(self) -> String {
+ // SAFETY: self.0 is guaranteed to be valid UTF-8.
+ unsafe { String::from_utf8_unchecked(self.0.into_bytes()) }
+ }
+}
+
+impl std::ops::Deref for PropertyName {
+ type Target = PropName;
+
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ // SAFETY: 1. PropName and CStr have the same representation so casting
+ // is safe. 2. self.0 is guaranteed to be valid nul-terminated UTF-8
+ // string.
+ unsafe { &*(self.0.as_c_str() as *const CStr as *const PropName) }
+ }
+}
+
+impl core::convert::AsRef<CStr> for PropertyName {
+ #[inline]
+ fn as_ref(&self) -> &CStr {
+ self.as_c_str()
+ }
+}
+
+impl core::convert::AsRef<str> for PropertyName {
+ #[inline]
+ fn as_ref(&self) -> &str {
+ self.as_str()
+ }
+}
+
+impl std::borrow::Borrow<PropName> for PropertyName {
+ #[inline]
+ fn borrow(&self) -> &PropName {
+ self
+ }
+}
+
+impl core::fmt::Display for PropertyName {
+ #[inline]
+ fn fmt(&self, fmtr: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ self.as_str().fmt(fmtr)
+ }
+}
+
+impl core::fmt::Debug for PropertyName {
+ #[inline]
+ fn fmt(&self, fmtr: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ self.as_str().fmt(fmtr)
+ }
+}
+
+impl core::cmp::PartialEq<CString> for PropertyName {
+ #[inline]
+ fn eq(&self, other: &CString) -> bool {
+ self.as_c_str().eq(other.as_c_str())
+ }
+}
+
+impl core::cmp::PartialEq<String> for PropertyName {
+ #[inline]
+ fn eq(&self, other: &String) -> bool {
+ self.as_str().eq(other.as_str())
+ }
+}
+
+impl core::cmp::PartialEq<PropertyName> for CString {
+ #[inline]
+ fn eq(&self, other: &PropertyName) -> bool {
+ self.as_c_str().eq(other.as_c_str())
+ }
+}
+
+impl core::cmp::PartialEq<PropertyName> for String {
+ #[inline]
+ fn eq(&self, other: &PropertyName) -> bool {
+ self.as_str().eq(other.as_str())
+ }
+}
+
+impl CStrLike for PropertyName {
+ type Baked = CString;
+ type Error = std::convert::Infallible;
+
+ #[inline]
+ fn bake(self) -> Result<Self::Baked, Self::Error> {
+ Ok(self.0)
+ }
+
+ #[inline]
+ fn into_c_string(self) -> Result<CString, Self::Error> {
+ Ok(self.0)
+ }
+}
+
+impl<'a> CStrLike for &'a PropertyName {
+ type Baked = &'a CStr;
+ type Error = std::convert::Infallible;
+
+ #[inline]
+ fn bake(self) -> Result<Self::Baked, Self::Error> {
+ Ok(self.as_c_str())
+ }
+
+ #[inline]
+ fn into_c_string(self) -> Result<CString, Self::Error> {
+ Ok(self.0.clone())
+ }
+}
+
+/// Constructs a property name for an ‘at level’ property.
+///
+/// `name` is the infix of the property name (e.g. `"num-files-at-level"`) and
+/// `level` is level to get statistics of. The property name is constructed as
+/// `"rocksdb.<name><level>"`.
+///
+/// Expects `name` not to contain any interior nul bytes.
+pub(crate) unsafe fn level_property(name: &str, level: usize) -> PropertyName {
+ let bytes = format!("rocksdb.{name}{level}\0").into_bytes();
+ // SAFETY: We’re appending terminating nul and caller promises `name` has no
+ // interior nul bytes.
+ PropertyName::from_vec_with_nul_unchecked(bytes)
+}
+
+#[test]
+fn sanity_checks() {
+ let want = "rocksdb.cfstats-no-file-histogram";
+ assert_eq!(want, crate::properties::CFSTATS_NO_FILE_HISTOGRAM);
+
+ let want = "rocksdb.num-files-at-level5";
+ assert_eq!(want, &*crate::properties::num_files_at_level(5));
+}
+
+#[test]
+#[should_panic]
+fn test_interior_nul() {
+ PropName::new_unwrap("interior nul\0\0");
+}
+
+#[test]
+#[should_panic]
+fn test_non_nul_terminated() {
+ PropName::new_unwrap("no nul terminator");
+}
diff --git a/src/properties.rs b/src/properties.rs
index 0f70123..f80ca2d 100644
--- a/src/properties.rs
+++ b/src/properties.rs
@@ -3,22 +3,19 @@
//! Full list of valid properties and descriptions pulled from
//! [here](https:///github.com/facebook/rocksdb/blob/08809f5e6cd9cc4bc3958dd4d59457ae78c76660/include/rocksdb/db.h#L428-L634).
-use std::ffi::{CStr, CString};
+use crate::prop_name::level_property;
+pub use crate::prop_name::{PropName, PropertyName};
macro_rules! property {
($suffix: literal) => {
- // SAFETY: We’re appending terminating NUL byte and this macro is always
- // called with values without interior NUL bytes.
- unsafe {
- CStr::from_bytes_with_nul_unchecked(concat!("rocksdb.", $suffix, "\0").as_bytes())
- }
+ PropName::new_unwrap(concat!("rocksdb.", $suffix, "\0"))
};
}
/// "rocksdb.num-files-at-level<N>" - returns string containing the number
/// of files at level <N>, where <N> is an ASCII representation of a
/// level number (e.g., "0").
-pub fn num_files_at_level(level: usize) -> CString {
+pub fn num_files_at_level(level: usize) -> PropertyName {
unsafe { level_property("num-files-at-level", level) }
}
@@ -27,22 +24,22 @@ pub fn num_files_at_level(level: usize) -> CString {
/// representation of a level number (e.g., "0"). Here, compression
/// ratio is defined as uncompressed data size / compressed file size.
/// Returns "-1.0" if no open files at level <N>.
-pub fn compression_ratio_at_level(level: usize) -> CString {
+pub fn compression_ratio_at_level(level: usize) -> PropertyName {
unsafe { level_property("compression-ratio-at-level", level) }
}
/// "rocksdb.stats" - returns a multi-line string containing the data
/// described by kCFStats followed by the data described by kDBStats.
-pub const STATS: &CStr = property!("stats");
+pub const STATS: &PropName = property!("stats");
/// "rocksdb.sstables" - returns a multi-line string summarizing current
/// SST files.
-pub const SSTABLES: &CStr = property!("sstables");
+pub const SSTABLES: &PropName = property!("sstables");
/// "rocksdb.cfstats" - Both of "rocksdb.cfstats-no-file-histogram" and
/// "rocksdb.cf-file-histogram" together. See below for description
/// of the two.
-pub const CFSTATS: &CStr = property!("CFSTATS");
+pub const CFSTATS: &PropName = property!("CFSTATS");
/// "rocksdb.cfstats-no-file-histogram" - returns a multi-line string with
/// general columm family stats per-level over db's lifetime ("L<n>"),
@@ -52,200 +49,178 @@ pub const CFSTATS: &CStr = property!("CFSTATS");
/// In this case there will a pair of string to array of double for
/// each level as well as for "Sum". "Int" stats will not be affected
/// when this form of stats are retrieved.
-pub const CFSTATS_NO_FILE_HISTOGRAM: &CStr = property!("cfstats-no-file-histogram");
+pub const CFSTATS_NO_FILE_HISTOGRAM: &PropName = property!("cfstats-no-file-histogram");
/// "rocksdb.cf-file-histogram" - print out how many file reads to every
/// level, as well as the histogram of latency of single requests.
-pub const CF_FILE_HISTOGRAM: &CStr = property!("cf-file-histogram");
+pub const CF_FILE_HISTOGRAM: &PropName = property!("cf-file-histogram");
/// "rocksdb.dbstats" - returns a multi-line string with general database
/// stats, both cumulative (over the db's lifetime) and interval (since
/// the last retrieval of kDBStats).
-pub const DBSTATS: &CStr = property!("dbstats");
+pub const DBSTATS: &PropName = property!("dbstats");
/// "rocksdb.levelstats" - returns multi-line string containing the number
/// of files per level and total size of each level (MB).
-pub const LEVELSTATS: &CStr = property!("levelstats");
+pub const LEVELSTATS: &PropName = property!("levelstats");
/// "rocksdb.num-immutable-mem-table" - returns number of immutable
/// memtables that have not yet been flushed.
-pub const NUM_IMMUTABLE_MEM_TABLE: &CStr = property!("num-immutable-mem-table");
+pub const NUM_IMMUTABLE_MEM_TABLE: &PropName = property!("num-immutable-mem-table");
/// "rocksdb.num-immutable-mem-table-flushed" - returns number of immutable
/// memtables that have already been flushed.
-pub const NUM_IMMUTABLE_MEM_TABLE_FLUSHED: &CStr = property!("num-immutable-mem-table-flushed");
+pub const NUM_IMMUTABLE_MEM_TABLE_FLUSHED: &PropName = property!("num-immutable-mem-table-flushed");
/// "rocksdb.mem-table-flush-pending" - returns 1 if a memtable flush is
/// pending; otherwise, returns 0.
-pub const MEM_TABLE_FLUSH_PENDING: &CStr = property!("mem-table-flush-pending");
+pub const MEM_TABLE_FLUSH_PENDING: &PropName = property!("mem-table-flush-pending");
/// "rocksdb.num-running-flushes" - returns the number of currently running
/// flushes.
-pub const NUM_RUNNING_FLUSHES: &CStr = property!("num-running-flushes");
+pub const NUM_RUNNING_FLUSHES: &PropName = property!("num-running-flushes");
/// "rocksdb.compaction-pending" - returns 1 if at least one compaction is
/// pending; otherwise, returns 0.
-pub const COMPACTION_PENDING: &CStr = property!("compaction-pending");
+pub const COMPACTION_PENDING: &PropName = property!("compaction-pending");
/// "rocksdb.num-running-compactions" - returns the number of currently
/// running compactions.
-pub const NUM_RUNNING_COMPACTIONS: &CStr = property!("num-running-compactions");
+pub const NUM_RUNNING_COMPACTIONS: &PropName = property!("num-running-compactions");
/// "rocksdb.background-errors" - returns accumulated number of background
/// errors.
-pub const BACKGROUND_ERRORS: &CStr = property!("background-errors");
+pub const BACKGROUND_ERRORS: &PropName = property!("background-errors");
/// "rocksdb.cur-size-active-mem-table" - returns approximate size of active
/// memtable (bytes).
-pub const CUR_SIZE_ACTIVE_MEM_TABLE: &CStr = property!("cur-size-active-mem-table");
+pub const CUR_SIZE_ACTIVE_MEM_TABLE: &PropName = property!("cur-size-active-mem-table");
/// "rocksdb.cur-size-all-mem-tables" - returns approximate size of active
/// and unflushed immutable memtables (bytes).
-pub const CUR_SIZE_ALL_MEM_TABLES: &CStr = property!("cur-size-all-mem-tables");
+pub const CUR_SIZE_ALL_MEM_TABLES: &PropName = property!("cur-size-all-mem-tables");
/// "rocksdb.size-all-mem-tables" - returns approximate size of active,
/// unflushed immutable, and pinned immutable memtables (bytes).
-pub const SIZE_ALL_MEM_TABLES: &CStr = property!("size-all-mem-tables");
+pub const SIZE_ALL_MEM_TABLES: &PropName = property!("size-all-mem-tables");
/// "rocksdb.num-entries-active-mem-table" - returns total number of entries
/// in the active memtable.
-pub const NUM_ENTRIES_ACTIVE_MEM_TABLE: &CStr = property!("num-entries-active-mem-table");
+pub const NUM_ENTRIES_ACTIVE_MEM_TABLE: &PropName = property!("num-entries-active-mem-table");
/// "rocksdb.num-entries-imm-mem-tables" - returns total number of entries
/// in the unflushed immutable memtables.
-pub const NUM_ENTRIES_IMM_MEM_TABLES: &CStr = property!("num-entries-imm-mem-tables");
+pub const NUM_ENTRIES_IMM_MEM_TABLES: &PropName = property!("num-entries-imm-mem-tables");
/// "rocksdb.num-deletes-active-mem-table" - returns total number of delete
/// entries in the active memtable.
-pub const NUM_DELETES_ACTIVE_MEM_TABLE: &CStr = property!("num-deletes-active-mem-table");
+pub const NUM_DELETES_ACTIVE_MEM_TABLE: &PropName = property!("num-deletes-active-mem-table");
/// "rocksdb.num-deletes-imm-mem-tables" - returns total number of delete
/// entries in the unflushed immutable memtables.
-pub const NUM_DELETES_IMM_MEM_TABLES: &CStr = property!("num-deletes-imm-mem-tables");
+pub const NUM_DELETES_IMM_MEM_TABLES: &PropName = property!("num-deletes-imm-mem-tables");
/// "rocksdb.estimate-num-keys" - returns estimated number of total keys in
/// the active and unflushed immutable memtables and storage.
-pub const ESTIMATE_NUM_KEYS: &CStr = property!("estimate-num-keys");
+pub const ESTIMATE_NUM_KEYS: &PropName = property!("estimate-num-keys");
/// "rocksdb.estimate-table-readers-mem" - returns estimated memory used for
/// reading SST tables, excluding memory used in block cache (e.g.,
/// filter and index blocks).
-pub const ESTIMATE_TABLE_READERS_MEM: &CStr = property!("estimate-table-readers-mem");
+pub const ESTIMATE_TABLE_READERS_MEM: &PropName = property!("estimate-table-readers-mem");
/// "rocksdb.is-file-deletions-enabled" - returns 0 if deletion of obsolete
/// files is enabled; otherwise, returns a non-zero number.
-pub const IS_FILE_DELETIONS_ENABLED: &CStr = property!("is-file-deletions-enabled");
+pub const IS_FILE_DELETIONS_ENABLED: &PropName = property!("is-file-deletions-enabled");
/// "rocksdb.num-snapshots" - returns number of unreleased snapshots of the
/// database.
-pub const NUM_SNAPSHOTS: &CStr = property!("num-snapshots");
+pub const NUM_SNAPSHOTS: &PropName = property!("num-snapshots");
/// "rocksdb.oldest-snapshot-time" - returns number representing unix
/// timestamp of oldest unreleased snapshot.
-pub const OLDEST_SNAPSHOT_TIME: &CStr = property!("oldest-snapshot-time");
+pub const OLDEST_SNAPSHOT_TIME: &PropName = property!("oldest-snapshot-time");
/// "rocksdb.num-live-versions" - returns number of live versions. `Version`
/// is an internal data structure. See version_set.h for details. More
/// live versions often mean more SST files are held from being deleted,
/// by iterators or unfinished compactions.
-pub const NUM_LIVE_VERSIONS: &CStr = property!("num-live-versions");
+pub const NUM_LIVE_VERSIONS: &PropName = property!("num-live-versions");
/// "rocksdb.current-super-version-number" - returns number of current LSM
/// version. It is a uint64_t integer number, incremented after there is
/// any change to the LSM tree. The number is not preserved after restarting
/// the DB. After DB restart, it will start from 0 again.
-pub const CURRENT_SUPER_VERSION_NUMBER: &CStr = property!("current-super-version-number");
+pub const CURRENT_SUPER_VERSION_NUMBER: &PropName = property!("current-super-version-number");
/// "rocksdb.estimate-live-data-size" - returns an estimate of the amount of
/// live data in bytes.
-pub const ESTIMATE_LIVE_DATA_SIZE: &CStr = property!("estimate-live-data-size");
+pub const ESTIMATE_LIVE_DATA_SIZE: &PropName = property!("estimate-live-data-size");
/// "rocksdb.min-log-number-to-keep" - return the minimum log number of the
/// log files that should be kept.
-pub const MIN_LOG_NUMBER_TO_KEEP: &CStr = property!("min-log-number-to-keep");
+pub const MIN_LOG_NUMBER_TO_KEEP: &PropName = property!("min-log-number-to-keep");
/// "rocksdb.min-obsolete-sst-number-to-keep" - return the minimum file
/// number for an obsolete SST to be kept. The max value of `uint64_t`
/// will be returned if all obsolete files can be deleted.
-pub const MIN_OBSOLETE_SST_NUMBER_TO_KEEP: &CStr = property!("min-obsolete-sst-number-to-keep");
+pub const MIN_OBSOLETE_SST_NUMBER_TO_KEEP: &PropName = property!("min-obsolete-sst-number-to-keep");
/// "rocksdb.total-sst-files-size" - returns total size (bytes) of all SST
/// files.
/// WARNING: may slow down online queries if there are too many files.
-pub const TOTAL_SST_FILES_SIZE: &CStr = property!("total-sst-files-size");
+pub const TOTAL_SST_FILES_SIZE: &PropName = property!("total-sst-files-size");
/// "rocksdb.live-sst-files-size" - returns total size (bytes) of all SST
/// files belong to the latest LSM tree.
-pub const LIVE_SST_FILES_SIZE: &CStr = property!("live-sst-files-size");
+pub const LIVE_SST_FILES_SIZE: &PropName = property!("live-sst-files-size");
/// "rocksdb.base-level" - returns number of level to which L0 data will be
/// compacted.
-pub const BASE_LEVEL: &CStr = property!("base-level");
+pub const BASE_LEVEL: &PropName = property!("base-level");
/// "rocksdb.estimate-pending-compaction-bytes" - returns estimated total
/// number of bytes compaction needs to rewrite to get all levels down
/// to under target size. Not valid for other compactions than level-
/// based.
-pub const ESTIMATE_PENDING_COMPACTION_BYTES: &CStr = property!("estimate-pending-compaction-bytes");
+pub const ESTIMATE_PENDING_COMPACTION_BYTES: &PropName =
+ property!("estimate-pending-compaction-bytes");
/// "rocksdb.aggregated-table-properties" - returns a string representation
/// of the aggregated table properties of the target column family.
-pub const AGGREGATED_TABLE_PROPERTIES: &CStr = property!("aggregated-table-properties");
+pub const AGGREGATED_TABLE_PROPERTIES: &PropName = property!("aggregated-table-properties");
/// "rocksdb.aggregated-table-properties-at-level<N>", same as the previous
/// one but only returns the aggregated table properties of the
/// specified level "N" at the target column family.
-pub fn aggregated_table_properties_at_level(level: usize) -> CString {
+pub fn aggregated_table_properties_at_level(level: usize) -> PropertyName {
unsafe { level_property("aggregated-table-properties-at-level", level) }
}
/// "rocksdb.actual-delayed-write-rate" - returns the current actual delayed
/// write rate. 0 means no delay.
-pub const ACTUAL_DELAYED_WRITE_RATE: &CStr = property!("actual-delayed-write-rate");
+pub const ACTUAL_DELAYED_WRITE_RATE: &PropName = property!("actual-delayed-write-rate");
/// "rocksdb.is-write-stopped" - Return 1 if write has been stopped.
-pub const IS_WRITE_STOPPED: &CStr = property!("is-write-stopped");
+pub const IS_WRITE_STOPPED: &PropName = property!("is-write-stopped");
/// "rocksdb.estimate-oldest-key-time" - returns an estimation of
/// oldest key timestamp in the DB. Currently only available for
/// FIFO compaction with
/// compaction_options_fifo.allow_compaction = false.
-pub const ESTIMATE_OLDEST_KEY_TIME: &CStr = property!("estimate-oldest-key-time");
+pub const ESTIMATE_OLDEST_KEY_TIME: &PropName = property!("estimate-oldest-key-time");
/// "rocksdb.block-cache-capacity" - returns block cache capacity.
-pub const BLOCK_CACHE_CAPACITY: &CStr = property!("block-cache-capacity");
+pub const BLOCK_CACHE_CAPACITY: &PropName = property!("block-cache-capacity");
/// "rocksdb.block-cache-usage" - returns the memory size for the entries
/// residing in block cache.
-pub const BLOCK_CACHE_USAGE: &CStr = property!("block-cache-usage");
+pub const BLOCK_CACHE_USAGE: &PropName = property!("block-cache-usage");
/// "rocksdb.block-cache-pinned-usage" - returns the memory size for the
/// entries being pinned.
-pub const BLOCK_CACHE_PINNED_USAGE: &CStr = property!("block-cache-pinned-usage");
+pub const BLOCK_CACHE_PINNED_USAGE: &PropName = property!("block-cache-pinned-usage");
/// "rocksdb.options-statistics" - returns multi-line string
/// of options.statistics
-pub const OPTIONS_STATISTICS: &CStr = property!("options-statistics");
-
-/// Constructs a property name for an ‘at level’ property.
-///
-/// `name` is the infix of the property name (e.g. `"num-files-at-level"`) and
-/// `level` is level to get statistics of. The property name is constructed as
-/// `"rocksdb.<name><level>"`.
-///
-/// Expects `name` not to contain any interior NUL bytes.
-unsafe fn level_property(name: &str, level: usize) -> CString {
- let bytes = format!("rocksdb.{name}{level}\0").into_bytes();
- // SAFETY: We’re appending terminating NUL and all our call sites pass
- // a string without interior NUL bytes.
- CString::from_vec_with_nul_unchecked(bytes)
-}
-
-#[test]
-fn sanity_checks() {
- let want = CString::new("rocksdb.cfstats-no-file-histogram".to_string()).unwrap();
- assert_eq!(want.as_c_str(), CFSTATS_NO_FILE_HISTOGRAM);
-
- let want = CString::new("rocksdb.num-files-at-level5".to_string()).unwrap();
- assert_eq!(want, num_files_at_level(5));
-}
+pub const OPTIONS_STATISTICS: &PropName = property!("options-statistics");
diff --git a/tests/test_property.rs b/tests/test_property.rs
index 5225305..9782bd2 100644
--- a/tests/test_property.rs
+++ b/tests/test_property.rs
@@ -31,14 +31,14 @@ fn property_test() {
{
let db = DB::open_default(&n).unwrap();
- let prop_name: std::ffi::CString = properties::STATS.to_owned();
+ let prop_name: properties::PropertyName = properties::STATS.to_owned();
let value = db.property_value(&prop_name).unwrap().unwrap();
assert!(value.contains("Stats"));
}
{
let db = DB::open_default(&n).unwrap();
- let prop_name: String = properties::STATS.to_owned().into_string().unwrap();
+ let prop_name: String = properties::STATS.to_owned().into_string();
let value = db.property_value(&prop_name).unwrap().unwrap();
assert!(value.contains("Stats"));
}