leveldb/database/
statistics.rs1use crate::binding::leveldb_approximate_sizes;
3use crate::database::Database;
4use crate::database::property::Property;
5use crate::database::slice::Slice;
6use std::ffi::NulError;
7use std::os::raw::{c_char, c_int};
8
9pub struct KeyRange {
11 pub start: Vec<u8>,
13 pub end: Vec<u8>,
15}
16
17impl KeyRange {
18 pub fn new(start: Slice<'_>, end: Slice<'_>) -> Self {
20 KeyRange {
21 start: start.as_bytes().to_vec(),
22 end: end.as_bytes().to_vec(),
23 }
24 }
25
26 pub fn start(&self) -> Slice<'_> {
28 Slice::from(self.start.as_slice())
29 }
30
31 pub fn end(&self) -> Slice<'_> {
33 Slice::from(self.end.as_slice())
34 }
35}
36
37pub trait Statistics: Property {
39 fn get_num_files_at_level(&self, level: u32) -> Result<Option<String>, NulError> {
41 let property_name = format!(
42 "{}{}",
43 crate::database::property::property_name::NUM_FILES_AT_LEVEL,
44 level
45 );
46 self.get_property(&property_name)
47 }
48
49 fn get_stats(&self) -> Result<Option<String>, NulError> {
51 self.get_property(crate::database::property::property_name::STATS)
52 }
53
54 fn get_property_of_sstables(&self) -> Result<Option<String>, NulError> {
56 self.get_property(crate::database::property::property_name::SSTABLES)
57 }
58
59 fn get_approximate_memory_usage(&self) -> Result<Option<String>, NulError> {
61 self.get_property(crate::database::property::property_name::APPROXIMATE_MEMORY_USAGE)
62 }
63
64 fn get_approximate_sizes(&self, ranges: Vec<KeyRange>) -> Vec<u64>;
84
85 fn get_approximate_size_for_range(&self, start: Slice<'_>, end: Slice<'_>) -> u64 {
96 let range = KeyRange::new(start, end);
97 let sizes = self.get_approximate_sizes(vec![range]);
98 assert!(sizes.len() == 1);
99 sizes[0]
100 }
101}
102
103impl Statistics for Database {
104 fn get_approximate_sizes(&self, ranges: Vec<KeyRange>) -> Vec<u64> {
105 let db_ptr = self.database.ptr;
106 let num_ranges = ranges.len();
107 if num_ranges == 0 {
108 return vec![];
109 }
110
111 let mut start_keys = Vec::with_capacity(num_ranges);
112 let mut start_key_lens = Vec::with_capacity(num_ranges);
113 let mut limit_keys = Vec::with_capacity(num_ranges);
114 let mut limit_key_lens = Vec::with_capacity(num_ranges);
115
116 for range in &ranges {
117 start_keys.push(range.start.as_ptr());
118 start_key_lens.push(range.start.len());
119
120 limit_keys.push(range.end.as_ptr());
121 limit_key_lens.push(range.end.len());
122 }
123
124 let mut sizes = vec![0u64; num_ranges];
125 unsafe {
126 leveldb_approximate_sizes(
127 db_ptr,
128 num_ranges as c_int,
129 start_keys.as_ptr() as *const *const c_char,
130 start_key_lens.as_ptr(),
131 limit_keys.as_ptr() as *const *const c_char,
132 limit_key_lens.as_ptr(),
133 sizes.as_mut_ptr(),
134 );
135 }
136
137 sizes
138 }
139}