(
self,
index: &InvertedIndexRoot,
// 4, 5, 6
quantization_bits: u8,
values_upper_bound: f32,
early_terminate_threshold: f32,
reranking_factor:
| 67 | } |
| 68 | |
| 69 | pub fn sequential_search( |
| 70 | self, |
| 71 | index: &InvertedIndexRoot, |
| 72 | // 4, 5, 6 |
| 73 | quantization_bits: u8, |
| 74 | values_upper_bound: f32, |
| 75 | early_terminate_threshold: f32, |
| 76 | reranking_factor: usize, |
| 77 | k: Option<usize>, |
| 78 | ) -> Result<Vec<SparseAnnResult>, BufIoError> { |
| 79 | let mut dot_products = FxHashMap::default(); |
| 80 | // same as `1` quantized |
| 81 | let one_quantized = ((1u32 << quantization_bits) - 1) as u8; |
| 82 | let early_terminate_value = ((1u32 << quantization_bits) as f32 * early_terminate_threshold) |
| 83 | .min(u8::MAX as f32) as u8; |
| 84 | let low_threshold = (early_terminate_threshold * (1u32 << quantization_bits) as f32) as u32; |
| 85 | |
| 86 | let mut sorted_query_dims = self.query_vector.entries; |
| 87 | sorted_query_dims.sort_by(|(_, a), (_, b)| b.total_cmp(a)); |
| 88 | |
| 89 | // Iterate over the query vector dimensions |
| 90 | for &(dim_index, dim_value) in &sorted_query_dims { |
| 91 | let Some(node) = index.find_node(dim_index) else { |
| 92 | continue; |
| 93 | }; |
| 94 | let quantized_query_value = node.quantize(dim_value, values_upper_bound) as u32; |
| 95 | |
| 96 | if quantized_query_value > low_threshold { |
| 97 | // High quantized value |
| 98 | // Iterate through the full list of values for this dimension |
| 99 | for key in (0..=one_quantized).rev() { |
| 100 | unsafe { &*node.data } |
| 101 | .try_get_data(&index.cache)? |
| 102 | .map |
| 103 | .with_value(&key, |vec| { |
| 104 | for vec_id in vec.iter() { |
| 105 | let dot_product = dot_products.entry(vec_id).or_insert(0u32); |
| 106 | *dot_product += quantized_query_value * key as u32; |
| 107 | } |
| 108 | }); |
| 109 | } |
| 110 | } else { |
| 111 | // Low quantized value |
| 112 | // Iterate through the map/list ONLY for until a certain threshold (say 3/4th) |
| 113 | // of quantized keys (i.e. 48..64 for 6 bit quantization). |
| 114 | |
| 115 | for key in (early_terminate_value..=one_quantized).rev() { |
| 116 | unsafe { &*node.data } |
| 117 | .try_get_data(&index.cache)? |
| 118 | .map |
| 119 | .with_value(&key, |vec| { |
| 120 | for vec_id in vec.iter() { |
| 121 | let dot_product = dot_products.entry(vec_id).or_insert(0u32); |
| 122 | *dot_product += quantized_query_value * key as u32; |
| 123 | } |
| 124 | }); |
| 125 | } |
| 126 | } |
no test coverage detected