oxirs_vec/
vector_index.rs1use anyhow::Result;
4use std::collections::HashMap;
5
6use crate::similarity;
7use crate::Vector;
8use crate::VectorId;
9
10pub trait VectorIndex: Send + Sync {
12 fn insert(&mut self, uri: String, vector: Vector) -> Result<()>;
14
15 fn search_knn(&self, query: &Vector, k: usize) -> Result<Vec<(String, f32)>>;
17
18 fn search_threshold(&self, query: &Vector, threshold: f32) -> Result<Vec<(String, f32)>>;
20
21 fn get_vector(&self, uri: &str) -> Option<&Vector>;
23
24 fn add_vector(
26 &mut self,
27 id: VectorId,
28 vector: Vector,
29 _metadata: Option<HashMap<String, String>>,
30 ) -> Result<()> {
31 self.insert(id, vector)
33 }
34
35 fn update_vector(&mut self, id: VectorId, vector: Vector) -> Result<()> {
37 self.insert(id, vector)
39 }
40
41 fn update_metadata(&mut self, _id: VectorId, _metadata: HashMap<String, String>) -> Result<()> {
43 Ok(())
45 }
46
47 fn remove_vector(&mut self, _id: VectorId) -> Result<()> {
49 Ok(())
51 }
52
53 fn iter_vectors(&self) -> Vec<(String, Vector)> {
61 Vec::new()
62 }
63
64 fn supports_enumeration(&self) -> bool {
74 false
75 }
76}
77
78pub struct MemoryVectorIndex {
80 vectors: Vec<(String, Vector)>,
81 similarity_config: similarity::SimilarityConfig,
82}
83
84impl MemoryVectorIndex {
85 pub fn new() -> Self {
87 Self {
88 vectors: Vec::new(),
89 similarity_config: similarity::SimilarityConfig::default(),
90 }
91 }
92
93 pub fn with_similarity_config(config: similarity::SimilarityConfig) -> Self {
95 Self {
96 vectors: Vec::new(),
97 similarity_config: config,
98 }
99 }
100}
101
102impl Default for MemoryVectorIndex {
103 fn default() -> Self {
104 Self::new()
105 }
106}
107
108impl VectorIndex for MemoryVectorIndex {
109 fn insert(&mut self, uri: String, vector: Vector) -> Result<()> {
110 if let Some(pos) = self.vectors.iter().position(|(id, _)| id == &uri) {
112 self.vectors[pos] = (uri, vector);
113 } else {
114 self.vectors.push((uri, vector));
115 }
116 Ok(())
117 }
118
119 fn search_knn(&self, query: &Vector, k: usize) -> Result<Vec<(String, f32)>> {
120 let metric = self.similarity_config.primary_metric;
121 let query_f32 = query.as_f32();
122 let mut similarities: Vec<(String, f32)> = self
123 .vectors
124 .iter()
125 .map(|(uri, vec)| {
126 let vec_f32 = vec.as_f32();
127 let sim = metric.similarity(&query_f32, &vec_f32).unwrap_or(0.0);
128 (uri.clone(), sim)
129 })
130 .collect();
131
132 similarities.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
133 similarities.truncate(k);
134
135 Ok(similarities)
136 }
137
138 fn search_threshold(&self, query: &Vector, threshold: f32) -> Result<Vec<(String, f32)>> {
139 let metric = self.similarity_config.primary_metric;
140 let query_f32 = query.as_f32();
141 let similarities: Vec<(String, f32)> = self
142 .vectors
143 .iter()
144 .filter_map(|(uri, vec)| {
145 let vec_f32 = vec.as_f32();
146 let sim = metric.similarity(&query_f32, &vec_f32).unwrap_or(0.0);
147 if sim >= threshold {
148 Some((uri.clone(), sim))
149 } else {
150 None
151 }
152 })
153 .collect();
154
155 Ok(similarities)
156 }
157
158 fn get_vector(&self, uri: &str) -> Option<&Vector> {
159 self.vectors.iter().find(|(u, _)| u == uri).map(|(_, v)| v)
160 }
161
162 fn update_vector(&mut self, id: VectorId, vector: Vector) -> Result<()> {
163 if let Some(pos) = self.vectors.iter().position(|(uri, _)| uri == &id) {
164 self.vectors[pos] = (id, vector);
165 Ok(())
166 } else {
167 Err(anyhow::anyhow!("Vector with id '{}' not found", id))
168 }
169 }
170
171 fn remove_vector(&mut self, id: VectorId) -> Result<()> {
172 if let Some(pos) = self.vectors.iter().position(|(uri, _)| uri == &id) {
173 self.vectors.remove(pos);
174 Ok(())
175 } else {
176 Err(anyhow::anyhow!("Vector with id '{}' not found", id))
177 }
178 }
179
180 fn iter_vectors(&self) -> Vec<(String, Vector)> {
181 self.vectors.clone()
182 }
183
184 fn supports_enumeration(&self) -> bool {
185 true
186 }
187}