Skip to content

Commit e26428b

Browse files
authored
Convert properties to &CStr (tikv#643)
1 parent e99a12b commit e26428b

File tree

2 files changed

+88
-53
lines changed

2 files changed

+88
-53
lines changed

src/properties.rs

Lines changed: 82 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,46 @@
33
//! Full list of valid properties and descriptions pulled from
44
//! [here](https:///github.com/facebook/rocksdb/blob/08809f5e6cd9cc4bc3958dd4d59457ae78c76660/include/rocksdb/db.h#L428-L634).
55
6+
use std::ffi::{CStr, CString};
7+
68
macro_rules! property {
79
($suffix: literal) => {
8-
concat!("rocksdb.", $suffix)
10+
// SAFETY: We’re appending terminating NUL byte and this macro is always
11+
// called with values without interior NUL bytes.
12+
unsafe {
13+
CStr::from_bytes_with_nul_unchecked(concat!("rocksdb.", $suffix, "\0").as_bytes())
14+
}
915
};
1016
}
1117

1218
/// "rocksdb.num-files-at-level<N>" - returns string containing the number
1319
/// of files at level <N>, where <N> is an ASCII representation of a
1420
/// level number (e.g., "0").
15-
pub const NUM_FILES_AT_LEVEL_PREFIX: &str = property!("num-files-at-level");
21+
pub fn num_files_at_level(level: usize) -> CString {
22+
unsafe { level_property("num-files-at-level", level) }
23+
}
1624

1725
/// "rocksdb.compression-ratio-at-level<N>" - returns string containing the
1826
/// compression ratio of data at level <N>, where <N> is an ASCII
1927
/// representation of a level number (e.g., "0"). Here, compression
2028
/// ratio is defined as uncompressed data size / compressed file size.
2129
/// Returns "-1.0" if no open files at level <N>.
22-
pub const COMPRESSION_RATIO_AT_LEVEL: &str = property!("compression-ratio-at-level");
30+
pub fn compression_ratio_at_level(level: usize) -> CString {
31+
unsafe { level_property("compression-ratio-at-level", level) }
32+
}
2333

2434
/// "rocksdb.stats" - returns a multi-line string containing the data
2535
/// described by kCFStats followed by the data described by kDBStats.
26-
pub const STATS: &str = property!("stats");
36+
pub const STATS: &CStr = property!("stats");
2737

2838
/// "rocksdb.sstables" - returns a multi-line string summarizing current
2939
/// SST files.
30-
pub const SSTABLES: &str = property!("sstables");
40+
pub const SSTABLES: &CStr = property!("sstables");
3141

3242
/// "rocksdb.cfstats" - Both of "rocksdb.cfstats-no-file-histogram" and
3343
/// "rocksdb.cf-file-histogram" together. See below for description
3444
/// of the two.
35-
pub const CFSTATS: &str = property!("CFSTATS");
45+
pub const CFSTATS: &CStr = property!("CFSTATS");
3646

3747
/// "rocksdb.cfstats-no-file-histogram" - returns a multi-line string with
3848
/// general columm family stats per-level over db's lifetime ("L<n>"),
@@ -42,176 +52,200 @@ pub const CFSTATS: &str = property!("CFSTATS");
4252
/// In this case there will a pair of string to array of double for
4353
/// each level as well as for "Sum". "Int" stats will not be affected
4454
/// when this form of stats are retrieved.
45-
pub const CFSTATS_NO_FILE_HISTOGRAM: &str = property!("cfstats-no-file-histogram");
55+
pub const CFSTATS_NO_FILE_HISTOGRAM: &CStr = property!("cfstats-no-file-histogram");
4656

4757
/// "rocksdb.cf-file-histogram" - print out how many file reads to every
4858
/// level, as well as the histogram of latency of single requests.
49-
pub const CF_FILE_HISTOGRAM: &str = property!("cf-file-histogram");
59+
pub const CF_FILE_HISTOGRAM: &CStr = property!("cf-file-histogram");
5060

5161
/// "rocksdb.dbstats" - returns a multi-line string with general database
5262
/// stats, both cumulative (over the db's lifetime) and interval (since
5363
/// the last retrieval of kDBStats).
54-
pub const DBSTATS: &str = property!("dbstats");
64+
pub const DBSTATS: &CStr = property!("dbstats");
5565

5666
/// "rocksdb.levelstats" - returns multi-line string containing the number
5767
/// of files per level and total size of each level (MB).
58-
pub const LEVELSTATS: &str = property!("levelstats");
68+
pub const LEVELSTATS: &CStr = property!("levelstats");
5969

6070
/// "rocksdb.num-immutable-mem-table" - returns number of immutable
6171
/// memtables that have not yet been flushed.
62-
pub const NUM_IMMUTABLE_MEM_TABLE: &str = property!("num-immutable-mem-table");
72+
pub const NUM_IMMUTABLE_MEM_TABLE: &CStr = property!("num-immutable-mem-table");
6373

6474
/// "rocksdb.num-immutable-mem-table-flushed" - returns number of immutable
6575
/// memtables that have already been flushed.
66-
pub const NUM_IMMUTABLE_MEM_TABLE_FLUSHED: &str = property!("num-immutable-mem-table-flushed");
76+
pub const NUM_IMMUTABLE_MEM_TABLE_FLUSHED: &CStr = property!("num-immutable-mem-table-flushed");
6777

6878
/// "rocksdb.mem-table-flush-pending" - returns 1 if a memtable flush is
6979
/// pending; otherwise, returns 0.
70-
pub const MEM_TABLE_FLUSH_PENDING: &str = property!("mem-table-flush-pending");
80+
pub const MEM_TABLE_FLUSH_PENDING: &CStr = property!("mem-table-flush-pending");
7181

7282
/// "rocksdb.num-running-flushes" - returns the number of currently running
7383
/// flushes.
74-
pub const NUM_RUNNING_FLUSHES: &str = property!("num-running-flushes");
84+
pub const NUM_RUNNING_FLUSHES: &CStr = property!("num-running-flushes");
7585

7686
/// "rocksdb.compaction-pending" - returns 1 if at least one compaction is
7787
/// pending; otherwise, returns 0.
78-
pub const COMPACTION_PENDING: &str = property!("compaction-pending");
88+
pub const COMPACTION_PENDING: &CStr = property!("compaction-pending");
7989

8090
/// "rocksdb.num-running-compactions" - returns the number of currently
8191
/// running compactions.
82-
pub const NUM_RUNNING_COMPACTIONS: &str = property!("num-running-compactions");
92+
pub const NUM_RUNNING_COMPACTIONS: &CStr = property!("num-running-compactions");
8393

8494
/// "rocksdb.background-errors" - returns accumulated number of background
8595
/// errors.
86-
pub const BACKGROUND_ERRORS: &str = property!("background-errors");
96+
pub const BACKGROUND_ERRORS: &CStr = property!("background-errors");
8797

8898
/// "rocksdb.cur-size-active-mem-table" - returns approximate size of active
8999
/// memtable (bytes).
90-
pub const CUR_SIZE_ACTIVE_MEM_TABLE: &str = property!("cur-size-active-mem-table");
100+
pub const CUR_SIZE_ACTIVE_MEM_TABLE: &CStr = property!("cur-size-active-mem-table");
91101

92102
/// "rocksdb.cur-size-all-mem-tables" - returns approximate size of active
93103
/// and unflushed immutable memtables (bytes).
94-
pub const CUR_SIZE_ALL_MEM_TABLES: &str = property!("cur-size-all-mem-tables");
104+
pub const CUR_SIZE_ALL_MEM_TABLES: &CStr = property!("cur-size-all-mem-tables");
95105

96106
/// "rocksdb.size-all-mem-tables" - returns approximate size of active,
97107
/// unflushed immutable, and pinned immutable memtables (bytes).
98-
pub const SIZE_ALL_MEM_TABLES: &str = property!("size-all-mem-tables");
108+
pub const SIZE_ALL_MEM_TABLES: &CStr = property!("size-all-mem-tables");
99109

100110
/// "rocksdb.num-entries-active-mem-table" - returns total number of entries
101111
/// in the active memtable.
102-
pub const NUM_ENTRIES_ACTIVE_MEM_TABLE: &str = property!("num-entries-active-mem-table");
112+
pub const NUM_ENTRIES_ACTIVE_MEM_TABLE: &CStr = property!("num-entries-active-mem-table");
103113

104114
/// "rocksdb.num-entries-imm-mem-tables" - returns total number of entries
105115
/// in the unflushed immutable memtables.
106-
pub const NUM_ENTRIES_IMM_MEM_TABLES: &str = property!("num-entries-imm-mem-tables");
116+
pub const NUM_ENTRIES_IMM_MEM_TABLES: &CStr = property!("num-entries-imm-mem-tables");
107117

108118
/// "rocksdb.num-deletes-active-mem-table" - returns total number of delete
109119
/// entries in the active memtable.
110-
pub const NUM_DELETES_ACTIVE_MEM_TABLE: &str = property!("num-deletes-active-mem-table");
120+
pub const NUM_DELETES_ACTIVE_MEM_TABLE: &CStr = property!("num-deletes-active-mem-table");
111121

112122
/// "rocksdb.num-deletes-imm-mem-tables" - returns total number of delete
113123
/// entries in the unflushed immutable memtables.
114-
pub const NUM_DELETES_IMM_MEM_TABLES: &str = property!("num-deletes-imm-mem-tables");
124+
pub const NUM_DELETES_IMM_MEM_TABLES: &CStr = property!("num-deletes-imm-mem-tables");
115125

116126
/// "rocksdb.estimate-num-keys" - returns estimated number of total keys in
117127
/// the active and unflushed immutable memtables and storage.
118-
pub const ESTIMATE_NUM_KEYS: &str = property!("estimate-num-keys");
128+
pub const ESTIMATE_NUM_KEYS: &CStr = property!("estimate-num-keys");
119129

120130
/// "rocksdb.estimate-table-readers-mem" - returns estimated memory used for
121131
/// reading SST tables, excluding memory used in block cache (e.g.,
122132
/// filter and index blocks).
123-
pub const ESTIMATE_TABLE_READERS_MEM: &str = property!("estimate-table-readers-mem");
133+
pub const ESTIMATE_TABLE_READERS_MEM: &CStr = property!("estimate-table-readers-mem");
124134

125135
/// "rocksdb.is-file-deletions-enabled" - returns 0 if deletion of obsolete
126136
/// files is enabled; otherwise, returns a non-zero number.
127-
pub const IS_FILE_DELETIONS_ENABLED: &str = property!("is-file-deletions-enabled");
137+
pub const IS_FILE_DELETIONS_ENABLED: &CStr = property!("is-file-deletions-enabled");
128138

129139
/// "rocksdb.num-snapshots" - returns number of unreleased snapshots of the
130140
/// database.
131-
pub const NUM_SNAPSHOTS: &str = property!("num-snapshots");
141+
pub const NUM_SNAPSHOTS: &CStr = property!("num-snapshots");
132142

133143
/// "rocksdb.oldest-snapshot-time" - returns number representing unix
134144
/// timestamp of oldest unreleased snapshot.
135-
pub const OLDEST_SNAPSHOT_TIME: &str = property!("oldest-snapshot-time");
145+
pub const OLDEST_SNAPSHOT_TIME: &CStr = property!("oldest-snapshot-time");
136146

137147
/// "rocksdb.num-live-versions" - returns number of live versions. `Version`
138148
/// is an internal data structure. See version_set.h for details. More
139149
/// live versions often mean more SST files are held from being deleted,
140150
/// by iterators or unfinished compactions.
141-
pub const NUM_LIVE_VERSIONS: &str = property!("num-live-versions");
151+
pub const NUM_LIVE_VERSIONS: &CStr = property!("num-live-versions");
142152

143153
/// "rocksdb.current-super-version-number" - returns number of current LSM
144154
/// version. It is a uint64_t integer number, incremented after there is
145155
/// any change to the LSM tree. The number is not preserved after restarting
146156
/// the DB. After DB restart, it will start from 0 again.
147-
pub const CURRENT_SUPER_VERSION_NUMBER: &str = property!("current-super-version-number");
157+
pub const CURRENT_SUPER_VERSION_NUMBER: &CStr = property!("current-super-version-number");
148158

149159
/// "rocksdb.estimate-live-data-size" - returns an estimate of the amount of
150160
/// live data in bytes.
151-
pub const ESTIMATE_LIVE_DATA_SIZE: &str = property!("estimate-live-data-size");
161+
pub const ESTIMATE_LIVE_DATA_SIZE: &CStr = property!("estimate-live-data-size");
152162

153163
/// "rocksdb.min-log-number-to-keep" - return the minimum log number of the
154164
/// log files that should be kept.
155-
pub const MIN_LOG_NUMBER_TO_KEEP: &str = property!("min-log-number-to-keep");
165+
pub const MIN_LOG_NUMBER_TO_KEEP: &CStr = property!("min-log-number-to-keep");
156166

157167
/// "rocksdb.min-obsolete-sst-number-to-keep" - return the minimum file
158168
/// number for an obsolete SST to be kept. The max value of `uint64_t`
159169
/// will be returned if all obsolete files can be deleted.
160-
pub const MIN_OBSOLETE_SST_NUMBER_TO_KEEP: &str = property!("min-obsolete-sst-number-to-keep");
170+
pub const MIN_OBSOLETE_SST_NUMBER_TO_KEEP: &CStr = property!("min-obsolete-sst-number-to-keep");
161171

162172
/// "rocksdb.total-sst-files-size" - returns total size (bytes) of all SST
163173
/// files.
164174
/// WARNING: may slow down online queries if there are too many files.
165-
pub const TOTAL_SST_FILES_SIZE: &str = property!("total-sst-files-size");
175+
pub const TOTAL_SST_FILES_SIZE: &CStr = property!("total-sst-files-size");
166176

167177
/// "rocksdb.live-sst-files-size" - returns total size (bytes) of all SST
168178
/// files belong to the latest LSM tree.
169-
pub const LIVE_SST_FILES_SIZE: &str = property!("live-sst-files-size");
179+
pub const LIVE_SST_FILES_SIZE: &CStr = property!("live-sst-files-size");
170180

171181
/// "rocksdb.base-level" - returns number of level to which L0 data will be
172182
/// compacted.
173-
pub const BASE_LEVEL: &str = property!("base-level");
183+
pub const BASE_LEVEL: &CStr = property!("base-level");
174184

175185
/// "rocksdb.estimate-pending-compaction-bytes" - returns estimated total
176186
/// number of bytes compaction needs to rewrite to get all levels down
177187
/// to under target size. Not valid for other compactions than level-
178188
/// based.
179-
pub const ESTIMATE_PENDING_COMPACTION_BYTES: &str = property!("estimate-pending-compaction-bytes");
189+
pub const ESTIMATE_PENDING_COMPACTION_BYTES: &CStr = property!("estimate-pending-compaction-bytes");
180190

181191
/// "rocksdb.aggregated-table-properties" - returns a string representation
182192
/// of the aggregated table properties of the target column family.
183-
pub const AGGREGATED_TABLE_PROPERTIES: &str = property!("aggregated-table-properties");
193+
pub const AGGREGATED_TABLE_PROPERTIES: &CStr = property!("aggregated-table-properties");
184194

185195
/// "rocksdb.aggregated-table-properties-at-level<N>", same as the previous
186196
/// one but only returns the aggregated table properties of the
187197
/// specified level "N" at the target column family.
188-
pub const AGGREGATED_TABLE_PROPERTIES_AT_LEVEL: &str =
189-
property!("aggregated-table-properties-at-level");
198+
pub fn aggregated_table_properties_at_level(level: usize) -> CString {
199+
unsafe { level_property("aggregated-table-properties-at-level", level) }
200+
}
190201

191202
/// "rocksdb.actual-delayed-write-rate" - returns the current actual delayed
192203
/// write rate. 0 means no delay.
193-
pub const ACTUAL_DELAYED_WRITE_RATE: &str = property!("actual-delayed-write-rate");
204+
pub const ACTUAL_DELAYED_WRITE_RATE: &CStr = property!("actual-delayed-write-rate");
194205

195206
/// "rocksdb.is-write-stopped" - Return 1 if write has been stopped.
196-
pub const IS_WRITE_STOPPED: &str = property!("is-write-stopped");
207+
pub const IS_WRITE_STOPPED: &CStr = property!("is-write-stopped");
197208

198209
/// "rocksdb.estimate-oldest-key-time" - returns an estimation of
199210
/// oldest key timestamp in the DB. Currently only available for
200211
/// FIFO compaction with
201212
/// compaction_options_fifo.allow_compaction = false.
202-
pub const ESTIMATE_OLDEST_KEY_TIME: &str = property!("estimate-oldest-key-time");
213+
pub const ESTIMATE_OLDEST_KEY_TIME: &CStr = property!("estimate-oldest-key-time");
203214

204215
/// "rocksdb.block-cache-capacity" - returns block cache capacity.
205-
pub const BLOCK_CACHE_CAPACITY: &str = property!("block-cache-capacity");
216+
pub const BLOCK_CACHE_CAPACITY: &CStr = property!("block-cache-capacity");
206217

207218
/// "rocksdb.block-cache-usage" - returns the memory size for the entries
208219
/// residing in block cache.
209-
pub const BLOCK_CACHE_USAGE: &str = property!("block-cache-usage");
220+
pub const BLOCK_CACHE_USAGE: &CStr = property!("block-cache-usage");
210221

211222
/// "rocksdb.block-cache-pinned-usage" - returns the memory size for the
212223
/// entries being pinned.
213-
pub const BLOCK_CACHE_PINNED_USAGE: &str = property!("block-cache-pinned-usage");
224+
pub const BLOCK_CACHE_PINNED_USAGE: &CStr = property!("block-cache-pinned-usage");
214225

215226
/// "rocksdb.options-statistics" - returns multi-line string
216227
/// of options.statistics
217-
pub const OPTIONS_STATISTICS: &str = property!("options-statistics");
228+
pub const OPTIONS_STATISTICS: &CStr = property!("options-statistics");
229+
230+
/// Constructs a property name for an ‘at level’ property.
231+
///
232+
/// `name` is the infix of the property name (e.g. `"num-files-at-level"`) and
233+
/// `level` is level to get statistics of. The property name is constructed as
234+
/// `"rocksdb.<name><level>"`.
235+
///
236+
/// Expects `name` not to contain any interior NUL bytes.
237+
unsafe fn level_property(name: &str, level: usize) -> CString {
238+
let bytes = format!("rocksdb.{}{}\0", name, level).into_bytes();
239+
// SAFETY: We’re appending terminating NUL and all our call sites pass
240+
// a string without interior NUL bytes.
241+
CString::from_vec_with_nul_unchecked(bytes)
242+
}
243+
244+
#[test]
245+
fn sanity_checks() {
246+
let want = CString::new("rocksdb.cfstats-no-file-histogram".to_string()).unwrap();
247+
assert_eq!(want.as_c_str(), CFSTATS_NO_FILE_HISTOGRAM);
248+
249+
let want = CString::new("rocksdb.num-files-at-level5".to_string()).unwrap();
250+
assert_eq!(want, num_files_at_level(5));
251+
}

tests/test_property.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,22 @@ fn property_test() {
2424
let n = DBPath::new("_rust_rocksdb_property_test");
2525
{
2626
let db = DB::open_default(&n).unwrap();
27-
let value = db.property_value(properties::STATS).unwrap().unwrap();
27+
let prop_name: &std::ffi::CStr = properties::STATS;
28+
let value = db.property_value(prop_name).unwrap().unwrap();
2829
assert!(value.contains("Stats"));
2930
}
3031

3132
{
3233
let db = DB::open_default(&n).unwrap();
33-
let prop_name = std::ffi::CString::new(properties::STATS).unwrap();
34-
let value = db.property_value(prop_name).unwrap().unwrap();
34+
let prop_name: std::ffi::CString = properties::STATS.to_owned();
35+
let value = db.property_value(&prop_name).unwrap().unwrap();
3536
assert!(value.contains("Stats"));
3637
}
3738

3839
{
3940
let db = DB::open_default(&n).unwrap();
40-
let prop_name = std::ffi::CString::new(properties::STATS).unwrap();
41-
let value = db.property_value(prop_name.as_ref()).unwrap().unwrap();
41+
let prop_name: String = properties::STATS.to_owned().into_string().unwrap();
42+
let value = db.property_value(&prop_name).unwrap().unwrap();
4243
assert!(value.contains("Stats"));
4344
}
4445
}

0 commit comments

Comments
 (0)