use super::builder::resize_factor_multiplier;
use super::{CompactTupleSketch, TupleInput, TupleSummary};
use crate::error::SketchError;
use crate::tuple::ResizeFactor;
use apache_datasketches_sys::tuple_generic_input::TupleGenericInputRef;
use apache_datasketches_sys::tuple_generic_union::ffi as sys;
use cxx::UniquePtr;
use std::marker::PhantomData;
pub struct TupleUnionBuilder<S: TupleSummary> {
lg_k: u8,
resize_factor: ResizeFactor,
p: f32,
_marker: PhantomData<fn() -> S>,
}
impl<S: TupleSummary> std::fmt::Debug for TupleUnionBuilder<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TupleUnionBuilder")
.field("lg_k", &self.lg_k)
.field("resize_factor", &self.resize_factor)
.field("p", &self.p)
.finish()
}
}
impl<S: TupleSummary> Clone for TupleUnionBuilder<S> {
fn clone(&self) -> Self {
*self
}
}
impl<S: TupleSummary> Copy for TupleUnionBuilder<S> {}
impl<S: TupleSummary> Default for TupleUnionBuilder<S> {
fn default() -> Self {
Self {
lg_k: 12,
resize_factor: ResizeFactor::X8,
p: 1.0,
_marker: PhantomData,
}
}
}
impl<S: TupleSummary> TupleUnionBuilder<S> {
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 build(self) -> Result<TupleUnion<S>, SketchError> {
let inner = sys::new_tuple_generic_union(
self.lg_k,
resize_factor_multiplier(self.resize_factor),
self.p,
)
.map_err(|e| SketchError::InvalidConfig(e.what().to_string()))?;
Ok(TupleUnion {
inner,
_marker: PhantomData,
})
}
}
pub struct TupleUnion<S: TupleSummary> {
inner: UniquePtr<sys::TupleGenericUnionShim>,
_marker: PhantomData<fn() -> S>,
}
unsafe impl<S: TupleSummary> Send for TupleUnion<S> {}
impl<S: TupleSummary> TupleUnion<S> {
pub fn update(&mut self, input: &impl TupleInput<S>) {
match input.as_input() {
TupleGenericInputRef::Sketch(s) => self.inner.pin_mut().update_with_sketch(s),
TupleGenericInputRef::Compact(c) => self.inner.pin_mut().update_with_compact(c),
}
}
pub fn get_result(&self, ordered: bool) -> CompactTupleSketch<S> {
CompactTupleSketch::from_shim(self.inner.get_result(ordered))
}
pub fn reset(&mut self) {
self.inner.pin_mut().reset();
}
}