diff options
| author | chenzizhan <[email protected]> | 2023-10-07 14:21:15 +0800 |
|---|---|---|
| committer | chenzizhan <[email protected]> | 2023-10-07 14:21:15 +0800 |
| commit | 0bf7feca252a12e08063e899aa052bd2a6a43f18 (patch) | |
| tree | 7f670c3081ecf607900b01d2bc977a145cbd2c16 | |
| parent | 6a7fb56e8dad5bd9c57ed8f106a3559970a3c17c (diff) | |
doc for binding
| -rw-r--r-- | src/c_lang/fieldstat.rs | 192 | ||||
| -rw-r--r-- | src/c_lang/mod.rs | 2 | ||||
| -rw-r--r-- | src/c_lang/timeval.rs | 2 | ||||
| -rw-r--r-- | src/session/mod.rs | 2 |
4 files changed, 187 insertions, 11 deletions
diff --git a/src/c_lang/fieldstat.rs b/src/c_lang/fieldstat.rs index 1b11815..aa80140 100644 --- a/src/c_lang/fieldstat.rs +++ b/src/c_lang/fieldstat.rs @@ -1,4 +1,3 @@ - use std::ffi::{CString, CStr}; use std::os::raw::{c_longlong, c_char}; use std::fmt::Debug; @@ -38,6 +37,7 @@ pub enum FieldstatErr { InvalidMetricId, InvalidTag, InvalidName, + EmptyStr, WrongParameter, DuplicateKey, } @@ -108,7 +108,7 @@ impl Taggable for String { } impl<T: Taggable> FieldstatTag<T> { - fn new(name: &str, value: T) -> Self { + pub fn new(name: &str, value: T) -> Self { let c_string = CString::new(name).unwrap(); let typeid = value.type_id(); Self { @@ -123,11 +123,11 @@ impl<T: Taggable> FieldstatTag<T> { } } - fn value_type(&self) -> FieldstatTagType { + pub fn value_type(&self) -> FieldstatTagType { self.value_type.clone() } - fn key(&self) -> String { + pub fn key(&self) -> String { unsafe { let rust_str = CStr::from_ptr(self.content.key).to_owned(); rust_str.to_str().unwrap().to_string() @@ -137,7 +137,7 @@ impl<T: Taggable> FieldstatTag<T> { impl FieldstatTag<i64> { - fn value(&self) -> i64 { + pub fn value(&self) -> i64 { unsafe { self.content.__bindgen_anon_1.value_longlong } @@ -146,7 +146,7 @@ impl FieldstatTag<i64> impl FieldstatTag<f64> { - fn value(&self) -> f64 { + pub fn value(&self) -> f64 { unsafe { self.content.__bindgen_anon_1.value_double } @@ -155,7 +155,7 @@ impl FieldstatTag<f64> impl FieldstatTag<String> { - fn value(&self) -> String { + pub fn value(&self) -> String { unsafe { let rust_str = CStr::from_ptr(self.content.__bindgen_anon_1.value_str).to_owned(); rust_str.to_str().unwrap().to_string() @@ -182,6 +182,15 @@ pub enum FieldstatTagWrapper { String(FieldstatTag<String>), } +/// #example +/// ``` +/// let tag = FieldstatTag::<i64>::new("key", 1); +/// let wrapper = FieldstatTagWrapper::LongLong(tag); +/// let tag = wrapper.inner::<i64>(); +/// assert_eq!(tag.value(), 1); +/// assert_eq!(tag.key(), "key"); +/// assert_eq!(tag.value_type(), FieldstatTagType::LongLong); +/// ``` impl FieldstatTagWrapper { fn content(&self) -> fieldstat_binding::fieldstat_tag { match self { @@ -190,7 +199,7 @@ impl FieldstatTagWrapper { FieldstatTagWrapper::String(tag) => tag.content, } } - fn inner<T:Taggable>(&self) -> FieldstatTag<T> { + pub fn inner<T:Taggable>(&self) -> FieldstatTag<T> { match self { FieldstatTagWrapper::LongLong(tag) => FieldstatTag::<T> { content: tag.content, @@ -220,16 +229,34 @@ impl Fieldstat { content: unsafe { fieldstat_binding::fieldstat_new() }, } } + + /// copy only registered cubes and metrics, not including cells. Used to new a instance of the same schema. pub fn fork(&self) -> Self { Self { content: unsafe { fieldstat_binding::fieldstat_fork(self.content) }, } } + /// let the configuration of target be the same as master, no matter what the configuration of target is. + /// the configurations will be kept as much as possible, like cells in the same cube will be kept, but the cells in different cubes will be deleted. pub fn calibrate(&self, other: &mut Fieldstat) { unsafe { fieldstat_binding::fieldstat_calibrate(self.content, other.content); } } + /// Adds a cube to this instance. A cube represents a template with a user-defined set of cells and metrics. + /// + /// # Arguments + /// + /// * `shared_tags` - Tags that are shared by all cells in this cube. This is the key of the cube. Can be NULL. Must be unique. Shared_tags are ordered, which means that {"TAG_KEY": "123", "TAG_KEY2": "456"} and {"TAG_KEY2": "456", "TAG_KEY": "123"} map to different cubes. + /// * `n_tag` - Number of shared tags. + /// * `mode` - Sampling mode. Refer to enum `sampling_mode`. + /// * `max_n_cell` - Maximum number of samplings (cells) in each cube. When mode is TOPK, `max_n_cell` > 0, while in COMPREHENSIVE mode, `max_n_cell` can be 0, meaning that there is no limit. + /// + /// # Returns + /// + /// * Cube id, if successful; + /// * `WrongParameter` when (`max_n_cell` == 0 && mode == TOPK). + /// * `DuplicateKey` when the `shared_tags` is not unique. pub fn create_cube(&mut self, shared_tags: &[FieldstatTagWrapper], mode: SampleMode, max_n_cell: usize) -> Result<i32, FieldstatErr> { let c_mode = match mode { SampleMode::Comprehensive => fieldstat_binding::sampling_mode_SAMPLING_MODE_COMPREHENSIVE, @@ -255,6 +282,15 @@ impl Fieldstat { } } } + /// Change the topk cube primary metric id. When fieldstat_counter_add or fieldstat_counter_set are called on the primary metric, the topk record of such cell will be updated. + /// the default primary metric id is 0. + /// + /// # Returns + /// + /// * Ok(()) if successful; + /// * `InvalidCubeId` when the cube id is invalid; + /// * `InvalidMetricId` when the metric id is invalid; + /// * `WrongParameter` when the metric id is not in the cube. pub fn set_primary_metric(&mut self, cube_id: i32, metric_id: i32) -> Result<(), FieldstatErr> { unsafe { let ret = fieldstat_binding::fieldstat_cube_set_primary_metric(self.content, cube_id as std::os::raw::c_int, metric_id as std::os::raw::c_int); @@ -267,6 +303,7 @@ impl Fieldstat { } } } + /// Delete the cube of cube_id. All the cells and metrics are deleted. The cube_id may be reused by other new cubes. Increase the corresponding cube_version by 1. pub fn destroy_cube(&mut self, cube_id: i64) -> Result<(), FieldstatErr> { unsafe { let ret = fieldstat_binding::fieldstat_destroy_cube(self.content, cube_id as std::os::raw::c_int); @@ -277,6 +314,7 @@ impl Fieldstat { } } } + /// Get the cube_version of the cube of cube_id. pub fn get_cube_version(&self, cube_id: i64) -> Result<i64, FieldstatErr> { unsafe { let ret = fieldstat_binding::fieldstat_get_cube_version(self.content, cube_id as std::os::raw::c_int); @@ -287,7 +325,19 @@ impl Fieldstat { } } } + /// add a metric to the cube of cube_id. One metric may be associated with different cells. + /// + /// # Arguments + /// * `name`: The name of the metric. Must be unique in the cube. + /// + /// # Returns + /// * metric id, if successful; + /// * `InvalidName` when the name is not unique in the cube; + /// * `EmptyStr` when the name is empty. pub fn register_counter(&mut self, name: &str) -> Result<i32, FieldstatErr> { + if name.len() == 0 { + return Err(FieldstatErr::EmptyStr); + } let c_name = CString::new(name).unwrap(); unsafe { let ret = fieldstat_binding::fieldstat_register_counter( @@ -301,7 +351,18 @@ impl Fieldstat { } } } + /// # Arguments + /// * `precision`: the bigger, the larger memory consumption, while accuracy improved. Must be in [4, 18]. + /// + /// # Returns + /// * metric id, if successful; + /// * `InvalidName` when the name is not unique in the cube; + /// * `WrongParameter` when the precision is not in [4, 18]. + /// * `EmptyStr` when the name is empty. pub fn register_hll(&mut self, name: &str, precision: u8) -> Result<i32, FieldstatErr> { + if name.len() == 0 { + return Err(FieldstatErr::EmptyStr); + } let c_name = CString::new(name).unwrap(); unsafe { let ret = fieldstat_binding::fieldstat_register_hll( @@ -317,7 +378,15 @@ impl Fieldstat { } } } + /// # Arguments + /// * `lowest_trackable_value`: the lowest value that can be tracked by the histogram. Must be >= 1. + /// * `highest_trackable_value`: the highest value to be tracked by the histogram. Must be >= 2 * lowest_trackable_value. + /// * `significant_figures`: the precision of the histogram. Must be in [1, 5]. + /// * `EmptyStr` when the name is empty. pub fn register_histogram(&mut self, name: &str, lowest_trackable_value: i64, highest_trackable_value: i64, significant_figures: i32) -> Result<i32, FieldstatErr> { + if name.len() == 0 { + return Err(FieldstatErr::EmptyStr); + } let c_name = CString::new(name).unwrap(); unsafe { let ret = fieldstat_binding::fieldstat_register_hist( @@ -335,6 +404,22 @@ impl Fieldstat { } } } + /// let the value of counter metric of cell_id increase by `increment`. + /// + /// # Arguments + /// * `cube_id`: the cube id of the cell.previously returned by fieldstat_create_cube. + /// * `metric_id`: the metric id of the cell.previously returned by fieldstat_register_counter. + /// * `tags`: the tags of the cell. + /// * `increment`: the value to be increased. + /// + /// # Returns + /// * Ok(()) if successful; + /// * `InvalidCubeId` when the cube id is invalid; + /// * `InvalidMetricId` when the metric id is invalid; + /// * `WrongParameter` when the metric type is not counter; + /// * `TooManyCells` when the the cube is full. + /// In comprehensive mode, a full cube cannot be added any more cells. + /// In topk mode, every increment matters, so even the cube is full, the cell can also replace the least frequent cell. pub fn counter_incrby(&mut self, cube_id: i32, metric_id: i32, tags: &[FieldstatTagWrapper], increment: i64) -> Result<(), FieldstatErr> { let c_tag_structs: Vec<_> = tags.iter().map(|tag| tag.content()).collect(); @@ -357,6 +442,9 @@ impl Fieldstat { } } } + /// let the value of counter metric equal to value. Other annotations refer to fieldstat_counter_incrby. + /// What's more, be cautious to call this function if the metric is a primary metric of a topk cube, + /// in such case, WrongParameter will be the output when the value is set to a smaller one(increment is negative). pub fn counter_set(&mut self, cube_id: i32, metric_id: i32, tags: &[FieldstatTagWrapper], value: i64) -> Result<(), FieldstatErr> { let c_tag_structs: Vec<_> = tags.iter().map(|tag| tag.content()).collect(); @@ -379,7 +467,21 @@ impl Fieldstat { } } } + /// add a key to the hll metric of cell_id. HLL approximates the number of distinct elements in a set of `key`s. + /// + /// # Arguments + /// * `cube_id`: the cube id of the cell.previously returned by fieldstat_create_cube. + /// * `metric_id`: the metric id of the cell.previously returned by fieldstat_register_hll. + /// * `tags`: the tags of the cell. + /// * `key`: the key to be added. Cannot be empty. + /// + /// # Returns + /// Since topk only support counter, `WrongParameter` is returned when the cube is topk. + /// The others refer to fieldstat_counter_incrby. pub fn hll_add(&mut self, cube_id: i32, metric_id: i32, tags: &[FieldstatTagWrapper], key: &str) -> Result<(), FieldstatErr> { + if key.len() == 0 { + return Err(FieldstatErr::EmptyStr); + } let c_tag_structs: Vec<_> = tags.iter().map(|tag| tag.content()).collect(); let c_key = CString::new(key).unwrap(); unsafe { @@ -402,6 +504,9 @@ impl Fieldstat { } } } + /// Add a value to the histogram metric of cell_id. Histogram will record the distribution of the values. + /// The value bigger than highest_trackable_value will be set to highest_trackable_value. The value less than lowest_trackable_value will be tried to record, and, if succeed, remains in the record as -inf(most of the time) or 0(if value == 0) + /// The other annotations refer to fieldstat_counter_incrby. pub fn histogram_record(&mut self, cube_id: i32, metric_id: i32, tags: &[FieldstatTagWrapper], value: i64) -> Result<(), FieldstatErr> { let c_tag_structs: Vec<_> = tags.iter().map(|tag| tag.content()).collect(); @@ -424,16 +529,24 @@ impl Fieldstat { } } } + /// Delete all the cells, also the content of every metrics. The cube and metrics are not deleted. Increase cell_version by 1. + /// Note that the cell record won't be deleted at once, they just seem to be deleted. The cell record will be deleted when they are not used since the last reset and until the next reset. pub fn reset(&mut self) { unsafe { fieldstat_binding::fieldstat_reset(self.content); } } + /// version is increased by 1 when we call fieldstat_reset. pub fn get_version(&self) -> u64 { unsafe { fieldstat_binding::fieldstat_get_version(self.content) } } + /// Merge the instance. The registered cubes and metrics are merged even if there are no cells added. + /// + /// # Returns + /// * Ok(()) if successful; + /// * `WrongParameter` when the registered cubes or metrics between dest and src of the same keys has different types or configurations(like different primary metric). pub fn merge(&mut self, other: &Fieldstat) -> Result<(), FieldstatErr> { unsafe { let ret = fieldstat_binding::fieldstat_merge(self.content, other.content); @@ -446,6 +559,7 @@ impl Fieldstat { } /* ---------------------------------- query --------------------------------- */ + /// Get all the registered cubes. pub fn get_cubes(&self) -> Vec<i32> { unsafe { let mut cubes: *mut i32 = std::ptr::null_mut(); @@ -465,6 +579,7 @@ impl Fieldstat { vec } } + /// Get all the registered metrics of a cube. pub fn get_metrics_used_by_cube(&self, cube_id: i32) -> Result<Vec<i32>, FieldstatErr> { unsafe { let mut metric_ids = std::ptr::null_mut(); @@ -485,6 +600,7 @@ impl Fieldstat { Ok(vec) } } + /// Get all the registered metrics by fieldstat_register_counter, fieldstat_register_hll, fieldstat_register_hist. pub fn get_metrics(&self) -> Vec<i32> { unsafe { let mut metrics: *mut i32 = std::ptr::null_mut(); @@ -503,6 +619,11 @@ impl Fieldstat { vec } } + /// query the name of the metric. + /// + /// # Returns + /// * Ok(metric_name) if successful; + /// * `InvalidMetricId` when the metric id is invalid. pub fn get_metric_name(&self, metric_id: i32) -> Result<String, FieldstatErr> { unsafe { let ret = fieldstat_binding::fieldstat_get_metric_name(self.content, metric_id as std::os::raw::c_int); @@ -514,6 +635,11 @@ impl Fieldstat { } } } + /// query the type of the metric. + /// + /// # Returns + /// * Ok(metric_type) if successful; + /// * `InvalidMetricId` when the metric id is invalid. pub fn get_metric_type(&self, metric_id: i32) -> Result<MetricType, FieldstatErr> { unsafe { let ret = fieldstat_binding::fieldstat_get_metric_type(self.content, metric_id as std::os::raw::c_int); @@ -526,6 +652,7 @@ impl Fieldstat { } } } + /// get the tags added to metric when calling fieldstat_counter_incrby, fieldstat_counter_set, fieldstat_hll_add, fieldstat_hist_record. pub fn get_cells_used_by_metric(&self, cube_id: i32, metric_id: i32) -> Vec<Vec<FieldstatTagWrapper>> { unsafe { let mut tags: *mut fieldstat_binding::fieldstat_tag_list = std::ptr::null_mut(); @@ -553,6 +680,7 @@ impl Fieldstat { ret } } + /// get the tags added to cube when calling fieldstat_counter_incrby, fieldstat_counter_set, fieldstat_hll_add, fieldstat_hist_record. pub fn get_cells_used_by_cube(&self, cube_id: i32) -> Vec<Vec<FieldstatTagWrapper>> { unsafe { let mut tags: *mut fieldstat_binding::fieldstat_tag_list = std::ptr::null_mut(); @@ -579,6 +707,7 @@ impl Fieldstat { ret } } + /// get the shared tag of fieldstat_create_cube. pub fn get_shared_tags(&self, cube_id: i32) -> Vec<FieldstatTagWrapper> { unsafe { let tags: *mut fieldstat_binding::fieldstat_tag_list = fieldstat_binding::fieldstat_get_shared_tags( @@ -596,6 +725,7 @@ impl Fieldstat { tag_vec } } + /// return a cube id corresponding to the shared tags. pub fn find_cube(&self, tags: &[FieldstatTagWrapper]) -> Option<i32> { let mut c_tag_structs = Vec::with_capacity(tags.len()); for tag in tags { @@ -616,6 +746,7 @@ impl Fieldstat { } } } + /// get the number of different cells in a cube. pub fn get_used_sampling(&self, cube_id: i32) -> Result<i32, FieldstatErr> { unsafe { let ret = fieldstat_binding::fieldstat_get_used_sampling(self.content, cube_id as std::os::raw::c_int); @@ -626,6 +757,7 @@ impl Fieldstat { } } } + /// Get the value of a metric of a cell. pub fn counter_get(&self, cube_id: i32, metric_id: i32, tags: &[FieldstatTagWrapper]) -> Result<i64, FieldstatErr> { let c_tag_list = vec_to_fieldstat_tag_list(tags); let mut value = 0; @@ -648,6 +780,7 @@ impl Fieldstat { } } } + /// Get an approximate count of the number of distinct elements in the cell. pub fn hll_get(&self, cube_id: i32, metric_id: i32, tags: &[FieldstatTagWrapper]) -> Result<f64, FieldstatErr> { let c_tag_list = vec_to_fieldstat_tag_list(tags); let mut value = 0.0; @@ -669,6 +802,7 @@ impl Fieldstat { } } } + /// Get the value taken by the histogram at a specific percentile. pub fn histogram_value_at_percentile(&self, cube_id: i32, metric_id: i32, tags: &[FieldstatTagWrapper], percentile: f64) -> Result<i64, FieldstatErr> { let c_tag_list = vec_to_fieldstat_tag_list(tags); @@ -690,6 +824,7 @@ impl Fieldstat { } } } + /// Get the number of values that are less or equal than `value`. pub fn histogram_count_le_value(&self, cube_id: i32, metric_id: i32, tags: &[FieldstatTagWrapper], value: i64) -> Result<i64, FieldstatErr> { let c_tag_list = vec_to_fieldstat_tag_list(tags); @@ -722,6 +857,41 @@ impl Drop for Fieldstat { } } +/// Output the fieldstat instance to json string array. +/// +/// # Safety +/// This structure is unsafe when the lifetime of the instance is shorter than the lifetime of the JsonExporter. +/// Lifetime is not checked because we have to ensure the instance can be mutably borrowed after calling export. +/// +/// In multi-threaded environment, the instance binding to Exporter must be Read Only. +/// +/// # Example +/// ``` +/// use fieldstat::*; +/// let mut fs = Fieldstat::new(); +/// exporter.set_global_tag(global_tag.as_slice()); +/// exporter.set_name("test abcde"); +/// let ts = TimeVal::new(1, 2000); +/// let ret = exporter.export(ts).unwrap(); +/// ``` +/// ret is: +/// ``` +/// [ +/// { +/// "name": "test abcde", +/// "tags": { +/// "tag cell": 123, +/// "tag2": "abc", +/// "global tag": 1 +/// }, +/// "fields": { +/// "test": 10 +/// }, +/// "timestamp_ms": 1002 +/// } +/// ] +/// ``` +/// `set_global_tag`, `set_name` and `enable_delta` are optional. pub struct JsonExporter { content: *mut fieldstat_binding::fieldstat_json_exporter, } @@ -787,6 +957,12 @@ impl JsonExporter { ret } } + /// let json exporter output delta value by the side of the original value(accumulated). If a cell / metric is new, the delta value is the same as the original value. + /// Outputting delta value is disabled by default. + /// When the exporter name or exporter global tags are changed, or the fieldstat instance is reset, or one of the cube is deleted, the delta value will be reset. (next output will be the original value) + /// it is recommended to call this function after fieldstat_json_exporter_set_name and fieldstat_json_exporter_set_global_tag. + /// Only affects the metrics of counter type. + /// Outputting delta value is time-consuming. pub fn enable_delta(&mut self) { unsafe { fieldstat_binding::fieldstat_json_exporter_enable_delta(self.content) diff --git a/src/c_lang/mod.rs b/src/c_lang/mod.rs index 3ed5b4d..608206a 100644 --- a/src/c_lang/mod.rs +++ b/src/c_lang/mod.rs @@ -1,3 +1,3 @@ -pub(crate) mod fieldstat; +pub mod fieldstat; pub(super) mod fieldstat_binding; pub(crate) mod timeval;
\ No newline at end of file diff --git a/src/c_lang/timeval.rs b/src/c_lang/timeval.rs index a3018c9..79786fd 100644 --- a/src/c_lang/timeval.rs +++ b/src/c_lang/timeval.rs @@ -19,7 +19,7 @@ impl TimeVal { pub fn new(sec: u64, usec: u64) -> Self { TimeVal { sec, usec } } - pub fn as_c(&self) -> libc::timeval { + pub(crate) fn as_c(&self) -> libc::timeval { libc::timeval { tv_sec: self.sec as libc::time_t, tv_usec: self.usec as libc::suseconds_t, diff --git a/src/session/mod.rs b/src/session/mod.rs index 1540c92..d3a09dc 100644 --- a/src/session/mod.rs +++ b/src/session/mod.rs @@ -1 +1 @@ -pub(crate) mod tcp_reassembly;
\ No newline at end of file +pub mod tcp_reassembly;
\ No newline at end of file |
