weavatrix_search_vector/mutable/
mutations.rs1use super::support::{
2 current_vector, key_exists, prepare_records, prepare_vector, replace_metadata,
3};
4use super::{MutableVectorIndex, MutationOutcome, VectorRecord};
5use crate::error::SearchError;
6use crate::metadata::Metadata;
7
8impl MutableVectorIndex {
9 pub fn insert(&self, key: u64, vector: &[f32], metadata: Metadata) -> Result<(), SearchError> {
16 let normalized = prepare_vector(self.config.dimensions, self.config.metric, vector)?;
17 let mut state = self
18 .state
19 .write()
20 .unwrap_or_else(std::sync::PoisonError::into_inner);
21 if key_exists(&state, key) {
22 return Err(SearchError::DuplicateKey(key));
23 }
24 state.deleted.remove(&key);
25 state.pending.insert(key, normalized);
26 replace_metadata(&mut state.metadata, key, metadata);
27 state.generation = state.generation.wrapping_add(1);
28 Ok(())
29 }
30
31 pub fn upsert(
37 &self,
38 key: u64,
39 vector: &[f32],
40 metadata: Metadata,
41 ) -> Result<MutationOutcome, SearchError> {
42 let normalized = prepare_vector(self.config.dimensions, self.config.metric, vector)?;
43 let mut state = self
44 .state
45 .write()
46 .unwrap_or_else(std::sync::PoisonError::into_inner);
47 let outcome = if key_exists(&state, key) {
48 MutationOutcome::Updated
49 } else {
50 MutationOutcome::Inserted
51 };
52 state.deleted.remove(&key);
53 state.pending.insert(key, normalized);
54 replace_metadata(&mut state.metadata, key, metadata);
55 state.generation = state.generation.wrapping_add(1);
56 Ok(outcome)
57 }
58
59 pub fn insert_batch(&self, records: &[VectorRecord]) -> Result<(), SearchError> {
66 let prepared = prepare_records(&self.config, records)?;
67 let mut state = self
68 .state
69 .write()
70 .unwrap_or_else(std::sync::PoisonError::into_inner);
71 for (key, _, _) in &prepared {
72 if key_exists(&state, *key) {
73 return Err(SearchError::DuplicateKey(*key));
74 }
75 }
76 for (key, vector, metadata) in prepared {
77 state.deleted.remove(&key);
78 state.pending.insert(key, vector);
79 replace_metadata(&mut state.metadata, key, metadata);
80 }
81 state.generation = state.generation.wrapping_add(1);
82 Ok(())
83 }
84
85 pub fn upsert_batch(
94 &self,
95 records: &[VectorRecord],
96 ) -> Result<Vec<MutationOutcome>, SearchError> {
97 let prepared = prepare_records(&self.config, records)?;
98 let mut state = self
99 .state
100 .write()
101 .unwrap_or_else(std::sync::PoisonError::into_inner);
102 let outcomes = prepared
103 .iter()
104 .map(|(key, _, _)| {
105 if key_exists(&state, *key) {
106 MutationOutcome::Updated
107 } else {
108 MutationOutcome::Inserted
109 }
110 })
111 .collect::<Vec<_>>();
112 for (key, vector, metadata) in prepared {
113 state.deleted.remove(&key);
114 state.pending.insert(key, vector);
115 replace_metadata(&mut state.metadata, key, metadata);
116 }
117 state.generation = state.generation.wrapping_add(1);
118 Ok(outcomes)
119 }
120
121 pub fn delete(&self, key: u64) -> bool {
123 let mut state = self
124 .state
125 .write()
126 .unwrap_or_else(std::sync::PoisonError::into_inner);
127 if !key_exists(&state, key) {
128 return false;
129 }
130 state.pending.remove(&key);
131 if state.base.vector(key).is_some()
132 || state
133 .sealed
134 .as_ref()
135 .is_some_and(|index| index.vector(key).is_some())
136 {
137 state.deleted.insert(key);
138 }
139 state.metadata.remove(key);
140 state.generation = state.generation.wrapping_add(1);
141 true
142 }
143
144 pub fn delete_batch(&self, keys: &[u64]) -> usize {
146 let mut state = self
147 .state
148 .write()
149 .unwrap_or_else(std::sync::PoisonError::into_inner);
150 let mut removed = 0;
151 for key in keys {
152 if !key_exists(&state, *key) {
153 continue;
154 }
155 state.pending.remove(key);
156 if state.base.vector(*key).is_some()
157 || state
158 .sealed
159 .as_ref()
160 .is_some_and(|index| index.vector(*key).is_some())
161 {
162 state.deleted.insert(*key);
163 }
164 state.metadata.remove(*key);
165 removed += 1;
166 }
167 if removed != 0 {
168 state.generation = state.generation.wrapping_add(1);
169 }
170 removed
171 }
172
173 pub fn rename(&self, from: u64, to: u64) -> Result<bool, SearchError> {
179 if from == to {
180 let state = self
181 .state
182 .read()
183 .unwrap_or_else(std::sync::PoisonError::into_inner);
184 return Ok(key_exists(&state, from));
185 }
186 let mut state = self
187 .state
188 .write()
189 .unwrap_or_else(std::sync::PoisonError::into_inner);
190 if !key_exists(&state, from) {
191 return Ok(false);
192 }
193 if key_exists(&state, to) {
194 return Err(SearchError::DuplicateKey(to));
195 }
196 let vector = current_vector(&state, from)
197 .ok_or(SearchError::MissingKey(from))?
198 .to_vec();
199 let metadata = state.metadata.remove(from);
200 state.pending.remove(&from);
201 if state.base.vector(from).is_some()
202 || state
203 .sealed
204 .as_ref()
205 .is_some_and(|index| index.vector(from).is_some())
206 {
207 state.deleted.insert(from);
208 }
209 state.deleted.remove(&to);
210 state.pending.insert(to, vector);
211 if let Some(metadata) = metadata {
212 state.metadata.insert(to, metadata);
213 }
214 state.generation = state.generation.wrapping_add(1);
215 Ok(true)
216 }
217
218 pub fn set_metadata(&self, key: u64, metadata: Metadata) -> Result<(), SearchError> {
224 let mut state = self
225 .state
226 .write()
227 .unwrap_or_else(std::sync::PoisonError::into_inner);
228 if !key_exists(&state, key) {
229 return Err(SearchError::MissingKey(key));
230 }
231 replace_metadata(&mut state.metadata, key, metadata);
232 state.generation = state.generation.wrapping_add(1);
233 Ok(())
234 }
235
236 #[must_use]
237 pub fn metadata(&self, key: u64) -> Option<Metadata> {
238 let state = self
239 .state
240 .read()
241 .unwrap_or_else(std::sync::PoisonError::into_inner);
242 state.metadata.get(key).cloned()
243 }
244}