use super::input::ArrayOfDoublesInput;
use super::{CompactArrayOfDoublesSketch, ResizeFactor};
use crate::error::SketchError;
use apache_datasketches_sys::array_of_doubles_input::ArrayOfDoublesInputRef;
use apache_datasketches_sys::array_of_doubles_union::ffi as sys;
use cxx::UniquePtr;
#[derive(Debug, Clone, Copy)]
pub struct ArrayOfDoublesUnionBuilder {
lg_k: u8,
resize_factor: ResizeFactor,
p: f32,
num_values: u8,
}
impl Default for ArrayOfDoublesUnionBuilder {
fn default() -> Self {
Self {
lg_k: 12,
resize_factor: ResizeFactor::default(),
p: 1.0,
num_values: 1,
}
}
}
impl ArrayOfDoublesUnionBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn lg_k(mut self, lg_k: u8) -> Self {
self.lg_k = lg_k;
self
}
pub fn resize_factor(mut self, resize_factor: ResizeFactor) -> Self {
self.resize_factor = resize_factor;
self
}
pub fn p(mut self, p: f32) -> Self {
self.p = p;
self
}
pub fn num_values(mut self, num_values: u8) -> Self {
self.num_values = num_values;
self
}
pub fn build(self) -> Result<ArrayOfDoublesUnion, SketchError> {
if self.num_values == 0 {
return Err(SketchError::InvalidConfig(
"num_values must be at least 1".to_string(),
));
}
let inner = sys::new_array_of_doubles_union(
self.lg_k,
self.resize_factor.into(),
self.p,
self.num_values,
)
.map_err(|e| SketchError::InvalidConfig(e.what().to_string()))?;
Ok(ArrayOfDoublesUnion {
inner,
num_values: self.num_values,
})
}
}
pub struct ArrayOfDoublesUnion {
inner: UniquePtr<sys::ArrayOfDoublesUnionShim>,
num_values: u8,
}
unsafe impl Send for ArrayOfDoublesUnion {}
impl ArrayOfDoublesUnion {
pub fn update(&mut self, input: &impl ArrayOfDoublesInput) -> Result<(), SketchError> {
let actual = input.get_num_values();
if actual != self.num_values {
return Err(SketchError::InvalidConfig(format!(
"num_values mismatch: union has {}, input has {actual}",
self.num_values
)));
}
match input.as_input() {
ArrayOfDoublesInputRef::Sketch(s) => self.inner.pin_mut().update_with_sketch(s),
ArrayOfDoublesInputRef::Compact(c) => self.inner.pin_mut().update_with_compact(c),
}
Ok(())
}
pub fn get_result(&self, ordered: bool) -> CompactArrayOfDoublesSketch {
CompactArrayOfDoublesSketch::from_shim(self.inner.get_result(ordered))
}
pub fn reset(&mut self) {
self.inner.pin_mut().reset();
}
pub fn get_num_values(&self) -> u8 {
self.num_values
}
}