rust_rocksdb/
statistics.rs1use crate::ffi;
2use libc::c_int;
3
4#[derive(Debug, Clone)]
5pub struct NameParseError;
6impl core::fmt::Display for NameParseError {
7 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8 write!(f, "unrecognized name")
9 }
10}
11
12impl std::error::Error for NameParseError {}
13
14macro_rules! iterable_named_enum {
17 (
18 $(#[$m:meta])*
19 $type_vis:vis enum $typename:ident {
20 $(
21 $(#[$variant_meta:meta])*
22 $variant:ident($variant_str:literal) $(= $value:expr)?,
23 )+
24 }
25 ) => {
26 #[allow(clippy::all)]
28 $(#[$m])*
29 $type_vis enum $typename {
30 $(
31 $(#[$variant_meta])*
32 $variant$( = $value)?,
33 )+
34 }
35
36 impl $typename {
37 #[doc = "The corresponding rocksdb string identifier for this variant"]
38 pub const fn name(&self) -> &'static str {
39 match self {
40 $(
41 $typename::$variant => $variant_str,
42 )+
43 }
44 }
45 pub fn iter() -> ::core::slice::Iter<'static, $typename> {
46 static VARIANTS: &'static [$typename] = &[
47 $(
48 $typename::$variant,
49 )+
50 ];
51 VARIANTS.iter()
52 }
53 }
54
55
56 #[automatically_derived]
57 impl ::core::str::FromStr for $typename {
58 type Err = NameParseError;
59 fn from_str(s: &str) -> Result<Self, Self::Err> {
60 match s {
61 $(
62 $variant_str => Ok($typename::$variant),
63 )+
64 _ => Err(NameParseError),
65 }
66 }
67 }
68
69 #[automatically_derived]
70 impl ::core::fmt::Display for $typename {
71 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
72 self.name().fmt(f)
73 }
74 }
75 };
76}
77
78#[derive(Debug, Copy, Clone, PartialEq, Eq)]
91#[repr(u32)]
92#[allow(clippy::unnecessary_cast)]
96pub enum StatsLevel {
97 DisableAll = ffi::rocksdb_statistics_level_disable_all as u32,
101 ExceptHistogramOrTimers = ffi::rocksdb_statistics_level_except_histogram_or_timers as u32,
103 ExceptTimers = ffi::rocksdb_statistics_level_except_timers as u32,
105 ExceptDetailedTimers = ffi::rocksdb_statistics_level_except_detailed_timers as u32,
108 ExceptTimeForMutex = ffi::rocksdb_statistics_level_except_time_for_mutex as u32,
111 All = ffi::rocksdb_statistics_level_all as u32,
115}
116
117impl StatsLevel {
118 pub(crate) fn try_from_raw(raw: c_int) -> Option<Self> {
123 match raw {
124 n if n == Self::DisableAll as c_int => Some(Self::DisableAll),
125 n if n == Self::ExceptHistogramOrTimers as c_int => Some(Self::ExceptHistogramOrTimers),
126 n if n == Self::ExceptTimers as c_int => Some(Self::ExceptTimers),
127 n if n == Self::ExceptDetailedTimers as c_int => Some(Self::ExceptDetailedTimers),
128 n if n == Self::ExceptTimeForMutex as c_int => Some(Self::ExceptTimeForMutex),
129 n if n == Self::All as c_int => Some(Self::All),
130 _ => None,
131 }
132 }
133}
134
135include!("statistics_enum_ticker.rs");
136include!("statistics_enum_histogram.rs");
137
138pub struct HistogramData {
139 pub(crate) inner: *mut ffi::rocksdb_statistics_histogram_data_t,
140}
141
142impl HistogramData {
143 pub fn new() -> HistogramData {
144 HistogramData::default()
145 }
146 pub fn median(&self) -> f64 {
147 unsafe { ffi::rocksdb_statistics_histogram_data_get_median(self.inner) }
148 }
149 pub fn average(&self) -> f64 {
150 unsafe { ffi::rocksdb_statistics_histogram_data_get_average(self.inner) }
151 }
152 pub fn p95(&self) -> f64 {
153 unsafe { ffi::rocksdb_statistics_histogram_data_get_p95(self.inner) }
154 }
155 pub fn p99(&self) -> f64 {
156 unsafe { ffi::rocksdb_statistics_histogram_data_get_p99(self.inner) }
157 }
158 pub fn max(&self) -> f64 {
159 unsafe { ffi::rocksdb_statistics_histogram_data_get_max(self.inner) }
160 }
161 pub fn min(&self) -> f64 {
162 unsafe { ffi::rocksdb_statistics_histogram_data_get_min(self.inner) }
163 }
164 pub fn sum(&self) -> u64 {
165 unsafe { ffi::rocksdb_statistics_histogram_data_get_sum(self.inner) }
166 }
167 pub fn count(&self) -> u64 {
168 unsafe { ffi::rocksdb_statistics_histogram_data_get_count(self.inner) }
169 }
170 pub fn std_dev(&self) -> f64 {
171 unsafe { ffi::rocksdb_statistics_histogram_data_get_std_dev(self.inner) }
172 }
173}
174
175impl Default for HistogramData {
176 fn default() -> Self {
177 let histogram_data_inner = unsafe { ffi::rocksdb_statistics_histogram_data_create() };
178 assert!(
179 !histogram_data_inner.is_null(),
180 "Could not create RocksDB histogram data"
181 );
182
183 Self {
184 inner: histogram_data_inner,
185 }
186 }
187}
188
189impl Drop for HistogramData {
190 fn drop(&mut self) {
191 unsafe {
192 ffi::rocksdb_statistics_histogram_data_destroy(self.inner);
193 }
194 }
195}
196
197#[test]
198fn sanity_checks() {
199 let want = "rocksdb.async.read.bytes";
200 assert_eq!(want, Histogram::AsyncReadBytes.name());
201
202 let want = "rocksdb.block.cache.index.miss";
203 assert_eq!(want, Ticker::BlockCacheIndexMiss.to_string());
204
205 assert_eq!(Ticker::iter().count(), 263 );
207 assert_eq!(Histogram::iter().count(), 80 );
208}