use super::input::ArrayOfDoublesInput;
use crate::error::SketchError;
use apache_datasketches_sys::array_of_doubles_input::ArrayOfDoublesInputRef;
use apache_datasketches_sys::array_of_doubles_jaccard::ffi as sys;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct JaccardBounds {
pub lower_bound: f64,
pub estimate: f64,
pub upper_bound: f64,
}
impl From<sys::TupleJaccardBoundsFfi> for JaccardBounds {
fn from(ffi: sys::TupleJaccardBoundsFfi) -> Self {
Self {
lower_bound: ffi.lower_bound,
estimate: ffi.estimate,
upper_bound: ffi.upper_bound,
}
}
}
pub fn array_of_doubles_jaccard_similarity(
a: &impl ArrayOfDoublesInput,
b: &impl ArrayOfDoublesInput,
) -> Result<JaccardBounds, SketchError> {
let (a_num, b_num) = (a.get_num_values(), b.get_num_values());
if a_num != b_num {
return Err(SketchError::InvalidConfig(format!(
"num_values mismatch: a has {a_num}, b has {b_num}"
)));
}
let ffi = match (a.as_input(), b.as_input()) {
(ArrayOfDoublesInputRef::Sketch(a), ArrayOfDoublesInputRef::Sketch(b)) => {
sys::tuple_jaccard_sketch_sketch(a, b)
}
(ArrayOfDoublesInputRef::Sketch(a), ArrayOfDoublesInputRef::Compact(b)) => {
sys::tuple_jaccard_sketch_compact(a, b)
}
(ArrayOfDoublesInputRef::Compact(a), ArrayOfDoublesInputRef::Sketch(b)) => {
sys::tuple_jaccard_compact_sketch(a, b)
}
(ArrayOfDoublesInputRef::Compact(a), ArrayOfDoublesInputRef::Compact(b)) => {
sys::tuple_jaccard_compact_compact(a, b)
}
};
Ok(ffi.into())
}