use super::summary::{unerase, TupleSummary};
use crate::error::SketchError;
use apache_datasketches_sys::tuple_generic::ffi as sys;
use cxx::UniquePtr;
use std::marker::PhantomData;
pub struct CompactTupleSketch<S: TupleSummary> {
pub(crate) inner: UniquePtr<sys::CompactTupleGenericSketchShim>,
pub(crate) _marker: PhantomData<fn() -> S>,
}
unsafe impl<S: TupleSummary> Send for CompactTupleSketch<S> {}
impl<S: TupleSummary> CompactTupleSketch<S> {
pub(crate) fn from_shim(inner: UniquePtr<sys::CompactTupleGenericSketchShim>) -> Self {
Self {
inner,
_marker: PhantomData,
}
}
pub fn get_estimate(&self) -> f64 {
self.inner.get_estimate()
}
pub fn get_lower_bound(&self, num_std_dev: u8) -> Result<f64, SketchError> {
self.inner
.get_lower_bound(num_std_dev)
.map_err(|e| SketchError::InvalidConfig(e.what().to_string()))
}
pub fn get_upper_bound(&self, num_std_dev: u8) -> Result<f64, SketchError> {
self.inner
.get_upper_bound(num_std_dev)
.map_err(|e| SketchError::InvalidConfig(e.what().to_string()))
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn is_estimation_mode(&self) -> bool {
self.inner.is_estimation_mode()
}
pub fn is_ordered(&self) -> bool {
self.inner.is_ordered()
}
pub fn get_theta(&self) -> f64 {
self.inner.get_theta()
}
pub fn get_num_retained(&self) -> u32 {
self.inner.get_num_retained()
}
pub fn entries(&self) -> impl Iterator<Item = (u64, S)> + '_ {
(0..self.inner.entry_count()).map(move |i| {
let hash = self
.inner
.entry_hash(i)
.expect("index derived from entry_count is always in range");
let summary = self
.inner
.entry_summary(i)
.expect("index derived from entry_count is always in range");
(hash, unerase::<S>(&summary))
})
}
}