From 0a9980f2f1f30d39b479d0d90f9821bea2c619c7 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Tue, 19 May 2026 13:01:41 -0400 Subject: [PATCH 01/34] add specificity utility --- .../examples/compute_specificities.rs | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 diskann-label-filter/examples/compute_specificities.rs diff --git a/diskann-label-filter/examples/compute_specificities.rs b/diskann-label-filter/examples/compute_specificities.rs new file mode 100644 index 000000000..d73947af4 --- /dev/null +++ b/diskann-label-filter/examples/compute_specificities.rs @@ -0,0 +1,103 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + +use diskann_label_filter::{read_and_parse_queries, read_baselabels, eval_query_expr}; +use rayon::prelude::*; +use std::env; +use std::process; +use std::fs::File; +use std::io::Write; + +fn main() { + let args: Vec = env::args().collect(); + if args.len() != 3 && args.len() != 4 { + eprintln!("Usage: {} [specificity_output_file]", args[0]); + process::exit(1); + } + let base_label_file = &args[1]; + let query_label_file = &args[2]; + let output_file = if args.len() == 4 { Some(&args[3]) } else { None }; + + // Read base labels + let base_labels = match read_baselabels(base_label_file) { + Ok(labels) => labels, + Err(e) => { + eprintln!("Failed to read base label file: {}", e); + process::exit(1); + } + }; + let total_base = base_labels.len(); + if total_base == 0 { + eprintln!("No base points found in base label file."); + process::exit(1); + } + + // Read and parse queries + let parsed_queries = match read_and_parse_queries(query_label_file) { + Ok(q) => q, + Err(e) => { + eprintln!("Failed to read query label file: {}", e); + process::exit(1); + } + }; + + // Collect query ids and expressions into a vector for parallel iteration + let query_vec: Vec<_> = parsed_queries.iter().collect(); + + let results: Vec<(usize, usize, f64)> = query_vec + .par_iter() + .map(|(query_id, query_expr)| { + let mut count = 0; + for base_label in base_labels.iter() { + if eval_query_expr(query_expr, &base_label.label) { + count += 1; + } + } + let specificity = count as f64 / total_base as f64; + (**query_id, count, specificity) + }) + .collect(); + + let mut specificities = Vec::with_capacity(results.len()); + for (query_id, count, specificity) in &results { + specificities.push(*specificity); + println!("query_id {}: {} matches (specificity {:.6})", query_id, count, specificity); + } + + if let Some(path) = output_file { + let mut file = match File::create(path) { + Ok(f) => f, + Err(e) => { + eprintln!("Failed to create output file {}: {}", path, e); + process::exit(1); + } + }; + for spec in &specificities { + if let Err(e) = writeln!(file, "{:.6}", spec) { + eprintln!("Failed to write to output file: {}", e); + process::exit(1); + } + } + println!("Specificities written to {}", path); + } + + if !specificities.is_empty() { + specificities.sort_by(|a, b| a.partial_cmp(b).unwrap()); + let min = specificities[0]; + let max = specificities[specificities.len() - 1]; + let median = if specificities.len() % 2 == 0 { + let mid = specificities.len() / 2; + (specificities[mid - 1] + specificities[mid]) / 2.0 + } else { + specificities[specificities.len() / 2] + }; + let avg = specificities.iter().sum::() / specificities.len() as f64; + println!("\nSpecificity stats:"); + println!(" average: {:.6}", avg); + println!(" median: {:.6}", median); + println!(" min: {:.6}", min); + println!(" max: {:.6}", max); + } +} From e99177ac68779a4ba48e390a945b1595993050b2 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Wed, 20 May 2026 09:53:34 -0400 Subject: [PATCH 02/34] refactor example, add compute_bitmap --- Cargo.lock | 2 + diskann-label-filter/Cargo.toml | 3 + .../examples/compute_specificities.rs | 77 +++--- diskann-label-filter/src/lib.rs | 1 + .../src/utils/compute_bitmap.rs | 223 ++++++++++++++++++ .../src/utils/flatten_utils.rs | 6 +- 6 files changed, 274 insertions(+), 38 deletions(-) create mode 100644 diskann-label-filter/src/utils/compute_bitmap.rs diff --git a/Cargo.lock b/Cargo.lock index 94c12d370..0752f279b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -788,6 +788,7 @@ version = "0.52.0" dependencies = [ "anyhow", "bf-tree", + "bit-set", "criterion", "diskann", "diskann-utils", @@ -796,6 +797,7 @@ dependencies = [ "hashbrown 0.16.1", "num-traits", "rand 0.9.4", + "rayon", "roaring", "scc", "serde", diff --git a/diskann-label-filter/Cargo.toml b/diskann-label-filter/Cargo.toml index 98fe3879c..18b5d1f56 100644 --- a/diskann-label-filter/Cargo.toml +++ b/diskann-label-filter/Cargo.toml @@ -23,6 +23,9 @@ scc = "3.3.2" diskann-utils = { workspace = true, default-features = false } diskann-vector.workspace = true tracing.workspace = true +bit-set.workspace = true +rayon.workspace = true +anyhow.workspace = true [dev-dependencies] diff --git a/diskann-label-filter/examples/compute_specificities.rs b/diskann-label-filter/examples/compute_specificities.rs index d73947af4..13815e12e 100644 --- a/diskann-label-filter/examples/compute_specificities.rs +++ b/diskann-label-filter/examples/compute_specificities.rs @@ -10,6 +10,36 @@ use std::process; use std::fs::File; use std::io::Write; +use crate::utils::compute_bitmaps::read_labels_and_compute_bitmap; + +pub fn read_labels_and_compute_bitmap_naive( + base_label_filename: &str, + query_label_filename: &str, +) -> Result, anyhow::Error> { + // Read base labels + let base_labels = read_baselabels(base_label_filename)?; + + // Parse queries and evaluate against labels + let parsed_queries = read_and_parse_queries(query_label_filename)?; + + // using the global threadpool is fine here + #[allow(clippy::disallowed_methods)] + let query_bitmaps: Vec = parsed_queries + .par_iter() + .map(|(_query_id, query_expr)| { + let mut bitmap = BitSet::new(); + for base_label in base_labels.iter() { + if eval_query_expr(query_expr, &base_label.label) { + bitmap.insert(base_label.doc_id); + } + } + bitmap + }) + .collect(); + + Ok(query_bitmaps) +} + fn main() { let args: Vec = env::args().collect(); if args.len() != 3 && args.len() != 4 { @@ -20,51 +50,28 @@ fn main() { let query_label_file = &args[2]; let output_file = if args.len() == 4 { Some(&args[3]) } else { None }; - // Read base labels - let base_labels = match read_baselabels(base_label_file) { - Ok(labels) => labels, - Err(e) => { - eprintln!("Failed to read base label file: {}", e); - process::exit(1); - } - }; - let total_base = base_labels.len(); - if total_base == 0 { - eprintln!("No base points found in base label file."); - process::exit(1); - } - - // Read and parse queries - let parsed_queries = match read_and_parse_queries(query_label_file) { - Ok(q) => q, + let bitmaps = match read_labels_and_compute_bitmap_naive(base_label_file, query_label_file) { + Ok(b) => b, Err(e) => { - eprintln!("Failed to read query label file: {}", e); + eprintln!("Error computing bitmaps: {}", e); process::exit(1); } }; - // Collect query ids and expressions into a vector for parallel iteration - let query_vec: Vec<_> = parsed_queries.iter().collect(); - - let results: Vec<(usize, usize, f64)> = query_vec + let specificities: Vec = bitmaps .par_iter() - .map(|(query_id, query_expr)| { - let mut count = 0; - for base_label in base_labels.iter() { - if eval_query_expr(query_expr, &base_label.label) { - count += 1; - } - } + .map(|bitmap| { + let count = bitmap.len(); let specificity = count as f64 / total_base as f64; - (**query_id, count, specificity) + specificity }) .collect(); - let mut specificities = Vec::with_capacity(results.len()); - for (query_id, count, specificity) in &results { - specificities.push(*specificity); - println!("query_id {}: {} matches (specificity {:.6})", query_id, count, specificity); - } + // let mut specificities = Vec::with_capacity(results.len()); + // for (query_id, count, specificity) in &results { + // specificities.push(*specificity); + // println!("query_id {}: {} matches (specificity {:.6})", query_id, count, specificity); + // } if let Some(path) = output_file { let mut file = match File::create(path) { diff --git a/diskann-label-filter/src/lib.rs b/diskann-label-filter/src/lib.rs index 106845f98..1745ec712 100644 --- a/diskann-label-filter/src/lib.rs +++ b/diskann-label-filter/src/lib.rs @@ -15,6 +15,7 @@ pub mod parser { pub mod utils { pub mod flatten_utils; pub mod jsonl_reader; + pub mod compute_bitmap; } pub mod inline_beta_search { diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs new file mode 100644 index 000000000..3c57751ea --- /dev/null +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -0,0 +1,223 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + +use bit_set::BitSet; +use std::collections::HashMap; +use std::mem::discriminant; +// use serde_json::Value; +use crate::{ASTExpr, CompareOp}; +use crate::attribute::AttributeValue; +use crate::parser::evaluator::eval_query_expr; +use crate::utils::jsonl_reader::read_and_parse_queries; +use crate::utils::jsonl_reader::read_baselabels; +use crate::utils::{flatten_utils::flatten_json_pointers}; +// use crate::parser::{format::Document}; +use rayon::prelude::*; + +pub enum QueryAccelerator { + InvertedIndex(HashMap), + RTree, // Placeholder for future implementation +} + +pub fn eval_query_using_accelerators( + query_expr: &ASTExpr, + query_accelerators: &HashMap, +) -> BitSet { + let bitset = match query_expr { + ASTExpr::And(subs) => + subs.iter().map(|e| eval_query_using_accelerators(e, query_accelerators)).fold(BitSet::new(), |acc, b| { + if acc.is_empty() { + b + } else { + acc.intersection(&b).collect() + } + }), + ASTExpr::Or(subs) => subs.iter().map(|e| eval_query_using_accelerators(e, query_accelerators)).fold(BitSet::new(), |acc, b| { + if acc.is_empty() { + b + } else { + acc.union(&b).collect() + } + }), + ASTExpr::Not(sub) => { + // Want to flip all the bits in the bitmap, but we need to know + // the document universe for that. We could potentially disallow + // empty labels, and then compute the complement + panic!("NOT operator is not supported yet"); + }, + ASTExpr::Compare { field, op } => { + if let Some(accelerator) = query_accelerators.get(field) { + match accelerator { + QueryAccelerator::InvertedIndex(bitmap) => { + // We can only accelerate equality comparisons + // with the inverted index + match op { + CompareOp::Eq(value) => bitmap.get(&AttributeValue::try_from(value).unwrap()).cloned().unwrap_or_default(), + CompareOp::Ne(value) => { + let mut result = BitSet::new(); + for (val, bits) in bitmap.iter() { + if val != &AttributeValue::try_from(value).unwrap() { + result.extend(bits); + } + } + result + }, + _ => { + // For other comparison operators, we would need a different accelerator (e.g. an RTree) + panic!("Only equality comparisons are supported with the inverted index accelerator"); + } + } + }, + QueryAccelerator::RTree => { + // RTree acceleration logic would go here + panic!("RTree accelerator is not implemented yet"); + // match op { + // CompareOp::Eq(value) => field_val == value, + // CompareOp::Ne(value) => field_val != value, + // CompareOp::Lt(num) => { + // if let Some(f1) = field_val.as_f64() { + // f1 < *num + // } else { + // false + // } + // } + // CompareOp::Lte(num) => { + // if let Some(f1) = field_val.as_f64() { + // f1 <= *num + // } else { + // false + // } + // } + // CompareOp::Gt(num) => { + // if let Some(f1) = field_val.as_f64() { + // f1 > *num + // } else { + // false + // } + // } + // CompareOp::Gte(num) => { + // if let Some(f1) = field_val.as_f64() { + // f1 >= *num + // } else { + // false + // } + // } + // } + } + } + } else{ + // if field not present, return an empty bitset + return BitSet::new(); + } + } + }; + bitset +} + +pub fn compute_inverted_index_bitmap( + key: String, + labels: Vec>) + -> Result, anyhow::Error> +{ + let mut inverted_index: HashMap = HashMap::new(); + for (doc_id, label) in labels.iter().enumerate() { + if let Some(value) = label.get(&key) { + inverted_index.entry(value.clone()).or_insert_with(BitSet::new).insert(doc_id); + } + } + Ok(inverted_index) +} + +// Compute a global label set across all documents with a representative element +// Make sure that each global label only maps to the same type of AttributeValue, and throw an error otherwise +pub fn compute_global_label_set(flattened_base_labels: &Vec>) -> Result, anyhow::Error> { + let mut global_label_set = HashMap::new(); + for labels in flattened_base_labels { + for (key, value) in labels { + if let Some(existing_value) = global_label_set.get(key) { + if discriminant(existing_value) != discriminant(value) { + return Err(anyhow::anyhow!("Inconsistent types for key: {}", key)); + } + } + global_label_set.insert(key.clone(), value.clone()); + } + } + Ok(global_label_set) +} + +pub fn compute_query_accelerator( + key: String, + value: AttributeValue, + flattened_base_labels: &Vec> +) -> QueryAccelerator { + match value { + AttributeValue::String(_) | AttributeValue::Bool(_) => { + let bitmap = compute_inverted_index_bitmap(key.clone(), flattened_base_labels.clone()).unwrap_or_default(); + QueryAccelerator::InvertedIndex(bitmap) + }, + AttributeValue::Integer(_) | AttributeValue::Real(_) => { + // For integers and reals, we use an RTree + QueryAccelerator::RTree + } + AttributeValue::Empty => { + // TODO this should be an error or something + QueryAccelerator::RTree + } + } +} + +pub fn read_labels_and_compute_bitmap( + base_label_filename: &str, + query_label_filename: &str, +) -> Result, anyhow::Error> { + // Read base labels + let base_labels = read_baselabels(base_label_filename)?; + + // Flatten base labels + let flattened_base_labels: Vec> = base_labels + .iter() + .map(|base_label| flatten_json_pointers(&base_label.label)) + .collect(); + + let flattened_base_label_hashmaps: Result>, anyhow::Error> = + flattened_base_labels.iter().map(|labels| { + let mut map = HashMap::new(); + for (key, value) in labels { + if let Some(_existing_value) = map.get(key) { + return Err(anyhow::anyhow!("Duplicate keys in the same document: {}", key)); + } + map.insert(key.clone(), value.clone()); + } + Ok(map) + }).collect(); + + let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; + + let global_label_set = compute_global_label_set(&flattened_base_label_hashmaps)?; + + #[allow(clippy::disallowed_methods)] + let query_accelerators: Vec<(String, QueryAccelerator)> = global_label_set.par_iter() + .map(|(key, value)| { + (key.clone(), compute_query_accelerator(key.clone(), value.clone(), &flattened_base_label_hashmaps)) + }) + .collect(); + + // Convert to a HashMap for easier access during query evaluation + let query_accelerators: HashMap = query_accelerators.into_iter().collect(); + + // Parse queries and evaluate against labels + let parsed_queries = read_and_parse_queries(query_label_filename)?; + + // using the global threadpool is fine here + #[allow(clippy::disallowed_methods)] + let query_bitmaps: Vec = parsed_queries + .par_iter() + .map(|(_query_id, query_expr)| { + eval_query_using_accelerators(query_expr, &query_accelerators) + }) + .collect(); + + Ok(query_bitmaps) +} \ No newline at end of file diff --git a/diskann-label-filter/src/utils/flatten_utils.rs b/diskann-label-filter/src/utils/flatten_utils.rs index 16404af4b..c3c7c61df 100644 --- a/diskann-label-filter/src/utils/flatten_utils.rs +++ b/diskann-label-filter/src/utils/flatten_utils.rs @@ -13,7 +13,7 @@ pub type Attributes = HashMap; /// Configuration for JSON flattening behavior #[derive(Debug, Clone)] pub struct FlattenConfig { - /// Separator used between path segments (default: "/") + /// Separator used between path segments (default: ".") pub separator: String, /// Whether to include array indices in paths (default: true) pub include_array_indices: bool, @@ -24,7 +24,7 @@ pub struct FlattenConfig { impl Default for FlattenConfig { fn default() -> Self { Self { - separator: "/".to_string(), + separator: ".".to_string(), include_array_indices: true, root_prefix: "".to_string(), } @@ -191,7 +191,7 @@ pub fn flatten_json_pointers(value: &Value) -> AttributesVec { /// Configurable version that uses FlattenConfig /// /// Example: -/// With config.separator="/": {"a": {"b": [1, 2]}} -> [ ("/a/b/0", 1), ("/a/b/1", 2) ] +/// With config.separator=".": {"a": {"b": [1, 2]}} -> [ ("/a/b/0", 1), ("/a/b/1", 2) ] pub fn flatten_json_pointers_with_config(value: &Value, config: &FlattenConfig) -> AttributesVec { let mut out = Vec::new(); flatten_json_pointer_inner(value, &config.root_prefix, &mut out, &config.separator); From ce447a3d4248ab5d23e2c62c089d397f0e7f3cd6 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Wed, 20 May 2026 15:22:24 +0000 Subject: [PATCH 03/34] commit to switch --- .../examples/compute_specificities.rs | 21 +++++++++++++++---- diskann-label-filter/src/lib.rs | 1 + .../src/utils/compute_bitmap.rs | 15 +++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/diskann-label-filter/examples/compute_specificities.rs b/diskann-label-filter/examples/compute_specificities.rs index 13815e12e..e584da8bd 100644 --- a/diskann-label-filter/examples/compute_specificities.rs +++ b/diskann-label-filter/examples/compute_specificities.rs @@ -3,14 +3,14 @@ * Licensed under the MIT license. */ -use diskann_label_filter::{read_and_parse_queries, read_baselabels, eval_query_expr}; +use diskann_label_filter::{read_and_parse_queries, read_baselabels, eval_query_expr, read_labels_and_compute_bitmap}; use rayon::prelude::*; use std::env; use std::process; use std::fs::File; use std::io::Write; +use bit_set::BitSet; -use crate::utils::compute_bitmaps::read_labels_and_compute_bitmap; pub fn read_labels_and_compute_bitmap_naive( base_label_filename: &str, @@ -50,15 +50,28 @@ fn main() { let query_label_file = &args[2]; let output_file = if args.len() == 4 { Some(&args[3]) } else { None }; - let bitmaps = match read_labels_and_compute_bitmap_naive(base_label_file, query_label_file) { + let base_labels = match read_baselabels(base_label_file) { + Ok(labels) => labels, + Err(e) => { + eprintln!("Error reading base labels: {}", e); + process::exit(1); + } + }; + + let total_base = base_labels.len() as u64; + + let start = std::time::Instant::now(); + let bitmaps = match read_labels_and_compute_bitmap(base_label_file, query_label_file) { Ok(b) => b, Err(e) => { eprintln!("Error computing bitmaps: {}", e); process::exit(1); } }; + let elapsed = start.elapsed(); + println!("read_labels_and_compute_bitmap_naive took {:.3?}", elapsed); - let specificities: Vec = bitmaps + let mut specificities: Vec = bitmaps .par_iter() .map(|bitmap| { let count = bitmap.len(); diff --git a/diskann-label-filter/src/lib.rs b/diskann-label-filter/src/lib.rs index 1745ec712..d2bddc32a 100644 --- a/diskann-label-filter/src/lib.rs +++ b/diskann-label-filter/src/lib.rs @@ -78,3 +78,4 @@ pub use utils::flatten_utils::Attributes; pub use utils::jsonl_reader::{ read_and_parse_queries, read_baselabels, read_ground_truth, read_queries, JsonlReadError, }; +pub use utils::compute_bitmap::read_labels_and_compute_bitmap; diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 3c57751ea..91c9bab07 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -181,6 +181,14 @@ pub fn read_labels_and_compute_bitmap( .map(|base_label| flatten_json_pointers(&base_label.label)) .collect(); + // print the string in the first document for debugging + if let Some(first_doc) = flattened_base_labels.first() { + println!("First document flattened labels:"); + for (key, value) in first_doc { + println!("{}: {:?}", key, value); + } + } + let flattened_base_label_hashmaps: Result>, anyhow::Error> = flattened_base_labels.iter().map(|labels| { let mut map = HashMap::new(); @@ -195,7 +203,14 @@ pub fn read_labels_and_compute_bitmap( let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; + // print all the keys in the global label set for debugging let global_label_set = compute_global_label_set(&flattened_base_label_hashmaps)?; + println!("Global label set:"); + for (key, value) in &global_label_set { + println!("{}: {:?}", key, value); + } + + // let global_label_set = compute_global_label_set(&flattened_base_label_hashmaps)?; #[allow(clippy::disallowed_methods)] let query_accelerators: Vec<(String, QueryAccelerator)> = global_label_set.par_iter() From e03905198ee18625d1b8f27504976c4d0d884ee9 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Thu, 21 May 2026 21:58:50 +0000 Subject: [PATCH 04/34] work out kinks in OrderedFloat --- .../examples/compute_specificities.rs | 61 +- diskann-label-filter/src/lib.rs | 4 +- .../src/utils/compute_bitmap.rs | 1014 ++++++++++++++--- .../src/utils/flatten_utils.rs | 4 +- 4 files changed, 877 insertions(+), 206 deletions(-) diff --git a/diskann-label-filter/examples/compute_specificities.rs b/diskann-label-filter/examples/compute_specificities.rs index e584da8bd..9ded85342 100644 --- a/diskann-label-filter/examples/compute_specificities.rs +++ b/diskann-label-filter/examples/compute_specificities.rs @@ -3,52 +3,29 @@ * Licensed under the MIT license. */ -use diskann_label_filter::{read_and_parse_queries, read_baselabels, eval_query_expr, read_labels_and_compute_bitmap}; +use diskann_label_filter::{compute_query_bitmaps, read_and_parse_queries, read_baselabels}; use rayon::prelude::*; use std::env; -use std::process; use std::fs::File; use std::io::Write; -use bit_set::BitSet; - - -pub fn read_labels_and_compute_bitmap_naive( - base_label_filename: &str, - query_label_filename: &str, -) -> Result, anyhow::Error> { - // Read base labels - let base_labels = read_baselabels(base_label_filename)?; - - // Parse queries and evaluate against labels - let parsed_queries = read_and_parse_queries(query_label_filename)?; - - // using the global threadpool is fine here - #[allow(clippy::disallowed_methods)] - let query_bitmaps: Vec = parsed_queries - .par_iter() - .map(|(_query_id, query_expr)| { - let mut bitmap = BitSet::new(); - for base_label in base_labels.iter() { - if eval_query_expr(query_expr, &base_label.label) { - bitmap.insert(base_label.doc_id); - } - } - bitmap - }) - .collect(); - - Ok(query_bitmaps) -} +use std::process; fn main() { let args: Vec = env::args().collect(); if args.len() != 3 && args.len() != 4 { - eprintln!("Usage: {} [specificity_output_file]", args[0]); + eprintln!( + "Usage: {} [specificity_output_file]", + args[0] + ); process::exit(1); } let base_label_file = &args[1]; let query_label_file = &args[2]; - let output_file = if args.len() == 4 { Some(&args[3]) } else { None }; + let output_file = if args.len() == 4 { + Some(&args[3]) + } else { + None + }; let base_labels = match read_baselabels(base_label_file) { Ok(labels) => labels, @@ -60,8 +37,16 @@ fn main() { let total_base = base_labels.len() as u64; + let query_labels = match read_and_parse_queries(query_label_file) { + Ok(queries) => queries, + Err(e) => { + eprintln!("Error reading query labels: {}", e); + process::exit(1); + } + }; + let start = std::time::Instant::now(); - let bitmaps = match read_labels_and_compute_bitmap(base_label_file, query_label_file) { + let bitmaps = match compute_query_bitmaps(base_labels, query_labels) { Ok(b) => b, Err(e) => { eprintln!("Error computing bitmaps: {}", e); @@ -80,12 +65,6 @@ fn main() { }) .collect(); - // let mut specificities = Vec::with_capacity(results.len()); - // for (query_id, count, specificity) in &results { - // specificities.push(*specificity); - // println!("query_id {}: {} matches (specificity {:.6})", query_id, count, specificity); - // } - if let Some(path) = output_file { let mut file = match File::create(path) { Ok(f) => f, diff --git a/diskann-label-filter/src/lib.rs b/diskann-label-filter/src/lib.rs index d2bddc32a..cdd9cc3ed 100644 --- a/diskann-label-filter/src/lib.rs +++ b/diskann-label-filter/src/lib.rs @@ -13,9 +13,9 @@ pub mod parser { // Utils pub mod utils { + pub mod compute_bitmap; pub mod flatten_utils; pub mod jsonl_reader; - pub mod compute_bitmap; } pub mod inline_beta_search { @@ -74,8 +74,8 @@ pub use parser::query_parser::{get_value_by_path, parse_query_filter}; pub use traits::inverted_index_trait::InvertedIndexProvider; pub use traits::key_codec::DefaultKeyCodec; pub use traits::kv_store_traits::KvStore; +pub use utils::compute_bitmap::compute_query_bitmaps; pub use utils::flatten_utils::Attributes; pub use utils::jsonl_reader::{ read_and_parse_queries, read_baselabels, read_ground_truth, read_queries, JsonlReadError, }; -pub use utils::compute_bitmap::read_labels_and_compute_bitmap; diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 91c9bab07..40bda62db 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -3,136 +3,260 @@ * Licensed under the MIT license. */ -use bit_set::BitSet; -use std::collections::HashMap; -use std::mem::discriminant; -// use serde_json::Value; -use crate::{ASTExpr, CompareOp}; use crate::attribute::AttributeValue; use crate::parser::evaluator::eval_query_expr; -use crate::utils::jsonl_reader::read_and_parse_queries; -use crate::utils::jsonl_reader::read_baselabels; -use crate::utils::{flatten_utils::flatten_json_pointers}; -// use crate::parser::{format::Document}; +use crate::utils::flatten_utils::{flatten_json_pointers_with_config, FlattenConfig}; +use crate::{parser::format::Document, ASTExpr, CompareOp}; +use bit_set::BitSet; use rayon::prelude::*; +use std::cmp::Ordering; +use std::collections::BTreeMap; +use std::collections::HashMap; +use std::mem::discriminant; +use std::ops::Bound::{Excluded, Included, Unbounded}; + +pub struct NotNonNan; +impl std::fmt::Display for NotNonNan { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "NotNonNan") + } +} + +#[derive(Debug, Copy, Clone, PartialEq)] +pub struct OrderedFloat(f64); + +impl OrderedFloat { + pub fn new(v: f64) -> Result { + if v.is_nan() { + Err(NotNonNan) + } else { + Ok(Self(v)) + } + } +} + +impl Eq for OrderedFloat {} +impl PartialOrd for OrderedFloat { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} +impl Ord for OrderedFloat { + fn cmp(&self, other: &Self) -> Ordering { + // By construction, we know the partial comparison will succeed. + // Return `Eq` if it doesn't for better code-gen. + self.0.partial_cmp(&other.0).unwrap_or(Ordering::Equal) + } +} pub enum QueryAccelerator { InvertedIndex(HashMap), - RTree, // Placeholder for future implementation + BTree(BTreeMap>), +} + +pub fn check_for_disallowed_operators(query_expr: &ASTExpr) -> bool { + match query_expr { + ASTExpr::Not(_) => true, + ASTExpr::And(subs) => subs.iter().any(check_for_disallowed_operators), + ASTExpr::Or(subs) => subs.iter().any(check_for_disallowed_operators), + ASTExpr::Compare { .. } => false, + } } pub fn eval_query_using_accelerators( query_expr: &ASTExpr, query_accelerators: &HashMap, -) -> BitSet { - let bitset = match query_expr { - ASTExpr::And(subs) => - subs.iter().map(|e| eval_query_using_accelerators(e, query_accelerators)).fold(BitSet::new(), |acc, b| { - if acc.is_empty() { - b - } else { - acc.intersection(&b).collect() +) -> Result { + match query_expr { + ASTExpr::And(subs) => { + let mut acc: Option = None; + for e in subs { + let b = eval_query_using_accelerators(e, query_accelerators)?; + acc = Some(match acc { + None => b, + Some(acc_b) => acc_b.intersection(&b).collect(), + }); } - }), - ASTExpr::Or(subs) => subs.iter().map(|e| eval_query_using_accelerators(e, query_accelerators)).fold(BitSet::new(), |acc, b| { - if acc.is_empty() { - b - } else { - acc.union(&b).collect() + Ok(acc.unwrap_or_else(BitSet::new)) + } + ASTExpr::Or(subs) => { + let mut acc: Option = None; + for e in subs { + let b = eval_query_using_accelerators(e, query_accelerators)?; + acc = Some(match acc { + None => b, + Some(acc_b) => acc_b.union(&b).collect(), + }); } - }), - ASTExpr::Not(sub) => { - // Want to flip all the bits in the bitmap, but we need to know - // the document universe for that. We could potentially disallow - // empty labels, and then compute the complement - panic!("NOT operator is not supported yet"); - }, + Ok(acc.unwrap_or_else(BitSet::new)) + } + ASTExpr::Not(_) => Err(anyhow::anyhow!( + "NOT operator is not supported when using query accelerators" + )), ASTExpr::Compare { field, op } => { - if let Some(accelerator) = query_accelerators.get(field) { + let separator = FlattenConfig::dot_notation().separator; + let field = if !field.starts_with(&separator) { + format!("{}{}", separator, field) + } else { + field.clone() + }; + if let Some(accelerator) = query_accelerators.get(&field) { match accelerator { QueryAccelerator::InvertedIndex(bitmap) => { - // We can only accelerate equality comparisons - // with the inverted index match op { - CompareOp::Eq(value) => bitmap.get(&AttributeValue::try_from(value).unwrap()).cloned().unwrap_or_default(), + CompareOp::Eq(value) => { + let attr_val = AttributeValue::try_from(value).map_err(|e| anyhow::anyhow!("Failed to convert value for Eq: {e}"))?; + Ok(bitmap.get(&attr_val).cloned().unwrap_or_default()) + } CompareOp::Ne(value) => { + let attr_val = AttributeValue::try_from(value).map_err(|e| anyhow::anyhow!("Failed to convert value for Ne: {e}"))?; let mut result = BitSet::new(); for (val, bits) in bitmap.iter() { - if val != &AttributeValue::try_from(value).unwrap() { + if val != &attr_val { result.extend(bits); } } - result - }, + Ok(result) + } _ => { - // For other comparison operators, we would need a different accelerator (e.g. an RTree) - panic!("Only equality comparisons are supported with the inverted index accelerator"); + Err(anyhow::anyhow!("Only equality comparisons are supported with the inverted index accelerator")) + } + } + } + QueryAccelerator::BTree(btree) => { + match op { + CompareOp::Eq(value) => { + let fval = value.as_f64().ok_or_else(|| anyhow::anyhow!("Failed to convert value to f64 for Eq"))?; + let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + if let Some(ids) = btree.get(&fval) { + let mut bitset = BitSet::new(); + bitset.extend(ids.iter().cloned()); + Ok(bitset) + } else { + Ok(BitSet::new()) + } + } + CompareOp::Ne(value) => { + let fval = value.as_f64().ok_or_else(|| anyhow::anyhow!("Failed to convert value to f64 for Ne"))?; + let mut all_ids = Vec::new(); + for (val, ids) in btree.iter() { + let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + if val != &fval { + all_ids.extend(ids.iter().cloned()); + } + } + let mut bitset = BitSet::new(); + bitset.extend(all_ids); + Ok(bitset) + } + CompareOp::Lt(value) => { + let fval = *value; + let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + let iter = btree.range((Unbounded, Excluded(fval))); + let mut all_ids = Vec::new(); + for (_, ids) in iter { + all_ids.extend(ids.iter().cloned()); + } + let mut bitset = BitSet::new(); + bitset.extend(all_ids); + Ok(bitset) + } + CompareOp::Lte(value) => { + let fval = *value; + let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + let iter = btree.range((Unbounded, Included(fval))); + let mut all_ids = Vec::new(); + for (_, ids) in iter { + all_ids.extend(ids.iter().cloned()); + } + let mut bitset = BitSet::new(); + bitset.extend(all_ids); + Ok(bitset) + } + CompareOp::Gt(value) => { + let fval = *value; + let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + let iter = btree.range((Excluded(fval), Unbounded)); + let mut all_ids = Vec::new(); + for (_, ids) in iter { + all_ids.extend(ids.iter().cloned()); + } + let mut bitset = BitSet::new(); + bitset.extend(all_ids); + Ok(bitset) + } + CompareOp::Gte(value) => { + let fval = *value; + let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + let iter = btree.range((Included(fval), Unbounded)); + let mut all_ids = Vec::new(); + for (_, ids) in iter { + all_ids.extend(ids.iter().cloned()); + } + let mut bitset = BitSet::new(); + bitset.extend(all_ids); + Ok(bitset) } } - }, - QueryAccelerator::RTree => { - // RTree acceleration logic would go here - panic!("RTree accelerator is not implemented yet"); - // match op { - // CompareOp::Eq(value) => field_val == value, - // CompareOp::Ne(value) => field_val != value, - // CompareOp::Lt(num) => { - // if let Some(f1) = field_val.as_f64() { - // f1 < *num - // } else { - // false - // } - // } - // CompareOp::Lte(num) => { - // if let Some(f1) = field_val.as_f64() { - // f1 <= *num - // } else { - // false - // } - // } - // CompareOp::Gt(num) => { - // if let Some(f1) = field_val.as_f64() { - // f1 > *num - // } else { - // false - // } - // } - // CompareOp::Gte(num) => { - // if let Some(f1) = field_val.as_f64() { - // f1 >= *num - // } else { - // false - // } - // } - // } } } - } else{ + } else { // if field not present, return an empty bitset - return BitSet::new(); + Ok(BitSet::new()) } } - }; - bitset + } } -pub fn compute_inverted_index_bitmap( - key: String, - labels: Vec>) - -> Result, anyhow::Error> -{ +pub fn compute_inverted_index_accelerator( + key: String, + labels: Vec>, +) -> Result, anyhow::Error> { let mut inverted_index: HashMap = HashMap::new(); for (doc_id, label) in labels.iter().enumerate() { if let Some(value) = label.get(&key) { - inverted_index.entry(value.clone()).or_insert_with(BitSet::new).insert(doc_id); + inverted_index + .entry(value.clone()) + .or_insert_with(BitSet::new) + .insert(doc_id); } } Ok(inverted_index) } +pub fn compute_btree_accelerator( + key: String, + labels: Vec>, +) -> Result>, anyhow::Error> { + // Implementation for computing BTree accelerator + let mut map: BTreeMap> = BTreeMap::new(); + for (doc_id, label) in labels.iter().enumerate() { + if let Some(value) = label.get(&key) { + if let Some(f64_value) = value.as_float() { + let f64_value = OrderedFloat::new(f64_value) + .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + map.entry(f64_value).or_default().push(doc_id); + } else if let Some(i64_value) = value.as_integer() { + let i64_value = OrderedFloat::new(i64_value as f64) + .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + map.entry(i64_value).or_default().push(doc_id); + } else { + // Error for other attribute values + return Err(anyhow::anyhow!( + "Unsupported attribute value for key: {}", + key + )); + } + } + } + Ok(map) +} + // Compute a global label set across all documents with a representative element // Make sure that each global label only maps to the same type of AttributeValue, and throw an error otherwise -pub fn compute_global_label_set(flattened_base_labels: &Vec>) -> Result, anyhow::Error> { +pub fn compute_global_label_set( + flattened_base_labels: &Vec>, +) -> Result, anyhow::Error> { let mut global_label_set = HashMap::new(); for labels in flattened_base_labels { for (key, value) in labels { @@ -150,89 +274,657 @@ pub fn compute_global_label_set(flattened_base_labels: &Vec> -) -> QueryAccelerator { + flattened_base_labels: &[HashMap], +) -> Result { match value { AttributeValue::String(_) | AttributeValue::Bool(_) => { - let bitmap = compute_inverted_index_bitmap(key.clone(), flattened_base_labels.clone()).unwrap_or_default(); - QueryAccelerator::InvertedIndex(bitmap) - }, - AttributeValue::Integer(_) | AttributeValue::Real(_) => { - // For integers and reals, we use an RTree - QueryAccelerator::RTree + let bitmap = + compute_inverted_index_accelerator(key.clone(), flattened_base_labels.to_vec()) + .unwrap_or_default(); + Ok(QueryAccelerator::InvertedIndex(bitmap)) } - AttributeValue::Empty => { - // TODO this should be an error or something - QueryAccelerator::RTree + AttributeValue::Integer(_) | AttributeValue::Real(_) => { + // For integers and reals, we use an BTree + let btree = compute_btree_accelerator(key.clone(), flattened_base_labels.to_vec()) + .unwrap_or_default(); + Ok(QueryAccelerator::BTree(btree)) } + AttributeValue::Empty => Err(anyhow::anyhow!("Empty attribute value is not allowed")), } } -pub fn read_labels_and_compute_bitmap( - base_label_filename: &str, - query_label_filename: &str, +pub fn compute_query_bitmaps( + base_labels: Vec, + query_labels: Vec<(usize, ASTExpr)>, ) -> Result, anyhow::Error> { - // Read base labels - let base_labels = read_baselabels(base_label_filename)?; - - // Flatten base labels - let flattened_base_labels: Vec> = base_labels + // read query labels and differentiate between fast and slow path + let bitmaps = if query_labels .iter() - .map(|base_label| flatten_json_pointers(&base_label.label)) - .collect(); - - // print the string in the first document for debugging - if let Some(first_doc) = flattened_base_labels.first() { - println!("First document flattened labels:"); - for (key, value) in first_doc { - println!("{}: {:?}", key, value); - } - } + .any(|(_, expr)| check_for_disallowed_operators(expr)) + { + // using the global threadpool is fine here + #[allow(clippy::disallowed_methods)] + let query_bitmaps: Vec = query_labels + .par_iter() + .map(|(_query_id, query_expr)| { + let mut bitmap = BitSet::new(); + for base_label in base_labels.iter() { + if eval_query_expr(query_expr, &base_label.label) { + bitmap.insert(base_label.doc_id); + } + } + bitmap + }) + .collect(); + query_bitmaps + } else { + // Flatten base labels so that nested structures are converted to a flat list of key-value pairs + let flattened_base_labels: Vec> = base_labels + .iter() + .map(|base_label| { + flatten_json_pointers_with_config(&base_label.label, &FlattenConfig::dot_notation()) + }) + .collect(); - let flattened_base_label_hashmaps: Result>, anyhow::Error> = - flattened_base_labels.iter().map(|labels| { - let mut map = HashMap::new(); - for (key, value) in labels { - if let Some(_existing_value) = map.get(key) { - return Err(anyhow::anyhow!("Duplicate keys in the same document: {}", key)); + let flattened_base_label_hashmaps: Result< + Vec>, + anyhow::Error, + > = flattened_base_labels + .iter() + .map(|labels| { + let mut map = HashMap::new(); + for (key, value) in labels { + // a base label may not have two values for the same key + if let Some(_existing_value) = map.get(key) { + return Err(anyhow::anyhow!( + "Duplicate keys in the same document: {}", + key + )); + } + map.insert(key.clone(), value.clone()); } - map.insert(key.clone(), value.clone()); + Ok(map) + }) + .collect(); + + let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; + + // compute the global set of labels ahead of time so that we can compute + // each accelerator in parallel + let global_label_set = compute_global_label_set(&flattened_base_label_hashmaps)?; + + // Compute the accelerators for each label in the global set + #[allow(clippy::disallowed_methods)] + let query_accelerators: Result, anyhow::Error> = + global_label_set + .par_iter() + .map(|(key, value)| { + compute_query_accelerator( + key.clone(), + value.clone(), + &flattened_base_label_hashmaps, + ) + .map(|accel| (key.clone(), accel)) + }) + .collect(); + + // Convert the query accelerators to a hashmap for faster lookups + let query_accelerators: HashMap = + query_accelerators?.into_iter().collect(); + + // Evaluate each query using the precomputed accelerators + #[allow(clippy::disallowed_methods)] + let query_bitmaps: Result, anyhow::Error> = query_labels + .par_iter() + .map(|(_query_id, query_expr)| { + eval_query_using_accelerators(query_expr, &query_accelerators) + }) + .collect(); + + query_bitmaps? + }; + + Ok(bitmaps) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::attribute::AttributeValue; + use crate::parser::format::Document; + use crate::{ASTExpr, CompareOp}; + use serde_json::json; + use std::collections::HashMap; + + #[test] + fn test_compute_query_bitmap_duplicate_key_in_doc() { + // serde_json does not allow duplicate keys, but we can simulate this by flattening a document with a nested object that, when flattened, produces duplicate keys + // For this test, we will directly call compute_query_bitmaps with a document that, after flattening, would have duplicate keys + // This is a synthetic test: we create a document with a nested object and a top-level key that would flatten to the same key + let base_labels = vec![Document { + doc_id: 0, + label: json!({"color": {"color": "red"}, "color.color": "blue"}), + }]; + // Query: color == "red" + let query = ASTExpr::Compare { + field: "color".to_string(), + op: CompareOp::Eq(json!("red")), + }; + let result = compute_query_bitmaps(base_labels.clone(), vec![(0, query)]); + assert!( + result.is_err(), + "Should error on duplicate keys in the same document" + ); + } + + #[test] + fn test_compute_query_bitmap_inconsistent_types() { + // Two documents, same key, different value types + let base_labels = vec![ + Document { + doc_id: 0, + label: json!({"foo": "bar"}), + }, + Document { + doc_id: 1, + label: json!({"foo": 123}), + }, + ]; + // Query: foo == "bar" + let query = ASTExpr::Compare { + field: "foo".to_string(), + op: CompareOp::Eq(json!("bar")), + }; + let result = compute_query_bitmaps(base_labels.clone(), vec![(0, query)]); + assert!(result.is_err(), "Should error on inconsistent value types"); + } + + #[test] + fn test_compute_query_bitmap_missing_field() { + use crate::parser::format::Document; + use serde_json::json; + // Three documents, one missing the 'color' field + let base_labels = vec![ + Document { + doc_id: 0, + label: json!({"weight": 30}), // no color field + }, + Document { + doc_id: 1, + label: json!({"color": "red", "weight": 10}), + }, + Document { + doc_id: 2, + label: json!({"color": "blue", "weight": 20}), + }, + ]; + + // Query: color == "red" + let query_color = ASTExpr::Compare { + field: "color".to_string(), + op: CompareOp::Eq(json!("red")), + }; + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_color)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(0), false); + assert_eq!(bitmaps[0].contains(1), true); + assert_eq!(bitmaps[0].contains(2), false); + + // Query: weight >= 20 + let query_weight = ASTExpr::Compare { + field: "weight".to_string(), + op: CompareOp::Gte(20.0), + }; + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_weight)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(1), false); + assert_eq!(bitmaps[0].contains(2), true); + assert_eq!(bitmaps[0].contains(0), true); + } + + #[test] + fn test_compute_query_bitmap_nested_value() { + use crate::parser::format::Document; + use serde_json::json; + // Two documents with nested car.color + let base_labels = vec![ + Document { + doc_id: 0, + label: json!({"car": {"color": "red"}}), + }, + Document { + doc_id: 1, + label: json!({"car": {"color": "blue"}}), + }, + ]; + + // Query: car.color == "red" + let query_eq = ASTExpr::Compare { + field: "car.color".to_string(), + op: CompareOp::Eq(json!("red")), + }; + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_eq)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(0), true); + assert_eq!(bitmaps[0].contains(1), false); + + // Query: NOT car.color == "red" (should match blue) + let query_not = ASTExpr::Not(Box::new(ASTExpr::Compare { + field: "car.color".to_string(), + op: CompareOp::Eq(json!("red")), + })); + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_not)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(1), true); + assert_eq!(bitmaps[0].contains(0), false); + } + + #[test] + fn test_compute_query_bitmap_floats() { + let base_labels = vec![ + Document { + doc_id: 0, + label: json!({"score": 1.5}), + }, + Document { + doc_id: 1, + label: json!({"score": 2.0}), + }, + Document { + doc_id: 2, + label: json!({"score": 3.5}), + }, + ]; + + // score < 2.0 + let query_lt = ASTExpr::Compare { + field: "score".to_string(), + op: CompareOp::Lt(2.0), + }; + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_lt)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(0), true); + assert_eq!(bitmaps[0].contains(1), false); + assert_eq!(bitmaps[0].contains(2), false); + + // score > 2.0 + let query_gt = ASTExpr::Compare { + field: "score".to_string(), + op: CompareOp::Gt(2.0), + }; + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_gt)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(2), true); + assert_eq!(bitmaps[0].contains(0), false); + assert_eq!(bitmaps[0].contains(1), false); + + // score <= 2.0 + let query_lte = ASTExpr::Compare { + field: "score".to_string(), + op: CompareOp::Lte(2.0), + }; + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_lte)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(0), true); + assert_eq!(bitmaps[0].contains(1), true); + assert_eq!(bitmaps[0].contains(2), false); + + // score >= 2.0 + let query_gte = ASTExpr::Compare { + field: "score".to_string(), + op: CompareOp::Gte(2.0), + }; + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_gte)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(1), true); + assert_eq!(bitmaps[0].contains(2), true); + assert_eq!(bitmaps[0].contains(0), false); + + // score >= 2.0 AND score <= 3.5 (range: [2.0, 3.5]) + let query_range = ASTExpr::And(vec![ + ASTExpr::Compare { + field: "score".to_string(), + op: CompareOp::Gte(2.0), + }, + ASTExpr::Compare { + field: "score".to_string(), + op: CompareOp::Lte(3.5), + }, + ]); + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_range)]) + .expect("should succeed"); + // Should match doc 1 (2.0) and doc 2 (3.5) + assert_eq!(bitmaps[0].contains(1), true); + assert_eq!(bitmaps[0].contains(2), true); + assert_eq!(bitmaps[0].contains(0), false); + } + + #[test] + fn test_compute_query_bitmap_ints() { + let base_labels = vec![ + Document { + doc_id: 0, + label: json!({"age": 10}), + }, + Document { + doc_id: 1, + label: json!({"age": 20}), + }, + Document { + doc_id: 2, + label: json!({"age": 30}), + }, + ]; + + // age < 20 + let query_lt = ASTExpr::Compare { + field: "age".to_string(), + op: CompareOp::Lt(20.0), + }; + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_lt)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(0), true); + assert_eq!(bitmaps[0].contains(1), false); + assert_eq!(bitmaps[0].contains(2), false); + + // age > 20 + let query_gt = ASTExpr::Compare { + field: "age".to_string(), + op: CompareOp::Gt(20.0), + }; + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_gt)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(2), true); + assert_eq!(bitmaps[0].contains(0), false); + assert_eq!(bitmaps[0].contains(1), false); + + // age <= 20 + let query_lte = ASTExpr::Compare { + field: "age".to_string(), + op: CompareOp::Lte(20.0), + }; + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_lte)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(0), true); + assert_eq!(bitmaps[0].contains(1), true); + assert_eq!(bitmaps[0].contains(2), false); + + // age >= 20 + let query_gte = ASTExpr::Compare { + field: "age".to_string(), + op: CompareOp::Gte(20.0), + }; + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_gte)]) + .expect("should succeed"); + assert_eq!(bitmaps[0].contains(1), true); + assert_eq!(bitmaps[0].contains(2), true); + assert_eq!(bitmaps[0].contains(0), false); + + // age >= 20 AND age <= 30 (range: [20, 30]) + let query_range = ASTExpr::And(vec![ + ASTExpr::Compare { + field: "age".to_string(), + op: CompareOp::Gte(20.0), + }, + ASTExpr::Compare { + field: "age".to_string(), + op: CompareOp::Lte(30.0), + }, + ]); + let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_range)]) + .expect("should succeed"); + // Should match doc 1 (20) and doc 2 (30) + assert_eq!(bitmaps[0].contains(1), true); + assert_eq!(bitmaps[0].contains(2), true); + assert_eq!(bitmaps[0].contains(0), false); + } + + #[test] + fn test_compute_query_bitmap_bools() { + use crate::parser::format::Document; + use serde_json::json; + // Two documents with a boolean field + let base_labels = vec![ + Document { + doc_id: 0, + label: json!({"flag": true}), + }, + Document { + doc_id: 1, + label: json!({"flag": false}), + }, + ]; + + // Query: flag == true + let query = ASTExpr::Compare { + field: "flag".to_string(), + op: CompareOp::Eq(json!(true)), + }; + let queries = vec![(0, query)]; + let bitmaps = compute_query_bitmaps(base_labels.clone(), queries).expect("should succeed"); + // Only doc 0 should match + assert_eq!(bitmaps[0].contains(0), true); + assert_eq!(bitmaps[0].contains(1), false); + } + + #[test] + fn test_compute_query_bitmaps_mixed_labels() { + let base_labels = vec![ + Document { + doc_id: 0, + label: json!({"color": "red", "size": 10}), + }, + Document { + doc_id: 1, + label: json!({"color": "blue", "size": 20}), + }, + Document { + doc_id: 2, + label: json!({"color": "red", "size": 20}), + }, + ]; + + // Query: color == "red" + let query1 = ASTExpr::Compare { + field: "color".to_string(), + op: CompareOp::Eq(serde_json::Value::String("red".to_string())), + }; + // Query: size == 20 + let query2 = ASTExpr::Compare { + field: "size".to_string(), + op: CompareOp::Eq(20.into()), + }; + // Query: color == "red" AND size == 20 + let query3 = ASTExpr::And(vec![ + ASTExpr::Compare { + field: "color".to_string(), + op: CompareOp::Eq(serde_json::Value::String("red".to_string())), + }, + ASTExpr::Compare { + field: "size".to_string(), + op: CompareOp::Eq(20.into()), + }, + ]); + // Query: color == "red" OR size == 10 + let query4 = ASTExpr::Or(vec![ + ASTExpr::Compare { + field: "color".to_string(), + op: CompareOp::Eq(serde_json::Value::String("red".to_string())), + }, + ASTExpr::Compare { + field: "size".to_string(), + op: CompareOp::Eq(10.into()), + }, + ]); + + let queries = vec![(0, query1), (1, query2), (2, query3), (3, query4)]; + + let bitmaps = compute_query_bitmaps(base_labels.clone(), queries).expect("should succeed"); + // color == "red" => doc 0, 2 + assert_eq!(bitmaps[0].contains(0), true); + assert_eq!(bitmaps[0].contains(2), true); + assert_eq!(bitmaps[0].contains(1), false); + // size == 20 => doc 1, 2 + assert_eq!(bitmaps[1].contains(1), true); + assert_eq!(bitmaps[1].contains(2), true); + assert_eq!(bitmaps[1].contains(0), false); + // color == "red" AND size == 20 => doc 2 + assert_eq!(bitmaps[2].contains(2), true); + assert_eq!(bitmaps[2].contains(0), false); + assert_eq!(bitmaps[2].contains(1), false); + // color == "red" OR size == 10 => doc 0, 2 + assert_eq!(bitmaps[3].contains(0), true); + assert_eq!(bitmaps[3].contains(2), true); + assert_eq!(bitmaps[3].contains(1), false); + + // Query: NOT color == "red" + let not_query = ASTExpr::Not(Box::new(ASTExpr::Compare { + field: "color".to_string(), + op: CompareOp::Eq(serde_json::json!("red")), + })); + let queries_with_not = vec![(0, not_query)]; + let result = compute_query_bitmaps(base_labels.clone(), queries_with_not); + assert!( + result.is_ok(), + "Slow path should not error, but NOT is not accelerated" + ); + // The result should be a bitmap with doc 1 (not red) + let bitmaps = result.unwrap(); + assert_eq!(bitmaps[0].contains(1), true); + assert_eq!(bitmaps[0].contains(0), false); + assert_eq!(bitmaps[0].contains(2), false); + } + + #[test] + fn test_compute_query_accelerator() { + // Prepare base labels + let mut doc1 = HashMap::new(); + doc1.insert("foo".to_string(), AttributeValue::String("bar".to_string())); + doc1.insert("num".to_string(), AttributeValue::Integer(42)); + doc1.insert("real".to_string(), AttributeValue::Real(3.14)); + doc1.insert("flag".to_string(), AttributeValue::Bool(true)); + let mut doc2 = HashMap::new(); + doc2.insert("foo".to_string(), AttributeValue::String("baz".to_string())); + doc2.insert("num".to_string(), AttributeValue::Integer(7)); + doc2.insert("real".to_string(), AttributeValue::Real(2.71)); + doc2.insert("flag".to_string(), AttributeValue::Bool(false)); + let base = vec![doc1, doc2]; + + // String + let accel = compute_query_accelerator( + "foo".to_string(), + AttributeValue::String("bar".to_string()), + &base, + ) + .expect("Should succeed for String"); + match accel { + QueryAccelerator::InvertedIndex(map) => { + assert!(map.contains_key(&AttributeValue::String("bar".to_string()))); + assert!(map.contains_key(&AttributeValue::String("baz".to_string()))); + } + _ => panic!("Expected InvertedIndex for String"), + } + + // Bool + let accel = + compute_query_accelerator("flag".to_string(), AttributeValue::Bool(true), &base) + .expect("Should succeed for Bool"); + match accel { + QueryAccelerator::InvertedIndex(map) => { + assert!(map.contains_key(&AttributeValue::Bool(true))); + assert!(map.contains_key(&AttributeValue::Bool(false))); } - Ok(map) - }).collect(); - - let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; - - // print all the keys in the global label set for debugging - let global_label_set = compute_global_label_set(&flattened_base_label_hashmaps)?; - println!("Global label set:"); - for (key, value) in &global_label_set { - println!("{}: {:?}", key, value); - } - - // let global_label_set = compute_global_label_set(&flattened_base_label_hashmaps)?; - - #[allow(clippy::disallowed_methods)] - let query_accelerators: Vec<(String, QueryAccelerator)> = global_label_set.par_iter() - .map(|(key, value)| { - (key.clone(), compute_query_accelerator(key.clone(), value.clone(), &flattened_base_label_hashmaps)) - }) - .collect(); - - // Convert to a HashMap for easier access during query evaluation - let query_accelerators: HashMap = query_accelerators.into_iter().collect(); - - // Parse queries and evaluate against labels - let parsed_queries = read_and_parse_queries(query_label_filename)?; - - // using the global threadpool is fine here - #[allow(clippy::disallowed_methods)] - let query_bitmaps: Vec = parsed_queries - .par_iter() - .map(|(_query_id, query_expr)| { - eval_query_using_accelerators(query_expr, &query_accelerators) - }) - .collect(); - - Ok(query_bitmaps) -} \ No newline at end of file + _ => panic!("Expected InvertedIndex for Bool"), + } + + // Integer + let accel = + compute_query_accelerator("num".to_string(), AttributeValue::Integer(42), &base) + .expect("Should succeed for Integer"); + match accel { + QueryAccelerator::BTree(map) => { + assert!(map.contains_key(&super::OrderedFloat(42.0))); + assert!(map.contains_key(&super::OrderedFloat(7.0))); + } + _ => panic!("Expected BTree for Integer"), + } + + // Real + let accel = + compute_query_accelerator("real".to_string(), AttributeValue::Real(3.14), &base) + .expect("Should succeed for Real"); + match accel { + QueryAccelerator::BTree(map) => { + assert!(map.contains_key(&super::OrderedFloat(3.14))); + assert!(map.contains_key(&super::OrderedFloat(2.71))); + } + _ => panic!("Expected BTree for Real"), + } + + // Empty + let err = compute_query_accelerator("none".to_string(), AttributeValue::Empty, &base); + assert!(err.is_err()); + } + + #[test] + fn test_check_for_disallowed_operators() { + // Compare only (no NOT) + let expr = ASTExpr::Compare { + field: "foo".to_string(), + op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), + }; + assert_eq!(check_for_disallowed_operators(&expr), false); + + // NOT at root + let expr = ASTExpr::Not(Box::new(ASTExpr::Compare { + field: "foo".to_string(), + op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), + })); + assert_eq!(check_for_disallowed_operators(&expr), true); + + // AND with NOT inside + let expr = ASTExpr::And(vec![ + ASTExpr::Compare { + field: "foo".to_string(), + op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), + }, + ASTExpr::Not(Box::new(ASTExpr::Compare { + field: "baz".to_string(), + op: CompareOp::Eq(serde_json::Value::String("qux".to_string())), + })), + ]); + assert_eq!(check_for_disallowed_operators(&expr), true); + + // OR with only Compare + let expr = ASTExpr::Or(vec![ + ASTExpr::Compare { + field: "foo".to_string(), + op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), + }, + ASTExpr::Compare { + field: "baz".to_string(), + op: CompareOp::Eq(serde_json::Value::String("qux".to_string())), + }, + ]); + assert_eq!(check_for_disallowed_operators(&expr), false); + + // Nested AND/OR with NOT deep inside + let expr = ASTExpr::And(vec![ + ASTExpr::Or(vec![ + ASTExpr::Compare { + field: "a".to_string(), + op: CompareOp::Eq(serde_json::Value::String("b".to_string())), + }, + ASTExpr::Not(Box::new(ASTExpr::Compare { + field: "c".to_string(), + op: CompareOp::Eq(serde_json::Value::String("d".to_string())), + })), + ]), + ASTExpr::Compare { + field: "e".to_string(), + op: CompareOp::Eq(serde_json::Value::String("f".to_string())), + }, + ]); + assert_eq!(check_for_disallowed_operators(&expr), true); + } +} diff --git a/diskann-label-filter/src/utils/flatten_utils.rs b/diskann-label-filter/src/utils/flatten_utils.rs index c3c7c61df..5d6a042fe 100644 --- a/diskann-label-filter/src/utils/flatten_utils.rs +++ b/diskann-label-filter/src/utils/flatten_utils.rs @@ -13,7 +13,7 @@ pub type Attributes = HashMap; /// Configuration for JSON flattening behavior #[derive(Debug, Clone)] pub struct FlattenConfig { - /// Separator used between path segments (default: ".") + /// Separator used between path segments (default: "/") pub separator: String, /// Whether to include array indices in paths (default: true) pub include_array_indices: bool, @@ -24,7 +24,7 @@ pub struct FlattenConfig { impl Default for FlattenConfig { fn default() -> Self { Self { - separator: ".".to_string(), + separator: "/".to_string(), include_array_indices: true, root_prefix: "".to_string(), } From 8b47aef2f300e8367365ff03f769c41f0cef6512 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Thu, 21 May 2026 22:12:47 +0000 Subject: [PATCH 05/34] undo change in docstring --- diskann-label-filter/src/utils/flatten_utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diskann-label-filter/src/utils/flatten_utils.rs b/diskann-label-filter/src/utils/flatten_utils.rs index 5d6a042fe..0ef11dbe7 100644 --- a/diskann-label-filter/src/utils/flatten_utils.rs +++ b/diskann-label-filter/src/utils/flatten_utils.rs @@ -72,7 +72,7 @@ impl Document { } /// Configurable version that uses FlattenConfig - /// For example, with config.separator=".": {"details": {"color": "red"}} becomes {".details.color": "red"} + /// For example, with config.separator="/": {"details": {"color": "red"}} becomes {"/details/color": "red"} pub fn flatten_metadata_with_config(&self, config: &FlattenConfig) -> Attributes { flatten_json_pointers_map_with_config(&self.label, config) } From 962fdf64a8a22197f9fe9838813c6cd5f23aafc2 Mon Sep 17 00:00:00 2001 From: magdalendobson <58752279+magdalendobson@users.noreply.github.com> Date: Fri, 22 May 2026 10:07:04 -0400 Subject: [PATCH 06/34] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- diskann-label-filter/src/utils/flatten_utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diskann-label-filter/src/utils/flatten_utils.rs b/diskann-label-filter/src/utils/flatten_utils.rs index 0ef11dbe7..ea80cfed5 100644 --- a/diskann-label-filter/src/utils/flatten_utils.rs +++ b/diskann-label-filter/src/utils/flatten_utils.rs @@ -191,7 +191,7 @@ pub fn flatten_json_pointers(value: &Value) -> AttributesVec { /// Configurable version that uses FlattenConfig /// /// Example: -/// With config.separator=".": {"a": {"b": [1, 2]}} -> [ ("/a/b/0", 1), ("/a/b/1", 2) ] +/// With config.separator=".": {"a": {"b": [1, 2]}} -> [ (".a.b.0", 1), (".a.b.1", 2) ] pub fn flatten_json_pointers_with_config(value: &Value, config: &FlattenConfig) -> AttributesVec { let mut out = Vec::new(); flatten_json_pointer_inner(value, &config.root_prefix, &mut out, &config.separator); From 07cb5bdbedef18f391d4b109c0859894499cd10a Mon Sep 17 00:00:00 2001 From: magdalendobson <58752279+magdalendobson@users.noreply.github.com> Date: Fri, 22 May 2026 10:07:55 -0400 Subject: [PATCH 07/34] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- diskann-label-filter/src/utils/compute_bitmap.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 40bda62db..130ef11be 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -138,15 +138,13 @@ pub fn eval_query_using_accelerators( } CompareOp::Ne(value) => { let fval = value.as_f64().ok_or_else(|| anyhow::anyhow!("Failed to convert value to f64 for Ne"))?; - let mut all_ids = Vec::new(); + let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + let mut bitset = BitSet::new(); for (val, ids) in btree.iter() { - let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; if val != &fval { - all_ids.extend(ids.iter().cloned()); + bitset.extend(ids.iter().cloned()); } } - let mut bitset = BitSet::new(); - bitset.extend(all_ids); Ok(bitset) } CompareOp::Lt(value) => { From 80574cad7d2db1565451109cf02cc137eb5113c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 14:11:36 +0000 Subject: [PATCH 08/34] fix label-filter accelerator doc id mapping for inverted index Agent-Logs-Url: https://github.com/microsoft/DiskANN/sessions/f16c59eb-89cf-4480-b6fe-afe4be5e7c8e Co-authored-by: magdalendobson <58752279+magdalendobson@users.noreply.github.com> --- .../src/utils/compute_bitmap.rs | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 130ef11be..0c91d2301 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -207,16 +207,17 @@ pub fn eval_query_using_accelerators( } pub fn compute_inverted_index_accelerator( - key: String, - labels: Vec>, + key: &str, + doc_ids: &[usize], + labels: &[HashMap], ) -> Result, anyhow::Error> { let mut inverted_index: HashMap = HashMap::new(); - for (doc_id, label) in labels.iter().enumerate() { - if let Some(value) = label.get(&key) { + for (doc_id, label) in doc_ids.iter().zip(labels.iter()) { + if let Some(value) = label.get(key) { inverted_index .entry(value.clone()) .or_insert_with(BitSet::new) - .insert(doc_id); + .insert(*doc_id); } } Ok(inverted_index) @@ -272,13 +273,13 @@ pub fn compute_global_label_set( pub fn compute_query_accelerator( key: String, value: AttributeValue, + doc_ids: &[usize], flattened_base_labels: &[HashMap], ) -> Result { match value { AttributeValue::String(_) | AttributeValue::Bool(_) => { - let bitmap = - compute_inverted_index_accelerator(key.clone(), flattened_base_labels.to_vec()) - .unwrap_or_default(); + let bitmap = compute_inverted_index_accelerator(&key, doc_ids, flattened_base_labels) + .unwrap_or_default(); Ok(QueryAccelerator::InvertedIndex(bitmap)) } AttributeValue::Integer(_) | AttributeValue::Real(_) => { @@ -346,6 +347,7 @@ pub fn compute_query_bitmaps( .collect(); let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; + let base_doc_ids: Vec = base_labels.iter().map(|base_label| base_label.doc_id).collect(); // compute the global set of labels ahead of time so that we can compute // each accelerator in parallel @@ -360,6 +362,7 @@ pub fn compute_query_bitmaps( compute_query_accelerator( key.clone(), value.clone(), + &base_doc_ids, &flattened_base_label_hashmaps, ) .map(|accel| (key.clone(), accel)) @@ -807,11 +810,13 @@ mod tests { doc2.insert("real".to_string(), AttributeValue::Real(2.71)); doc2.insert("flag".to_string(), AttributeValue::Bool(false)); let base = vec![doc1, doc2]; + let doc_ids = vec![10, 42]; // String let accel = compute_query_accelerator( "foo".to_string(), AttributeValue::String("bar".to_string()), + &doc_ids, &base, ) .expect("Should succeed for String"); @@ -819,13 +824,27 @@ mod tests { QueryAccelerator::InvertedIndex(map) => { assert!(map.contains_key(&AttributeValue::String("bar".to_string()))); assert!(map.contains_key(&AttributeValue::String("baz".to_string()))); + assert_eq!( + map.get(&AttributeValue::String("bar".to_string())) + .expect("bar key should exist") + .iter() + .collect::>(), + vec![10] + ); + assert_eq!( + map.get(&AttributeValue::String("baz".to_string())) + .expect("baz key should exist") + .iter() + .collect::>(), + vec![42] + ); } _ => panic!("Expected InvertedIndex for String"), } // Bool let accel = - compute_query_accelerator("flag".to_string(), AttributeValue::Bool(true), &base) + compute_query_accelerator("flag".to_string(), AttributeValue::Bool(true), &doc_ids, &base) .expect("Should succeed for Bool"); match accel { QueryAccelerator::InvertedIndex(map) => { @@ -837,7 +856,7 @@ mod tests { // Integer let accel = - compute_query_accelerator("num".to_string(), AttributeValue::Integer(42), &base) + compute_query_accelerator("num".to_string(), AttributeValue::Integer(42), &doc_ids, &base) .expect("Should succeed for Integer"); match accel { QueryAccelerator::BTree(map) => { @@ -849,7 +868,7 @@ mod tests { // Real let accel = - compute_query_accelerator("real".to_string(), AttributeValue::Real(3.14), &base) + compute_query_accelerator("real".to_string(), AttributeValue::Real(3.14), &doc_ids, &base) .expect("Should succeed for Real"); match accel { QueryAccelerator::BTree(map) => { @@ -860,7 +879,7 @@ mod tests { } // Empty - let err = compute_query_accelerator("none".to_string(), AttributeValue::Empty, &base); + let err = compute_query_accelerator("none".to_string(), AttributeValue::Empty, &doc_ids, &base); assert!(err.is_err()); } From ecc3895b8454214f49295fa6505907fc5e45e5d9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 14:13:00 +0000 Subject: [PATCH 09/34] fix: use document ids for numeric btree accelerator postings Agent-Logs-Url: https://github.com/microsoft/DiskANN/sessions/727d3d88-3d0b-47bf-a023-9170d72fb87a Co-authored-by: magdalendobson <58752279+magdalendobson@users.noreply.github.com> --- .../src/utils/compute_bitmap.rs | 70 ++++++++++++++++--- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 0c91d2301..4596e9794 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -226,10 +226,11 @@ pub fn compute_inverted_index_accelerator( pub fn compute_btree_accelerator( key: String, labels: Vec>, + doc_ids: &[usize], ) -> Result>, anyhow::Error> { // Implementation for computing BTree accelerator let mut map: BTreeMap> = BTreeMap::new(); - for (doc_id, label) in labels.iter().enumerate() { + for (label, doc_id) in labels.iter().zip(doc_ids.iter().copied()) { if let Some(value) = label.get(&key) { if let Some(f64_value) = value.as_float() { let f64_value = OrderedFloat::new(f64_value) @@ -284,7 +285,7 @@ pub fn compute_query_accelerator( } AttributeValue::Integer(_) | AttributeValue::Real(_) => { // For integers and reals, we use an BTree - let btree = compute_btree_accelerator(key.clone(), flattened_base_labels.to_vec()) + let btree = compute_btree_accelerator(key.clone(), flattened_base_labels.to_vec(), doc_ids) .unwrap_or_default(); Ok(QueryAccelerator::BTree(btree)) } @@ -680,6 +681,37 @@ mod tests { assert_eq!(bitmaps[0].contains(0), false); } + #[test] + fn test_compute_query_bitmap_ints_uses_document_ids_in_accelerator() { + let base_labels = vec![ + Document { + doc_id: 10, + label: json!({"age": 10}), + }, + Document { + doc_id: 20, + label: json!({"age": 20}), + }, + Document { + doc_id: 30, + label: json!({"age": 30}), + }, + ]; + + let query_gte = ASTExpr::Compare { + field: "age".to_string(), + op: CompareOp::Gte(20.0), + }; + let bitmaps = compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); + + assert_eq!(bitmaps[0].contains(20), true); + assert_eq!(bitmaps[0].contains(30), true); + assert_eq!(bitmaps[0].contains(10), false); + assert_eq!(bitmaps[0].contains(0), false); + assert_eq!(bitmaps[0].contains(1), false); + assert_eq!(bitmaps[0].contains(2), false); + } + #[test] fn test_compute_query_bitmap_bools() { use crate::parser::format::Document; @@ -844,8 +876,13 @@ mod tests { // Bool let accel = - compute_query_accelerator("flag".to_string(), AttributeValue::Bool(true), &doc_ids, &base) - .expect("Should succeed for Bool"); + compute_query_accelerator( + "flag".to_string(), + AttributeValue::Bool(true), + &doc_ids, + &base, + ) + .expect("Should succeed for Bool"); match accel { QueryAccelerator::InvertedIndex(map) => { assert!(map.contains_key(&AttributeValue::Bool(true))); @@ -856,8 +893,13 @@ mod tests { // Integer let accel = - compute_query_accelerator("num".to_string(), AttributeValue::Integer(42), &doc_ids, &base) - .expect("Should succeed for Integer"); + compute_query_accelerator( + "num".to_string(), + AttributeValue::Integer(42), + &doc_ids, + &base, + ) + .expect("Should succeed for Integer"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(42.0))); @@ -868,8 +910,13 @@ mod tests { // Real let accel = - compute_query_accelerator("real".to_string(), AttributeValue::Real(3.14), &doc_ids, &base) - .expect("Should succeed for Real"); + compute_query_accelerator( + "real".to_string(), + AttributeValue::Real(3.14), + &doc_ids, + &base, + ) + .expect("Should succeed for Real"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(3.14))); @@ -879,7 +926,12 @@ mod tests { } // Empty - let err = compute_query_accelerator("none".to_string(), AttributeValue::Empty, &doc_ids, &base); + let err = compute_query_accelerator( + "none".to_string(), + AttributeValue::Empty, + &doc_ids, + &base, + ); assert!(err.is_err()); } From 4fe2935064a0cfdd6323236ef3b7fe13be64ec30 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 14:17:24 +0000 Subject: [PATCH 10/34] fix: guard compute_specificities against empty base labels Agent-Logs-Url: https://github.com/microsoft/DiskANN/sessions/47e2bd0f-cb8b-495f-8274-02a88596b0e6 Co-authored-by: magdalendobson <58752279+magdalendobson@users.noreply.github.com> --- diskann-label-filter/examples/compute_specificities.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/diskann-label-filter/examples/compute_specificities.rs b/diskann-label-filter/examples/compute_specificities.rs index 9ded85342..4cb7fa03d 100644 --- a/diskann-label-filter/examples/compute_specificities.rs +++ b/diskann-label-filter/examples/compute_specificities.rs @@ -36,6 +36,10 @@ fn main() { }; let total_base = base_labels.len() as u64; + if total_base == 0 { + eprintln!("Base labels are empty: cannot compute specificities."); + process::exit(1); + } let query_labels = match read_and_parse_queries(query_label_file) { Ok(queries) => queries, From 2161a1d1f8da1174b9dc6d24cdfcfd977a76aa11 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 22 May 2026 14:16:39 +0000 Subject: [PATCH 11/34] Avoid cloning/silencing errors in query accelerator build Agent-Logs-Url: https://github.com/microsoft/DiskANN/sessions/1bc31d27-7a19-4c4c-9ecc-c10260b944a3 Co-authored-by: magdalendobson <58752279+magdalendobson@users.noreply.github.com> --- diskann-label-filter/src/utils/compute_bitmap.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 4596e9794..3394d353c 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -224,14 +224,14 @@ pub fn compute_inverted_index_accelerator( } pub fn compute_btree_accelerator( - key: String, - labels: Vec>, + key: &str, + labels: &[HashMap], doc_ids: &[usize], ) -> Result>, anyhow::Error> { // Implementation for computing BTree accelerator let mut map: BTreeMap> = BTreeMap::new(); for (label, doc_id) in labels.iter().zip(doc_ids.iter().copied()) { - if let Some(value) = label.get(&key) { + if let Some(value) = label.get(key) { if let Some(f64_value) = value.as_float() { let f64_value = OrderedFloat::new(f64_value) .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; @@ -279,14 +279,12 @@ pub fn compute_query_accelerator( ) -> Result { match value { AttributeValue::String(_) | AttributeValue::Bool(_) => { - let bitmap = compute_inverted_index_accelerator(&key, doc_ids, flattened_base_labels) - .unwrap_or_default(); + let bitmap = compute_inverted_index_accelerator(&key, doc_ids, flattened_base_labels)?; Ok(QueryAccelerator::InvertedIndex(bitmap)) } AttributeValue::Integer(_) | AttributeValue::Real(_) => { // For integers and reals, we use an BTree - let btree = compute_btree_accelerator(key.clone(), flattened_base_labels.to_vec(), doc_ids) - .unwrap_or_default(); + let btree = compute_btree_accelerator(&key, flattened_base_labels, doc_ids)?; Ok(QueryAccelerator::BTree(btree)) } AttributeValue::Empty => Err(anyhow::anyhow!("Empty attribute value is not allowed")), From 164f4b90b3cd4905cc8ed3a20ca0b9e69ca46de7 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 14:24:48 +0000 Subject: [PATCH 12/34] change format --- diskann-label-filter/examples/compute_specificities.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diskann-label-filter/examples/compute_specificities.rs b/diskann-label-filter/examples/compute_specificities.rs index 4cb7fa03d..e22f00f52 100644 --- a/diskann-label-filter/examples/compute_specificities.rs +++ b/diskann-label-filter/examples/compute_specificities.rs @@ -58,7 +58,7 @@ fn main() { } }; let elapsed = start.elapsed(); - println!("read_labels_and_compute_bitmap_naive took {:.3?}", elapsed); + println!("Computing bitmap took {:.3?} seconds", elapsed); let mut specificities: Vec = bitmaps .par_iter() From cce1a8a04cf06df3055c9b456a57eb972f853a88 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 14:30:00 +0000 Subject: [PATCH 13/34] fmt --- .../src/utils/compute_bitmap.rs | 61 +++++++++---------- .../spherical/quantizer_generated.rs | 51 ++++++++-------- .../spherical_quantizer_generated.rs | 48 +++++---------- .../spherical/supported_metric_generated.rs | 25 ++++---- .../transforms/double_hadamard_generated.rs | 42 +++++-------- .../transforms/null_transform_generated.rs | 28 +++------ .../transforms/padding_hadamard_generated.rs | 40 ++++-------- .../transforms/random_rotation_generated.rs | 38 ++++-------- .../transforms/transform_generated.rs | 53 +++++----------- .../transforms/transform_kind_generated.rs | 25 ++++---- 10 files changed, 155 insertions(+), 256 deletions(-) diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 3394d353c..7d5fbcfde 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -346,7 +346,10 @@ pub fn compute_query_bitmaps( .collect(); let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; - let base_doc_ids: Vec = base_labels.iter().map(|base_label| base_label.doc_id).collect(); + let base_doc_ids: Vec = base_labels + .iter() + .map(|base_label| base_label.doc_id) + .collect(); // compute the global set of labels ahead of time so that we can compute // each accelerator in parallel @@ -700,7 +703,8 @@ mod tests { field: "age".to_string(), op: CompareOp::Gte(20.0), }; - let bitmaps = compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); + let bitmaps = + compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); assert_eq!(bitmaps[0].contains(20), true); assert_eq!(bitmaps[0].contains(30), true); @@ -873,14 +877,13 @@ mod tests { } // Bool - let accel = - compute_query_accelerator( - "flag".to_string(), - AttributeValue::Bool(true), - &doc_ids, - &base, - ) - .expect("Should succeed for Bool"); + let accel = compute_query_accelerator( + "flag".to_string(), + AttributeValue::Bool(true), + &doc_ids, + &base, + ) + .expect("Should succeed for Bool"); match accel { QueryAccelerator::InvertedIndex(map) => { assert!(map.contains_key(&AttributeValue::Bool(true))); @@ -890,14 +893,13 @@ mod tests { } // Integer - let accel = - compute_query_accelerator( - "num".to_string(), - AttributeValue::Integer(42), - &doc_ids, - &base, - ) - .expect("Should succeed for Integer"); + let accel = compute_query_accelerator( + "num".to_string(), + AttributeValue::Integer(42), + &doc_ids, + &base, + ) + .expect("Should succeed for Integer"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(42.0))); @@ -907,14 +909,13 @@ mod tests { } // Real - let accel = - compute_query_accelerator( - "real".to_string(), - AttributeValue::Real(3.14), - &doc_ids, - &base, - ) - .expect("Should succeed for Real"); + let accel = compute_query_accelerator( + "real".to_string(), + AttributeValue::Real(3.14), + &doc_ids, + &base, + ) + .expect("Should succeed for Real"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(3.14))); @@ -924,12 +925,8 @@ mod tests { } // Empty - let err = compute_query_accelerator( - "none".to_string(), - AttributeValue::Empty, - &doc_ids, - &base, - ); + let err = + compute_query_accelerator("none".to_string(), AttributeValue::Empty, &doc_ids, &base); assert!(err.is_err()); } diff --git a/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs b/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs index 320ca651d..b90062b09 100644 --- a/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct Quantizer<'a> { impl<'a> flatbuffers::Follow<'a> for Quantizer<'a> { type Inner = Quantizer<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -34,12 +29,12 @@ impl<'a> Quantizer<'a> { pub const VT_NBITS: flatbuffers::VOffsetT = 6; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { Quantizer { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args QuantizerArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = QuantizerBuilder::new(_fbb); @@ -51,17 +46,11 @@ impl<'a> Quantizer<'a> { #[inline] pub fn quantizer(&self) -> SphericalQuantizer<'a> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>(Quantizer::VT_QUANTIZER, None).unwrap()} + self._tab.get::>(Quantizer::VT_QUANTIZER, None).unwrap() } #[inline] pub fn nbits(&self) -> u32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(Quantizer::VT_NBITS, Some(0)).unwrap()} + self._tab.get::(Quantizer::VT_NBITS, Some(0)).unwrap() } } @@ -92,11 +81,11 @@ impl<'a> Default for QuantizerArgs<'a> { } } -pub struct QuantizerBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct QuantizerBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> QuantizerBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> QuantizerBuilder<'a, 'b> { #[inline] pub fn add_quantizer(&mut self, quantizer: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(Quantizer::VT_QUANTIZER, quantizer); @@ -106,7 +95,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> QuantizerBuilder<'a, 'b, A> { self.fbb_.push_slot::(Quantizer::VT_NBITS, nbits, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> QuantizerBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> QuantizerBuilder<'a, 'b> { let start = _fbb.start_table(); QuantizerBuilder { fbb_: _fbb, @@ -129,6 +118,18 @@ impl core::fmt::Debug for Quantizer<'_> { ds.finish() } } +#[inline] +#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")] +pub fn get_root_as_quantizer<'a>(buf: &'a [u8]) -> Quantizer<'a> { + unsafe { flatbuffers::root_unchecked::>(buf) } +} + +#[inline] +#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")] +pub fn get_size_prefixed_root_as_quantizer<'a>(buf: &'a [u8]) -> Quantizer<'a> { + unsafe { flatbuffers::size_prefixed_root_unchecked::>(buf) } +} + #[inline] /// Verifies that a buffer of bytes contains a `Quantizer` /// and returns it. @@ -202,13 +203,13 @@ pub fn quantizer_size_prefixed_buffer_has_identifier(buf: &[u8]) -> bool { } #[inline] -pub fn finish_quantizer_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub fn finish_quantizer_buffer<'a, 'b>( + fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset>) { fbb.finish(root, Some(QUANTIZER_IDENTIFIER)); } #[inline] -pub fn finish_size_prefixed_quantizer_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { +pub fn finish_size_prefixed_quantizer_buffer<'a, 'b>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset>) { fbb.finish_size_prefixed(root, Some(QUANTIZER_IDENTIFIER)); } diff --git a/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs b/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs index 9039d45fc..7d9c38be0 100644 --- a/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct SphericalQuantizer<'a> { impl<'a> flatbuffers::Follow<'a> for SphericalQuantizer<'a> { type Inner = SphericalQuantizer<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -37,12 +32,12 @@ impl<'a> SphericalQuantizer<'a> { pub const VT_PRE_SCALE: flatbuffers::VOffsetT = 12; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { SphericalQuantizer { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args SphericalQuantizerArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = SphericalQuantizerBuilder::new(_fbb); @@ -57,38 +52,23 @@ impl<'a> SphericalQuantizer<'a> { #[inline] pub fn centroid(&self) -> flatbuffers::Vector<'a, f32> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(SphericalQuantizer::VT_CENTROID, None).unwrap()} + self._tab.get::>>(SphericalQuantizer::VT_CENTROID, None).unwrap() } #[inline] pub fn transform(&self) -> super::transforms::Transform<'a> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>(SphericalQuantizer::VT_TRANSFORM, None).unwrap()} + self._tab.get::>(SphericalQuantizer::VT_TRANSFORM, None).unwrap() } #[inline] pub fn metric(&self) -> SupportedMetric { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(SphericalQuantizer::VT_METRIC, Some(SupportedMetric::SquaredL2)).unwrap()} + self._tab.get::(SphericalQuantizer::VT_METRIC, Some(SupportedMetric::SquaredL2)).unwrap() } #[inline] pub fn mean_norm(&self) -> f32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(SphericalQuantizer::VT_MEAN_NORM, Some(0.0)).unwrap()} + self._tab.get::(SphericalQuantizer::VT_MEAN_NORM, Some(0.0)).unwrap() } #[inline] pub fn pre_scale(&self) -> f32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(SphericalQuantizer::VT_PRE_SCALE, Some(0.0)).unwrap()} + self._tab.get::(SphericalQuantizer::VT_PRE_SCALE, Some(0.0)).unwrap() } } @@ -128,11 +108,11 @@ impl<'a> Default for SphericalQuantizerArgs<'a> { } } -pub struct SphericalQuantizerBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct SphericalQuantizerBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> SphericalQuantizerBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> SphericalQuantizerBuilder<'a, 'b> { #[inline] pub fn add_centroid(&mut self, centroid: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(SphericalQuantizer::VT_CENTROID, centroid); @@ -154,7 +134,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> SphericalQuantizerBuilder<'a, ' self.fbb_.push_slot::(SphericalQuantizer::VT_PRE_SCALE, pre_scale, 0.0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> SphericalQuantizerBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> SphericalQuantizerBuilder<'a, 'b> { let start = _fbb.start_table(); SphericalQuantizerBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs b/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs index d96ac6da6..18270ea62 100644 --- a/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -64,8 +59,10 @@ impl core::fmt::Debug for SupportedMetric { impl<'a> flatbuffers::Follow<'a> for SupportedMetric { type Inner = Self; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - let b = flatbuffers::read_scalar_at::(buf, loc); + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { + flatbuffers::read_scalar_at::(buf, loc) + }; Self(b) } } @@ -73,21 +70,21 @@ impl<'a> flatbuffers::Follow<'a> for SupportedMetric { impl flatbuffers::Push for SupportedMetric { type Output = SupportedMetric; #[inline] - unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { - flatbuffers::emplace_scalar::(dst, self.0); + fn push(&self, dst: &mut [u8], _rest: &[u8]) { + unsafe { flatbuffers::emplace_scalar::(dst, self.0); } } } impl flatbuffers::EndianScalar for SupportedMetric { - type Scalar = i8; #[inline] - fn to_little_endian(self) -> i8 { - self.0.to_le() + fn to_little_endian(self) -> Self { + let b = i8::to_le(self.0); + Self(b) } #[inline] #[allow(clippy::wrong_self_convention)] - fn from_little_endian(v: i8) -> Self { - let b = i8::from_le(v); + fn from_little_endian(self) -> Self { + let b = i8::from_le(self.0); Self(b) } } diff --git a/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs b/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs index d4694e8e4..1bc6eb50d 100644 --- a/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct DoubleHadamard<'a> { impl<'a> flatbuffers::Follow<'a> for DoubleHadamard<'a> { type Inner = DoubleHadamard<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -35,12 +30,12 @@ impl<'a> DoubleHadamard<'a> { pub const VT_SUBSAMPLE: flatbuffers::VOffsetT = 8; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { DoubleHadamard { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args DoubleHadamardArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = DoubleHadamardBuilder::new(_fbb); @@ -52,25 +47,16 @@ impl<'a> DoubleHadamard<'a> { #[inline] - pub fn signs0(&self) -> flatbuffers::Vector<'a, bool> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(DoubleHadamard::VT_SIGNS0, None).unwrap()} + pub fn signs0(&self) -> &'a [bool] { + self._tab.get::>>(DoubleHadamard::VT_SIGNS0, None).map(|v| v.safe_slice()).unwrap() } #[inline] - pub fn signs1(&self) -> flatbuffers::Vector<'a, bool> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(DoubleHadamard::VT_SIGNS1, None).unwrap()} + pub fn signs1(&self) -> &'a [bool] { + self._tab.get::>>(DoubleHadamard::VT_SIGNS1, None).map(|v| v.safe_slice()).unwrap() } #[inline] pub fn subsample(&self) -> Option> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(DoubleHadamard::VT_SUBSAMPLE, None)} + self._tab.get::>>(DoubleHadamard::VT_SUBSAMPLE, None) } } @@ -104,11 +90,11 @@ impl<'a> Default for DoubleHadamardArgs<'a> { } } -pub struct DoubleHadamardBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct DoubleHadamardBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> DoubleHadamardBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> DoubleHadamardBuilder<'a, 'b> { #[inline] pub fn add_signs0(&mut self, signs0: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(DoubleHadamard::VT_SIGNS0, signs0); @@ -122,7 +108,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> DoubleHadamardBuilder<'a, 'b, A self.fbb_.push_slot_always::>(DoubleHadamard::VT_SUBSAMPLE, subsample); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> DoubleHadamardBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> DoubleHadamardBuilder<'a, 'b> { let start = _fbb.start_table(); DoubleHadamardBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs b/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs index 3c4f7788a..162eb35c7 100644 --- a/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct NullTransform<'a> { impl<'a> flatbuffers::Follow<'a> for NullTransform<'a> { type Inner = NullTransform<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -33,12 +28,12 @@ impl<'a> NullTransform<'a> { pub const VT_DIM: flatbuffers::VOffsetT = 4; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { NullTransform { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args NullTransformArgs ) -> flatbuffers::WIPOffset> { let mut builder = NullTransformBuilder::new(_fbb); @@ -49,10 +44,7 @@ impl<'a> NullTransform<'a> { #[inline] pub fn dim(&self) -> u32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(NullTransform::VT_DIM, Some(0)).unwrap()} + self._tab.get::(NullTransform::VT_DIM, Some(0)).unwrap() } } @@ -80,17 +72,17 @@ impl<'a> Default for NullTransformArgs { } } -pub struct NullTransformBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct NullTransformBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> NullTransformBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> NullTransformBuilder<'a, 'b> { #[inline] pub fn add_dim(&mut self, dim: u32) { self.fbb_.push_slot::(NullTransform::VT_DIM, dim, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> NullTransformBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> NullTransformBuilder<'a, 'b> { let start = _fbb.start_table(); NullTransformBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs b/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs index 26931d836..274d39c9a 100644 --- a/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct PaddingHadamard<'a> { impl<'a> flatbuffers::Follow<'a> for PaddingHadamard<'a> { type Inner = PaddingHadamard<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -35,12 +30,12 @@ impl<'a> PaddingHadamard<'a> { pub const VT_SUBSAMPLE: flatbuffers::VOffsetT = 8; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { PaddingHadamard { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args PaddingHadamardArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = PaddingHadamardBuilder::new(_fbb); @@ -52,25 +47,16 @@ impl<'a> PaddingHadamard<'a> { #[inline] - pub fn signs(&self) -> flatbuffers::Vector<'a, bool> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(PaddingHadamard::VT_SIGNS, None).unwrap()} + pub fn signs(&self) -> &'a [bool] { + self._tab.get::>>(PaddingHadamard::VT_SIGNS, None).map(|v| v.safe_slice()).unwrap() } #[inline] pub fn padded_dim(&self) -> u32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(PaddingHadamard::VT_PADDED_DIM, Some(0)).unwrap()} + self._tab.get::(PaddingHadamard::VT_PADDED_DIM, Some(0)).unwrap() } #[inline] pub fn subsample(&self) -> Option> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(PaddingHadamard::VT_SUBSAMPLE, None)} + self._tab.get::>>(PaddingHadamard::VT_SUBSAMPLE, None) } } @@ -104,11 +90,11 @@ impl<'a> Default for PaddingHadamardArgs<'a> { } } -pub struct PaddingHadamardBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct PaddingHadamardBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> PaddingHadamardBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> PaddingHadamardBuilder<'a, 'b> { #[inline] pub fn add_signs(&mut self, signs: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(PaddingHadamard::VT_SIGNS, signs); @@ -122,7 +108,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> PaddingHadamardBuilder<'a, 'b, self.fbb_.push_slot_always::>(PaddingHadamard::VT_SUBSAMPLE, subsample); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> PaddingHadamardBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> PaddingHadamardBuilder<'a, 'b> { let start = _fbb.start_table(); PaddingHadamardBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs b/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs index 64e518e1e..2f0196846 100644 --- a/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct RandomRotation<'a> { impl<'a> flatbuffers::Follow<'a> for RandomRotation<'a> { type Inner = RandomRotation<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -35,12 +30,12 @@ impl<'a> RandomRotation<'a> { pub const VT_NCOLS: flatbuffers::VOffsetT = 8; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { RandomRotation { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args RandomRotationArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = RandomRotationBuilder::new(_fbb); @@ -53,24 +48,15 @@ impl<'a> RandomRotation<'a> { #[inline] pub fn data(&self) -> flatbuffers::Vector<'a, f32> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(RandomRotation::VT_DATA, None).unwrap()} + self._tab.get::>>(RandomRotation::VT_DATA, None).unwrap() } #[inline] pub fn nrows(&self) -> u32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(RandomRotation::VT_NROWS, Some(0)).unwrap()} + self._tab.get::(RandomRotation::VT_NROWS, Some(0)).unwrap() } #[inline] pub fn ncols(&self) -> u32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(RandomRotation::VT_NCOLS, Some(0)).unwrap()} + self._tab.get::(RandomRotation::VT_NCOLS, Some(0)).unwrap() } } @@ -104,11 +90,11 @@ impl<'a> Default for RandomRotationArgs<'a> { } } -pub struct RandomRotationBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct RandomRotationBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> RandomRotationBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> RandomRotationBuilder<'a, 'b> { #[inline] pub fn add_data(&mut self, data: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(RandomRotation::VT_DATA, data); @@ -122,7 +108,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> RandomRotationBuilder<'a, 'b, A self.fbb_.push_slot::(RandomRotation::VT_NCOLS, ncols, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> RandomRotationBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> RandomRotationBuilder<'a, 'b> { let start = _fbb.start_table(); RandomRotationBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs b/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs index 7cc3b3afa..f20b493ce 100644 --- a/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct Transform<'a> { impl<'a> flatbuffers::Follow<'a> for Transform<'a> { type Inner = Transform<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -34,12 +29,12 @@ impl<'a> Transform<'a> { pub const VT_TRANSFORM: flatbuffers::VOffsetT = 6; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { Transform { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args TransformArgs ) -> flatbuffers::WIPOffset> { let mut builder = TransformBuilder::new(_fbb); @@ -51,27 +46,18 @@ impl<'a> Transform<'a> { #[inline] pub fn transform_type(&self) -> TransformKind { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(Transform::VT_TRANSFORM_TYPE, Some(TransformKind::NONE)).unwrap()} + self._tab.get::(Transform::VT_TRANSFORM_TYPE, Some(TransformKind::NONE)).unwrap() } #[inline] pub fn transform(&self) -> flatbuffers::Table<'a> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(Transform::VT_TRANSFORM, None).unwrap()} + self._tab.get::>>(Transform::VT_TRANSFORM, None).unwrap() } #[inline] #[allow(non_snake_case)] pub fn transform_as_random_rotation(&self) -> Option> { if self.transform_type() == TransformKind::RandomRotation { let u = self.transform(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { RandomRotation::init_from_table(u) }) + Some(RandomRotation::init_from_table(u)) } else { None } @@ -82,10 +68,7 @@ impl<'a> Transform<'a> { pub fn transform_as_padding_hadamard(&self) -> Option> { if self.transform_type() == TransformKind::PaddingHadamard { let u = self.transform(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { PaddingHadamard::init_from_table(u) }) + Some(PaddingHadamard::init_from_table(u)) } else { None } @@ -96,10 +79,7 @@ impl<'a> Transform<'a> { pub fn transform_as_double_hadamard(&self) -> Option> { if self.transform_type() == TransformKind::DoubleHadamard { let u = self.transform(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { DoubleHadamard::init_from_table(u) }) + Some(DoubleHadamard::init_from_table(u)) } else { None } @@ -110,10 +90,7 @@ impl<'a> Transform<'a> { pub fn transform_as_null_transform(&self) -> Option> { if self.transform_type() == TransformKind::NullTransform { let u = self.transform(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { NullTransform::init_from_table(u) }) + Some(NullTransform::init_from_table(u)) } else { None } @@ -155,11 +132,11 @@ impl<'a> Default for TransformArgs { } } -pub struct TransformBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct TransformBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TransformBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> TransformBuilder<'a, 'b> { #[inline] pub fn add_transform_type(&mut self, transform_type: TransformKind) { self.fbb_.push_slot::(Transform::VT_TRANSFORM_TYPE, transform_type, TransformKind::NONE); @@ -169,7 +146,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TransformBuilder<'a, 'b, A> { self.fbb_.push_slot_always::>(Transform::VT_TRANSFORM, transform); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> TransformBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TransformBuilder<'a, 'b> { let start = _fbb.start_table(); TransformBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs b/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs index fbfb9918f..e2815c9e9 100644 --- a/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -72,8 +67,10 @@ impl core::fmt::Debug for TransformKind { impl<'a> flatbuffers::Follow<'a> for TransformKind { type Inner = Self; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - let b = flatbuffers::read_scalar_at::(buf, loc); + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { + flatbuffers::read_scalar_at::(buf, loc) + }; Self(b) } } @@ -81,21 +78,21 @@ impl<'a> flatbuffers::Follow<'a> for TransformKind { impl flatbuffers::Push for TransformKind { type Output = TransformKind; #[inline] - unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { - flatbuffers::emplace_scalar::(dst, self.0); + fn push(&self, dst: &mut [u8], _rest: &[u8]) { + unsafe { flatbuffers::emplace_scalar::(dst, self.0); } } } impl flatbuffers::EndianScalar for TransformKind { - type Scalar = u8; #[inline] - fn to_little_endian(self) -> u8 { - self.0.to_le() + fn to_little_endian(self) -> Self { + let b = u8::to_le(self.0); + Self(b) } #[inline] #[allow(clippy::wrong_self_convention)] - fn from_little_endian(v: u8) -> Self { - let b = u8::from_le(v); + fn from_little_endian(self) -> Self { + let b = u8::from_le(self.0); Self(b) } } From 8f22beb1e09f68b20f16160a2c2b3be70aff0fb1 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 14:34:38 +0000 Subject: [PATCH 14/34] Revert "Avoid cloning/silencing errors in query accelerator build" This reverts commit 2161a1d1f8da1174b9dc6d24cdfcfd977a76aa11. --- diskann-label-filter/src/utils/compute_bitmap.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 7d5fbcfde..5951b161b 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -224,14 +224,14 @@ pub fn compute_inverted_index_accelerator( } pub fn compute_btree_accelerator( - key: &str, - labels: &[HashMap], + key: String, + labels: Vec>, doc_ids: &[usize], ) -> Result>, anyhow::Error> { // Implementation for computing BTree accelerator let mut map: BTreeMap> = BTreeMap::new(); for (label, doc_id) in labels.iter().zip(doc_ids.iter().copied()) { - if let Some(value) = label.get(key) { + if let Some(value) = label.get(&key) { if let Some(f64_value) = value.as_float() { let f64_value = OrderedFloat::new(f64_value) .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; @@ -279,12 +279,14 @@ pub fn compute_query_accelerator( ) -> Result { match value { AttributeValue::String(_) | AttributeValue::Bool(_) => { - let bitmap = compute_inverted_index_accelerator(&key, doc_ids, flattened_base_labels)?; + let bitmap = compute_inverted_index_accelerator(&key, doc_ids, flattened_base_labels) + .unwrap_or_default(); Ok(QueryAccelerator::InvertedIndex(bitmap)) } AttributeValue::Integer(_) | AttributeValue::Real(_) => { // For integers and reals, we use an BTree - let btree = compute_btree_accelerator(&key, flattened_base_labels, doc_ids)?; + let btree = compute_btree_accelerator(key.clone(), flattened_base_labels.to_vec(), doc_ids) + .unwrap_or_default(); Ok(QueryAccelerator::BTree(btree)) } AttributeValue::Empty => Err(anyhow::anyhow!("Empty attribute value is not allowed")), From f09f9b8691dbb9eee2da80912931da24ab73ba13 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 14:38:49 +0000 Subject: [PATCH 15/34] Revert "fmt" This reverts commit cce1a8a04cf06df3055c9b456a57eb972f853a88. --- .../src/utils/compute_bitmap.rs | 61 ++++++++++--------- .../spherical/quantizer_generated.rs | 51 ++++++++-------- .../spherical_quantizer_generated.rs | 48 ++++++++++----- .../spherical/supported_metric_generated.rs | 25 ++++---- .../transforms/double_hadamard_generated.rs | 42 ++++++++----- .../transforms/null_transform_generated.rs | 28 ++++++--- .../transforms/padding_hadamard_generated.rs | 40 ++++++++---- .../transforms/random_rotation_generated.rs | 38 ++++++++---- .../transforms/transform_generated.rs | 53 +++++++++++----- .../transforms/transform_kind_generated.rs | 25 ++++---- 10 files changed, 256 insertions(+), 155 deletions(-) diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 5951b161b..4596e9794 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -348,10 +348,7 @@ pub fn compute_query_bitmaps( .collect(); let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; - let base_doc_ids: Vec = base_labels - .iter() - .map(|base_label| base_label.doc_id) - .collect(); + let base_doc_ids: Vec = base_labels.iter().map(|base_label| base_label.doc_id).collect(); // compute the global set of labels ahead of time so that we can compute // each accelerator in parallel @@ -705,8 +702,7 @@ mod tests { field: "age".to_string(), op: CompareOp::Gte(20.0), }; - let bitmaps = - compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); + let bitmaps = compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); assert_eq!(bitmaps[0].contains(20), true); assert_eq!(bitmaps[0].contains(30), true); @@ -879,13 +875,14 @@ mod tests { } // Bool - let accel = compute_query_accelerator( - "flag".to_string(), - AttributeValue::Bool(true), - &doc_ids, - &base, - ) - .expect("Should succeed for Bool"); + let accel = + compute_query_accelerator( + "flag".to_string(), + AttributeValue::Bool(true), + &doc_ids, + &base, + ) + .expect("Should succeed for Bool"); match accel { QueryAccelerator::InvertedIndex(map) => { assert!(map.contains_key(&AttributeValue::Bool(true))); @@ -895,13 +892,14 @@ mod tests { } // Integer - let accel = compute_query_accelerator( - "num".to_string(), - AttributeValue::Integer(42), - &doc_ids, - &base, - ) - .expect("Should succeed for Integer"); + let accel = + compute_query_accelerator( + "num".to_string(), + AttributeValue::Integer(42), + &doc_ids, + &base, + ) + .expect("Should succeed for Integer"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(42.0))); @@ -911,13 +909,14 @@ mod tests { } // Real - let accel = compute_query_accelerator( - "real".to_string(), - AttributeValue::Real(3.14), - &doc_ids, - &base, - ) - .expect("Should succeed for Real"); + let accel = + compute_query_accelerator( + "real".to_string(), + AttributeValue::Real(3.14), + &doc_ids, + &base, + ) + .expect("Should succeed for Real"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(3.14))); @@ -927,8 +926,12 @@ mod tests { } // Empty - let err = - compute_query_accelerator("none".to_string(), AttributeValue::Empty, &doc_ids, &base); + let err = compute_query_accelerator( + "none".to_string(), + AttributeValue::Empty, + &doc_ids, + &base, + ); assert!(err.is_err()); } diff --git a/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs b/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs index b90062b09..320ca651d 100644 --- a/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct Quantizer<'a> { impl<'a> flatbuffers::Follow<'a> for Quantizer<'a> { type Inner = Quantizer<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -29,12 +34,12 @@ impl<'a> Quantizer<'a> { pub const VT_NBITS: flatbuffers::VOffsetT = 6; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { Quantizer { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args QuantizerArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = QuantizerBuilder::new(_fbb); @@ -46,11 +51,17 @@ impl<'a> Quantizer<'a> { #[inline] pub fn quantizer(&self) -> SphericalQuantizer<'a> { - self._tab.get::>(Quantizer::VT_QUANTIZER, None).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(Quantizer::VT_QUANTIZER, None).unwrap()} } #[inline] pub fn nbits(&self) -> u32 { - self._tab.get::(Quantizer::VT_NBITS, Some(0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Quantizer::VT_NBITS, Some(0)).unwrap()} } } @@ -81,11 +92,11 @@ impl<'a> Default for QuantizerArgs<'a> { } } -pub struct QuantizerBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct QuantizerBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> QuantizerBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> QuantizerBuilder<'a, 'b, A> { #[inline] pub fn add_quantizer(&mut self, quantizer: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(Quantizer::VT_QUANTIZER, quantizer); @@ -95,7 +106,7 @@ impl<'a: 'b, 'b> QuantizerBuilder<'a, 'b> { self.fbb_.push_slot::(Quantizer::VT_NBITS, nbits, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> QuantizerBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> QuantizerBuilder<'a, 'b, A> { let start = _fbb.start_table(); QuantizerBuilder { fbb_: _fbb, @@ -118,18 +129,6 @@ impl core::fmt::Debug for Quantizer<'_> { ds.finish() } } -#[inline] -#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")] -pub fn get_root_as_quantizer<'a>(buf: &'a [u8]) -> Quantizer<'a> { - unsafe { flatbuffers::root_unchecked::>(buf) } -} - -#[inline] -#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")] -pub fn get_size_prefixed_root_as_quantizer<'a>(buf: &'a [u8]) -> Quantizer<'a> { - unsafe { flatbuffers::size_prefixed_root_unchecked::>(buf) } -} - #[inline] /// Verifies that a buffer of bytes contains a `Quantizer` /// and returns it. @@ -203,13 +202,13 @@ pub fn quantizer_size_prefixed_buffer_has_identifier(buf: &[u8]) -> bool { } #[inline] -pub fn finish_quantizer_buffer<'a, 'b>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub fn finish_quantizer_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( + fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { fbb.finish(root, Some(QUANTIZER_IDENTIFIER)); } #[inline] -pub fn finish_size_prefixed_quantizer_buffer<'a, 'b>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset>) { +pub fn finish_size_prefixed_quantizer_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { fbb.finish_size_prefixed(root, Some(QUANTIZER_IDENTIFIER)); } diff --git a/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs b/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs index 7d9c38be0..9039d45fc 100644 --- a/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct SphericalQuantizer<'a> { impl<'a> flatbuffers::Follow<'a> for SphericalQuantizer<'a> { type Inner = SphericalQuantizer<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -32,12 +37,12 @@ impl<'a> SphericalQuantizer<'a> { pub const VT_PRE_SCALE: flatbuffers::VOffsetT = 12; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { SphericalQuantizer { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args SphericalQuantizerArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = SphericalQuantizerBuilder::new(_fbb); @@ -52,23 +57,38 @@ impl<'a> SphericalQuantizer<'a> { #[inline] pub fn centroid(&self) -> flatbuffers::Vector<'a, f32> { - self._tab.get::>>(SphericalQuantizer::VT_CENTROID, None).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(SphericalQuantizer::VT_CENTROID, None).unwrap()} } #[inline] pub fn transform(&self) -> super::transforms::Transform<'a> { - self._tab.get::>(SphericalQuantizer::VT_TRANSFORM, None).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(SphericalQuantizer::VT_TRANSFORM, None).unwrap()} } #[inline] pub fn metric(&self) -> SupportedMetric { - self._tab.get::(SphericalQuantizer::VT_METRIC, Some(SupportedMetric::SquaredL2)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(SphericalQuantizer::VT_METRIC, Some(SupportedMetric::SquaredL2)).unwrap()} } #[inline] pub fn mean_norm(&self) -> f32 { - self._tab.get::(SphericalQuantizer::VT_MEAN_NORM, Some(0.0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(SphericalQuantizer::VT_MEAN_NORM, Some(0.0)).unwrap()} } #[inline] pub fn pre_scale(&self) -> f32 { - self._tab.get::(SphericalQuantizer::VT_PRE_SCALE, Some(0.0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(SphericalQuantizer::VT_PRE_SCALE, Some(0.0)).unwrap()} } } @@ -108,11 +128,11 @@ impl<'a> Default for SphericalQuantizerArgs<'a> { } } -pub struct SphericalQuantizerBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct SphericalQuantizerBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> SphericalQuantizerBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> SphericalQuantizerBuilder<'a, 'b, A> { #[inline] pub fn add_centroid(&mut self, centroid: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(SphericalQuantizer::VT_CENTROID, centroid); @@ -134,7 +154,7 @@ impl<'a: 'b, 'b> SphericalQuantizerBuilder<'a, 'b> { self.fbb_.push_slot::(SphericalQuantizer::VT_PRE_SCALE, pre_scale, 0.0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> SphericalQuantizerBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> SphericalQuantizerBuilder<'a, 'b, A> { let start = _fbb.start_table(); SphericalQuantizerBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs b/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs index 18270ea62..d96ac6da6 100644 --- a/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -59,10 +64,8 @@ impl core::fmt::Debug for SupportedMetric { impl<'a> flatbuffers::Follow<'a> for SupportedMetric { type Inner = Self; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - let b = unsafe { - flatbuffers::read_scalar_at::(buf, loc) - }; + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = flatbuffers::read_scalar_at::(buf, loc); Self(b) } } @@ -70,21 +73,21 @@ impl<'a> flatbuffers::Follow<'a> for SupportedMetric { impl flatbuffers::Push for SupportedMetric { type Output = SupportedMetric; #[inline] - fn push(&self, dst: &mut [u8], _rest: &[u8]) { - unsafe { flatbuffers::emplace_scalar::(dst, self.0); } + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + flatbuffers::emplace_scalar::(dst, self.0); } } impl flatbuffers::EndianScalar for SupportedMetric { + type Scalar = i8; #[inline] - fn to_little_endian(self) -> Self { - let b = i8::to_le(self.0); - Self(b) + fn to_little_endian(self) -> i8 { + self.0.to_le() } #[inline] #[allow(clippy::wrong_self_convention)] - fn from_little_endian(self) -> Self { - let b = i8::from_le(self.0); + fn from_little_endian(v: i8) -> Self { + let b = i8::from_le(v); Self(b) } } diff --git a/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs b/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs index 1bc6eb50d..d4694e8e4 100644 --- a/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct DoubleHadamard<'a> { impl<'a> flatbuffers::Follow<'a> for DoubleHadamard<'a> { type Inner = DoubleHadamard<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -30,12 +35,12 @@ impl<'a> DoubleHadamard<'a> { pub const VT_SUBSAMPLE: flatbuffers::VOffsetT = 8; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { DoubleHadamard { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args DoubleHadamardArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = DoubleHadamardBuilder::new(_fbb); @@ -47,16 +52,25 @@ impl<'a> DoubleHadamard<'a> { #[inline] - pub fn signs0(&self) -> &'a [bool] { - self._tab.get::>>(DoubleHadamard::VT_SIGNS0, None).map(|v| v.safe_slice()).unwrap() + pub fn signs0(&self) -> flatbuffers::Vector<'a, bool> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(DoubleHadamard::VT_SIGNS0, None).unwrap()} } #[inline] - pub fn signs1(&self) -> &'a [bool] { - self._tab.get::>>(DoubleHadamard::VT_SIGNS1, None).map(|v| v.safe_slice()).unwrap() + pub fn signs1(&self) -> flatbuffers::Vector<'a, bool> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(DoubleHadamard::VT_SIGNS1, None).unwrap()} } #[inline] pub fn subsample(&self) -> Option> { - self._tab.get::>>(DoubleHadamard::VT_SUBSAMPLE, None) + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(DoubleHadamard::VT_SUBSAMPLE, None)} } } @@ -90,11 +104,11 @@ impl<'a> Default for DoubleHadamardArgs<'a> { } } -pub struct DoubleHadamardBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct DoubleHadamardBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> DoubleHadamardBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> DoubleHadamardBuilder<'a, 'b, A> { #[inline] pub fn add_signs0(&mut self, signs0: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(DoubleHadamard::VT_SIGNS0, signs0); @@ -108,7 +122,7 @@ impl<'a: 'b, 'b> DoubleHadamardBuilder<'a, 'b> { self.fbb_.push_slot_always::>(DoubleHadamard::VT_SUBSAMPLE, subsample); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> DoubleHadamardBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> DoubleHadamardBuilder<'a, 'b, A> { let start = _fbb.start_table(); DoubleHadamardBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs b/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs index 162eb35c7..3c4f7788a 100644 --- a/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct NullTransform<'a> { impl<'a> flatbuffers::Follow<'a> for NullTransform<'a> { type Inner = NullTransform<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -28,12 +33,12 @@ impl<'a> NullTransform<'a> { pub const VT_DIM: flatbuffers::VOffsetT = 4; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { NullTransform { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args NullTransformArgs ) -> flatbuffers::WIPOffset> { let mut builder = NullTransformBuilder::new(_fbb); @@ -44,7 +49,10 @@ impl<'a> NullTransform<'a> { #[inline] pub fn dim(&self) -> u32 { - self._tab.get::(NullTransform::VT_DIM, Some(0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(NullTransform::VT_DIM, Some(0)).unwrap()} } } @@ -72,17 +80,17 @@ impl<'a> Default for NullTransformArgs { } } -pub struct NullTransformBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct NullTransformBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> NullTransformBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> NullTransformBuilder<'a, 'b, A> { #[inline] pub fn add_dim(&mut self, dim: u32) { self.fbb_.push_slot::(NullTransform::VT_DIM, dim, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> NullTransformBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> NullTransformBuilder<'a, 'b, A> { let start = _fbb.start_table(); NullTransformBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs b/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs index 274d39c9a..26931d836 100644 --- a/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct PaddingHadamard<'a> { impl<'a> flatbuffers::Follow<'a> for PaddingHadamard<'a> { type Inner = PaddingHadamard<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -30,12 +35,12 @@ impl<'a> PaddingHadamard<'a> { pub const VT_SUBSAMPLE: flatbuffers::VOffsetT = 8; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { PaddingHadamard { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args PaddingHadamardArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = PaddingHadamardBuilder::new(_fbb); @@ -47,16 +52,25 @@ impl<'a> PaddingHadamard<'a> { #[inline] - pub fn signs(&self) -> &'a [bool] { - self._tab.get::>>(PaddingHadamard::VT_SIGNS, None).map(|v| v.safe_slice()).unwrap() + pub fn signs(&self) -> flatbuffers::Vector<'a, bool> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(PaddingHadamard::VT_SIGNS, None).unwrap()} } #[inline] pub fn padded_dim(&self) -> u32 { - self._tab.get::(PaddingHadamard::VT_PADDED_DIM, Some(0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(PaddingHadamard::VT_PADDED_DIM, Some(0)).unwrap()} } #[inline] pub fn subsample(&self) -> Option> { - self._tab.get::>>(PaddingHadamard::VT_SUBSAMPLE, None) + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(PaddingHadamard::VT_SUBSAMPLE, None)} } } @@ -90,11 +104,11 @@ impl<'a> Default for PaddingHadamardArgs<'a> { } } -pub struct PaddingHadamardBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct PaddingHadamardBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> PaddingHadamardBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> PaddingHadamardBuilder<'a, 'b, A> { #[inline] pub fn add_signs(&mut self, signs: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(PaddingHadamard::VT_SIGNS, signs); @@ -108,7 +122,7 @@ impl<'a: 'b, 'b> PaddingHadamardBuilder<'a, 'b> { self.fbb_.push_slot_always::>(PaddingHadamard::VT_SUBSAMPLE, subsample); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> PaddingHadamardBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> PaddingHadamardBuilder<'a, 'b, A> { let start = _fbb.start_table(); PaddingHadamardBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs b/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs index 2f0196846..64e518e1e 100644 --- a/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct RandomRotation<'a> { impl<'a> flatbuffers::Follow<'a> for RandomRotation<'a> { type Inner = RandomRotation<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -30,12 +35,12 @@ impl<'a> RandomRotation<'a> { pub const VT_NCOLS: flatbuffers::VOffsetT = 8; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { RandomRotation { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args RandomRotationArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = RandomRotationBuilder::new(_fbb); @@ -48,15 +53,24 @@ impl<'a> RandomRotation<'a> { #[inline] pub fn data(&self) -> flatbuffers::Vector<'a, f32> { - self._tab.get::>>(RandomRotation::VT_DATA, None).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(RandomRotation::VT_DATA, None).unwrap()} } #[inline] pub fn nrows(&self) -> u32 { - self._tab.get::(RandomRotation::VT_NROWS, Some(0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(RandomRotation::VT_NROWS, Some(0)).unwrap()} } #[inline] pub fn ncols(&self) -> u32 { - self._tab.get::(RandomRotation::VT_NCOLS, Some(0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(RandomRotation::VT_NCOLS, Some(0)).unwrap()} } } @@ -90,11 +104,11 @@ impl<'a> Default for RandomRotationArgs<'a> { } } -pub struct RandomRotationBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct RandomRotationBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> RandomRotationBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> RandomRotationBuilder<'a, 'b, A> { #[inline] pub fn add_data(&mut self, data: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(RandomRotation::VT_DATA, data); @@ -108,7 +122,7 @@ impl<'a: 'b, 'b> RandomRotationBuilder<'a, 'b> { self.fbb_.push_slot::(RandomRotation::VT_NCOLS, ncols, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> RandomRotationBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> RandomRotationBuilder<'a, 'b, A> { let start = _fbb.start_table(); RandomRotationBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs b/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs index f20b493ce..7cc3b3afa 100644 --- a/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct Transform<'a> { impl<'a> flatbuffers::Follow<'a> for Transform<'a> { type Inner = Transform<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -29,12 +34,12 @@ impl<'a> Transform<'a> { pub const VT_TRANSFORM: flatbuffers::VOffsetT = 6; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { Transform { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args TransformArgs ) -> flatbuffers::WIPOffset> { let mut builder = TransformBuilder::new(_fbb); @@ -46,18 +51,27 @@ impl<'a> Transform<'a> { #[inline] pub fn transform_type(&self) -> TransformKind { - self._tab.get::(Transform::VT_TRANSFORM_TYPE, Some(TransformKind::NONE)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Transform::VT_TRANSFORM_TYPE, Some(TransformKind::NONE)).unwrap()} } #[inline] pub fn transform(&self) -> flatbuffers::Table<'a> { - self._tab.get::>>(Transform::VT_TRANSFORM, None).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(Transform::VT_TRANSFORM, None).unwrap()} } #[inline] #[allow(non_snake_case)] pub fn transform_as_random_rotation(&self) -> Option> { if self.transform_type() == TransformKind::RandomRotation { let u = self.transform(); - Some(RandomRotation::init_from_table(u)) + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { RandomRotation::init_from_table(u) }) } else { None } @@ -68,7 +82,10 @@ impl<'a> Transform<'a> { pub fn transform_as_padding_hadamard(&self) -> Option> { if self.transform_type() == TransformKind::PaddingHadamard { let u = self.transform(); - Some(PaddingHadamard::init_from_table(u)) + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { PaddingHadamard::init_from_table(u) }) } else { None } @@ -79,7 +96,10 @@ impl<'a> Transform<'a> { pub fn transform_as_double_hadamard(&self) -> Option> { if self.transform_type() == TransformKind::DoubleHadamard { let u = self.transform(); - Some(DoubleHadamard::init_from_table(u)) + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { DoubleHadamard::init_from_table(u) }) } else { None } @@ -90,7 +110,10 @@ impl<'a> Transform<'a> { pub fn transform_as_null_transform(&self) -> Option> { if self.transform_type() == TransformKind::NullTransform { let u = self.transform(); - Some(NullTransform::init_from_table(u)) + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { NullTransform::init_from_table(u) }) } else { None } @@ -132,11 +155,11 @@ impl<'a> Default for TransformArgs { } } -pub struct TransformBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct TransformBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> TransformBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TransformBuilder<'a, 'b, A> { #[inline] pub fn add_transform_type(&mut self, transform_type: TransformKind) { self.fbb_.push_slot::(Transform::VT_TRANSFORM_TYPE, transform_type, TransformKind::NONE); @@ -146,7 +169,7 @@ impl<'a: 'b, 'b> TransformBuilder<'a, 'b> { self.fbb_.push_slot_always::>(Transform::VT_TRANSFORM, transform); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TransformBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> TransformBuilder<'a, 'b, A> { let start = _fbb.start_table(); TransformBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs b/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs index e2815c9e9..fbfb9918f 100644 --- a/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -67,10 +72,8 @@ impl core::fmt::Debug for TransformKind { impl<'a> flatbuffers::Follow<'a> for TransformKind { type Inner = Self; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - let b = unsafe { - flatbuffers::read_scalar_at::(buf, loc) - }; + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = flatbuffers::read_scalar_at::(buf, loc); Self(b) } } @@ -78,21 +81,21 @@ impl<'a> flatbuffers::Follow<'a> for TransformKind { impl flatbuffers::Push for TransformKind { type Output = TransformKind; #[inline] - fn push(&self, dst: &mut [u8], _rest: &[u8]) { - unsafe { flatbuffers::emplace_scalar::(dst, self.0); } + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + flatbuffers::emplace_scalar::(dst, self.0); } } impl flatbuffers::EndianScalar for TransformKind { + type Scalar = u8; #[inline] - fn to_little_endian(self) -> Self { - let b = u8::to_le(self.0); - Self(b) + fn to_little_endian(self) -> u8 { + self.0.to_le() } #[inline] #[allow(clippy::wrong_self_convention)] - fn from_little_endian(self) -> Self { - let b = u8::from_le(self.0); + fn from_little_endian(v: u8) -> Self { + let b = u8::from_le(v); Self(b) } } From 1696ee369af13d53098e3519e62afe16d63b40da Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 14:40:11 +0000 Subject: [PATCH 16/34] Reapply "Avoid cloning/silencing errors in query accelerator build" This reverts commit 8f22beb1e09f68b20f16160a2c2b3be70aff0fb1. --- diskann-label-filter/src/utils/compute_bitmap.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 4596e9794..3394d353c 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -224,14 +224,14 @@ pub fn compute_inverted_index_accelerator( } pub fn compute_btree_accelerator( - key: String, - labels: Vec>, + key: &str, + labels: &[HashMap], doc_ids: &[usize], ) -> Result>, anyhow::Error> { // Implementation for computing BTree accelerator let mut map: BTreeMap> = BTreeMap::new(); for (label, doc_id) in labels.iter().zip(doc_ids.iter().copied()) { - if let Some(value) = label.get(&key) { + if let Some(value) = label.get(key) { if let Some(f64_value) = value.as_float() { let f64_value = OrderedFloat::new(f64_value) .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; @@ -279,14 +279,12 @@ pub fn compute_query_accelerator( ) -> Result { match value { AttributeValue::String(_) | AttributeValue::Bool(_) => { - let bitmap = compute_inverted_index_accelerator(&key, doc_ids, flattened_base_labels) - .unwrap_or_default(); + let bitmap = compute_inverted_index_accelerator(&key, doc_ids, flattened_base_labels)?; Ok(QueryAccelerator::InvertedIndex(bitmap)) } AttributeValue::Integer(_) | AttributeValue::Real(_) => { // For integers and reals, we use an BTree - let btree = compute_btree_accelerator(key.clone(), flattened_base_labels.to_vec(), doc_ids) - .unwrap_or_default(); + let btree = compute_btree_accelerator(&key, flattened_base_labels, doc_ids)?; Ok(QueryAccelerator::BTree(btree)) } AttributeValue::Empty => Err(anyhow::anyhow!("Empty attribute value is not allowed")), From d631aae1fd2edaab9700bca6949f072b6c98030b Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 14:41:07 +0000 Subject: [PATCH 17/34] small changes --- .../src/utils/compute_bitmap.rs | 61 +++++++++---------- .../spherical/quantizer_generated.rs | 51 ++++++++-------- .../spherical_quantizer_generated.rs | 48 +++++---------- .../spherical/supported_metric_generated.rs | 25 ++++---- .../transforms/double_hadamard_generated.rs | 42 +++++-------- .../transforms/null_transform_generated.rs | 28 +++------ .../transforms/padding_hadamard_generated.rs | 40 ++++-------- .../transforms/random_rotation_generated.rs | 38 ++++-------- .../transforms/transform_generated.rs | 53 +++++----------- .../transforms/transform_kind_generated.rs | 25 ++++---- 10 files changed, 155 insertions(+), 256 deletions(-) diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 3394d353c..7d5fbcfde 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -346,7 +346,10 @@ pub fn compute_query_bitmaps( .collect(); let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; - let base_doc_ids: Vec = base_labels.iter().map(|base_label| base_label.doc_id).collect(); + let base_doc_ids: Vec = base_labels + .iter() + .map(|base_label| base_label.doc_id) + .collect(); // compute the global set of labels ahead of time so that we can compute // each accelerator in parallel @@ -700,7 +703,8 @@ mod tests { field: "age".to_string(), op: CompareOp::Gte(20.0), }; - let bitmaps = compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); + let bitmaps = + compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); assert_eq!(bitmaps[0].contains(20), true); assert_eq!(bitmaps[0].contains(30), true); @@ -873,14 +877,13 @@ mod tests { } // Bool - let accel = - compute_query_accelerator( - "flag".to_string(), - AttributeValue::Bool(true), - &doc_ids, - &base, - ) - .expect("Should succeed for Bool"); + let accel = compute_query_accelerator( + "flag".to_string(), + AttributeValue::Bool(true), + &doc_ids, + &base, + ) + .expect("Should succeed for Bool"); match accel { QueryAccelerator::InvertedIndex(map) => { assert!(map.contains_key(&AttributeValue::Bool(true))); @@ -890,14 +893,13 @@ mod tests { } // Integer - let accel = - compute_query_accelerator( - "num".to_string(), - AttributeValue::Integer(42), - &doc_ids, - &base, - ) - .expect("Should succeed for Integer"); + let accel = compute_query_accelerator( + "num".to_string(), + AttributeValue::Integer(42), + &doc_ids, + &base, + ) + .expect("Should succeed for Integer"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(42.0))); @@ -907,14 +909,13 @@ mod tests { } // Real - let accel = - compute_query_accelerator( - "real".to_string(), - AttributeValue::Real(3.14), - &doc_ids, - &base, - ) - .expect("Should succeed for Real"); + let accel = compute_query_accelerator( + "real".to_string(), + AttributeValue::Real(3.14), + &doc_ids, + &base, + ) + .expect("Should succeed for Real"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(3.14))); @@ -924,12 +925,8 @@ mod tests { } // Empty - let err = compute_query_accelerator( - "none".to_string(), - AttributeValue::Empty, - &doc_ids, - &base, - ); + let err = + compute_query_accelerator("none".to_string(), AttributeValue::Empty, &doc_ids, &base); assert!(err.is_err()); } diff --git a/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs b/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs index 320ca651d..b90062b09 100644 --- a/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct Quantizer<'a> { impl<'a> flatbuffers::Follow<'a> for Quantizer<'a> { type Inner = Quantizer<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -34,12 +29,12 @@ impl<'a> Quantizer<'a> { pub const VT_NBITS: flatbuffers::VOffsetT = 6; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { Quantizer { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args QuantizerArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = QuantizerBuilder::new(_fbb); @@ -51,17 +46,11 @@ impl<'a> Quantizer<'a> { #[inline] pub fn quantizer(&self) -> SphericalQuantizer<'a> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>(Quantizer::VT_QUANTIZER, None).unwrap()} + self._tab.get::>(Quantizer::VT_QUANTIZER, None).unwrap() } #[inline] pub fn nbits(&self) -> u32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(Quantizer::VT_NBITS, Some(0)).unwrap()} + self._tab.get::(Quantizer::VT_NBITS, Some(0)).unwrap() } } @@ -92,11 +81,11 @@ impl<'a> Default for QuantizerArgs<'a> { } } -pub struct QuantizerBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct QuantizerBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> QuantizerBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> QuantizerBuilder<'a, 'b> { #[inline] pub fn add_quantizer(&mut self, quantizer: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(Quantizer::VT_QUANTIZER, quantizer); @@ -106,7 +95,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> QuantizerBuilder<'a, 'b, A> { self.fbb_.push_slot::(Quantizer::VT_NBITS, nbits, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> QuantizerBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> QuantizerBuilder<'a, 'b> { let start = _fbb.start_table(); QuantizerBuilder { fbb_: _fbb, @@ -129,6 +118,18 @@ impl core::fmt::Debug for Quantizer<'_> { ds.finish() } } +#[inline] +#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")] +pub fn get_root_as_quantizer<'a>(buf: &'a [u8]) -> Quantizer<'a> { + unsafe { flatbuffers::root_unchecked::>(buf) } +} + +#[inline] +#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")] +pub fn get_size_prefixed_root_as_quantizer<'a>(buf: &'a [u8]) -> Quantizer<'a> { + unsafe { flatbuffers::size_prefixed_root_unchecked::>(buf) } +} + #[inline] /// Verifies that a buffer of bytes contains a `Quantizer` /// and returns it. @@ -202,13 +203,13 @@ pub fn quantizer_size_prefixed_buffer_has_identifier(buf: &[u8]) -> bool { } #[inline] -pub fn finish_quantizer_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub fn finish_quantizer_buffer<'a, 'b>( + fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset>) { fbb.finish(root, Some(QUANTIZER_IDENTIFIER)); } #[inline] -pub fn finish_size_prefixed_quantizer_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { +pub fn finish_size_prefixed_quantizer_buffer<'a, 'b>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset>) { fbb.finish_size_prefixed(root, Some(QUANTIZER_IDENTIFIER)); } diff --git a/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs b/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs index 9039d45fc..7d9c38be0 100644 --- a/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct SphericalQuantizer<'a> { impl<'a> flatbuffers::Follow<'a> for SphericalQuantizer<'a> { type Inner = SphericalQuantizer<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -37,12 +32,12 @@ impl<'a> SphericalQuantizer<'a> { pub const VT_PRE_SCALE: flatbuffers::VOffsetT = 12; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { SphericalQuantizer { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args SphericalQuantizerArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = SphericalQuantizerBuilder::new(_fbb); @@ -57,38 +52,23 @@ impl<'a> SphericalQuantizer<'a> { #[inline] pub fn centroid(&self) -> flatbuffers::Vector<'a, f32> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(SphericalQuantizer::VT_CENTROID, None).unwrap()} + self._tab.get::>>(SphericalQuantizer::VT_CENTROID, None).unwrap() } #[inline] pub fn transform(&self) -> super::transforms::Transform<'a> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>(SphericalQuantizer::VT_TRANSFORM, None).unwrap()} + self._tab.get::>(SphericalQuantizer::VT_TRANSFORM, None).unwrap() } #[inline] pub fn metric(&self) -> SupportedMetric { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(SphericalQuantizer::VT_METRIC, Some(SupportedMetric::SquaredL2)).unwrap()} + self._tab.get::(SphericalQuantizer::VT_METRIC, Some(SupportedMetric::SquaredL2)).unwrap() } #[inline] pub fn mean_norm(&self) -> f32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(SphericalQuantizer::VT_MEAN_NORM, Some(0.0)).unwrap()} + self._tab.get::(SphericalQuantizer::VT_MEAN_NORM, Some(0.0)).unwrap() } #[inline] pub fn pre_scale(&self) -> f32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(SphericalQuantizer::VT_PRE_SCALE, Some(0.0)).unwrap()} + self._tab.get::(SphericalQuantizer::VT_PRE_SCALE, Some(0.0)).unwrap() } } @@ -128,11 +108,11 @@ impl<'a> Default for SphericalQuantizerArgs<'a> { } } -pub struct SphericalQuantizerBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct SphericalQuantizerBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> SphericalQuantizerBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> SphericalQuantizerBuilder<'a, 'b> { #[inline] pub fn add_centroid(&mut self, centroid: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(SphericalQuantizer::VT_CENTROID, centroid); @@ -154,7 +134,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> SphericalQuantizerBuilder<'a, ' self.fbb_.push_slot::(SphericalQuantizer::VT_PRE_SCALE, pre_scale, 0.0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> SphericalQuantizerBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> SphericalQuantizerBuilder<'a, 'b> { let start = _fbb.start_table(); SphericalQuantizerBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs b/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs index d96ac6da6..18270ea62 100644 --- a/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -64,8 +59,10 @@ impl core::fmt::Debug for SupportedMetric { impl<'a> flatbuffers::Follow<'a> for SupportedMetric { type Inner = Self; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - let b = flatbuffers::read_scalar_at::(buf, loc); + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { + flatbuffers::read_scalar_at::(buf, loc) + }; Self(b) } } @@ -73,21 +70,21 @@ impl<'a> flatbuffers::Follow<'a> for SupportedMetric { impl flatbuffers::Push for SupportedMetric { type Output = SupportedMetric; #[inline] - unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { - flatbuffers::emplace_scalar::(dst, self.0); + fn push(&self, dst: &mut [u8], _rest: &[u8]) { + unsafe { flatbuffers::emplace_scalar::(dst, self.0); } } } impl flatbuffers::EndianScalar for SupportedMetric { - type Scalar = i8; #[inline] - fn to_little_endian(self) -> i8 { - self.0.to_le() + fn to_little_endian(self) -> Self { + let b = i8::to_le(self.0); + Self(b) } #[inline] #[allow(clippy::wrong_self_convention)] - fn from_little_endian(v: i8) -> Self { - let b = i8::from_le(v); + fn from_little_endian(self) -> Self { + let b = i8::from_le(self.0); Self(b) } } diff --git a/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs b/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs index d4694e8e4..1bc6eb50d 100644 --- a/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct DoubleHadamard<'a> { impl<'a> flatbuffers::Follow<'a> for DoubleHadamard<'a> { type Inner = DoubleHadamard<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -35,12 +30,12 @@ impl<'a> DoubleHadamard<'a> { pub const VT_SUBSAMPLE: flatbuffers::VOffsetT = 8; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { DoubleHadamard { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args DoubleHadamardArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = DoubleHadamardBuilder::new(_fbb); @@ -52,25 +47,16 @@ impl<'a> DoubleHadamard<'a> { #[inline] - pub fn signs0(&self) -> flatbuffers::Vector<'a, bool> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(DoubleHadamard::VT_SIGNS0, None).unwrap()} + pub fn signs0(&self) -> &'a [bool] { + self._tab.get::>>(DoubleHadamard::VT_SIGNS0, None).map(|v| v.safe_slice()).unwrap() } #[inline] - pub fn signs1(&self) -> flatbuffers::Vector<'a, bool> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(DoubleHadamard::VT_SIGNS1, None).unwrap()} + pub fn signs1(&self) -> &'a [bool] { + self._tab.get::>>(DoubleHadamard::VT_SIGNS1, None).map(|v| v.safe_slice()).unwrap() } #[inline] pub fn subsample(&self) -> Option> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(DoubleHadamard::VT_SUBSAMPLE, None)} + self._tab.get::>>(DoubleHadamard::VT_SUBSAMPLE, None) } } @@ -104,11 +90,11 @@ impl<'a> Default for DoubleHadamardArgs<'a> { } } -pub struct DoubleHadamardBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct DoubleHadamardBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> DoubleHadamardBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> DoubleHadamardBuilder<'a, 'b> { #[inline] pub fn add_signs0(&mut self, signs0: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(DoubleHadamard::VT_SIGNS0, signs0); @@ -122,7 +108,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> DoubleHadamardBuilder<'a, 'b, A self.fbb_.push_slot_always::>(DoubleHadamard::VT_SUBSAMPLE, subsample); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> DoubleHadamardBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> DoubleHadamardBuilder<'a, 'b> { let start = _fbb.start_table(); DoubleHadamardBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs b/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs index 3c4f7788a..162eb35c7 100644 --- a/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct NullTransform<'a> { impl<'a> flatbuffers::Follow<'a> for NullTransform<'a> { type Inner = NullTransform<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -33,12 +28,12 @@ impl<'a> NullTransform<'a> { pub const VT_DIM: flatbuffers::VOffsetT = 4; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { NullTransform { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args NullTransformArgs ) -> flatbuffers::WIPOffset> { let mut builder = NullTransformBuilder::new(_fbb); @@ -49,10 +44,7 @@ impl<'a> NullTransform<'a> { #[inline] pub fn dim(&self) -> u32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(NullTransform::VT_DIM, Some(0)).unwrap()} + self._tab.get::(NullTransform::VT_DIM, Some(0)).unwrap() } } @@ -80,17 +72,17 @@ impl<'a> Default for NullTransformArgs { } } -pub struct NullTransformBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct NullTransformBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> NullTransformBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> NullTransformBuilder<'a, 'b> { #[inline] pub fn add_dim(&mut self, dim: u32) { self.fbb_.push_slot::(NullTransform::VT_DIM, dim, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> NullTransformBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> NullTransformBuilder<'a, 'b> { let start = _fbb.start_table(); NullTransformBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs b/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs index 26931d836..274d39c9a 100644 --- a/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct PaddingHadamard<'a> { impl<'a> flatbuffers::Follow<'a> for PaddingHadamard<'a> { type Inner = PaddingHadamard<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -35,12 +30,12 @@ impl<'a> PaddingHadamard<'a> { pub const VT_SUBSAMPLE: flatbuffers::VOffsetT = 8; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { PaddingHadamard { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args PaddingHadamardArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = PaddingHadamardBuilder::new(_fbb); @@ -52,25 +47,16 @@ impl<'a> PaddingHadamard<'a> { #[inline] - pub fn signs(&self) -> flatbuffers::Vector<'a, bool> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(PaddingHadamard::VT_SIGNS, None).unwrap()} + pub fn signs(&self) -> &'a [bool] { + self._tab.get::>>(PaddingHadamard::VT_SIGNS, None).map(|v| v.safe_slice()).unwrap() } #[inline] pub fn padded_dim(&self) -> u32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(PaddingHadamard::VT_PADDED_DIM, Some(0)).unwrap()} + self._tab.get::(PaddingHadamard::VT_PADDED_DIM, Some(0)).unwrap() } #[inline] pub fn subsample(&self) -> Option> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(PaddingHadamard::VT_SUBSAMPLE, None)} + self._tab.get::>>(PaddingHadamard::VT_SUBSAMPLE, None) } } @@ -104,11 +90,11 @@ impl<'a> Default for PaddingHadamardArgs<'a> { } } -pub struct PaddingHadamardBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct PaddingHadamardBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> PaddingHadamardBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> PaddingHadamardBuilder<'a, 'b> { #[inline] pub fn add_signs(&mut self, signs: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(PaddingHadamard::VT_SIGNS, signs); @@ -122,7 +108,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> PaddingHadamardBuilder<'a, 'b, self.fbb_.push_slot_always::>(PaddingHadamard::VT_SUBSAMPLE, subsample); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> PaddingHadamardBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> PaddingHadamardBuilder<'a, 'b> { let start = _fbb.start_table(); PaddingHadamardBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs b/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs index 64e518e1e..2f0196846 100644 --- a/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct RandomRotation<'a> { impl<'a> flatbuffers::Follow<'a> for RandomRotation<'a> { type Inner = RandomRotation<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -35,12 +30,12 @@ impl<'a> RandomRotation<'a> { pub const VT_NCOLS: flatbuffers::VOffsetT = 8; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { RandomRotation { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args RandomRotationArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = RandomRotationBuilder::new(_fbb); @@ -53,24 +48,15 @@ impl<'a> RandomRotation<'a> { #[inline] pub fn data(&self) -> flatbuffers::Vector<'a, f32> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(RandomRotation::VT_DATA, None).unwrap()} + self._tab.get::>>(RandomRotation::VT_DATA, None).unwrap() } #[inline] pub fn nrows(&self) -> u32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(RandomRotation::VT_NROWS, Some(0)).unwrap()} + self._tab.get::(RandomRotation::VT_NROWS, Some(0)).unwrap() } #[inline] pub fn ncols(&self) -> u32 { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(RandomRotation::VT_NCOLS, Some(0)).unwrap()} + self._tab.get::(RandomRotation::VT_NCOLS, Some(0)).unwrap() } } @@ -104,11 +90,11 @@ impl<'a> Default for RandomRotationArgs<'a> { } } -pub struct RandomRotationBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct RandomRotationBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> RandomRotationBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> RandomRotationBuilder<'a, 'b> { #[inline] pub fn add_data(&mut self, data: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(RandomRotation::VT_DATA, data); @@ -122,7 +108,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> RandomRotationBuilder<'a, 'b, A self.fbb_.push_slot::(RandomRotation::VT_NCOLS, ncols, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> RandomRotationBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> RandomRotationBuilder<'a, 'b> { let start = _fbb.start_table(); RandomRotationBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs b/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs index 7cc3b3afa..f20b493ce 100644 --- a/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -24,8 +19,8 @@ pub struct Transform<'a> { impl<'a> flatbuffers::Follow<'a> for Transform<'a> { type Inner = Transform<'a>; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table { buf, loc } } } } @@ -34,12 +29,12 @@ impl<'a> Transform<'a> { pub const VT_TRANSFORM: flatbuffers::VOffsetT = 6; #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { Transform { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, args: &'args TransformArgs ) -> flatbuffers::WIPOffset> { let mut builder = TransformBuilder::new(_fbb); @@ -51,27 +46,18 @@ impl<'a> Transform<'a> { #[inline] pub fn transform_type(&self) -> TransformKind { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::(Transform::VT_TRANSFORM_TYPE, Some(TransformKind::NONE)).unwrap()} + self._tab.get::(Transform::VT_TRANSFORM_TYPE, Some(TransformKind::NONE)).unwrap() } #[inline] pub fn transform(&self) -> flatbuffers::Table<'a> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(Transform::VT_TRANSFORM, None).unwrap()} + self._tab.get::>>(Transform::VT_TRANSFORM, None).unwrap() } #[inline] #[allow(non_snake_case)] pub fn transform_as_random_rotation(&self) -> Option> { if self.transform_type() == TransformKind::RandomRotation { let u = self.transform(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { RandomRotation::init_from_table(u) }) + Some(RandomRotation::init_from_table(u)) } else { None } @@ -82,10 +68,7 @@ impl<'a> Transform<'a> { pub fn transform_as_padding_hadamard(&self) -> Option> { if self.transform_type() == TransformKind::PaddingHadamard { let u = self.transform(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { PaddingHadamard::init_from_table(u) }) + Some(PaddingHadamard::init_from_table(u)) } else { None } @@ -96,10 +79,7 @@ impl<'a> Transform<'a> { pub fn transform_as_double_hadamard(&self) -> Option> { if self.transform_type() == TransformKind::DoubleHadamard { let u = self.transform(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { DoubleHadamard::init_from_table(u) }) + Some(DoubleHadamard::init_from_table(u)) } else { None } @@ -110,10 +90,7 @@ impl<'a> Transform<'a> { pub fn transform_as_null_transform(&self) -> Option> { if self.transform_type() == TransformKind::NullTransform { let u = self.transform(); - // Safety: - // Created from a valid Table for this object - // Which contains a valid union in this slot - Some(unsafe { NullTransform::init_from_table(u) }) + Some(NullTransform::init_from_table(u)) } else { None } @@ -155,11 +132,11 @@ impl<'a> Default for TransformArgs { } } -pub struct TransformBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, +pub struct TransformBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TransformBuilder<'a, 'b, A> { +impl<'a: 'b, 'b> TransformBuilder<'a, 'b> { #[inline] pub fn add_transform_type(&mut self, transform_type: TransformKind) { self.fbb_.push_slot::(Transform::VT_TRANSFORM_TYPE, transform_type, TransformKind::NONE); @@ -169,7 +146,7 @@ impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TransformBuilder<'a, 'b, A> { self.fbb_.push_slot_always::>(Transform::VT_TRANSFORM, transform); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> TransformBuilder<'a, 'b, A> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TransformBuilder<'a, 'b> { let start = _fbb.start_table(); TransformBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs b/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs index fbfb9918f..e2815c9e9 100644 --- a/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs @@ -1,8 +1,3 @@ -/* - * Copyright (c) Microsoft Corporation. - * Licensed under the MIT license. - */ - // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -72,8 +67,10 @@ impl core::fmt::Debug for TransformKind { impl<'a> flatbuffers::Follow<'a> for TransformKind { type Inner = Self; #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - let b = flatbuffers::read_scalar_at::(buf, loc); + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = unsafe { + flatbuffers::read_scalar_at::(buf, loc) + }; Self(b) } } @@ -81,21 +78,21 @@ impl<'a> flatbuffers::Follow<'a> for TransformKind { impl flatbuffers::Push for TransformKind { type Output = TransformKind; #[inline] - unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { - flatbuffers::emplace_scalar::(dst, self.0); + fn push(&self, dst: &mut [u8], _rest: &[u8]) { + unsafe { flatbuffers::emplace_scalar::(dst, self.0); } } } impl flatbuffers::EndianScalar for TransformKind { - type Scalar = u8; #[inline] - fn to_little_endian(self) -> u8 { - self.0.to_le() + fn to_little_endian(self) -> Self { + let b = u8::to_le(self.0); + Self(b) } #[inline] #[allow(clippy::wrong_self_convention)] - fn from_little_endian(v: u8) -> Self { - let b = u8::from_le(v); + fn from_little_endian(self) -> Self { + let b = u8::from_le(self.0); Self(b) } } From 38688be387a1e88e106e8caabf4c6a10bdbcf579 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 14:42:35 +0000 Subject: [PATCH 18/34] Revert "small changes" This reverts commit d631aae1fd2edaab9700bca6949f072b6c98030b. --- .../src/utils/compute_bitmap.rs | 61 ++++++++++--------- .../spherical/quantizer_generated.rs | 51 ++++++++-------- .../spherical_quantizer_generated.rs | 48 ++++++++++----- .../spherical/supported_metric_generated.rs | 25 ++++---- .../transforms/double_hadamard_generated.rs | 42 ++++++++----- .../transforms/null_transform_generated.rs | 28 ++++++--- .../transforms/padding_hadamard_generated.rs | 40 ++++++++---- .../transforms/random_rotation_generated.rs | 38 ++++++++---- .../transforms/transform_generated.rs | 53 +++++++++++----- .../transforms/transform_kind_generated.rs | 25 ++++---- 10 files changed, 256 insertions(+), 155 deletions(-) diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 7d5fbcfde..3394d353c 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -346,10 +346,7 @@ pub fn compute_query_bitmaps( .collect(); let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; - let base_doc_ids: Vec = base_labels - .iter() - .map(|base_label| base_label.doc_id) - .collect(); + let base_doc_ids: Vec = base_labels.iter().map(|base_label| base_label.doc_id).collect(); // compute the global set of labels ahead of time so that we can compute // each accelerator in parallel @@ -703,8 +700,7 @@ mod tests { field: "age".to_string(), op: CompareOp::Gte(20.0), }; - let bitmaps = - compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); + let bitmaps = compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); assert_eq!(bitmaps[0].contains(20), true); assert_eq!(bitmaps[0].contains(30), true); @@ -877,13 +873,14 @@ mod tests { } // Bool - let accel = compute_query_accelerator( - "flag".to_string(), - AttributeValue::Bool(true), - &doc_ids, - &base, - ) - .expect("Should succeed for Bool"); + let accel = + compute_query_accelerator( + "flag".to_string(), + AttributeValue::Bool(true), + &doc_ids, + &base, + ) + .expect("Should succeed for Bool"); match accel { QueryAccelerator::InvertedIndex(map) => { assert!(map.contains_key(&AttributeValue::Bool(true))); @@ -893,13 +890,14 @@ mod tests { } // Integer - let accel = compute_query_accelerator( - "num".to_string(), - AttributeValue::Integer(42), - &doc_ids, - &base, - ) - .expect("Should succeed for Integer"); + let accel = + compute_query_accelerator( + "num".to_string(), + AttributeValue::Integer(42), + &doc_ids, + &base, + ) + .expect("Should succeed for Integer"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(42.0))); @@ -909,13 +907,14 @@ mod tests { } // Real - let accel = compute_query_accelerator( - "real".to_string(), - AttributeValue::Real(3.14), - &doc_ids, - &base, - ) - .expect("Should succeed for Real"); + let accel = + compute_query_accelerator( + "real".to_string(), + AttributeValue::Real(3.14), + &doc_ids, + &base, + ) + .expect("Should succeed for Real"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(3.14))); @@ -925,8 +924,12 @@ mod tests { } // Empty - let err = - compute_query_accelerator("none".to_string(), AttributeValue::Empty, &doc_ids, &base); + let err = compute_query_accelerator( + "none".to_string(), + AttributeValue::Empty, + &doc_ids, + &base, + ); assert!(err.is_err()); } diff --git a/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs b/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs index b90062b09..320ca651d 100644 --- a/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/quantizer_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct Quantizer<'a> { impl<'a> flatbuffers::Follow<'a> for Quantizer<'a> { type Inner = Quantizer<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -29,12 +34,12 @@ impl<'a> Quantizer<'a> { pub const VT_NBITS: flatbuffers::VOffsetT = 6; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { Quantizer { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args QuantizerArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = QuantizerBuilder::new(_fbb); @@ -46,11 +51,17 @@ impl<'a> Quantizer<'a> { #[inline] pub fn quantizer(&self) -> SphericalQuantizer<'a> { - self._tab.get::>(Quantizer::VT_QUANTIZER, None).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(Quantizer::VT_QUANTIZER, None).unwrap()} } #[inline] pub fn nbits(&self) -> u32 { - self._tab.get::(Quantizer::VT_NBITS, Some(0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Quantizer::VT_NBITS, Some(0)).unwrap()} } } @@ -81,11 +92,11 @@ impl<'a> Default for QuantizerArgs<'a> { } } -pub struct QuantizerBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct QuantizerBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> QuantizerBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> QuantizerBuilder<'a, 'b, A> { #[inline] pub fn add_quantizer(&mut self, quantizer: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(Quantizer::VT_QUANTIZER, quantizer); @@ -95,7 +106,7 @@ impl<'a: 'b, 'b> QuantizerBuilder<'a, 'b> { self.fbb_.push_slot::(Quantizer::VT_NBITS, nbits, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> QuantizerBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> QuantizerBuilder<'a, 'b, A> { let start = _fbb.start_table(); QuantizerBuilder { fbb_: _fbb, @@ -118,18 +129,6 @@ impl core::fmt::Debug for Quantizer<'_> { ds.finish() } } -#[inline] -#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")] -pub fn get_root_as_quantizer<'a>(buf: &'a [u8]) -> Quantizer<'a> { - unsafe { flatbuffers::root_unchecked::>(buf) } -} - -#[inline] -#[deprecated(since="2.0.0", note="Deprecated in favor of `root_as...` methods.")] -pub fn get_size_prefixed_root_as_quantizer<'a>(buf: &'a [u8]) -> Quantizer<'a> { - unsafe { flatbuffers::size_prefixed_root_unchecked::>(buf) } -} - #[inline] /// Verifies that a buffer of bytes contains a `Quantizer` /// and returns it. @@ -203,13 +202,13 @@ pub fn quantizer_size_prefixed_buffer_has_identifier(buf: &[u8]) -> bool { } #[inline] -pub fn finish_quantizer_buffer<'a, 'b>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub fn finish_quantizer_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( + fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { fbb.finish(root, Some(QUANTIZER_IDENTIFIER)); } #[inline] -pub fn finish_size_prefixed_quantizer_buffer<'a, 'b>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset>) { +pub fn finish_size_prefixed_quantizer_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { fbb.finish_size_prefixed(root, Some(QUANTIZER_IDENTIFIER)); } diff --git a/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs b/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs index 7d9c38be0..9039d45fc 100644 --- a/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/spherical_quantizer_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct SphericalQuantizer<'a> { impl<'a> flatbuffers::Follow<'a> for SphericalQuantizer<'a> { type Inner = SphericalQuantizer<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -32,12 +37,12 @@ impl<'a> SphericalQuantizer<'a> { pub const VT_PRE_SCALE: flatbuffers::VOffsetT = 12; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { SphericalQuantizer { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args SphericalQuantizerArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = SphericalQuantizerBuilder::new(_fbb); @@ -52,23 +57,38 @@ impl<'a> SphericalQuantizer<'a> { #[inline] pub fn centroid(&self) -> flatbuffers::Vector<'a, f32> { - self._tab.get::>>(SphericalQuantizer::VT_CENTROID, None).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(SphericalQuantizer::VT_CENTROID, None).unwrap()} } #[inline] pub fn transform(&self) -> super::transforms::Transform<'a> { - self._tab.get::>(SphericalQuantizer::VT_TRANSFORM, None).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>(SphericalQuantizer::VT_TRANSFORM, None).unwrap()} } #[inline] pub fn metric(&self) -> SupportedMetric { - self._tab.get::(SphericalQuantizer::VT_METRIC, Some(SupportedMetric::SquaredL2)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(SphericalQuantizer::VT_METRIC, Some(SupportedMetric::SquaredL2)).unwrap()} } #[inline] pub fn mean_norm(&self) -> f32 { - self._tab.get::(SphericalQuantizer::VT_MEAN_NORM, Some(0.0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(SphericalQuantizer::VT_MEAN_NORM, Some(0.0)).unwrap()} } #[inline] pub fn pre_scale(&self) -> f32 { - self._tab.get::(SphericalQuantizer::VT_PRE_SCALE, Some(0.0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(SphericalQuantizer::VT_PRE_SCALE, Some(0.0)).unwrap()} } } @@ -108,11 +128,11 @@ impl<'a> Default for SphericalQuantizerArgs<'a> { } } -pub struct SphericalQuantizerBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct SphericalQuantizerBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> SphericalQuantizerBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> SphericalQuantizerBuilder<'a, 'b, A> { #[inline] pub fn add_centroid(&mut self, centroid: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(SphericalQuantizer::VT_CENTROID, centroid); @@ -134,7 +154,7 @@ impl<'a: 'b, 'b> SphericalQuantizerBuilder<'a, 'b> { self.fbb_.push_slot::(SphericalQuantizer::VT_PRE_SCALE, pre_scale, 0.0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> SphericalQuantizerBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> SphericalQuantizerBuilder<'a, 'b, A> { let start = _fbb.start_table(); SphericalQuantizerBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs b/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs index 18270ea62..d96ac6da6 100644 --- a/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs +++ b/diskann-quantization/src/flatbuffers/spherical/supported_metric_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -59,10 +64,8 @@ impl core::fmt::Debug for SupportedMetric { impl<'a> flatbuffers::Follow<'a> for SupportedMetric { type Inner = Self; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - let b = unsafe { - flatbuffers::read_scalar_at::(buf, loc) - }; + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = flatbuffers::read_scalar_at::(buf, loc); Self(b) } } @@ -70,21 +73,21 @@ impl<'a> flatbuffers::Follow<'a> for SupportedMetric { impl flatbuffers::Push for SupportedMetric { type Output = SupportedMetric; #[inline] - fn push(&self, dst: &mut [u8], _rest: &[u8]) { - unsafe { flatbuffers::emplace_scalar::(dst, self.0); } + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + flatbuffers::emplace_scalar::(dst, self.0); } } impl flatbuffers::EndianScalar for SupportedMetric { + type Scalar = i8; #[inline] - fn to_little_endian(self) -> Self { - let b = i8::to_le(self.0); - Self(b) + fn to_little_endian(self) -> i8 { + self.0.to_le() } #[inline] #[allow(clippy::wrong_self_convention)] - fn from_little_endian(self) -> Self { - let b = i8::from_le(self.0); + fn from_little_endian(v: i8) -> Self { + let b = i8::from_le(v); Self(b) } } diff --git a/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs b/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs index 1bc6eb50d..d4694e8e4 100644 --- a/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/double_hadamard_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct DoubleHadamard<'a> { impl<'a> flatbuffers::Follow<'a> for DoubleHadamard<'a> { type Inner = DoubleHadamard<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -30,12 +35,12 @@ impl<'a> DoubleHadamard<'a> { pub const VT_SUBSAMPLE: flatbuffers::VOffsetT = 8; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { DoubleHadamard { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args DoubleHadamardArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = DoubleHadamardBuilder::new(_fbb); @@ -47,16 +52,25 @@ impl<'a> DoubleHadamard<'a> { #[inline] - pub fn signs0(&self) -> &'a [bool] { - self._tab.get::>>(DoubleHadamard::VT_SIGNS0, None).map(|v| v.safe_slice()).unwrap() + pub fn signs0(&self) -> flatbuffers::Vector<'a, bool> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(DoubleHadamard::VT_SIGNS0, None).unwrap()} } #[inline] - pub fn signs1(&self) -> &'a [bool] { - self._tab.get::>>(DoubleHadamard::VT_SIGNS1, None).map(|v| v.safe_slice()).unwrap() + pub fn signs1(&self) -> flatbuffers::Vector<'a, bool> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(DoubleHadamard::VT_SIGNS1, None).unwrap()} } #[inline] pub fn subsample(&self) -> Option> { - self._tab.get::>>(DoubleHadamard::VT_SUBSAMPLE, None) + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(DoubleHadamard::VT_SUBSAMPLE, None)} } } @@ -90,11 +104,11 @@ impl<'a> Default for DoubleHadamardArgs<'a> { } } -pub struct DoubleHadamardBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct DoubleHadamardBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> DoubleHadamardBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> DoubleHadamardBuilder<'a, 'b, A> { #[inline] pub fn add_signs0(&mut self, signs0: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(DoubleHadamard::VT_SIGNS0, signs0); @@ -108,7 +122,7 @@ impl<'a: 'b, 'b> DoubleHadamardBuilder<'a, 'b> { self.fbb_.push_slot_always::>(DoubleHadamard::VT_SUBSAMPLE, subsample); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> DoubleHadamardBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> DoubleHadamardBuilder<'a, 'b, A> { let start = _fbb.start_table(); DoubleHadamardBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs b/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs index 162eb35c7..3c4f7788a 100644 --- a/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/null_transform_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct NullTransform<'a> { impl<'a> flatbuffers::Follow<'a> for NullTransform<'a> { type Inner = NullTransform<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -28,12 +33,12 @@ impl<'a> NullTransform<'a> { pub const VT_DIM: flatbuffers::VOffsetT = 4; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { NullTransform { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args NullTransformArgs ) -> flatbuffers::WIPOffset> { let mut builder = NullTransformBuilder::new(_fbb); @@ -44,7 +49,10 @@ impl<'a> NullTransform<'a> { #[inline] pub fn dim(&self) -> u32 { - self._tab.get::(NullTransform::VT_DIM, Some(0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(NullTransform::VT_DIM, Some(0)).unwrap()} } } @@ -72,17 +80,17 @@ impl<'a> Default for NullTransformArgs { } } -pub struct NullTransformBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct NullTransformBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> NullTransformBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> NullTransformBuilder<'a, 'b, A> { #[inline] pub fn add_dim(&mut self, dim: u32) { self.fbb_.push_slot::(NullTransform::VT_DIM, dim, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> NullTransformBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> NullTransformBuilder<'a, 'b, A> { let start = _fbb.start_table(); NullTransformBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs b/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs index 274d39c9a..26931d836 100644 --- a/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/padding_hadamard_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct PaddingHadamard<'a> { impl<'a> flatbuffers::Follow<'a> for PaddingHadamard<'a> { type Inner = PaddingHadamard<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -30,12 +35,12 @@ impl<'a> PaddingHadamard<'a> { pub const VT_SUBSAMPLE: flatbuffers::VOffsetT = 8; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { PaddingHadamard { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args PaddingHadamardArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = PaddingHadamardBuilder::new(_fbb); @@ -47,16 +52,25 @@ impl<'a> PaddingHadamard<'a> { #[inline] - pub fn signs(&self) -> &'a [bool] { - self._tab.get::>>(PaddingHadamard::VT_SIGNS, None).map(|v| v.safe_slice()).unwrap() + pub fn signs(&self) -> flatbuffers::Vector<'a, bool> { + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(PaddingHadamard::VT_SIGNS, None).unwrap()} } #[inline] pub fn padded_dim(&self) -> u32 { - self._tab.get::(PaddingHadamard::VT_PADDED_DIM, Some(0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(PaddingHadamard::VT_PADDED_DIM, Some(0)).unwrap()} } #[inline] pub fn subsample(&self) -> Option> { - self._tab.get::>>(PaddingHadamard::VT_SUBSAMPLE, None) + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(PaddingHadamard::VT_SUBSAMPLE, None)} } } @@ -90,11 +104,11 @@ impl<'a> Default for PaddingHadamardArgs<'a> { } } -pub struct PaddingHadamardBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct PaddingHadamardBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> PaddingHadamardBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> PaddingHadamardBuilder<'a, 'b, A> { #[inline] pub fn add_signs(&mut self, signs: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(PaddingHadamard::VT_SIGNS, signs); @@ -108,7 +122,7 @@ impl<'a: 'b, 'b> PaddingHadamardBuilder<'a, 'b> { self.fbb_.push_slot_always::>(PaddingHadamard::VT_SUBSAMPLE, subsample); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> PaddingHadamardBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> PaddingHadamardBuilder<'a, 'b, A> { let start = _fbb.start_table(); PaddingHadamardBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs b/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs index 2f0196846..64e518e1e 100644 --- a/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/random_rotation_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct RandomRotation<'a> { impl<'a> flatbuffers::Follow<'a> for RandomRotation<'a> { type Inner = RandomRotation<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -30,12 +35,12 @@ impl<'a> RandomRotation<'a> { pub const VT_NCOLS: flatbuffers::VOffsetT = 8; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { RandomRotation { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args RandomRotationArgs<'args> ) -> flatbuffers::WIPOffset> { let mut builder = RandomRotationBuilder::new(_fbb); @@ -48,15 +53,24 @@ impl<'a> RandomRotation<'a> { #[inline] pub fn data(&self) -> flatbuffers::Vector<'a, f32> { - self._tab.get::>>(RandomRotation::VT_DATA, None).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(RandomRotation::VT_DATA, None).unwrap()} } #[inline] pub fn nrows(&self) -> u32 { - self._tab.get::(RandomRotation::VT_NROWS, Some(0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(RandomRotation::VT_NROWS, Some(0)).unwrap()} } #[inline] pub fn ncols(&self) -> u32 { - self._tab.get::(RandomRotation::VT_NCOLS, Some(0)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(RandomRotation::VT_NCOLS, Some(0)).unwrap()} } } @@ -90,11 +104,11 @@ impl<'a> Default for RandomRotationArgs<'a> { } } -pub struct RandomRotationBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct RandomRotationBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> RandomRotationBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> RandomRotationBuilder<'a, 'b, A> { #[inline] pub fn add_data(&mut self, data: flatbuffers::WIPOffset>) { self.fbb_.push_slot_always::>(RandomRotation::VT_DATA, data); @@ -108,7 +122,7 @@ impl<'a: 'b, 'b> RandomRotationBuilder<'a, 'b> { self.fbb_.push_slot::(RandomRotation::VT_NCOLS, ncols, 0); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> RandomRotationBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> RandomRotationBuilder<'a, 'b, A> { let start = _fbb.start_table(); RandomRotationBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs b/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs index f20b493ce..7cc3b3afa 100644 --- a/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/transform_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -19,8 +24,8 @@ pub struct Transform<'a> { impl<'a> flatbuffers::Follow<'a> for Transform<'a> { type Inner = Transform<'a>; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table { buf, loc } } + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { _tab: flatbuffers::Table::new(buf, loc) } } } @@ -29,12 +34,12 @@ impl<'a> Transform<'a> { pub const VT_TRANSFORM: flatbuffers::VOffsetT = 6; #[inline] - pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { Transform { _tab: table } } #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, args: &'args TransformArgs ) -> flatbuffers::WIPOffset> { let mut builder = TransformBuilder::new(_fbb); @@ -46,18 +51,27 @@ impl<'a> Transform<'a> { #[inline] pub fn transform_type(&self) -> TransformKind { - self._tab.get::(Transform::VT_TRANSFORM_TYPE, Some(TransformKind::NONE)).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::(Transform::VT_TRANSFORM_TYPE, Some(TransformKind::NONE)).unwrap()} } #[inline] pub fn transform(&self) -> flatbuffers::Table<'a> { - self._tab.get::>>(Transform::VT_TRANSFORM, None).unwrap() + // Safety: + // Created from valid Table for this object + // which contains a valid value in this slot + unsafe { self._tab.get::>>(Transform::VT_TRANSFORM, None).unwrap()} } #[inline] #[allow(non_snake_case)] pub fn transform_as_random_rotation(&self) -> Option> { if self.transform_type() == TransformKind::RandomRotation { let u = self.transform(); - Some(RandomRotation::init_from_table(u)) + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { RandomRotation::init_from_table(u) }) } else { None } @@ -68,7 +82,10 @@ impl<'a> Transform<'a> { pub fn transform_as_padding_hadamard(&self) -> Option> { if self.transform_type() == TransformKind::PaddingHadamard { let u = self.transform(); - Some(PaddingHadamard::init_from_table(u)) + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { PaddingHadamard::init_from_table(u) }) } else { None } @@ -79,7 +96,10 @@ impl<'a> Transform<'a> { pub fn transform_as_double_hadamard(&self) -> Option> { if self.transform_type() == TransformKind::DoubleHadamard { let u = self.transform(); - Some(DoubleHadamard::init_from_table(u)) + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { DoubleHadamard::init_from_table(u) }) } else { None } @@ -90,7 +110,10 @@ impl<'a> Transform<'a> { pub fn transform_as_null_transform(&self) -> Option> { if self.transform_type() == TransformKind::NullTransform { let u = self.transform(); - Some(NullTransform::init_from_table(u)) + // Safety: + // Created from a valid Table for this object + // Which contains a valid union in this slot + Some(unsafe { NullTransform::init_from_table(u) }) } else { None } @@ -132,11 +155,11 @@ impl<'a> Default for TransformArgs { } } -pub struct TransformBuilder<'a: 'b, 'b> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, +pub struct TransformBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, start_: flatbuffers::WIPOffset, } -impl<'a: 'b, 'b> TransformBuilder<'a, 'b> { +impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> TransformBuilder<'a, 'b, A> { #[inline] pub fn add_transform_type(&mut self, transform_type: TransformKind) { self.fbb_.push_slot::(Transform::VT_TRANSFORM_TYPE, transform_type, TransformKind::NONE); @@ -146,7 +169,7 @@ impl<'a: 'b, 'b> TransformBuilder<'a, 'b> { self.fbb_.push_slot_always::>(Transform::VT_TRANSFORM, transform); } #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TransformBuilder<'a, 'b> { + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> TransformBuilder<'a, 'b, A> { let start = _fbb.start_table(); TransformBuilder { fbb_: _fbb, diff --git a/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs b/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs index e2815c9e9..fbfb9918f 100644 --- a/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs +++ b/diskann-quantization/src/flatbuffers/transforms/transform_kind_generated.rs @@ -1,3 +1,8 @@ +/* + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT license. + */ + // automatically generated by the FlatBuffers compiler, do not modify // @generated extern crate alloc; @@ -67,10 +72,8 @@ impl core::fmt::Debug for TransformKind { impl<'a> flatbuffers::Follow<'a> for TransformKind { type Inner = Self; #[inline] - fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - let b = unsafe { - flatbuffers::read_scalar_at::(buf, loc) - }; + unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + let b = flatbuffers::read_scalar_at::(buf, loc); Self(b) } } @@ -78,21 +81,21 @@ impl<'a> flatbuffers::Follow<'a> for TransformKind { impl flatbuffers::Push for TransformKind { type Output = TransformKind; #[inline] - fn push(&self, dst: &mut [u8], _rest: &[u8]) { - unsafe { flatbuffers::emplace_scalar::(dst, self.0); } + unsafe fn push(&self, dst: &mut [u8], _written_len: usize) { + flatbuffers::emplace_scalar::(dst, self.0); } } impl flatbuffers::EndianScalar for TransformKind { + type Scalar = u8; #[inline] - fn to_little_endian(self) -> Self { - let b = u8::to_le(self.0); - Self(b) + fn to_little_endian(self) -> u8 { + self.0.to_le() } #[inline] #[allow(clippy::wrong_self_convention)] - fn from_little_endian(self) -> Self { - let b = u8::from_le(self.0); + fn from_little_endian(v: u8) -> Self { + let b = u8::from_le(v); Self(b) } } From 9dcca30bf7294488915ee5c81ce233bce56a6af3 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 14:43:45 +0000 Subject: [PATCH 19/34] fmt --- .../src/utils/compute_bitmap.rs | 61 +++++++++---------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 3394d353c..7d5fbcfde 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -346,7 +346,10 @@ pub fn compute_query_bitmaps( .collect(); let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; - let base_doc_ids: Vec = base_labels.iter().map(|base_label| base_label.doc_id).collect(); + let base_doc_ids: Vec = base_labels + .iter() + .map(|base_label| base_label.doc_id) + .collect(); // compute the global set of labels ahead of time so that we can compute // each accelerator in parallel @@ -700,7 +703,8 @@ mod tests { field: "age".to_string(), op: CompareOp::Gte(20.0), }; - let bitmaps = compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); + let bitmaps = + compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); assert_eq!(bitmaps[0].contains(20), true); assert_eq!(bitmaps[0].contains(30), true); @@ -873,14 +877,13 @@ mod tests { } // Bool - let accel = - compute_query_accelerator( - "flag".to_string(), - AttributeValue::Bool(true), - &doc_ids, - &base, - ) - .expect("Should succeed for Bool"); + let accel = compute_query_accelerator( + "flag".to_string(), + AttributeValue::Bool(true), + &doc_ids, + &base, + ) + .expect("Should succeed for Bool"); match accel { QueryAccelerator::InvertedIndex(map) => { assert!(map.contains_key(&AttributeValue::Bool(true))); @@ -890,14 +893,13 @@ mod tests { } // Integer - let accel = - compute_query_accelerator( - "num".to_string(), - AttributeValue::Integer(42), - &doc_ids, - &base, - ) - .expect("Should succeed for Integer"); + let accel = compute_query_accelerator( + "num".to_string(), + AttributeValue::Integer(42), + &doc_ids, + &base, + ) + .expect("Should succeed for Integer"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(42.0))); @@ -907,14 +909,13 @@ mod tests { } // Real - let accel = - compute_query_accelerator( - "real".to_string(), - AttributeValue::Real(3.14), - &doc_ids, - &base, - ) - .expect("Should succeed for Real"); + let accel = compute_query_accelerator( + "real".to_string(), + AttributeValue::Real(3.14), + &doc_ids, + &base, + ) + .expect("Should succeed for Real"); match accel { QueryAccelerator::BTree(map) => { assert!(map.contains_key(&super::OrderedFloat(3.14))); @@ -924,12 +925,8 @@ mod tests { } // Empty - let err = compute_query_accelerator( - "none".to_string(), - AttributeValue::Empty, - &doc_ids, - &base, - ); + let err = + compute_query_accelerator("none".to_string(), AttributeValue::Empty, &doc_ids, &base); assert!(err.is_err()); } From 7553b99b8604d383dd1bebef94bc4f49c3c864ef Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 15:03:25 +0000 Subject: [PATCH 20/34] fix clippy, fmt --- .../examples/compute_specificities.rs | 8 +- .../src/utils/compute_bitmap.rs | 142 +++++++++--------- 2 files changed, 74 insertions(+), 76 deletions(-) diff --git a/diskann-label-filter/examples/compute_specificities.rs b/diskann-label-filter/examples/compute_specificities.rs index e22f00f52..86cbe440c 100644 --- a/diskann-label-filter/examples/compute_specificities.rs +++ b/diskann-label-filter/examples/compute_specificities.rs @@ -4,7 +4,6 @@ */ use diskann_label_filter::{compute_query_bitmaps, read_and_parse_queries, read_baselabels}; -use rayon::prelude::*; use std::env; use std::fs::File; use std::io::Write; @@ -61,11 +60,10 @@ fn main() { println!("Computing bitmap took {:.3?} seconds", elapsed); let mut specificities: Vec = bitmaps - .par_iter() + .iter() .map(|bitmap| { let count = bitmap.len(); - let specificity = count as f64 / total_base as f64; - specificity + count as f64 / total_base as f64 }) .collect(); @@ -90,7 +88,7 @@ fn main() { specificities.sort_by(|a, b| a.partial_cmp(b).unwrap()); let min = specificities[0]; let max = specificities[specificities.len() - 1]; - let median = if specificities.len() % 2 == 0 { + let median = if specificities.len().is_multiple_of(2) { let mid = specificities.len() / 2; (specificities[mid - 1] + specificities[mid]) / 2.0 } else { diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index 7d5fbcfde..d2c33d34c 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -469,9 +469,9 @@ mod tests { }; let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_color)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(0), false); - assert_eq!(bitmaps[0].contains(1), true); - assert_eq!(bitmaps[0].contains(2), false); + assert!(!bitmaps[0].contains(0)); + assert!(bitmaps[0].contains(1)); + assert!(!bitmaps[0].contains(2)); // Query: weight >= 20 let query_weight = ASTExpr::Compare { @@ -480,9 +480,9 @@ mod tests { }; let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_weight)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(1), false); - assert_eq!(bitmaps[0].contains(2), true); - assert_eq!(bitmaps[0].contains(0), true); + assert!(!bitmaps[0].contains(1)); + assert!(bitmaps[0].contains(2)); + assert!(bitmaps[0].contains(0)); } #[test] @@ -508,8 +508,8 @@ mod tests { }; let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_eq)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(0), true); - assert_eq!(bitmaps[0].contains(1), false); + assert!(bitmaps[0].contains(0)); + assert!(!bitmaps[0].contains(1)); // Query: NOT car.color == "red" (should match blue) let query_not = ASTExpr::Not(Box::new(ASTExpr::Compare { @@ -518,8 +518,8 @@ mod tests { })); let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_not)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(1), true); - assert_eq!(bitmaps[0].contains(0), false); + assert!(bitmaps[0].contains(1)); + assert!(!bitmaps[0].contains(0)); } #[test] @@ -546,9 +546,9 @@ mod tests { }; let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_lt)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(0), true); - assert_eq!(bitmaps[0].contains(1), false); - assert_eq!(bitmaps[0].contains(2), false); + assert!(bitmaps[0].contains(0)); + assert!(!bitmaps[0].contains(1)); + assert!(!bitmaps[0].contains(2)); // score > 2.0 let query_gt = ASTExpr::Compare { @@ -557,9 +557,9 @@ mod tests { }; let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_gt)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(2), true); - assert_eq!(bitmaps[0].contains(0), false); - assert_eq!(bitmaps[0].contains(1), false); + assert!(bitmaps[0].contains(2)); + assert!(!bitmaps[0].contains(0)); + assert!(!bitmaps[0].contains(1)); // score <= 2.0 let query_lte = ASTExpr::Compare { @@ -568,9 +568,9 @@ mod tests { }; let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_lte)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(0), true); - assert_eq!(bitmaps[0].contains(1), true); - assert_eq!(bitmaps[0].contains(2), false); + assert!(bitmaps[0].contains(0)); + assert!(bitmaps[0].contains(1)); + assert!(!bitmaps[0].contains(2)); // score >= 2.0 let query_gte = ASTExpr::Compare { @@ -579,9 +579,9 @@ mod tests { }; let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_gte)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(1), true); - assert_eq!(bitmaps[0].contains(2), true); - assert_eq!(bitmaps[0].contains(0), false); + assert!(bitmaps[0].contains(1)); + assert!(bitmaps[0].contains(2)); + assert!(!bitmaps[0].contains(0)); // score >= 2.0 AND score <= 3.5 (range: [2.0, 3.5]) let query_range = ASTExpr::And(vec![ @@ -597,9 +597,9 @@ mod tests { let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_range)]) .expect("should succeed"); // Should match doc 1 (2.0) and doc 2 (3.5) - assert_eq!(bitmaps[0].contains(1), true); - assert_eq!(bitmaps[0].contains(2), true); - assert_eq!(bitmaps[0].contains(0), false); + assert!(bitmaps[0].contains(1)); + assert!(bitmaps[0].contains(2)); + assert!(!bitmaps[0].contains(0)); } #[test] @@ -626,9 +626,9 @@ mod tests { }; let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_lt)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(0), true); - assert_eq!(bitmaps[0].contains(1), false); - assert_eq!(bitmaps[0].contains(2), false); + assert!(bitmaps[0].contains(0)); + assert!(!bitmaps[0].contains(1)); + assert!(!bitmaps[0].contains(2)); // age > 20 let query_gt = ASTExpr::Compare { @@ -637,9 +637,9 @@ mod tests { }; let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_gt)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(2), true); - assert_eq!(bitmaps[0].contains(0), false); - assert_eq!(bitmaps[0].contains(1), false); + assert!(bitmaps[0].contains(2)); + assert!(!bitmaps[0].contains(0)); + assert!(!bitmaps[0].contains(1)); // age <= 20 let query_lte = ASTExpr::Compare { @@ -648,9 +648,9 @@ mod tests { }; let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_lte)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(0), true); - assert_eq!(bitmaps[0].contains(1), true); - assert_eq!(bitmaps[0].contains(2), false); + assert!(bitmaps[0].contains(0)); + assert!(bitmaps[0].contains(1)); + assert!(!bitmaps[0].contains(2)); // age >= 20 let query_gte = ASTExpr::Compare { @@ -659,9 +659,9 @@ mod tests { }; let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_gte)]) .expect("should succeed"); - assert_eq!(bitmaps[0].contains(1), true); - assert_eq!(bitmaps[0].contains(2), true); - assert_eq!(bitmaps[0].contains(0), false); + assert!(bitmaps[0].contains(1)); + assert!(bitmaps[0].contains(2)); + assert!(!bitmaps[0].contains(0)); // age >= 20 AND age <= 30 (range: [20, 30]) let query_range = ASTExpr::And(vec![ @@ -677,9 +677,9 @@ mod tests { let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_range)]) .expect("should succeed"); // Should match doc 1 (20) and doc 2 (30) - assert_eq!(bitmaps[0].contains(1), true); - assert_eq!(bitmaps[0].contains(2), true); - assert_eq!(bitmaps[0].contains(0), false); + assert!(bitmaps[0].contains(1)); + assert!(bitmaps[0].contains(2)); + assert!(!bitmaps[0].contains(0)); } #[test] @@ -706,12 +706,12 @@ mod tests { let bitmaps = compute_query_bitmaps(base_labels, vec![(0, query_gte)]).expect("should succeed"); - assert_eq!(bitmaps[0].contains(20), true); - assert_eq!(bitmaps[0].contains(30), true); - assert_eq!(bitmaps[0].contains(10), false); - assert_eq!(bitmaps[0].contains(0), false); - assert_eq!(bitmaps[0].contains(1), false); - assert_eq!(bitmaps[0].contains(2), false); + assert!(bitmaps[0].contains(20)); + assert!(bitmaps[0].contains(30)); + assert!(!bitmaps[0].contains(10)); + assert!(!bitmaps[0].contains(0)); + assert!(!bitmaps[0].contains(1)); + assert!(!bitmaps[0].contains(2)); } #[test] @@ -738,8 +738,8 @@ mod tests { let queries = vec![(0, query)]; let bitmaps = compute_query_bitmaps(base_labels.clone(), queries).expect("should succeed"); // Only doc 0 should match - assert_eq!(bitmaps[0].contains(0), true); - assert_eq!(bitmaps[0].contains(1), false); + assert!(bitmaps[0].contains(0)); + assert!(!bitmaps[0].contains(1)); } #[test] @@ -796,21 +796,21 @@ mod tests { let bitmaps = compute_query_bitmaps(base_labels.clone(), queries).expect("should succeed"); // color == "red" => doc 0, 2 - assert_eq!(bitmaps[0].contains(0), true); - assert_eq!(bitmaps[0].contains(2), true); - assert_eq!(bitmaps[0].contains(1), false); + assert!(bitmaps[0].contains(0)); + assert!(bitmaps[0].contains(2)); + assert!(!bitmaps[0].contains(1)); // size == 20 => doc 1, 2 - assert_eq!(bitmaps[1].contains(1), true); - assert_eq!(bitmaps[1].contains(2), true); - assert_eq!(bitmaps[1].contains(0), false); + assert!(bitmaps[1].contains(1)); + assert!(bitmaps[1].contains(2)); + assert!(!bitmaps[1].contains(0)); // color == "red" AND size == 20 => doc 2 - assert_eq!(bitmaps[2].contains(2), true); - assert_eq!(bitmaps[2].contains(0), false); - assert_eq!(bitmaps[2].contains(1), false); + assert!(bitmaps[2].contains(2)); + assert!(!bitmaps[2].contains(0)); + assert!(!bitmaps[2].contains(1)); // color == "red" OR size == 10 => doc 0, 2 - assert_eq!(bitmaps[3].contains(0), true); - assert_eq!(bitmaps[3].contains(2), true); - assert_eq!(bitmaps[3].contains(1), false); + assert!(bitmaps[3].contains(0)); + assert!(bitmaps[3].contains(2)); + assert!(!bitmaps[3].contains(1)); // Query: NOT color == "red" let not_query = ASTExpr::Not(Box::new(ASTExpr::Compare { @@ -825,9 +825,9 @@ mod tests { ); // The result should be a bitmap with doc 1 (not red) let bitmaps = result.unwrap(); - assert_eq!(bitmaps[0].contains(1), true); - assert_eq!(bitmaps[0].contains(0), false); - assert_eq!(bitmaps[0].contains(2), false); + assert!(bitmaps[0].contains(1)); + assert!(!bitmaps[0].contains(0)); + assert!(!bitmaps[0].contains(2)); } #[test] @@ -836,7 +836,7 @@ mod tests { let mut doc1 = HashMap::new(); doc1.insert("foo".to_string(), AttributeValue::String("bar".to_string())); doc1.insert("num".to_string(), AttributeValue::Integer(42)); - doc1.insert("real".to_string(), AttributeValue::Real(3.14)); + doc1.insert("real".to_string(), AttributeValue::Real(3.13)); doc1.insert("flag".to_string(), AttributeValue::Bool(true)); let mut doc2 = HashMap::new(); doc2.insert("foo".to_string(), AttributeValue::String("baz".to_string())); @@ -911,14 +911,14 @@ mod tests { // Real let accel = compute_query_accelerator( "real".to_string(), - AttributeValue::Real(3.14), + AttributeValue::Real(3.13), &doc_ids, &base, ) .expect("Should succeed for Real"); match accel { QueryAccelerator::BTree(map) => { - assert!(map.contains_key(&super::OrderedFloat(3.14))); + assert!(map.contains_key(&super::OrderedFloat(3.13))); assert!(map.contains_key(&super::OrderedFloat(2.71))); } _ => panic!("Expected BTree for Real"), @@ -937,14 +937,14 @@ mod tests { field: "foo".to_string(), op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), }; - assert_eq!(check_for_disallowed_operators(&expr), false); + assert!(!check_for_disallowed_operators(&expr)); // NOT at root let expr = ASTExpr::Not(Box::new(ASTExpr::Compare { field: "foo".to_string(), op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), })); - assert_eq!(check_for_disallowed_operators(&expr), true); + assert!(check_for_disallowed_operators(&expr)); // AND with NOT inside let expr = ASTExpr::And(vec![ @@ -957,7 +957,7 @@ mod tests { op: CompareOp::Eq(serde_json::Value::String("qux".to_string())), })), ]); - assert_eq!(check_for_disallowed_operators(&expr), true); + assert!(check_for_disallowed_operators(&expr)); // OR with only Compare let expr = ASTExpr::Or(vec![ @@ -970,7 +970,7 @@ mod tests { op: CompareOp::Eq(serde_json::Value::String("qux".to_string())), }, ]); - assert_eq!(check_for_disallowed_operators(&expr), false); + assert!(!check_for_disallowed_operators(&expr)); // Nested AND/OR with NOT deep inside let expr = ASTExpr::And(vec![ @@ -989,6 +989,6 @@ mod tests { op: CompareOp::Eq(serde_json::Value::String("f".to_string())), }, ]); - assert_eq!(check_for_disallowed_operators(&expr), true); + assert!(check_for_disallowed_operators(&expr)); } } From 9676dac9fe15c023b88691bd35aa1b8b582a8aa4 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 16:44:31 +0000 Subject: [PATCH 21/34] update groundtruth calculation to use fast bitmap computation --- diskann-tools/src/utils/ground_truth.rs | 27 +++++++++---------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/diskann-tools/src/utils/ground_truth.rs b/diskann-tools/src/utils/ground_truth.rs index d6b93a502..ceb07b969 100644 --- a/diskann-tools/src/utils/ground_truth.rs +++ b/diskann-tools/src/utils/ground_truth.rs @@ -4,7 +4,7 @@ */ use bit_set::BitSet; -use diskann_label_filter::{eval_query_expr, read_and_parse_queries, read_baselabels}; +use diskann_label_filter::{compute_query_bitmaps, read_and_parse_queries, read_baselabels}; use std::{io::Write, mem::size_of, str::FromStr}; @@ -35,25 +35,18 @@ pub fn read_labels_and_compute_bitmap( // Read base labels let base_labels = read_baselabels(base_label_filename)?; - // Parse queries and evaluate against labels + // Read and parse queries let parsed_queries = read_and_parse_queries(query_label_filename)?; - // using the global threadpool is fine here - #[allow(clippy::disallowed_methods)] - let query_bitmaps: Vec = parsed_queries - .par_iter() - .map(|(_query_id, query_expr)| { - let mut bitmap = BitSet::new(); - for base_label in base_labels.iter() { - if eval_query_expr(query_expr, &base_label.label) { - bitmap.insert(base_label.doc_id); - } - } - bitmap - }) - .collect(); + // Compute the query bitmaps + let query_bitmaps = compute_query_bitmaps(base_labels, parsed_queries); - Ok(query_bitmaps) + match query_bitmaps { + Ok(bitmaps) => Ok(bitmaps), + Err(e) => Err(CMDToolError { + details: format!("Error computing query bitmaps: {}", e), + }), + } } #[allow(clippy::too_many_arguments)] From 17d069e27b1f2426f66039156beee9f0c93f9de5 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 18:36:12 +0000 Subject: [PATCH 22/34] reduce repeated code, reduce instances of pub --- Cargo.lock | 1 + .../src/utils/compute_bitmap.rs | 77 +++++++------------ diskann-tools/Cargo.toml | 1 + 3 files changed, 30 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04030e6b7..4c1306424 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -937,6 +937,7 @@ dependencies = [ "rand 0.9.4", "rand_distr", "rayon", + "roaring", "rstest", "serde", "tracing", diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-label-filter/src/utils/compute_bitmap.rs index d2c33d34c..ada25da10 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-label-filter/src/utils/compute_bitmap.rs @@ -15,7 +15,7 @@ use std::collections::HashMap; use std::mem::discriminant; use std::ops::Bound::{Excluded, Included, Unbounded}; -pub struct NotNonNan; +struct NotNonNan; impl std::fmt::Display for NotNonNan { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -24,7 +24,7 @@ impl std::fmt::Display for NotNonNan { } #[derive(Debug, Copy, Clone, PartialEq)] -pub struct OrderedFloat(f64); +struct OrderedFloat(f64); impl OrderedFloat { pub fn new(v: f64) -> Result { @@ -49,12 +49,13 @@ impl Ord for OrderedFloat { self.0.partial_cmp(&other.0).unwrap_or(Ordering::Equal) } } -pub enum QueryAccelerator { + +enum QueryAccelerator { InvertedIndex(HashMap), BTree(BTreeMap>), } -pub fn check_for_disallowed_operators(query_expr: &ASTExpr) -> bool { +fn check_for_disallowed_operators(query_expr: &ASTExpr) -> bool { match query_expr { ASTExpr::Not(_) => true, ASTExpr::And(subs) => subs.iter().any(check_for_disallowed_operators), @@ -63,7 +64,13 @@ pub fn check_for_disallowed_operators(query_expr: &ASTExpr) -> bool { } } -pub fn eval_query_using_accelerators( +fn insert_into_bitset(ids: Vec) -> BitSet { + let mut bitset = BitSet::new(); + bitset.extend(ids); + bitset +} + +fn eval_query_using_accelerators( query_expr: &ASTExpr, query_accelerators: &HashMap, ) -> Result { @@ -147,53 +154,25 @@ pub fn eval_query_using_accelerators( } Ok(bitset) } - CompareOp::Lt(value) => { - let fval = *value; - let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + CompareOp::Lt(num) => { + let fval = OrderedFloat::new(*num).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; let iter = btree.range((Unbounded, Excluded(fval))); - let mut all_ids = Vec::new(); - for (_, ids) in iter { - all_ids.extend(ids.iter().cloned()); - } - let mut bitset = BitSet::new(); - bitset.extend(all_ids); - Ok(bitset) + Ok(insert_into_bitset(iter.flat_map(|(_, ids)| ids.iter().cloned()).collect::>())) } - CompareOp::Lte(value) => { - let fval = *value; - let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + CompareOp::Lte(num) => { + let fval = OrderedFloat::new(*num).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; let iter = btree.range((Unbounded, Included(fval))); - let mut all_ids = Vec::new(); - for (_, ids) in iter { - all_ids.extend(ids.iter().cloned()); - } - let mut bitset = BitSet::new(); - bitset.extend(all_ids); - Ok(bitset) + Ok(insert_into_bitset(iter.flat_map(|(_, ids)| ids.iter().cloned()).collect::>())) } - CompareOp::Gt(value) => { - let fval = *value; - let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + CompareOp::Gt(num) => { + let fval = OrderedFloat::new(*num).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; let iter = btree.range((Excluded(fval), Unbounded)); - let mut all_ids = Vec::new(); - for (_, ids) in iter { - all_ids.extend(ids.iter().cloned()); - } - let mut bitset = BitSet::new(); - bitset.extend(all_ids); - Ok(bitset) + Ok(insert_into_bitset(iter.flat_map(|(_, ids)| ids.iter().cloned()).collect::>())) } - CompareOp::Gte(value) => { - let fval = *value; - let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + CompareOp::Gte(num) => { + let fval = OrderedFloat::new(*num).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; let iter = btree.range((Included(fval), Unbounded)); - let mut all_ids = Vec::new(); - for (_, ids) in iter { - all_ids.extend(ids.iter().cloned()); - } - let mut bitset = BitSet::new(); - bitset.extend(all_ids); - Ok(bitset) + Ok(insert_into_bitset(iter.flat_map(|(_, ids)| ids.iter().cloned()).collect::>())) } } } @@ -206,7 +185,7 @@ pub fn eval_query_using_accelerators( } } -pub fn compute_inverted_index_accelerator( +fn compute_inverted_index_accelerator( key: &str, doc_ids: &[usize], labels: &[HashMap], @@ -223,7 +202,7 @@ pub fn compute_inverted_index_accelerator( Ok(inverted_index) } -pub fn compute_btree_accelerator( +fn compute_btree_accelerator( key: &str, labels: &[HashMap], doc_ids: &[usize], @@ -254,7 +233,7 @@ pub fn compute_btree_accelerator( // Compute a global label set across all documents with a representative element // Make sure that each global label only maps to the same type of AttributeValue, and throw an error otherwise -pub fn compute_global_label_set( +fn compute_global_label_set( flattened_base_labels: &Vec>, ) -> Result, anyhow::Error> { let mut global_label_set = HashMap::new(); @@ -271,7 +250,7 @@ pub fn compute_global_label_set( Ok(global_label_set) } -pub fn compute_query_accelerator( +fn compute_query_accelerator( key: String, value: AttributeValue, doc_ids: &[usize], diff --git a/diskann-tools/Cargo.toml b/diskann-tools/Cargo.toml index ae987dca9..9d6bea0fb 100644 --- a/diskann-tools/Cargo.toml +++ b/diskann-tools/Cargo.toml @@ -34,6 +34,7 @@ bit-set.workspace = true anyhow.workspace = true itertools.workspace = true diskann-label-filter.workspace = true +roaring.workspace = true [dev-dependencies] rstest.workspace = true From 287d438bb207261e68df7d0bb530a9a099190475 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 18:36:39 +0000 Subject: [PATCH 23/34] remove roaring --- diskann-tools/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/diskann-tools/Cargo.toml b/diskann-tools/Cargo.toml index 9d6bea0fb..ae987dca9 100644 --- a/diskann-tools/Cargo.toml +++ b/diskann-tools/Cargo.toml @@ -34,7 +34,6 @@ bit-set.workspace = true anyhow.workspace = true itertools.workspace = true diskann-label-filter.workspace = true -roaring.workspace = true [dev-dependencies] rstest.workspace = true From 43aefb32a0896b55eed097afd53c9c6a595b4bc5 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 18:37:36 +0000 Subject: [PATCH 24/34] remove crate --- Cargo.lock | 822 +++++++++++++++++++++++++---------------------------- 1 file changed, 382 insertions(+), 440 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c1306424..e0ec19c53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,9 +31,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -46,15 +46,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -81,9 +81,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "approx" @@ -96,18 +96,18 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d03449bb8ca2cc2ef70869af31463d1ae5ccc8fa3e334b307203fbf815207e" +checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" dependencies = [ "rustversion", ] [[package]] name = "async-compression" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f9ee0f6e02ffd7ad5816e9464499fba7b3effd01123b515c41d1697c43dad1" +checksum = "e79b3f8a79cccc2898f31920fc69f304859b3bd567490f75ebf51ae1c792a9ac" dependencies = [ "compression-codecs", "compression-core", @@ -134,7 +134,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -145,9 +145,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "azure_core" @@ -177,7 +177,7 @@ checksum = "4a2df13e12ead1bb9f3b45cebec7e2b36eb6c2e88305745adc34828c1e457f92" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", "tracing", "typespec_client_core", ] @@ -207,14 +207,14 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bf-tree" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07155f3f780c77c9ae58fcd1668140a6ac46a9b1e85bddf81489061291b3e80f" +checksum = "11a6082b72699bf88f431c4ebab0e9e2ab6c31cf0576a3b115653fb8a0a0018e" dependencies = [ "cfg-if", "io-uring", "libc", - "rand 0.8.5", + "rand 0.8.6", "rand 0.9.4", "serde", "serde_json", @@ -255,21 +255,21 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytemuck" -version = "1.24.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" dependencies = [ "bytemuck_derive", ] @@ -282,7 +282,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -305,9 +305,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.56" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "shlex", @@ -348,9 +348,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.54" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -358,9 +358,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.54" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -370,27 +370,27 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] name = "clap_lex" -version = "0.7.6" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "combine" @@ -408,9 +408,9 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb7b51a7d9c967fc26773061ba86150f19c50c0d65c887cb1fbe295fd16619b7" +checksum = "ce2548391e9c1929c21bf6aa2680af86fe4c1b33e6cea9ac1cfeec0bd11218cf" dependencies = [ "compression-core", "flate2", @@ -419,9 +419,9 @@ dependencies = [ [[package]] name = "compression-core" -version = "0.4.31" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" +checksum = "cc14f565cf027a105f7a44ccf9e5b424348421a1d8952a8fc9d499d313107789" [[package]] name = "concurrent-queue" @@ -434,13 +434,12 @@ dependencies = [ [[package]] name = "console" -version = "0.16.2" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4" +checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" dependencies = [ "encode_unicode", "libc", - "once_cell", "unicode-width", "windows-sys 0.61.2", ] @@ -616,7 +615,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -638,7 +637,7 @@ dependencies = [ "relative-path 2.0.1", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", ] @@ -676,7 +675,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", ] @@ -693,7 +692,7 @@ dependencies = [ "itertools 0.13.0", "serde_yaml", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", ] @@ -708,7 +707,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -725,7 +724,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -746,7 +745,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", ] @@ -781,7 +780,7 @@ dependencies = [ "rstest", "serde", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "vfs", @@ -800,7 +799,7 @@ dependencies = [ "diskann-utils", "diskann-vector", "foldhash 0.2.0", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", ] @@ -825,7 +824,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", ] @@ -840,7 +839,7 @@ dependencies = [ "rand_distr", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -885,7 +884,7 @@ dependencies = [ "rstest", "serde", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "vfs", @@ -908,7 +907,7 @@ dependencies = [ "rayon", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "trybuild", ] @@ -937,7 +936,6 @@ dependencies = [ "rand 0.9.4", "rand_distr", "rayon", - "roaring", "rstest", "serde", "tracing", @@ -958,7 +956,7 @@ dependencies = [ "rand_distr", "rayon", "rstest", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -994,7 +992,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -1021,9 +1019,9 @@ checksum = "e1d926b4d407d372f141f93bb444696142c29d32962ccbd3531117cf3aa0bfa9" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "encode_unicode" @@ -1040,7 +1038,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -1069,7 +1067,7 @@ checksum = "3bf679796c0322556351f287a51b49e48f7c4986e727b5dd78c972d30e2e16cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -1080,7 +1078,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -1150,7 +1148,7 @@ checksum = "2cc4b8cd876795d3b19ddfd59b03faa303c0b8adb9af6e188e81fc647c485bb9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -1173,20 +1171,18 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "filetime" -version = "0.2.26" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", - "libredox", - "windows-sys 0.60.2", ] [[package]] @@ -1201,7 +1197,7 @@ version = "25.12.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35f6839d7b3b98adde531effaf34f0c2badc6f4735d26fe74709d8e513a96ef3" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "rustc_version", ] @@ -1313,7 +1309,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -1330,9 +1326,9 @@ checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" [[package]] name = "futures-util" @@ -1470,9 +1466,9 @@ dependencies = [ [[package]] name = "generativity" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5881e4c3c2433fe4905bb19cfd2b5d49d4248274862b68c27c33d9ba4e13f9ec" +checksum = "d2c81fb5260e37854d09d5c87183309fd8c555b75289427884b25660bc87a85e" [[package]] name = "getrandom" @@ -1493,19 +1489,19 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", ] [[package]] name = "getrandom" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 6.0.0", "wasip2", "wasip3", ] @@ -1557,6 +1553,12 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + [[package]] name = "heck" version = "0.5.0" @@ -1610,9 +1612,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" dependencies = [ "atomic-waker", "bytes", @@ -1623,7 +1625,6 @@ dependencies = [ "httparse", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -1692,7 +1693,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -1706,12 +1707,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1719,9 +1721,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -1732,9 +1734,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1746,15 +1748,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -1766,15 +1768,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -1804,9 +1806,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1814,21 +1816,21 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "serde", "serde_core", ] [[package]] name = "indicatif" -version = "0.18.3" +version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9375e112e4b463ec1b1c6c011953545c65a30164fbab5b581df32b3abf0dcb88" +checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" dependencies = [ "console", "portable-atomic", @@ -1860,19 +1862,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.10" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" -dependencies = [ - "memchr", - "serde", -] +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "is-terminal" @@ -1909,18 +1901,29 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -1939,38 +1942,27 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.179" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libm" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" - -[[package]] -name = "libredox" -version = "0.1.12" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" -dependencies = [ - "bitflags 2.10.0", - "libc", - "redox_syscall 0.7.0", -] +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "lock_api" @@ -1998,9 +1990,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "miniz_oxide" @@ -2014,9 +2006,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "wasi", @@ -2141,9 +2133,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" @@ -2176,9 +2168,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -2198,7 +2190,7 @@ version = "0.10.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "cfg-if", "foreign-types", "libc", @@ -2214,7 +2206,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -2245,7 +2237,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", ] @@ -2262,7 +2254,7 @@ dependencies = [ "percent-encoding", "rand 0.9.4", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -2298,7 +2290,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link", ] @@ -2317,41 +2309,35 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project" -version = "1.1.10" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "plotters" @@ -2383,15 +2369,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -2418,7 +2404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -2435,11 +2421,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.23.10+spec-1.0.0", + "toml_edit 0.25.11+spec-1.1.0", ] [[package]] @@ -2461,27 +2447,27 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] name = "proc-macro2" -version = "1.0.104" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.9.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.10.0", + "bitflags 2.11.1", "num-traits", "rand 0.9.4", "rand_chacha 0.9.0", @@ -2509,10 +2495,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", - "itertools 0.13.0", + "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -2549,9 +2535,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.42" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -2562,11 +2548,17 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -2580,7 +2572,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -2600,7 +2592,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -2614,9 +2606,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ "getrandom 0.3.4", ] @@ -2637,7 +2629,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" dependencies = [ - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -2646,14 +2638,14 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", ] [[package]] name = "rayon" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ "either", "rayon-core", @@ -2707,23 +2699,14 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "redox_syscall" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" -dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", ] [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -2733,9 +2716,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -2744,9 +2727,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "relative-path" @@ -2804,9 +2787,9 @@ dependencies = [ [[package]] name = "roaring" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba9ce64a8f45d7fc86358410bb1a82e8c987504c0d4900e9141d69a9f26c885" +checksum = "1dedc5658c6ecb3bdb5ef5f3295bb9253f42dcf3fd1402c03f6b1f7659c3c4a9" dependencies = [ "bytemuck", "byteorder", @@ -2838,7 +2821,7 @@ dependencies = [ "regex", "relative-path 1.9.3", "rustc_version", - "syn 2.0.113", + "syn 2.0.117", "unicode-ident", ] @@ -2853,11 +2836,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys", @@ -2866,9 +2849,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ "zeroize", ] @@ -2893,15 +2876,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "saa" -version = "5.4.2" +version = "5.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77cb23a1da9bcf98289bea29df468b782ddf2993836d1ebd171c403210b86baa" +checksum = "68f5acb362a0e75c2a963532fa7fabf13dff81626dc494df16488d30befcbea0" [[package]] name = "same-file" @@ -2914,9 +2897,9 @@ dependencies = [ [[package]] name = "scc" -version = "3.4.10" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79d533af0a5c0d082eb3f957aaca91e920ad7064a5ebabee3584ed1d90a0bb24" +checksum = "5bcd12b6caff5213cc3c03123cde8c3db5e413008a63b0c0ba35e6275825ea92" dependencies = [ "saa", "sdd", @@ -2924,9 +2907,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -2939,17 +2922,20 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sdd" -version = "4.5.3" +version = "4.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63d45f3526312c9c90d717aac28d37010e623fbd7ca6f21503e69784e86f40" +checksum = "e5f0e40a01b94e35d1dacbcfbe5bfd3d31e37d9590b2e6d86a82b0e87bd4f551" +dependencies = [ + "saa", +] [[package]] name = "security-framework" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "core-foundation", "core-foundation-sys", "libc", @@ -2968,9 +2954,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "seq-macro" @@ -3005,14 +2991,14 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] name = "serde_json" -version = "1.0.148" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -3032,9 +3018,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.4" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ "serde_core", ] @@ -3097,15 +3083,15 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" @@ -3115,12 +3101,12 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3148,9 +3134,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.113" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -3174,7 +3160,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -3183,7 +3169,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01198a2debb237c62b6826ec7081082d951f46dbb64b0e8c7649a452230d1dfc" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "byteorder", "enum-as-inner", "libc", @@ -3199,12 +3185,12 @@ checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" [[package]] name = "tempfile" -version = "3.24.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -3230,11 +3216,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -3245,18 +3231,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -3302,9 +3288,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -3322,9 +3308,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.49.0" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -3339,13 +3325,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -3385,17 +3371,32 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.10+spec-1.1.0" +version = "0.9.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.0.4", + "serde_spanned 1.1.1", "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", - "winnow", + "winnow 0.7.15", +] + +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.3", ] [[package]] @@ -3416,6 +3417,15 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.22.27" @@ -3427,28 +3437,28 @@ dependencies = [ "serde_spanned 0.6.9", "toml_datetime 0.6.11", "toml_write", - "winnow", + "winnow 0.7.15", ] [[package]] name = "toml_edit" -version = "0.23.10+spec-1.0.0" +version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ "indexmap", - "toml_datetime 0.7.5+spec-1.1.0", + "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow", + "winnow 1.0.3", ] [[package]] name = "toml_parser" -version = "1.0.6+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow", + "winnow 1.0.3", ] [[package]] @@ -3459,9 +3469,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "toml_writer" -version = "1.0.6+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "tower" @@ -3480,25 +3490,25 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "async-compression", - "bitflags 2.10.0", + "bitflags 2.11.1", "bytes", "futures-core", "futures-util", "http", "http-body", "http-body-util", - "iri-string", "pin-project-lite", "tokio", "tokio-util", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -3532,7 +3542,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -3558,9 +3568,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", @@ -3582,9 +3592,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.114" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17e807bff86d2a06b52bca4276746584a78375055b6e45843925ce2802b335" +checksum = "47c635f0191bd3a2941013e5062667100969f8c4e9cd787c14f977265d73616e" dependencies = [ "glob", "serde", @@ -3592,7 +3602,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 0.9.10+spec-1.1.0", + "toml 1.1.2+spec-1.1.0", ] [[package]] @@ -3643,7 +3653,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] @@ -3654,9 +3664,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-width" @@ -3708,11 +3718,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.21.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ - "getrandom 0.4.1", + "getrandom 0.4.2", "js-sys", "wasm-bindgen", ] @@ -3743,7 +3753,7 @@ dependencies = [ "redis", "serde", "tokio", - "toml 0.9.10+spec-1.1.0", + "toml 0.9.12+spec-1.1.0", ] [[package]] @@ -3797,11 +3807,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ - "wit-bindgen 0.46.0", + "wit-bindgen 0.57.1", ] [[package]] @@ -3815,9 +3825,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -3828,22 +3838,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ - "cfg-if", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3851,22 +3858,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] @@ -3912,7 +3919,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "hashbrown 0.15.5", "indexmap", "semver", @@ -3920,9 +3927,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" dependencies = [ "js-sys", "wasm-bindgen", @@ -3959,16 +3966,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -3986,31 +3984,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -4019,110 +4000,65 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" dependencies = [ "memchr", ] [[package]] -name = "wit-bindgen" -version = "0.46.0" +name = "winnow" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] [[package]] name = "wit-bindgen" @@ -4133,6 +4069,12 @@ dependencies = [ "wit-bindgen-rust-macro", ] +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + [[package]] name = "wit-bindgen-core" version = "0.51.0" @@ -4154,7 +4096,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.113", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -4170,7 +4112,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -4182,7 +4124,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.10.0", + "bitflags 2.11.1", "indexmap", "log", "serde", @@ -4214,15 +4156,15 @@ dependencies = [ [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -4231,54 +4173,54 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.31" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.31" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", "synstructure", ] @@ -4290,9 +4232,9 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -4301,9 +4243,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -4312,17 +4254,17 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn 2.0.113", + "syn 2.0.117", ] [[package]] name = "zmij" -version = "1.0.11" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb2c125bd7365735bebeb420ccb880265ed2d2bddcbcd49f597fdfe6bd5e577" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" From 50f274b4f939aa20946525bba1bd70c55de3df56 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 18:39:02 +0000 Subject: [PATCH 25/34] Revert "remove crate" This reverts commit 43aefb32a0896b55eed097afd53c9c6a595b4bc5. --- Cargo.lock | 822 ++++++++++++++++++++++++++++------------------------- 1 file changed, 440 insertions(+), 382 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0ec19c53..4c1306424 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,9 +31,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "1.0.0" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -46,15 +46,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.14" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "1.0.0" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] @@ -81,9 +81,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "approx" @@ -96,18 +96,18 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.9.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" +checksum = "51d03449bb8ca2cc2ef70869af31463d1ae5ccc8fa3e334b307203fbf815207e" dependencies = [ "rustversion", ] [[package]] name = "async-compression" -version = "0.4.42" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79b3f8a79cccc2898f31920fc69f304859b3bd567490f75ebf51ae1c792a9ac" +checksum = "d0f9ee0f6e02ffd7ad5816e9464499fba7b3effd01123b515c41d1697c43dad1" dependencies = [ "compression-codecs", "compression-core", @@ -134,7 +134,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -145,9 +145,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "azure_core" @@ -177,7 +177,7 @@ checksum = "4a2df13e12ead1bb9f3b45cebec7e2b36eb6c2e88305745adc34828c1e457f92" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", "tracing", "typespec_client_core", ] @@ -207,14 +207,14 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bf-tree" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a6082b72699bf88f431c4ebab0e9e2ab6c31cf0576a3b115653fb8a0a0018e" +checksum = "07155f3f780c77c9ae58fcd1668140a6ac46a9b1e85bddf81489061291b3e80f" dependencies = [ "cfg-if", "io-uring", "libc", - "rand 0.8.6", + "rand 0.8.5", "rand 0.9.4", "serde", "serde_json", @@ -255,21 +255,21 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bumpalo" -version = "3.20.3" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bytemuck" -version = "1.25.0" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" dependencies = [ "bytemuck_derive", ] @@ -282,7 +282,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -305,9 +305,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.62" +version = "1.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ "find-msvc-tools", "shlex", @@ -348,9 +348,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.1" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" dependencies = [ "clap_builder", "clap_derive", @@ -358,9 +358,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.6.0" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" dependencies = [ "anstream", "anstyle", @@ -370,27 +370,27 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.6.1" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] name = "clap_lex" -version = "1.1.0" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "colorchoice" -version = "1.0.5" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "combine" @@ -408,9 +408,9 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.38" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2548391e9c1929c21bf6aa2680af86fe4c1b33e6cea9ac1cfeec0bd11218cf" +checksum = "eb7b51a7d9c967fc26773061ba86150f19c50c0d65c887cb1fbe295fd16619b7" dependencies = [ "compression-core", "flate2", @@ -419,9 +419,9 @@ dependencies = [ [[package]] name = "compression-core" -version = "0.4.32" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc14f565cf027a105f7a44ccf9e5b424348421a1d8952a8fc9d499d313107789" +checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" [[package]] name = "concurrent-queue" @@ -434,12 +434,13 @@ dependencies = [ [[package]] name = "console" -version = "0.16.3" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4" dependencies = [ "encode_unicode", "libc", + "once_cell", "unicode-width", "windows-sys 0.61.2", ] @@ -615,7 +616,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -637,7 +638,7 @@ dependencies = [ "relative-path 2.0.1", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -675,7 +676,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", ] @@ -692,7 +693,7 @@ dependencies = [ "itertools 0.13.0", "serde_yaml", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", ] @@ -707,7 +708,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -724,7 +725,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -745,7 +746,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", ] @@ -780,7 +781,7 @@ dependencies = [ "rstest", "serde", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", "vfs", @@ -799,7 +800,7 @@ dependencies = [ "diskann-utils", "diskann-vector", "foldhash 0.2.0", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", ] @@ -824,7 +825,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", ] @@ -839,7 +840,7 @@ dependencies = [ "rand_distr", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -884,7 +885,7 @@ dependencies = [ "rstest", "serde", "tempfile", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tracing", "vfs", @@ -907,7 +908,7 @@ dependencies = [ "rayon", "serde", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.17", "trybuild", ] @@ -936,6 +937,7 @@ dependencies = [ "rand 0.9.4", "rand_distr", "rayon", + "roaring", "rstest", "serde", "tracing", @@ -956,7 +958,7 @@ dependencies = [ "rand_distr", "rayon", "rstest", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -992,7 +994,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -1019,9 +1021,9 @@ checksum = "e1d926b4d407d372f141f93bb444696142c29d32962ccbd3531117cf3aa0bfa9" [[package]] name = "either" -version = "1.16.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "encode_unicode" @@ -1038,7 +1040,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -1067,7 +1069,7 @@ checksum = "3bf679796c0322556351f287a51b49e48f7c4986e727b5dd78c972d30e2e16cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -1078,7 +1080,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -1148,7 +1150,7 @@ checksum = "2cc4b8cd876795d3b19ddfd59b03faa303c0b8adb9af6e188e81fc647c485bb9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -1171,18 +1173,20 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.4.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "filetime" -version = "0.2.29" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" +checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" dependencies = [ "cfg-if", "libc", + "libredox", + "windows-sys 0.60.2", ] [[package]] @@ -1197,7 +1201,7 @@ version = "25.12.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35f6839d7b3b98adde531effaf34f0c2badc6f4735d26fe74709d8e513a96ef3" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.10.0", "rustc_version", ] @@ -1309,7 +1313,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -1326,9 +1330,9 @@ checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" -version = "3.0.4" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" @@ -1466,9 +1470,9 @@ dependencies = [ [[package]] name = "generativity" -version = "1.2.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c81fb5260e37854d09d5c87183309fd8c555b75289427884b25660bc87a85e" +checksum = "5881e4c3c2433fe4905bb19cfd2b5d49d4248274862b68c27c33d9ba4e13f9ec" [[package]] name = "getrandom" @@ -1489,19 +1493,19 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "r-efi 5.3.0", + "r-efi", "wasip2", ] [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" dependencies = [ "cfg-if", "libc", - "r-efi 6.0.0", + "r-efi", "wasip2", "wasip3", ] @@ -1553,12 +1557,6 @@ dependencies = [ "foldhash 0.2.0", ] -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - [[package]] name = "heck" version = "0.5.0" @@ -1612,9 +1610,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" -version = "1.9.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ "atomic-waker", "bytes", @@ -1625,6 +1623,7 @@ dependencies = [ "httparse", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -1693,7 +1692,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -1707,13 +1706,12 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", - "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1721,9 +1719,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -1734,9 +1732,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1748,15 +1746,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -1768,15 +1766,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", @@ -1806,9 +1804,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -1816,21 +1814,21 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.14.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.17.1", + "hashbrown 0.16.1", "serde", "serde_core", ] [[package]] name = "indicatif" -version = "0.18.4" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" +checksum = "9375e112e4b463ec1b1c6c011953545c65a30164fbab5b581df32b3abf0dcb88" dependencies = [ "console", "portable-atomic", @@ -1862,9 +1860,19 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.12.0" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] [[package]] name = "is-terminal" @@ -1901,29 +1909,18 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - [[package]] name = "itoa" -version = "1.0.18" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "js-sys" -version = "0.3.99" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ - "cfg-if", - "futures-util", "once_cell", "wasm-bindgen", ] @@ -1942,27 +1939,38 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.179" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" [[package]] name = "libm" -version = "0.2.16" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "libredox" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags 2.10.0", + "libc", + "redox_syscall 0.7.0", +] [[package]] name = "linux-raw-sys" -version = "0.12.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" @@ -1990,9 +1998,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miniz_oxide" @@ -2006,9 +2014,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "wasi", @@ -2133,9 +2141,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-integer" @@ -2168,9 +2176,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.4" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" @@ -2190,7 +2198,7 @@ version = "0.10.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.10.0", "cfg-if", "foreign-types", "libc", @@ -2206,7 +2214,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -2237,7 +2245,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", ] @@ -2254,7 +2262,7 @@ dependencies = [ "percent-encoding", "rand 0.9.4", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -2290,7 +2298,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", "windows-link", ] @@ -2309,35 +2317,41 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project" -version = "1.1.13" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.13" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] name = "pin-project-lite" -version = "0.2.17" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.33" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plotters" @@ -2369,15 +2383,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" [[package]] name = "potential_utf" -version = "0.1.5" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -2404,7 +2418,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -2421,11 +2435,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.5.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit 0.25.11+spec-1.1.0", + "toml_edit 0.23.10+spec-1.0.0", ] [[package]] @@ -2447,27 +2461,27 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.11.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" +checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.11.1", + "bitflags 2.10.0", "num-traits", "rand 0.9.4", "rand_chacha 0.9.0", @@ -2495,10 +2509,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", - "itertools 0.14.0", + "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -2535,9 +2549,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.45" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -2548,17 +2562,11 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" -[[package]] -name = "r-efi" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" - [[package]] name = "rand" -version = "0.8.6" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -2572,7 +2580,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.5", + "rand_core 0.9.3", ] [[package]] @@ -2592,7 +2600,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.5", + "rand_core 0.9.3", ] [[package]] @@ -2606,9 +2614,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.5" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom 0.3.4", ] @@ -2629,7 +2637,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" dependencies = [ - "rand_core 0.9.5", + "rand_core 0.9.3", ] [[package]] @@ -2638,14 +2646,14 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.10.0", ] [[package]] name = "rayon" -version = "1.12.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -2699,14 +2707,23 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.10.0", +] + +[[package]] +name = "redox_syscall" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" +dependencies = [ + "bitflags 2.10.0", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -2716,9 +2733,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -2727,9 +2744,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "relative-path" @@ -2787,9 +2804,9 @@ dependencies = [ [[package]] name = "roaring" -version = "0.11.4" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dedc5658c6ecb3bdb5ef5f3295bb9253f42dcf3fd1402c03f6b1f7659c3c4a9" +checksum = "8ba9ce64a8f45d7fc86358410bb1a82e8c987504c0d4900e9141d69a9f26c885" dependencies = [ "bytemuck", "byteorder", @@ -2821,7 +2838,7 @@ dependencies = [ "regex", "relative-path 1.9.3", "rustc_version", - "syn 2.0.117", + "syn 2.0.113", "unicode-ident", ] @@ -2836,11 +2853,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.4" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys", @@ -2849,9 +2866,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ "zeroize", ] @@ -2876,15 +2893,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.23" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] name = "saa" -version = "5.6.0" +version = "5.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5acb362a0e75c2a963532fa7fabf13dff81626dc494df16488d30befcbea0" +checksum = "77cb23a1da9bcf98289bea29df468b782ddf2993836d1ebd171c403210b86baa" [[package]] name = "same-file" @@ -2897,9 +2914,9 @@ dependencies = [ [[package]] name = "scc" -version = "3.7.1" +version = "3.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bcd12b6caff5213cc3c03123cde8c3db5e413008a63b0c0ba35e6275825ea92" +checksum = "79d533af0a5c0d082eb3f957aaca91e920ad7064a5ebabee3584ed1d90a0bb24" dependencies = [ "saa", "sdd", @@ -2907,9 +2924,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.29" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ "windows-sys 0.61.2", ] @@ -2922,20 +2939,17 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sdd" -version = "4.8.6" +version = "4.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f0e40a01b94e35d1dacbcfbe5bfd3d31e37d9590b2e6d86a82b0e87bd4f551" -dependencies = [ - "saa", -] +checksum = "6e63d45f3526312c9c90d717aac28d37010e623fbd7ca6f21503e69784e86f40" [[package]] name = "security-framework" -version = "3.7.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.10.0", "core-foundation", "core-foundation-sys", "libc", @@ -2954,9 +2968,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.28" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "seq-macro" @@ -2991,14 +3005,14 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" dependencies = [ "itoa", "memchr", @@ -3018,9 +3032,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.1.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" dependencies = [ "serde_core", ] @@ -3083,15 +3097,15 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.9" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] name = "slab" -version = "0.4.12" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "smallvec" @@ -3101,12 +3115,12 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -3134,9 +3148,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4" dependencies = [ "proc-macro2", "quote", @@ -3160,7 +3174,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -3169,7 +3183,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01198a2debb237c62b6826ec7081082d951f46dbb64b0e8c7649a452230d1dfc" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.10.0", "byteorder", "enum-as-inner", "libc", @@ -3185,12 +3199,12 @@ checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" [[package]] name = "tempfile" -version = "3.27.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.3.4", "once_cell", "rustix", "windows-sys 0.61.2", @@ -3216,11 +3230,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.17", ] [[package]] @@ -3231,18 +3245,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -3288,9 +3302,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -3308,9 +3322,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.52.3" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ "bytes", "libc", @@ -3325,13 +3339,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -3371,32 +3385,17 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.12+spec-1.1.0" +version = "0.9.10+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48" dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.1.1", + "serde_spanned 1.0.4", "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", - "winnow 0.7.15", -] - -[[package]] -name = "toml" -version = "1.1.2+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" -dependencies = [ - "indexmap", - "serde_core", - "serde_spanned 1.1.1", - "toml_datetime 1.1.1+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 1.0.3", + "winnow", ] [[package]] @@ -3417,15 +3416,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "toml_datetime" -version = "1.1.1+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" -dependencies = [ - "serde_core", -] - [[package]] name = "toml_edit" version = "0.22.27" @@ -3437,28 +3427,28 @@ dependencies = [ "serde_spanned 0.6.9", "toml_datetime 0.6.11", "toml_write", - "winnow 0.7.15", + "winnow", ] [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap", - "toml_datetime 1.1.1+spec-1.1.0", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", - "winnow 1.0.3", + "winnow", ] [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ - "winnow 1.0.3", + "winnow", ] [[package]] @@ -3469,9 +3459,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] name = "tower" @@ -3490,25 +3480,25 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.11" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "async-compression", - "bitflags 2.11.1", + "bitflags 2.10.0", "bytes", "futures-core", "futures-util", "http", "http-body", "http-body-util", + "iri-string", "pin-project-lite", "tokio", "tokio-util", "tower", "tower-layer", "tower-service", - "url", ] [[package]] @@ -3542,7 +3532,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -3568,9 +3558,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.23" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", "nu-ansi-term", @@ -3592,9 +3582,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.116" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c635f0191bd3a2941013e5062667100969f8c4e9cd787c14f977265d73616e" +checksum = "3e17e807bff86d2a06b52bca4276746584a78375055b6e45843925ce2802b335" dependencies = [ "glob", "serde", @@ -3602,7 +3592,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 1.1.2+spec-1.1.0", + "toml 0.9.10+spec-1.1.0", ] [[package]] @@ -3653,7 +3643,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] @@ -3664,9 +3654,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.24" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-width" @@ -3718,11 +3708,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.1" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.1", "js-sys", "wasm-bindgen", ] @@ -3753,7 +3743,7 @@ dependencies = [ "redis", "serde", "tokio", - "toml 0.9.12+spec-1.1.0", + "toml 0.9.10+spec-1.1.0", ] [[package]] @@ -3807,11 +3797,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen 0.57.1", + "wit-bindgen 0.46.0", ] [[package]] @@ -3825,9 +3815,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.122" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", @@ -3838,19 +3828,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.72" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ + "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", + "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.122" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3858,22 +3851,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.122" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.122" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] @@ -3919,7 +3912,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.10.0", "hashbrown 0.15.5", "indexmap", "semver", @@ -3927,9 +3920,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.99" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -3966,7 +3959,16 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", ] [[package]] @@ -3984,14 +3986,31 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -4000,42 +4019,84 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -4043,23 +4104,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "winnow" -version = "0.7.15" +name = "windows_x86_64_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "1.0.3" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + [[package]] name = "wit-bindgen" version = "0.51.0" @@ -4069,12 +4133,6 @@ dependencies = [ "wit-bindgen-rust-macro", ] -[[package]] -name = "wit-bindgen" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - [[package]] name = "wit-bindgen-core" version = "0.51.0" @@ -4096,7 +4154,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.117", + "syn 2.0.113", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -4112,7 +4170,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -4124,7 +4182,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.1", + "bitflags 2.10.0", "indexmap", "log", "serde", @@ -4156,15 +4214,15 @@ dependencies = [ [[package]] name = "writeable" -version = "0.6.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -4173,54 +4231,54 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] name = "zerofrom" -version = "0.1.8" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", "synstructure", ] @@ -4232,9 +4290,9 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -4243,9 +4301,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.6" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -4254,17 +4312,17 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.113", ] [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "dcb2c125bd7365735bebeb420ccb880265ed2d2bddcbcd49f597fdfe6bd5e577" From 1f774bb94896e9ecb8031cd626fb4e510f0a3d12 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 18:39:19 +0000 Subject: [PATCH 26/34] remove crate --- Cargo.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 4c1306424..04030e6b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -937,7 +937,6 @@ dependencies = [ "rand 0.9.4", "rand_distr", "rayon", - "roaring", "rstest", "serde", "tracing", From 07b2d2b412d1a2301d11044ed527441e483859fd Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 19:02:14 +0000 Subject: [PATCH 27/34] move to diskann-tools --- Cargo.lock | 1 + diskann-label-filter/src/lib.rs | 2 -- diskann-tools/Cargo.toml | 1 + .../src/bin}/compute_specificities.rs | 3 ++- .../src/utils/compute_bitmap.rs | 23 ++++++++----------- diskann-tools/src/utils/ground_truth.rs | 3 ++- diskann-tools/src/utils/mod.rs | 3 +++ 7 files changed, 19 insertions(+), 17 deletions(-) rename {diskann-label-filter/examples => diskann-tools/src/bin}/compute_specificities.rs (95%) rename {diskann-label-filter => diskann-tools}/src/utils/compute_bitmap.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index 04030e6b7..b57ae33dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -939,6 +939,7 @@ dependencies = [ "rayon", "rstest", "serde", + "serde_json", "tracing", "tracing-subscriber", "vfs", diff --git a/diskann-label-filter/src/lib.rs b/diskann-label-filter/src/lib.rs index cdd9cc3ed..106845f98 100644 --- a/diskann-label-filter/src/lib.rs +++ b/diskann-label-filter/src/lib.rs @@ -13,7 +13,6 @@ pub mod parser { // Utils pub mod utils { - pub mod compute_bitmap; pub mod flatten_utils; pub mod jsonl_reader; } @@ -74,7 +73,6 @@ pub use parser::query_parser::{get_value_by_path, parse_query_filter}; pub use traits::inverted_index_trait::InvertedIndexProvider; pub use traits::key_codec::DefaultKeyCodec; pub use traits::kv_store_traits::KvStore; -pub use utils::compute_bitmap::compute_query_bitmaps; pub use utils::flatten_utils::Attributes; pub use utils::jsonl_reader::{ read_and_parse_queries, read_baselabels, read_ground_truth, read_queries, JsonlReadError, diff --git a/diskann-tools/Cargo.toml b/diskann-tools/Cargo.toml index ae987dca9..2d86e20a7 100644 --- a/diskann-tools/Cargo.toml +++ b/diskann-tools/Cargo.toml @@ -34,6 +34,7 @@ bit-set.workspace = true anyhow.workspace = true itertools.workspace = true diskann-label-filter.workspace = true +serde_json.workspace = true [dev-dependencies] rstest.workspace = true diff --git a/diskann-label-filter/examples/compute_specificities.rs b/diskann-tools/src/bin/compute_specificities.rs similarity index 95% rename from diskann-label-filter/examples/compute_specificities.rs rename to diskann-tools/src/bin/compute_specificities.rs index 86cbe440c..8ce17e142 100644 --- a/diskann-label-filter/examples/compute_specificities.rs +++ b/diskann-tools/src/bin/compute_specificities.rs @@ -3,7 +3,8 @@ * Licensed under the MIT license. */ -use diskann_label_filter::{compute_query_bitmaps, read_and_parse_queries, read_baselabels}; +use diskann_label_filter::{read_and_parse_queries, read_baselabels}; +use diskann_tools::utils::compute_bitmap::compute_query_bitmaps; use std::env; use std::fs::File; use std::io::Write; diff --git a/diskann-label-filter/src/utils/compute_bitmap.rs b/diskann-tools/src/utils/compute_bitmap.rs similarity index 98% rename from diskann-label-filter/src/utils/compute_bitmap.rs rename to diskann-tools/src/utils/compute_bitmap.rs index ada25da10..5e86b14ae 100644 --- a/diskann-label-filter/src/utils/compute_bitmap.rs +++ b/diskann-tools/src/utils/compute_bitmap.rs @@ -3,11 +3,13 @@ * Licensed under the MIT license. */ -use crate::attribute::AttributeValue; -use crate::parser::evaluator::eval_query_expr; -use crate::utils::flatten_utils::{flatten_json_pointers_with_config, FlattenConfig}; -use crate::{parser::format::Document, ASTExpr, CompareOp}; use bit_set::BitSet; +use diskann_label_filter::attribute::AttributeValue; +use diskann_label_filter::parser::{evaluator::eval_query_expr, format::Document}; +use diskann_label_filter::utils::flatten_utils::{ + flatten_json_pointers_with_config, FlattenConfig, +}; +use diskann_label_filter::{ASTExpr, CompareOp}; use rayon::prelude::*; use std::cmp::Ordering; use std::collections::BTreeMap; @@ -42,6 +44,7 @@ impl PartialOrd for OrderedFloat { Some(self.cmp(other)) } } + impl Ord for OrderedFloat { fn cmp(&self, other: &Self) -> Ordering { // By construction, we know the partial comparison will succeed. @@ -372,9 +375,9 @@ pub fn compute_query_bitmaps( #[cfg(test)] mod tests { use super::*; - use crate::attribute::AttributeValue; - use crate::parser::format::Document; - use crate::{ASTExpr, CompareOp}; + use diskann_label_filter::attribute::AttributeValue; + use diskann_label_filter::parser::format::Document; + use diskann_label_filter::{ASTExpr, CompareOp}; use serde_json::json; use std::collections::HashMap; @@ -423,8 +426,6 @@ mod tests { #[test] fn test_compute_query_bitmap_missing_field() { - use crate::parser::format::Document; - use serde_json::json; // Three documents, one missing the 'color' field let base_labels = vec![ Document { @@ -466,8 +467,6 @@ mod tests { #[test] fn test_compute_query_bitmap_nested_value() { - use crate::parser::format::Document; - use serde_json::json; // Two documents with nested car.color let base_labels = vec![ Document { @@ -695,8 +694,6 @@ mod tests { #[test] fn test_compute_query_bitmap_bools() { - use crate::parser::format::Document; - use serde_json::json; // Two documents with a boolean field let base_labels = vec![ Document { diff --git a/diskann-tools/src/utils/ground_truth.rs b/diskann-tools/src/utils/ground_truth.rs index ceb07b969..98e16713a 100644 --- a/diskann-tools/src/utils/ground_truth.rs +++ b/diskann-tools/src/utils/ground_truth.rs @@ -3,8 +3,9 @@ * Licensed under the MIT license. */ +use crate::utils::compute_bitmap::compute_query_bitmaps; use bit_set::BitSet; -use diskann_label_filter::{compute_query_bitmaps, read_and_parse_queries, read_baselabels}; +use diskann_label_filter::{read_and_parse_queries, read_baselabels}; use std::{io::Write, mem::size_of, str::FromStr}; diff --git a/diskann-tools/src/utils/mod.rs b/diskann-tools/src/utils/mod.rs index d39295595..3b102e091 100644 --- a/diskann-tools/src/utils/mod.rs +++ b/diskann-tools/src/utils/mod.rs @@ -54,3 +54,6 @@ pub mod multi_label; pub use multi_label::MultiLabel; pub mod relative_contrast; pub use relative_contrast::*; + +pub mod compute_bitmap; +pub use compute_bitmap::compute_query_bitmaps; From 071324405092aff0055ec010772d95a2b19577f4 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 19:04:40 +0000 Subject: [PATCH 28/34] remove from toml file --- Cargo.lock | 2 -- diskann-label-filter/Cargo.toml | 3 --- 2 files changed, 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b57ae33dd..bead53768 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -810,7 +810,6 @@ version = "0.52.0" dependencies = [ "anyhow", "bf-tree", - "bit-set", "criterion", "diskann", "diskann-utils", @@ -819,7 +818,6 @@ dependencies = [ "hashbrown 0.16.1", "num-traits", "rand 0.9.4", - "rayon", "roaring", "scc", "serde", diff --git a/diskann-label-filter/Cargo.toml b/diskann-label-filter/Cargo.toml index 18b5d1f56..98fe3879c 100644 --- a/diskann-label-filter/Cargo.toml +++ b/diskann-label-filter/Cargo.toml @@ -23,9 +23,6 @@ scc = "3.3.2" diskann-utils = { workspace = true, default-features = false } diskann-vector.workspace = true tracing.workspace = true -bit-set.workspace = true -rayon.workspace = true -anyhow.workspace = true [dev-dependencies] From c205a87a1e7c1a6591856242b770adcf2f88cc30 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Fri, 22 May 2026 19:24:11 +0000 Subject: [PATCH 29/34] add check that i64 -> f64 conversion is lossless --- diskann-tools/src/utils/compute_bitmap.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/diskann-tools/src/utils/compute_bitmap.rs b/diskann-tools/src/utils/compute_bitmap.rs index 5e86b14ae..b5f522f28 100644 --- a/diskann-tools/src/utils/compute_bitmap.rs +++ b/diskann-tools/src/utils/compute_bitmap.rs @@ -219,7 +219,15 @@ fn compute_btree_accelerator( .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; map.entry(f64_value).or_default().push(doc_id); } else if let Some(i64_value) = value.as_integer() { - let i64_value = OrderedFloat::new(i64_value as f64) + // convert from i64 to f64 + let f = i64_value as f64; + if f as i64 != i64_value { + return Err(anyhow::anyhow!( + "i64 value cannot be exactly represented as f64: {}", + i64_value + )); + } + let i64_value = OrderedFloat::new(f) .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; map.entry(i64_value).or_default().push(doc_id); } else { From 7bf657060d1c8cd2c2e57f35d9bf0b67f4206744 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Mon, 25 May 2026 18:32:03 +0000 Subject: [PATCH 30/34] add argparse interface, respond to other PR comments --- .../src/bin/compute_specificities.rs | 44 +++++++++++-------- diskann-tools/src/utils/compute_bitmap.rs | 24 +++++----- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/diskann-tools/src/bin/compute_specificities.rs b/diskann-tools/src/bin/compute_specificities.rs index 8ce17e142..3cb2bf174 100644 --- a/diskann-tools/src/bin/compute_specificities.rs +++ b/diskann-tools/src/bin/compute_specificities.rs @@ -3,31 +3,37 @@ * Licensed under the MIT license. */ +use clap::Parser; use diskann_label_filter::{read_and_parse_queries, read_baselabels}; use diskann_tools::utils::compute_bitmap::compute_query_bitmaps; -use std::env; use std::fs::File; use std::io::Write; use std::process; +#[derive(Debug, Parser)] +#[command( + about = "Compute specificities for queries against base labels", + author, + version +)] +struct Args { + /// File containing the base labels + #[arg(long = "base_label_file", short = 'b')] + pub base_label_file: String, + + /// File containing the query labels + #[arg(long = "query_label_file", short = 'q')] + pub query_label_file: String, + + /// Output file for specificities (optional) + #[arg(long = "specificity_output_file", short = 'o')] + pub specificity_output_file: Option, +} + fn main() { - let args: Vec = env::args().collect(); - if args.len() != 3 && args.len() != 4 { - eprintln!( - "Usage: {} [specificity_output_file]", - args[0] - ); - process::exit(1); - } - let base_label_file = &args[1]; - let query_label_file = &args[2]; - let output_file = if args.len() == 4 { - Some(&args[3]) - } else { - None - }; + let args = Args::parse(); - let base_labels = match read_baselabels(base_label_file) { + let base_labels = match read_baselabels(&args.base_label_file) { Ok(labels) => labels, Err(e) => { eprintln!("Error reading base labels: {}", e); @@ -41,7 +47,7 @@ fn main() { process::exit(1); } - let query_labels = match read_and_parse_queries(query_label_file) { + let query_labels = match read_and_parse_queries(&args.query_label_file) { Ok(queries) => queries, Err(e) => { eprintln!("Error reading query labels: {}", e); @@ -68,7 +74,7 @@ fn main() { }) .collect(); - if let Some(path) = output_file { + if let Some(path) = &args.specificity_output_file { let mut file = match File::create(path) { Ok(f) => f, Err(e) => { diff --git a/diskann-tools/src/utils/compute_bitmap.rs b/diskann-tools/src/utils/compute_bitmap.rs index b5f522f28..8d7c8a0fe 100644 --- a/diskann-tools/src/utils/compute_bitmap.rs +++ b/diskann-tools/src/utils/compute_bitmap.rs @@ -17,6 +17,10 @@ use std::collections::HashMap; use std::mem::discriminant; use std::ops::Bound::{Excluded, Included, Unbounded}; +// In order to construct a B-Tree over floats, we need to create a total +// ordering on the float values by excluding NaN values. This struct is +// used to throw an error if a NaN value is encountered when constructing +// the OrderedFloat type. struct NotNonNan; impl std::fmt::Display for NotNonNan { @@ -58,11 +62,11 @@ enum QueryAccelerator { BTree(BTreeMap>), } -fn check_for_disallowed_operators(query_expr: &ASTExpr) -> bool { +fn check_for_nonaccelerated_operators(query_expr: &ASTExpr) -> bool { match query_expr { ASTExpr::Not(_) => true, - ASTExpr::And(subs) => subs.iter().any(check_for_disallowed_operators), - ASTExpr::Or(subs) => subs.iter().any(check_for_disallowed_operators), + ASTExpr::And(subs) => subs.iter().any(check_for_nonaccelerated_operators), + ASTExpr::Or(subs) => subs.iter().any(check_for_nonaccelerated_operators), ASTExpr::Compare { .. } => false, } } @@ -288,7 +292,7 @@ pub fn compute_query_bitmaps( // read query labels and differentiate between fast and slow path let bitmaps = if query_labels .iter() - .any(|(_, expr)| check_for_disallowed_operators(expr)) + .any(|(_, expr)| check_for_nonaccelerated_operators(expr)) { // using the global threadpool is fine here #[allow(clippy::disallowed_methods)] @@ -915,20 +919,20 @@ mod tests { } #[test] - fn test_check_for_disallowed_operators() { + fn test_check_for_nonaccelerated_operators() { // Compare only (no NOT) let expr = ASTExpr::Compare { field: "foo".to_string(), op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), }; - assert!(!check_for_disallowed_operators(&expr)); + assert!(!check_for_nonaccelerated_operators(&expr)); // NOT at root let expr = ASTExpr::Not(Box::new(ASTExpr::Compare { field: "foo".to_string(), op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), })); - assert!(check_for_disallowed_operators(&expr)); + assert!(check_for_nonaccelerated_operators(&expr)); // AND with NOT inside let expr = ASTExpr::And(vec![ @@ -941,7 +945,7 @@ mod tests { op: CompareOp::Eq(serde_json::Value::String("qux".to_string())), })), ]); - assert!(check_for_disallowed_operators(&expr)); + assert!(check_for_nonaccelerated_operators(&expr)); // OR with only Compare let expr = ASTExpr::Or(vec![ @@ -954,7 +958,7 @@ mod tests { op: CompareOp::Eq(serde_json::Value::String("qux".to_string())), }, ]); - assert!(!check_for_disallowed_operators(&expr)); + assert!(!check_for_nonaccelerated_operators(&expr)); // Nested AND/OR with NOT deep inside let expr = ASTExpr::And(vec![ @@ -973,6 +977,6 @@ mod tests { op: CompareOp::Eq(serde_json::Value::String("f".to_string())), }, ]); - assert!(check_for_disallowed_operators(&expr)); + assert!(check_for_nonaccelerated_operators(&expr)); } } From 52070e743e75ea4279ab1a7140702b0db071f145 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Mon, 25 May 2026 18:34:38 +0000 Subject: [PATCH 31/34] move separator example back to / --- diskann-label-filter/src/utils/flatten_utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diskann-label-filter/src/utils/flatten_utils.rs b/diskann-label-filter/src/utils/flatten_utils.rs index ea80cfed5..96b04d0df 100644 --- a/diskann-label-filter/src/utils/flatten_utils.rs +++ b/diskann-label-filter/src/utils/flatten_utils.rs @@ -191,7 +191,7 @@ pub fn flatten_json_pointers(value: &Value) -> AttributesVec { /// Configurable version that uses FlattenConfig /// /// Example: -/// With config.separator=".": {"a": {"b": [1, 2]}} -> [ (".a.b.0", 1), (".a.b.1", 2) ] +/// With config.separator="/": {"a": {"b": [1, 2]}} -> [ ("/a/b/0", 1), ("/a/b/1", 2) ] pub fn flatten_json_pointers_with_config(value: &Value, config: &FlattenConfig) -> AttributesVec { let mut out = Vec::new(); flatten_json_pointer_inner(value, &config.root_prefix, &mut out, &config.separator); From af50dc42d510a543816dccb5fbb9b08184cb8327 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Mon, 25 May 2026 21:32:09 +0000 Subject: [PATCH 32/34] add universe computation for NOT operator --- diskann-tools/src/utils/compute_bitmap.rs | 619 ++++++++++++++-------- 1 file changed, 391 insertions(+), 228 deletions(-) diff --git a/diskann-tools/src/utils/compute_bitmap.rs b/diskann-tools/src/utils/compute_bitmap.rs index 8d7c8a0fe..20dbc8605 100644 --- a/diskann-tools/src/utils/compute_bitmap.rs +++ b/diskann-tools/src/utils/compute_bitmap.rs @@ -1,3 +1,35 @@ + #[test] + fn test_compute_query_bitmap_not_with_missing_field() { + use serde_json::json; + // Three documents: two with "color", one without + let base_labels = vec![ + Document { + doc_id: 0, + label: json!({"color": "red"}), + }, + Document { + doc_id: 1, + label: json!({"color": "blue"}), + }, + Document { + doc_id: 2, + label: json!({"shape": "circle"}), // no color field + }, + ]; + + // Query: NOT color == "red" + let not_query = ASTExpr::Not(Box::new(ASTExpr::Compare { + field: "color".to_string(), + op: CompareOp::Eq(json!("red")), + })); + let queries = vec![(0, not_query)]; + let bitmaps = compute_query_bitmaps(base_labels.clone(), queries).expect("Should succeed"); + // Only doc 1 should match (has color and is not red) + assert!(bitmaps[0].contains(1)); + assert!(!bitmaps[0].contains(0)); + // Doc 2 does not have color, so should not be included in the NOT universe + assert!(!bitmaps[0].contains(2)); + } /* * Copyright (c) Microsoft Corporation. * Licensed under the MIT license. @@ -5,12 +37,13 @@ use bit_set::BitSet; use diskann_label_filter::attribute::AttributeValue; -use diskann_label_filter::parser::{evaluator::eval_query_expr, format::Document}; +use diskann_label_filter::parser::format::Document; use diskann_label_filter::utils::flatten_utils::{ flatten_json_pointers_with_config, FlattenConfig, }; use diskann_label_filter::{ASTExpr, CompareOp}; use rayon::prelude::*; +use std::any::Any; use std::cmp::Ordering; use std::collections::BTreeMap; use std::collections::HashMap; @@ -57,9 +90,137 @@ impl Ord for OrderedFloat { } } -enum QueryAccelerator { - InvertedIndex(HashMap), - BTree(BTreeMap>), +trait QueryAccelerator: Send + Sync { + fn eval(&self, op: &CompareOp) -> Result; + + fn universe(&self) -> BitSet; + + // method for testing + #[allow(dead_code)] + fn as_any(&self) -> &dyn Any; +} + +struct InvertedIndexAccelerator { + map: HashMap, +} + +impl QueryAccelerator for InvertedIndexAccelerator { + fn as_any(&self) -> &dyn Any { + self + } + + fn universe(&self) -> BitSet { + let mut result = BitSet::new(); + for (_, bits) in self.map.iter() { + result.extend(bits); + } + result + } + + fn eval(&self, op: &CompareOp) -> Result { + match op { + CompareOp::Eq(v) => { + let attr_val = AttributeValue::try_from(v) + .map_err(|e| anyhow::anyhow!("Failed to convert value for Eq: {e}"))?; + Ok(self.map.get(&attr_val).cloned().unwrap_or_default()) + } + CompareOp::Ne(v) => { + let attr_val = AttributeValue::try_from(v) + .map_err(|e| anyhow::anyhow!("Failed to convert value for Ne: {e}"))?; + let mut result = BitSet::new(); + for (val, bits) in self.map.iter() { + if val != &attr_val { + result.extend(bits); + } + } + Ok(result) + } + _ => Err(anyhow::anyhow!( + "Only equality comparisons are supported with the inverted index accelerator" + )), + } + } +} + +struct BTreeAccelerator { + map: BTreeMap>, +} + +impl QueryAccelerator for BTreeAccelerator { + fn as_any(&self) -> &dyn Any { + self + } + + fn universe(&self) -> BitSet { + let mut result = BitSet::new(); + for (_, ids) in self.map.iter() { + result.extend(ids.iter().cloned()); + } + result + } + + fn eval(&self, op: &CompareOp) -> Result { + match op { + CompareOp::Eq(v) => { + let fval = v + .as_f64() + .ok_or_else(|| anyhow::anyhow!("Failed to convert value to f64 for Eq"))?; + let fval = OrderedFloat::new(fval) + .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + if let Some(ids) = self.map.get(&fval) { + Ok(insert_into_bitset(ids.to_vec())) + } else { + Ok(BitSet::new()) + } + } + CompareOp::Ne(v) => { + let fval = v + .as_f64() + .ok_or_else(|| anyhow::anyhow!("Failed to convert value to f64 for Ne"))?; + let fval = OrderedFloat::new(fval) + .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + let mut bitset = BitSet::new(); + for (val, ids) in self.map.iter() { + if val != &fval { + bitset.extend(ids.iter().cloned()); + } + } + Ok(bitset) + } + CompareOp::Lt(num) => { + let fval = OrderedFloat::new(*num) + .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + let iter = self.map.range((Unbounded, Excluded(fval))); + Ok(insert_into_bitset( + iter.flat_map(|(_, ids)| ids.iter().cloned()).collect(), + )) + } + CompareOp::Lte(num) => { + let fval = OrderedFloat::new(*num) + .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + let iter = self.map.range((Unbounded, Included(fval))); + Ok(insert_into_bitset( + iter.flat_map(|(_, ids)| ids.iter().cloned()).collect(), + )) + } + CompareOp::Gt(num) => { + let fval = OrderedFloat::new(*num) + .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + let iter = self.map.range((Excluded(fval), Unbounded)); + Ok(insert_into_bitset( + iter.flat_map(|(_, ids)| ids.iter().cloned()).collect(), + )) + } + CompareOp::Gte(num) => { + let fval = OrderedFloat::new(*num) + .map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; + let iter = self.map.range((Included(fval), Unbounded)); + Ok(insert_into_bitset( + iter.flat_map(|(_, ids)| ids.iter().cloned()).collect(), + )) + } + } + } } fn check_for_nonaccelerated_operators(query_expr: &ASTExpr) -> bool { @@ -71,6 +232,48 @@ fn check_for_nonaccelerated_operators(query_expr: &ASTExpr) -> bool { } } + +// Helper to prepend the separator if not present +fn prepend_separator(field: &str) -> String { + let separator = FlattenConfig::dot_notation().separator; + if !field.starts_with(&separator) { + format!("{}{}", separator, field) + } else { + field.to_string() + } +} + +// Takes in an expression and returns a vector of all the labels used in the expression (raw field names, no separator prepending) +fn compute_label_set(expr: &ASTExpr) -> Vec { + match expr { + ASTExpr::Not(sub) => compute_label_set(sub), + ASTExpr::And(subs) => subs.iter().flat_map(compute_label_set).collect(), + ASTExpr::Or(subs) => subs.iter().flat_map(compute_label_set).collect(), + ASTExpr::Compare { field, .. } => vec![field.clone()], + } +} + +// Takes in a set of labels and returns the universe of all possible values for those labels +fn compute_universe(universe_labels: Vec, query_accelerators: &HashMap>) -> BitSet { + let mut universe_iter = universe_labels.iter(); + // Initialize universe to the first accelerator's universe, then intersect with the rest + let mut universe = if let Some(first_label) = universe_iter.next() { + if let Some(accelerator) = query_accelerators.get(first_label) { + accelerator.universe() + } else { + BitSet::new() + } + } else { + BitSet::new() + }; + for label in universe_iter { + if let Some(accelerator) = query_accelerators.get(label) { + universe = universe.intersection(&accelerator.universe()).collect(); + } + } + universe +} + fn insert_into_bitset(ids: Vec) -> BitSet { let mut bitset = BitSet::new(); bitset.extend(ids); @@ -79,7 +282,7 @@ fn insert_into_bitset(ids: Vec) -> BitSet { fn eval_query_using_accelerators( query_expr: &ASTExpr, - query_accelerators: &HashMap, + query_accelerators: &HashMap>, ) -> Result { match query_expr { ASTExpr::And(subs) => { @@ -104,88 +307,23 @@ fn eval_query_using_accelerators( } Ok(acc.unwrap_or_else(BitSet::new)) } - ASTExpr::Not(_) => Err(anyhow::anyhow!( - "NOT operator is not supported when using query accelerators" - )), + ASTExpr::Not(sub) => { + // compute the universe of all possible values + let universe_labels_raw = compute_label_set(query_expr); + let universe_labels: Vec = universe_labels_raw.iter().map(|f| prepend_separator(f)).collect(); + let universe = compute_universe(universe_labels, query_accelerators); + + // Evaluate the sub-expression + let sub_result = eval_query_using_accelerators(sub, query_accelerators)?; + + // Return the difference between the sub-expression result and the universe + Ok(universe.difference(&sub_result).collect()) + }, ASTExpr::Compare { field, op } => { - let separator = FlattenConfig::dot_notation().separator; - let field = if !field.starts_with(&separator) { - format!("{}{}", separator, field) - } else { - field.clone() - }; + let field = prepend_separator(field); if let Some(accelerator) = query_accelerators.get(&field) { - match accelerator { - QueryAccelerator::InvertedIndex(bitmap) => { - match op { - CompareOp::Eq(value) => { - let attr_val = AttributeValue::try_from(value).map_err(|e| anyhow::anyhow!("Failed to convert value for Eq: {e}"))?; - Ok(bitmap.get(&attr_val).cloned().unwrap_or_default()) - } - CompareOp::Ne(value) => { - let attr_val = AttributeValue::try_from(value).map_err(|e| anyhow::anyhow!("Failed to convert value for Ne: {e}"))?; - let mut result = BitSet::new(); - for (val, bits) in bitmap.iter() { - if val != &attr_val { - result.extend(bits); - } - } - Ok(result) - } - _ => { - Err(anyhow::anyhow!("Only equality comparisons are supported with the inverted index accelerator")) - } - } - } - QueryAccelerator::BTree(btree) => { - match op { - CompareOp::Eq(value) => { - let fval = value.as_f64().ok_or_else(|| anyhow::anyhow!("Failed to convert value to f64 for Eq"))?; - let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; - if let Some(ids) = btree.get(&fval) { - let mut bitset = BitSet::new(); - bitset.extend(ids.iter().cloned()); - Ok(bitset) - } else { - Ok(BitSet::new()) - } - } - CompareOp::Ne(value) => { - let fval = value.as_f64().ok_or_else(|| anyhow::anyhow!("Failed to convert value to f64 for Ne"))?; - let fval = OrderedFloat::new(fval).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; - let mut bitset = BitSet::new(); - for (val, ids) in btree.iter() { - if val != &fval { - bitset.extend(ids.iter().cloned()); - } - } - Ok(bitset) - } - CompareOp::Lt(num) => { - let fval = OrderedFloat::new(*num).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; - let iter = btree.range((Unbounded, Excluded(fval))); - Ok(insert_into_bitset(iter.flat_map(|(_, ids)| ids.iter().cloned()).collect::>())) - } - CompareOp::Lte(num) => { - let fval = OrderedFloat::new(*num).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; - let iter = btree.range((Unbounded, Included(fval))); - Ok(insert_into_bitset(iter.flat_map(|(_, ids)| ids.iter().cloned()).collect::>())) - } - CompareOp::Gt(num) => { - let fval = OrderedFloat::new(*num).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; - let iter = btree.range((Excluded(fval), Unbounded)); - Ok(insert_into_bitset(iter.flat_map(|(_, ids)| ids.iter().cloned()).collect::>())) - } - CompareOp::Gte(num) => { - let fval = OrderedFloat::new(*num).map_err(|e| anyhow::anyhow!("Failed to create OrderedFloat: {e}"))?; - let iter = btree.range((Included(fval), Unbounded)); - Ok(insert_into_bitset(iter.flat_map(|(_, ids)| ids.iter().cloned()).collect::>())) - } - } - } - } + accelerator.eval(op) } else { - // if field not present, return an empty bitset Ok(BitSet::new()) } } @@ -270,16 +408,15 @@ fn compute_query_accelerator( value: AttributeValue, doc_ids: &[usize], flattened_base_labels: &[HashMap], -) -> Result { +) -> Result, anyhow::Error> { match value { AttributeValue::String(_) | AttributeValue::Bool(_) => { let bitmap = compute_inverted_index_accelerator(&key, doc_ids, flattened_base_labels)?; - Ok(QueryAccelerator::InvertedIndex(bitmap)) + Ok(Box::new(InvertedIndexAccelerator { map: bitmap })) } AttributeValue::Integer(_) | AttributeValue::Real(_) => { - // For integers and reals, we use an BTree let btree = compute_btree_accelerator(&key, flattened_base_labels, doc_ids)?; - Ok(QueryAccelerator::BTree(btree)) + Ok(Box::new(BTreeAccelerator { map: btree })) } AttributeValue::Empty => Err(anyhow::anyhow!("Empty attribute value is not allowed")), } @@ -289,99 +426,70 @@ pub fn compute_query_bitmaps( base_labels: Vec, query_labels: Vec<(usize, ASTExpr)>, ) -> Result, anyhow::Error> { - // read query labels and differentiate between fast and slow path - let bitmaps = if query_labels + // Flatten base labels so that nested structures are converted to a flat list of key-value pairs + let flattened_base_labels: Vec> = base_labels .iter() - .any(|(_, expr)| check_for_nonaccelerated_operators(expr)) - { - // using the global threadpool is fine here - #[allow(clippy::disallowed_methods)] - let query_bitmaps: Vec = query_labels - .par_iter() - .map(|(_query_id, query_expr)| { - let mut bitmap = BitSet::new(); - for base_label in base_labels.iter() { - if eval_query_expr(query_expr, &base_label.label) { - bitmap.insert(base_label.doc_id); - } - } - bitmap - }) - .collect(); - query_bitmaps - } else { - // Flatten base labels so that nested structures are converted to a flat list of key-value pairs - let flattened_base_labels: Vec> = base_labels - .iter() - .map(|base_label| { - flatten_json_pointers_with_config(&base_label.label, &FlattenConfig::dot_notation()) - }) - .collect(); - - let flattened_base_label_hashmaps: Result< - Vec>, - anyhow::Error, - > = flattened_base_labels - .iter() - .map(|labels| { - let mut map = HashMap::new(); - for (key, value) in labels { - // a base label may not have two values for the same key - if let Some(_existing_value) = map.get(key) { - return Err(anyhow::anyhow!( - "Duplicate keys in the same document: {}", - key - )); - } - map.insert(key.clone(), value.clone()); + .map(|base_label| { + flatten_json_pointers_with_config(&base_label.label, &FlattenConfig::dot_notation()) + }) + .collect(); + + let flattened_base_label_hashmaps: Result< + Vec>, + anyhow::Error, + > = flattened_base_labels + .iter() + .map(|labels| { + let mut map = HashMap::new(); + for (key, value) in labels { + // a base label may not have two values for the same key + if let Some(_existing_value) = map.get(key) { + return Err(anyhow::anyhow!( + "Duplicate keys in the same document: {}", + key + )); } - Ok(map) - }) - .collect(); - - let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; - let base_doc_ids: Vec = base_labels - .iter() - .map(|base_label| base_label.doc_id) - .collect(); - - // compute the global set of labels ahead of time so that we can compute - // each accelerator in parallel - let global_label_set = compute_global_label_set(&flattened_base_label_hashmaps)?; - - // Compute the accelerators for each label in the global set - #[allow(clippy::disallowed_methods)] - let query_accelerators: Result, anyhow::Error> = - global_label_set - .par_iter() - .map(|(key, value)| { - compute_query_accelerator( - key.clone(), - value.clone(), - &base_doc_ids, - &flattened_base_label_hashmaps, - ) - .map(|accel| (key.clone(), accel)) - }) - .collect(); - - // Convert the query accelerators to a hashmap for faster lookups - let query_accelerators: HashMap = - query_accelerators?.into_iter().collect(); - - // Evaluate each query using the precomputed accelerators - #[allow(clippy::disallowed_methods)] - let query_bitmaps: Result, anyhow::Error> = query_labels - .par_iter() - .map(|(_query_id, query_expr)| { - eval_query_using_accelerators(query_expr, &query_accelerators) - }) - .collect(); - - query_bitmaps? - }; + map.insert(key.clone(), value.clone()); + } + Ok(map) + }) + .collect(); - Ok(bitmaps) + let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; + let base_doc_ids: Vec = base_labels + .iter() + .map(|base_label| base_label.doc_id) + .collect(); + + // compute the global set of labels ahead of time so that we can compute + // each accelerator in parallel + let global_label_set = compute_global_label_set(&flattened_base_label_hashmaps)?; + + // Compute the accelerators for each label in the global set + #[allow(clippy::disallowed_methods)] + let query_accelerators: HashMap> = global_label_set + .par_iter() + .map(|(key, value)| { + compute_query_accelerator( + key.clone(), + value.clone(), + &base_doc_ids, + &flattened_base_label_hashmaps, + ) + .map(|accel| (key.clone(), accel)) + }) + .collect::>()?; + + // Evaluate each query using the precomputed accelerators + #[allow(clippy::disallowed_methods)] + let query_bitmaps: Result, anyhow::Error> = query_labels + .par_iter() + .map(|(_query_id, query_expr)| { + eval_query_using_accelerators(query_expr, &query_accelerators) + }) + .collect(); + + Ok(query_bitmaps?) } #[cfg(test)] @@ -393,6 +501,62 @@ mod tests { use serde_json::json; use std::collections::HashMap; + #[test] + fn test_compute_universe_function() { + // Sub-test 1: universe label not in query_accelerators, should return empty + let query_accelerators: HashMap> = HashMap::new(); + let universe_labels = vec!["missing_label".to_string()]; + let result = compute_universe(universe_labels, &query_accelerators); + assert!(result.is_empty(), "Universe should be empty if label is missing"); + + // Sub-test 2: both accelerator types, non-empty intersection + // InvertedIndexAccelerator for 'foo' with docs 1, 2 + let mut inv_map = HashMap::new(); + inv_map.insert(AttributeValue::String("a".to_string()), [1, 2].iter().cloned().collect()); + let inv_accel = Box::new(InvertedIndexAccelerator { map: inv_map }); + + // BTreeAccelerator for 'bar' with docs 2, 3 + let mut btree_map = BTreeMap::new(); + btree_map.insert(OrderedFloat(1.0), vec![2, 3]); + let btree_accel = Box::new(BTreeAccelerator { map: btree_map }); + + let mut query_accelerators: HashMap> = HashMap::new(); + query_accelerators.insert("foo".to_string(), inv_accel); + query_accelerators.insert("bar".to_string(), btree_accel); + + // The intersection of {1,2} and {2,3} is {2} + let universe_labels = vec!["foo".to_string(), "bar".to_string()]; + let result = compute_universe(universe_labels, &query_accelerators); + let expected: BitSet = [2].iter().cloned().collect(); + assert_eq!(result, expected, "Universe should be the intersection of both accelerator universes"); + } + + #[test] + fn test_compute_label_set() { + // OR expression: foo == 1 OR bar == 2 + let expr_or = ASTExpr::Or(vec![ + ASTExpr::Compare { + field: "foo".to_string(), + op: CompareOp::Eq(json!(1)), + }, + ASTExpr::Compare { + field: "bar".to_string(), + op: CompareOp::Eq(json!(2)), + }, + ]); + let mut result_or = compute_label_set(&expr_or); + result_or.sort(); + assert_eq!(result_or, vec!["bar".to_string(), "foo".to_string()]); + + // NOT expression: NOT (baz == 3) + let expr_not = ASTExpr::Not(Box::new(ASTExpr::Compare { + field: "baz".to_string(), + op: CompareOp::Eq(json!(3)), + })); + let result_not = compute_label_set(&expr_not); + assert_eq!(result_not, vec!["baz".to_string()]); + } + #[test] fn test_compute_query_bitmap_duplicate_key_in_doc() { // serde_json does not allow duplicate keys, but we can simulate this by flattening a document with a nested object that, when flattened, produces duplicate keys @@ -501,9 +665,9 @@ mod tests { assert!(bitmaps[0].contains(0)); assert!(!bitmaps[0].contains(1)); - // Query: NOT car.color == "red" (should match blue) + // Query: NOT .car.color == "red" (should match blue) let query_not = ASTExpr::Not(Box::new(ASTExpr::Compare { - field: "car.color".to_string(), + field: ".car.color".to_string(), op: CompareOp::Eq(json!("red")), })); let bitmaps = compute_query_bitmaps(base_labels.clone(), vec![(0, query_not)]) @@ -806,13 +970,8 @@ mod tests { op: CompareOp::Eq(serde_json::json!("red")), })); let queries_with_not = vec![(0, not_query)]; - let result = compute_query_bitmaps(base_labels.clone(), queries_with_not); - assert!( - result.is_ok(), - "Slow path should not error, but NOT is not accelerated" - ); + let bitmaps = compute_query_bitmaps(base_labels.clone(), queries_with_not).expect("Should succeed"); // The result should be a bitmap with doc 1 (not red) - let bitmaps = result.unwrap(); assert!(bitmaps[0].contains(1)); assert!(!bitmaps[0].contains(0)); assert!(!bitmaps[0].contains(2)); @@ -842,27 +1001,34 @@ mod tests { &base, ) .expect("Should succeed for String"); - match accel { - QueryAccelerator::InvertedIndex(map) => { - assert!(map.contains_key(&AttributeValue::String("bar".to_string()))); - assert!(map.contains_key(&AttributeValue::String("baz".to_string()))); - assert_eq!( - map.get(&AttributeValue::String("bar".to_string())) - .expect("bar key should exist") - .iter() - .collect::>(), - vec![10] - ); - assert_eq!( - map.get(&AttributeValue::String("baz".to_string())) - .expect("baz key should exist") - .iter() - .collect::>(), - vec![42] - ); - } - _ => panic!("Expected InvertedIndex for String"), - } + let accel = accel + .as_any() + .downcast_ref::() + .expect("Expected InvertedIndexAccelerator"); + assert!(accel + .map + .contains_key(&AttributeValue::String("bar".to_string()))); + assert!(accel + .map + .contains_key(&AttributeValue::String("baz".to_string()))); + assert_eq!( + accel + .map + .get(&AttributeValue::String("bar".to_string())) + .expect("bar key should exist") + .iter() + .collect::>(), + vec![10] + ); + assert_eq!( + accel + .map + .get(&AttributeValue::String("baz".to_string())) + .expect("baz key should exist") + .iter() + .collect::>(), + vec![42] + ); // Bool let accel = compute_query_accelerator( @@ -872,13 +1038,12 @@ mod tests { &base, ) .expect("Should succeed for Bool"); - match accel { - QueryAccelerator::InvertedIndex(map) => { - assert!(map.contains_key(&AttributeValue::Bool(true))); - assert!(map.contains_key(&AttributeValue::Bool(false))); - } - _ => panic!("Expected InvertedIndex for Bool"), - } + let accel = accel + .as_any() + .downcast_ref::() + .expect("Expected InvertedIndexAccelerator"); + assert!(accel.map.contains_key(&AttributeValue::Bool(true))); + assert!(accel.map.contains_key(&AttributeValue::Bool(false))); // Integer let accel = compute_query_accelerator( @@ -888,13 +1053,12 @@ mod tests { &base, ) .expect("Should succeed for Integer"); - match accel { - QueryAccelerator::BTree(map) => { - assert!(map.contains_key(&super::OrderedFloat(42.0))); - assert!(map.contains_key(&super::OrderedFloat(7.0))); - } - _ => panic!("Expected BTree for Integer"), - } + let accel = accel + .as_any() + .downcast_ref::() + .expect("Expected BTreeAccelerator"); + assert!(accel.map.contains_key(&super::OrderedFloat(42.0))); + assert!(accel.map.contains_key(&super::OrderedFloat(7.0))); // Real let accel = compute_query_accelerator( @@ -904,13 +1068,12 @@ mod tests { &base, ) .expect("Should succeed for Real"); - match accel { - QueryAccelerator::BTree(map) => { - assert!(map.contains_key(&super::OrderedFloat(3.13))); - assert!(map.contains_key(&super::OrderedFloat(2.71))); - } - _ => panic!("Expected BTree for Real"), - } + let accel = accel + .as_any() + .downcast_ref::() + .expect("Expected BTreeAccelerator"); + assert!(accel.map.contains_key(&super::OrderedFloat(3.13))); + assert!(accel.map.contains_key(&super::OrderedFloat(2.71))); // Empty let err = From e14d2055b32e105d38883db17281b2d16eb89233 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Mon, 25 May 2026 21:34:20 +0000 Subject: [PATCH 33/34] wrap up tests, fmt, clippy --- diskann-tools/src/utils/compute_bitmap.rs | 216 ++++++++-------------- 1 file changed, 80 insertions(+), 136 deletions(-) diff --git a/diskann-tools/src/utils/compute_bitmap.rs b/diskann-tools/src/utils/compute_bitmap.rs index 20dbc8605..e69549f3c 100644 --- a/diskann-tools/src/utils/compute_bitmap.rs +++ b/diskann-tools/src/utils/compute_bitmap.rs @@ -1,35 +1,35 @@ - #[test] - fn test_compute_query_bitmap_not_with_missing_field() { - use serde_json::json; - // Three documents: two with "color", one without - let base_labels = vec![ - Document { - doc_id: 0, - label: json!({"color": "red"}), - }, - Document { - doc_id: 1, - label: json!({"color": "blue"}), - }, - Document { - doc_id: 2, - label: json!({"shape": "circle"}), // no color field - }, - ]; - - // Query: NOT color == "red" - let not_query = ASTExpr::Not(Box::new(ASTExpr::Compare { - field: "color".to_string(), - op: CompareOp::Eq(json!("red")), - })); - let queries = vec![(0, not_query)]; - let bitmaps = compute_query_bitmaps(base_labels.clone(), queries).expect("Should succeed"); - // Only doc 1 should match (has color and is not red) - assert!(bitmaps[0].contains(1)); - assert!(!bitmaps[0].contains(0)); - // Doc 2 does not have color, so should not be included in the NOT universe - assert!(!bitmaps[0].contains(2)); - } +#[test] +fn test_compute_query_bitmap_not_with_missing_field() { + use serde_json::json; + // Three documents: two with "color", one without + let base_labels = vec![ + Document { + doc_id: 0, + label: json!({"color": "red"}), + }, + Document { + doc_id: 1, + label: json!({"color": "blue"}), + }, + Document { + doc_id: 2, + label: json!({"shape": "circle"}), // no color field + }, + ]; + + // Query: NOT color == "red" + let not_query = ASTExpr::Not(Box::new(ASTExpr::Compare { + field: "color".to_string(), + op: CompareOp::Eq(json!("red")), + })); + let queries = vec![(0, not_query)]; + let bitmaps = compute_query_bitmaps(base_labels.clone(), queries).expect("Should succeed"); + // Only doc 1 should match (has color and is not red) + assert!(bitmaps[0].contains(1)); + assert!(!bitmaps[0].contains(0)); + // Doc 2 does not have color, so should not be included in the NOT universe + assert!(!bitmaps[0].contains(2)); +} /* * Copyright (c) Microsoft Corporation. * Licensed under the MIT license. @@ -223,16 +223,6 @@ impl QueryAccelerator for BTreeAccelerator { } } -fn check_for_nonaccelerated_operators(query_expr: &ASTExpr) -> bool { - match query_expr { - ASTExpr::Not(_) => true, - ASTExpr::And(subs) => subs.iter().any(check_for_nonaccelerated_operators), - ASTExpr::Or(subs) => subs.iter().any(check_for_nonaccelerated_operators), - ASTExpr::Compare { .. } => false, - } -} - - // Helper to prepend the separator if not present fn prepend_separator(field: &str) -> String { let separator = FlattenConfig::dot_notation().separator; @@ -254,8 +244,11 @@ fn compute_label_set(expr: &ASTExpr) -> Vec { } // Takes in a set of labels and returns the universe of all possible values for those labels -fn compute_universe(universe_labels: Vec, query_accelerators: &HashMap>) -> BitSet { - let mut universe_iter = universe_labels.iter(); +fn compute_universe( + universe_labels: Vec, + query_accelerators: &HashMap>, +) -> BitSet { + let mut universe_iter = universe_labels.iter(); // Initialize universe to the first accelerator's universe, then intersect with the rest let mut universe = if let Some(first_label) = universe_iter.next() { if let Some(accelerator) = query_accelerators.get(first_label) { @@ -271,7 +264,7 @@ fn compute_universe(universe_labels: Vec, query_accelerators: &HashMap) -> BitSet { @@ -310,7 +303,10 @@ fn eval_query_using_accelerators( ASTExpr::Not(sub) => { // compute the universe of all possible values let universe_labels_raw = compute_label_set(query_expr); - let universe_labels: Vec = universe_labels_raw.iter().map(|f| prepend_separator(f)).collect(); + let universe_labels: Vec = universe_labels_raw + .iter() + .map(|f| prepend_separator(f)) + .collect(); let universe = compute_universe(universe_labels, query_accelerators); // Evaluate the sub-expression @@ -318,7 +314,7 @@ fn eval_query_using_accelerators( // Return the difference between the sub-expression result and the universe Ok(universe.difference(&sub_result).collect()) - }, + } ASTExpr::Compare { field, op } => { let field = prepend_separator(field); if let Some(accelerator) = query_accelerators.get(&field) { @@ -434,26 +430,24 @@ pub fn compute_query_bitmaps( }) .collect(); - let flattened_base_label_hashmaps: Result< - Vec>, - anyhow::Error, - > = flattened_base_labels - .iter() - .map(|labels| { - let mut map = HashMap::new(); - for (key, value) in labels { - // a base label may not have two values for the same key - if let Some(_existing_value) = map.get(key) { - return Err(anyhow::anyhow!( - "Duplicate keys in the same document: {}", - key - )); + let flattened_base_label_hashmaps: Result>, anyhow::Error> = + flattened_base_labels + .iter() + .map(|labels| { + let mut map = HashMap::new(); + for (key, value) in labels { + // a base label may not have two values for the same key + if let Some(_existing_value) = map.get(key) { + return Err(anyhow::anyhow!( + "Duplicate keys in the same document: {}", + key + )); + } + map.insert(key.clone(), value.clone()); } - map.insert(key.clone(), value.clone()); - } - Ok(map) - }) - .collect(); + Ok(map) + }) + .collect(); let flattened_base_label_hashmaps = flattened_base_label_hashmaps?; let base_doc_ids: Vec = base_labels @@ -489,7 +483,9 @@ pub fn compute_query_bitmaps( }) .collect(); - Ok(query_bitmaps?) + let query_bitmaps = query_bitmaps?; + + Ok(query_bitmaps) } #[cfg(test)] @@ -507,12 +503,18 @@ mod tests { let query_accelerators: HashMap> = HashMap::new(); let universe_labels = vec!["missing_label".to_string()]; let result = compute_universe(universe_labels, &query_accelerators); - assert!(result.is_empty(), "Universe should be empty if label is missing"); + assert!( + result.is_empty(), + "Universe should be empty if label is missing" + ); // Sub-test 2: both accelerator types, non-empty intersection // InvertedIndexAccelerator for 'foo' with docs 1, 2 let mut inv_map = HashMap::new(); - inv_map.insert(AttributeValue::String("a".to_string()), [1, 2].iter().cloned().collect()); + inv_map.insert( + AttributeValue::String("a".to_string()), + [1, 2].iter().cloned().collect(), + ); let inv_accel = Box::new(InvertedIndexAccelerator { map: inv_map }); // BTreeAccelerator for 'bar' with docs 2, 3 @@ -528,7 +530,10 @@ mod tests { let universe_labels = vec!["foo".to_string(), "bar".to_string()]; let result = compute_universe(universe_labels, &query_accelerators); let expected: BitSet = [2].iter().cloned().collect(); - assert_eq!(result, expected, "Universe should be the intersection of both accelerator universes"); + assert_eq!( + result, expected, + "Universe should be the intersection of both accelerator universes" + ); } #[test] @@ -544,9 +549,9 @@ mod tests { op: CompareOp::Eq(json!(2)), }, ]); - let mut result_or = compute_label_set(&expr_or); - result_or.sort(); - assert_eq!(result_or, vec!["bar".to_string(), "foo".to_string()]); + let mut result_or = compute_label_set(&expr_or); + result_or.sort(); + assert_eq!(result_or, vec!["bar".to_string(), "foo".to_string()]); // NOT expression: NOT (baz == 3) let expr_not = ASTExpr::Not(Box::new(ASTExpr::Compare { @@ -970,7 +975,8 @@ mod tests { op: CompareOp::Eq(serde_json::json!("red")), })); let queries_with_not = vec![(0, not_query)]; - let bitmaps = compute_query_bitmaps(base_labels.clone(), queries_with_not).expect("Should succeed"); + let bitmaps = + compute_query_bitmaps(base_labels.clone(), queries_with_not).expect("Should succeed"); // The result should be a bitmap with doc 1 (not red) assert!(bitmaps[0].contains(1)); assert!(!bitmaps[0].contains(0)); @@ -1080,66 +1086,4 @@ mod tests { compute_query_accelerator("none".to_string(), AttributeValue::Empty, &doc_ids, &base); assert!(err.is_err()); } - - #[test] - fn test_check_for_nonaccelerated_operators() { - // Compare only (no NOT) - let expr = ASTExpr::Compare { - field: "foo".to_string(), - op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), - }; - assert!(!check_for_nonaccelerated_operators(&expr)); - - // NOT at root - let expr = ASTExpr::Not(Box::new(ASTExpr::Compare { - field: "foo".to_string(), - op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), - })); - assert!(check_for_nonaccelerated_operators(&expr)); - - // AND with NOT inside - let expr = ASTExpr::And(vec![ - ASTExpr::Compare { - field: "foo".to_string(), - op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), - }, - ASTExpr::Not(Box::new(ASTExpr::Compare { - field: "baz".to_string(), - op: CompareOp::Eq(serde_json::Value::String("qux".to_string())), - })), - ]); - assert!(check_for_nonaccelerated_operators(&expr)); - - // OR with only Compare - let expr = ASTExpr::Or(vec![ - ASTExpr::Compare { - field: "foo".to_string(), - op: CompareOp::Eq(serde_json::Value::String("bar".to_string())), - }, - ASTExpr::Compare { - field: "baz".to_string(), - op: CompareOp::Eq(serde_json::Value::String("qux".to_string())), - }, - ]); - assert!(!check_for_nonaccelerated_operators(&expr)); - - // Nested AND/OR with NOT deep inside - let expr = ASTExpr::And(vec![ - ASTExpr::Or(vec![ - ASTExpr::Compare { - field: "a".to_string(), - op: CompareOp::Eq(serde_json::Value::String("b".to_string())), - }, - ASTExpr::Not(Box::new(ASTExpr::Compare { - field: "c".to_string(), - op: CompareOp::Eq(serde_json::Value::String("d".to_string())), - })), - ]), - ASTExpr::Compare { - field: "e".to_string(), - op: CompareOp::Eq(serde_json::Value::String("f".to_string())), - }, - ]); - assert!(check_for_nonaccelerated_operators(&expr)); - } } From 3703b37151ec8c32661135926a8f69d418de2231 Mon Sep 17 00:00:00 2001 From: Magdalen Manohar Date: Mon, 25 May 2026 21:36:54 +0000 Subject: [PATCH 34/34] move test to test mod --- diskann-tools/src/utils/compute_bitmap.rs | 63 +++++++++++------------ 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/diskann-tools/src/utils/compute_bitmap.rs b/diskann-tools/src/utils/compute_bitmap.rs index e69549f3c..f94edff0a 100644 --- a/diskann-tools/src/utils/compute_bitmap.rs +++ b/diskann-tools/src/utils/compute_bitmap.rs @@ -1,35 +1,3 @@ -#[test] -fn test_compute_query_bitmap_not_with_missing_field() { - use serde_json::json; - // Three documents: two with "color", one without - let base_labels = vec![ - Document { - doc_id: 0, - label: json!({"color": "red"}), - }, - Document { - doc_id: 1, - label: json!({"color": "blue"}), - }, - Document { - doc_id: 2, - label: json!({"shape": "circle"}), // no color field - }, - ]; - - // Query: NOT color == "red" - let not_query = ASTExpr::Not(Box::new(ASTExpr::Compare { - field: "color".to_string(), - op: CompareOp::Eq(json!("red")), - })); - let queries = vec![(0, not_query)]; - let bitmaps = compute_query_bitmaps(base_labels.clone(), queries).expect("Should succeed"); - // Only doc 1 should match (has color and is not red) - assert!(bitmaps[0].contains(1)); - assert!(!bitmaps[0].contains(0)); - // Doc 2 does not have color, so should not be included in the NOT universe - assert!(!bitmaps[0].contains(2)); -} /* * Copyright (c) Microsoft Corporation. * Licensed under the MIT license. @@ -497,6 +465,37 @@ mod tests { use serde_json::json; use std::collections::HashMap; + fn test_compute_query_bitmap_not_with_missing_field() { + // Three documents: two with "color", one without + let base_labels = vec![ + Document { + doc_id: 0, + label: json!({"color": "red"}), + }, + Document { + doc_id: 1, + label: json!({"color": "blue"}), + }, + Document { + doc_id: 2, + label: json!({"shape": "circle"}), // no color field + }, + ]; + + // Query: NOT color == "red" + let not_query = ASTExpr::Not(Box::new(ASTExpr::Compare { + field: "color".to_string(), + op: CompareOp::Eq(json!("red")), + })); + let queries = vec![(0, not_query)]; + let bitmaps = compute_query_bitmaps(base_labels.clone(), queries).expect("Should succeed"); + // Only doc 1 should match (has color and is not red) + assert!(bitmaps[0].contains(1)); + assert!(!bitmaps[0].contains(0)); + // Doc 2 does not have color, so should not be included in the NOT universe + assert!(!bitmaps[0].contains(2)); + } + #[test] fn test_compute_universe_function() { // Sub-test 1: universe label not in query_accelerators, should return empty