(
&mut self,
query_vector: &[f32; VECTOR_SIZE],
filters: &Filter,
top_k: usize,
)
| 20 | } |
| 21 | |
| 22 | pub fn query( |
| 23 | &mut self, |
| 24 | query_vector: &[f32; VECTOR_SIZE], |
| 25 | filters: &Filter, |
| 26 | top_k: usize, |
| 27 | ) -> io::Result<Vec<Vec<KVPair>>> { |
| 28 | let quantized_query_vector = quantize(query_vector); |
| 29 | |
| 30 | let (indices, ids) = |
| 31 | Filters::evaluate(filters, &mut self.state.inverted_index).get_indices(); |
| 32 | |
| 33 | // group contiguous indices to batch get vectors |
| 34 | |
| 35 | let mut batch_indices: Vec<Vec<usize>> = Vec::new(); |
| 36 | |
| 37 | let mut current_batch = Vec::new(); |
| 38 | |
| 39 | for index in indices { |
| 40 | if current_batch.len() == 0 { |
| 41 | current_batch.push(index); |
| 42 | } else { |
| 43 | let last_index = current_batch[current_batch.len() - 1]; |
| 44 | if index == last_index + 1 { |
| 45 | current_batch.push(index); |
| 46 | } else { |
| 47 | batch_indices.push(current_batch); |
| 48 | current_batch = Vec::new(); |
| 49 | current_batch.push(index); |
| 50 | } |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | current_batch.sort(); |
| 55 | current_batch.dedup(); |
| 56 | |
| 57 | if current_batch.len() > 0 { |
| 58 | batch_indices.push(current_batch); |
| 59 | } |
| 60 | |
| 61 | // println!("BATCH INDICES: {:?}", batch_indices.len()); |
| 62 | |
| 63 | let mut top_k_indices = Vec::new(); |
| 64 | |
| 65 | let top_k_to_use = top_k.min(ids.len()); |
| 66 | |
| 67 | for batch in batch_indices { |
| 68 | let vectors = self.state.vectors.get_contiguous(batch[0], batch.len())?; |
| 69 | top_k_indices.extend( |
| 70 | vectors |
| 71 | .par_iter() |
| 72 | .enumerate() |
| 73 | .fold( |
| 74 | || Vec::new(), |
| 75 | |mut acc, (idx, vector)| { |
| 76 | let distance = hamming_distance(&quantized_query_vector, vector); |
| 77 | |
| 78 | if acc.len() < top_k_to_use { |
| 79 | acc.push((ids[idx], distance)); |
no test coverage detected