Skip to main content

faiss_next/
result.rs

1use crate::idx::Idx;
2
3#[derive(Debug, Clone)]
4pub struct SearchResult {
5    pub distances: Vec<f32>,
6    pub labels: Vec<Idx>,
7}
8
9impl SearchResult {
10    pub fn new(distances: Vec<f32>, labels: Vec<Idx>) -> Self {
11        Self { distances, labels }
12    }
13
14    pub fn len(&self) -> usize {
15        self.labels.len()
16    }
17
18    pub fn is_empty(&self) -> bool {
19        self.labels.is_empty()
20    }
21
22    pub fn n_queries(&self) -> usize {
23        if self.labels.is_empty() {
24            0
25        } else {
26            self.distances.len() / self.labels.len() * self.labels.len()
27        }
28    }
29
30    pub fn iter(&self) -> impl Iterator<Item = (Idx, f32)> + '_ {
31        self.labels
32            .iter()
33            .copied()
34            .zip(self.distances.iter().copied())
35    }
36
37    pub fn labels(&self) -> impl Iterator<Item = Option<u64>> + '_ {
38        self.labels.iter().map(|&l| l.get())
39    }
40
41    pub fn get(&self, query_idx: usize, k: usize) -> Option<(Vec<Idx>, Vec<f32>)> {
42        let start = query_idx * k;
43        let end = start + k;
44        if end <= self.labels.len() && end <= self.distances.len() {
45            Some((
46                self.labels[start..end].to_vec(),
47                self.distances[start..end].to_vec(),
48            ))
49        } else {
50            None
51        }
52    }
53
54    pub fn first_label(&self) -> Option<u64> {
55        self.labels.first().and_then(|&l| l.get())
56    }
57
58    pub fn first_distance(&self) -> Option<f32> {
59        self.distances.first().copied()
60    }
61}
62
63#[derive(Debug, Clone)]
64pub struct RangeSearchResult {
65    pub labels: Vec<Idx>,
66    pub distances: Vec<f32>,
67    pub lims: Vec<usize>,
68}
69
70impl RangeSearchResult {
71    pub fn new(labels: Vec<Idx>, distances: Vec<f32>, lims: Vec<usize>) -> Self {
72        Self {
73            labels,
74            distances,
75            lims,
76        }
77    }
78
79    pub fn n_queries(&self) -> usize {
80        self.lims.len().saturating_sub(1)
81    }
82
83    pub fn total_results(&self) -> usize {
84        self.labels.len()
85    }
86
87    pub fn get(&self, query_idx: usize) -> Option<(Vec<Idx>, Vec<f32>)> {
88        let start = *self.lims.get(query_idx)?;
89        let end = *self.lims.get(query_idx + 1)?;
90        Some((
91            self.labels[start..end].to_vec(),
92            self.distances[start..end].to_vec(),
93        ))
94    }
95
96    pub fn iter(&self) -> RangeSearchResultIter<'_> {
97        RangeSearchResultIter {
98            result: self,
99            query_idx: 0,
100        }
101    }
102}
103
104pub struct RangeSearchResultIter<'a> {
105    result: &'a RangeSearchResult,
106    query_idx: usize,
107}
108
109impl<'a> Iterator for RangeSearchResultIter<'a> {
110    type Item = (Vec<Idx>, Vec<f32>);
111
112    fn next(&mut self) -> Option<Self::Item> {
113        let result = self.result.get(self.query_idx)?;
114        self.query_idx += 1;
115        Some(result)
116    }
117}
118
119#[derive(Debug, Clone)]
120pub struct BinarySearchResult {
121    pub distances: Vec<i32>,
122    pub labels: Vec<Idx>,
123}
124
125impl BinarySearchResult {
126    pub fn new(distances: Vec<i32>, labels: Vec<Idx>) -> Self {
127        Self { distances, labels }
128    }
129
130    pub fn len(&self) -> usize {
131        self.labels.len()
132    }
133
134    pub fn is_empty(&self) -> bool {
135        self.labels.is_empty()
136    }
137
138    pub fn iter(&self) -> impl Iterator<Item = (Idx, i32)> + '_ {
139        self.labels
140            .iter()
141            .copied()
142            .zip(self.distances.iter().copied())
143    }
144
145    pub fn get(&self, query_idx: usize, k: usize) -> Option<(Vec<Idx>, Vec<i32>)> {
146        let start = query_idx * k;
147        let end = start + k;
148        if end <= self.labels.len() && end <= self.distances.len() {
149            Some((
150                self.labels[start..end].to_vec(),
151                self.distances[start..end].to_vec(),
152            ))
153        } else {
154            None
155        }
156    }
157}