1use crate::ffi;
2
3#[derive(Debug, Clone)]
4pub struct NameParseError;
5impl core::fmt::Display for NameParseError {
6 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7 write!(f, "unrecognized name")
8 }
9}
10
11impl std::error::Error for NameParseError {}
12
13macro_rules! iterable_named_enum {
16 (
17 $(#[$m:meta])*
18 $type_vis:vis enum $typename:ident {
19 $(
20 $(#[$variant_meta:meta])*
21 $variant:ident($variant_str:literal) $(= $value:expr)?,
22 )+
23 }
24 ) => {
25 #[allow(clippy::all)]
27 $(#[$m])*
28 $type_vis enum $typename {
29 $(
30 $(#[$variant_meta])*
31 $variant$( = $value)?,
32 )+
33 }
34
35 #[automatically_derived]
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)]
81#[repr(u8)]
82pub enum StatsLevel {
83 DisableAll = 0,
85 ExceptHistogramOrTimers = 2,
87 ExceptTimers,
89 ExceptDetailedTimers,
92 ExceptTimeForMutex,
95 All,
99}
100
101include!("statistics_enum_ticker.rs");
102include!("statistics_enum_histogram.rs");
103
104pub struct HistogramData {
105 pub(crate) inner: *mut ffi::rocksdb_statistics_histogram_data_t,
106}
107
108impl HistogramData {
109 pub fn new() -> HistogramData {
110 HistogramData::default()
111 }
112 pub fn median(&self) -> f64 {
113 unsafe { ffi::rocksdb_statistics_histogram_data_get_median(self.inner) }
114 }
115 pub fn average(&self) -> f64 {
116 unsafe { ffi::rocksdb_statistics_histogram_data_get_average(self.inner) }
117 }
118 pub fn p95(&self) -> f64 {
119 unsafe { ffi::rocksdb_statistics_histogram_data_get_p95(self.inner) }
120 }
121 pub fn p99(&self) -> f64 {
122 unsafe { ffi::rocksdb_statistics_histogram_data_get_p99(self.inner) }
123 }
124 pub fn max(&self) -> f64 {
125 unsafe { ffi::rocksdb_statistics_histogram_data_get_max(self.inner) }
126 }
127 pub fn min(&self) -> f64 {
128 unsafe { ffi::rocksdb_statistics_histogram_data_get_min(self.inner) }
129 }
130 pub fn sum(&self) -> u64 {
131 unsafe { ffi::rocksdb_statistics_histogram_data_get_sum(self.inner) }
132 }
133 pub fn count(&self) -> u64 {
134 unsafe { ffi::rocksdb_statistics_histogram_data_get_count(self.inner) }
135 }
136 pub fn std_dev(&self) -> f64 {
137 unsafe { ffi::rocksdb_statistics_histogram_data_get_std_dev(self.inner) }
138 }
139}
140
141impl Default for HistogramData {
142 fn default() -> Self {
143 let histogram_data_inner = unsafe { ffi::rocksdb_statistics_histogram_data_create() };
144 assert!(
145 !histogram_data_inner.is_null(),
146 "Could not create RocksDB histogram data"
147 );
148
149 Self {
150 inner: histogram_data_inner,
151 }
152 }
153}
154
155impl Drop for HistogramData {
156 fn drop(&mut self) {
157 unsafe {
158 ffi::rocksdb_statistics_histogram_data_destroy(self.inner);
159 }
160 }
161}
162
163#[test]
164fn sanity_checks() {
165 let want = "rocksdb.async.read.bytes";
166 assert_eq!(want, Histogram::AsyncReadBytes.name());
167
168 let want = "rocksdb.block.cache.index.miss";
169 assert_eq!(want, Ticker::BlockCacheIndexMiss.to_string());
170
171 assert_eq!(Ticker::iter().count(), 211 );
173 assert_eq!(Histogram::iter().count(), 62 );
174}