Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,7 @@ where
let (vec, attrs) = changing.destructure();
let sim = self.inner_computer.evaluate_similarity(vec);
let pred_eval = PredicateEvaluator::new(attrs);
if self
.filter_expr
.encoded_filter_expr()
.accept(&pred_eval)
.expect("Expected predicate evaluation to not error out!")
{
if self.filter_expr.encoded_filter_expr().accept(&pred_eval) {
sim * self.beta_value
} else {
sim
Expand Down Expand Up @@ -180,7 +175,7 @@ where
let doc = accessor.get_element(candidate.id).await?;
let pe = PredicateEvaluator::new(doc.attributes());

if computer.filter_expr().encoded_filter_expr().accept(&pe)? {
if computer.filter_expr().encoded_filter_expr().accept(&pe) {
filtered_candidates.push(Neighbor::new(candidate.id, candidate.distance));
}
}
Expand Down
29 changes: 10 additions & 19 deletions diskann-label-filter/src/inline_beta_search/predicate_evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
* Licensed under the MIT license.
*/

use diskann::ANNResult;

use crate::{
attribute::AttributeType,
encoded_attribute_provider::ast_id_expr::{ASTIdExpr, ASTIdExprVisitor},
Expand Down Expand Up @@ -44,46 +42,39 @@ where
ST: Set<T>,
T: AttributeType,
{
type Output = ANNResult<bool>;
type Output = bool;

/// Visit an AND expression - all sub-expressions must be true
fn visit_and(&self, exprs: &[ASTIdExpr<T>]) -> Self::Output {
if exprs.is_empty() {
return Ok(true); // Empty AND is vacuously true
return true; // Empty AND is vacuously true
}

for expr in exprs {
match self.visit(expr) {
Ok(true) => continue, // Continue if true
Ok(false) => return Ok(false), // If any sub-expression is false, AND is false
Err(e) => return Err(e), // Propagate error
if !self.visit(expr) {
return false; // If any sub-expression is false, AND is false
}
}
Ok(true)
true
}

/// Visit an OR expression - at least one sub-expression must be true
fn visit_or(&self, exprs: &[ASTIdExpr<T>]) -> Self::Output {
if exprs.is_empty() {
return Ok(false); // Empty OR is false
return false; // Empty OR is false
}

for expr in exprs {
match self.visit(expr) {
Ok(true) => return Ok(true), // If any sub-expression is true, OR is true
Ok(false) => continue, // Continue if false
Err(e) => return Err(e), // Propagate error
if self.visit(expr) {
return true; // If any sub-expression is true, OR is true
}
}
Ok(false)
false
}

/// Visit a NOT expression - negate the result of the sub-expression
fn visit_not(&self, expr: &ASTIdExpr<T>) -> Self::Output {
match self.visit(expr) {
Ok(result) => Ok(!result),
Err(e) => Err(e),
}
!self.visit(expr)
}

/// Visit a comparison expression - check if the label exists in labels_of_point
Expand Down
48 changes: 24 additions & 24 deletions diskann-label-filter/src/set/roaring_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,21 @@ macro_rules! impl_set_for_roaring {
Ok(<$ty>::remove(self, *value))
}

fn contains(&self, value: &$elem) -> ANNResult<bool> {
Ok(<$ty>::contains(self, *value))
fn contains(&self, value: &$elem) -> bool {
<$ty>::contains(self, *value)
}

fn clear(&mut self) -> ANNResult<()> {
<$ty>::clear(self);
Ok(())
}

fn len(&self) -> ANNResult<usize> {
Ok(self.len() as usize)
fn len(&self) -> usize {
self.len() as usize
}

fn is_empty(&self) -> ANNResult<bool> {
Ok(self.is_empty())
fn is_empty(&self) -> bool {
self.is_empty()
}
}
};
Expand All @@ -69,8 +69,8 @@ mod tests {
{
// empty
let empty = S::empty_set();
assert_eq!(empty.len().unwrap(), 0);
assert!(empty.is_empty().unwrap());
assert_eq!(empty.len(), 0);
assert!(empty.is_empty());

// insert and contains
let mut a = S::empty_set();
Expand All @@ -86,21 +86,21 @@ mod tests {
// duplicate insert should return false since element already exists
assert!(!a.insert(&v3).unwrap());

assert_eq!(a.len().unwrap(), 3);
assert!(a.contains(&v1).unwrap());
assert!(a.contains(&v2).unwrap());
assert!(a.contains(&v3).unwrap());
assert!(!a.contains(&v4).unwrap());
assert_eq!(a.len(), 3);
assert!(a.contains(&v1));
assert!(a.contains(&v2));
assert!(a.contains(&v3));
assert!(!a.contains(&v4));

// is_empty on non-empty set
assert!(!a.is_empty().unwrap());
assert!(!a.is_empty());

// remove
assert!(a.remove(&v2).unwrap()); // should return true - element was present
assert!(!a.remove(&v2).unwrap()); // should return false - element no longer present
assert!(!a.remove(&v4).unwrap()); // should return false - element was never present
assert!(!a.contains(&v2).unwrap());
assert_eq!(a.len().unwrap(), 2);
assert!(!a.contains(&v2));
assert_eq!(a.len(), 2);
// add it back for following tests
assert!(a.insert(&v2).unwrap()); // should return true - element being newly inserted

Expand All @@ -111,23 +111,23 @@ mod tests {
assert!(b.insert(&v5).unwrap());

let u = a.union(&b);
assert_eq!(u.len().unwrap(), 5);
assert_eq!(u.len(), 5);
for v in [v1, v2, v3, v4, v5] {
assert!(u.contains(&v).unwrap());
assert!(u.contains(&v));
}

// intersection
let i = a.intersection(&b);
assert_eq!(i.len().unwrap(), 1);
assert!(i.contains(&v3).unwrap());
assert!(!i.contains(&v1).unwrap());
assert!(!i.contains(&v4).unwrap());
assert_eq!(i.len(), 1);
assert!(i.contains(&v3));
assert!(!i.contains(&v1));
assert!(!i.contains(&v4));

// clear
let mut c = a.clone();
assert!(c.len().unwrap() > 0);
assert!(c.len() > 0);
c.clear().unwrap();
assert_eq!(c.len().unwrap(), 0);
assert_eq!(c.len(), 0);

// iteration over owned set
let mut count = 0usize;
Expand Down
9 changes: 3 additions & 6 deletions diskann-label-filter/src/set/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,17 @@ pub trait Set<Element>: Clone + Default + IntoIterator<Item = Element> {
fn remove(&mut self, value: &Element) -> ANNResult<bool>;

/// Return true if `value` is a member of the set.
/// Return ANNError if the operation failed.
fn contains(&self, value: &Element) -> ANNResult<bool>;
fn contains(&self, value: &Element) -> bool;

/// Remove all elements from the set.
/// Return ANNError if the operation failed.
fn clear(&mut self) -> ANNResult<()>;

/// Return the number of elements in the set.
/// Return ANNError if the operation failed.
fn len(&self) -> ANNResult<usize>;
fn len(&self) -> usize;

/// Return true if the set is empty.
/// Return ANNError if the operation failed.
fn is_empty(&self) -> ANNResult<bool>;
fn is_empty(&self) -> bool;
}

/// Provider for sets that may live in memory or in a storage layer.
Expand Down