diff --git a/crates/service/src/prelude/global/mod.rs b/crates/service/src/prelude/global/mod.rs index a2761bd9b..aa0cbf288 100644 --- a/crates/service/src/prelude/global/mod.rs +++ b/crates/service/src/prelude/global/mod.rs @@ -46,8 +46,8 @@ pub trait G: Copy + Debug + 'static { + FloatCast; type Storage: for<'a> Storage = Self::VectorRef<'a>>; type L2: for<'a> G = &'a [Self::Scalar]>; - type VectorOwned: VectorOwned + Clone + Serialize + for<'a> Deserialize<'a>; - type VectorRef<'a>: VectorRef<'a> + Copy + 'a + type VectorOwned: Vector + Clone + Serialize + for<'a> Deserialize<'a>; + type VectorRef<'a>: Vector + Copy + 'a where Self: 'a; @@ -114,24 +114,17 @@ pub trait FloatCast: Sized { } } -pub trait VectorOwned { +pub trait Vector { fn dims(&self) -> u16; } -pub trait VectorRef<'a> { - fn dims(&self) -> u16; - fn length(&self) -> u16 { - self.dims() - } -} - -impl VectorOwned for Vec { +impl Vector for Vec { fn dims(&self) -> u16 { self.len().try_into().unwrap() } } -impl<'a, T> VectorRef<'a> for &'a [T] { +impl<'a, T> Vector for &'a [T] { fn dims(&self) -> u16 { self.len().try_into().unwrap() } diff --git a/crates/service/src/prelude/mod.rs b/crates/service/src/prelude/mod.rs index 16e20fb88..1ea2b02dc 100644 --- a/crates/service/src/prelude/mod.rs +++ b/crates/service/src/prelude/mod.rs @@ -7,7 +7,7 @@ mod sys; pub use self::error::ServiceError; pub use self::global::*; -pub use self::scalar::{SparseF32, SparseF32Element, SparseF32Ref, F16, F32}; +pub use self::scalar::{SparseF32, SparseF32Ref, F16, F32}; pub use self::search::{Element, Filter, Payload}; pub use self::storage::{DenseMmap, SparseMmap, Storage}; pub use self::sys::{Handle, Pointer}; diff --git a/crates/service/src/prelude/scalar/mod.rs b/crates/service/src/prelude/scalar/mod.rs index 237730926..1be763ff9 100644 --- a/crates/service/src/prelude/scalar/mod.rs +++ b/crates/service/src/prelude/scalar/mod.rs @@ -4,4 +4,4 @@ mod sparse_f32; pub use f16::F16; pub use f32::F32; -pub use sparse_f32::{SparseF32, SparseF32Element, SparseF32Ref}; +pub use sparse_f32::{SparseF32, SparseF32Ref}; diff --git a/crates/service/src/prelude/scalar/sparse_f32.rs b/crates/service/src/prelude/scalar/sparse_f32.rs index 72f000fa1..d8d28a233 100644 --- a/crates/service/src/prelude/scalar/sparse_f32.rs +++ b/crates/service/src/prelude/scalar/sparse_f32.rs @@ -1,12 +1,5 @@ use crate::prelude::*; use serde::{Deserialize, Serialize}; -use std::fmt::Display; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct SparseF32Element { - pub index: u16, - pub value: F32, -} #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SparseF32 { @@ -22,16 +15,6 @@ pub struct SparseF32Ref<'a> { pub values: &'a [F32], } -impl Display for SparseF32Element { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{{{}: {}}}", self.index, self.value) - } -} - -unsafe impl bytemuck::Zeroable for SparseF32Element {} - -unsafe impl bytemuck::Pod for SparseF32Element {} - impl<'a> From> for SparseF32 { fn from(value: SparseF32Ref<'a>) -> Self { Self { @@ -52,20 +35,16 @@ impl<'a> From<&'a SparseF32> for SparseF32Ref<'a> { } } -impl VectorOwned for SparseF32 { +impl Vector for SparseF32 { fn dims(&self) -> u16 { self.dims } } -impl<'a> VectorRef<'a> for SparseF32Ref<'a> { +impl<'a> Vector for SparseF32Ref<'a> { fn dims(&self) -> u16 { self.dims } - - fn length(&self) -> u16 { - self.indexes.len().try_into().unwrap() - } } impl<'a> SparseF32Ref<'a> { @@ -77,11 +56,7 @@ impl<'a> SparseF32Ref<'a> { dense } - pub fn iter(&self) -> impl Iterator + 'a { - self.indexes - .iter() - .copied() - .zip(self.values.iter().copied()) - .map(|(index, value)| SparseF32Element { index, value }) + pub fn length(&self) -> u16 { + self.indexes.len().try_into().unwrap() } } diff --git a/src/datatype/svecf32.rs b/src/datatype/svecf32.rs index 86fb55463..b882a7f12 100644 --- a/src/datatype/svecf32.rs +++ b/src/datatype/svecf32.rs @@ -141,7 +141,31 @@ impl PartialOrd for SVecf32 { impl Ord for SVecf32 { fn cmp(&self, other: &Self) -> Ordering { assert!(self.dims() == other.dims()); - self.data().iter().cmp(other.data().iter()) + let lhs = self.data(); + let rhs = other.data(); + let mut pos = 0; + let size1 = lhs.length() as usize; + let size2 = rhs.length() as usize; + while pos < size1 && pos < size2 { + let lhs_index = lhs.indexes[pos]; + let rhs_index = rhs.indexes[pos]; + let lhs_value = lhs.values[pos]; + let rhs_value = rhs.values[pos]; + match lhs_index.cmp(&rhs_index) { + Ordering::Less => return lhs_value.cmp(&F32::zero()), + Ordering::Greater => return F32::zero().cmp(&rhs_value), + Ordering::Equal => match lhs_value.cmp(&rhs_value) { + Ordering::Equal => {} + x => return x, + }, + } + pos += 1; + } + match size1.cmp(&size2) { + Ordering::Less => F32::zero().cmp(&rhs.values[pos]), + Ordering::Greater => lhs.values[pos].cmp(&F32::zero()), + Ordering::Equal => Ordering::Equal, + } } } @@ -640,23 +664,20 @@ fn _vectors_svector_from_array( } .friendly(); } - let mut vector: Vec = index + let mut vector: Vec<(u16, F32)> = index .iter_deny_null() .zip(value.iter_deny_null()) .map(|(index, value)| { if index < 0 || index >= dims as i32 { SessionError::BadValueDimensions.friendly(); } - SparseF32Element { - index: index as u16, - value: F32(value), - } + (index as u16, F32(value)) }) .collect(); - vector.sort_unstable_by_key(|x| x.index); + vector.sort_unstable_by_key(|x| x.0); if vector.len() > 1 { for i in 0..vector.len() - 1 { - if vector[i].index == vector[i + 1].index { + if vector[i].0 == vector[i + 1].0 { SessionError::BadLiteral { hint: "Duplicated index.".to_string(), } @@ -668,8 +689,8 @@ fn _vectors_svector_from_array( let mut indexes = Vec::::with_capacity(vector.len()); let mut values = Vec::::with_capacity(vector.len()); for x in vector { - indexes.push(x.index); - values.push(x.value); + indexes.push(x.0); + values.push(x.1); } SVecf32::new_in_postgres(SparseF32Ref { dims,