qdrant_edge/edge/update_only/batch/
mutation.rs1use crate::segment::common::operation_error::{OperationError, OperationResult};
5use crate::segment::data_types::fully_qualified_point::{FullyQualifiedPoint, StoredPoint};
6use crate::segment::data_types::named_vectors::NamedVectors;
7use crate::segment::data_types::segment_record::NamedVectorBytesOwned;
8use crate::segment::json_path::JsonPath;
9use crate::segment::types::{Payload, PayloadKeyType, PointIdType, SeqNumberType, VectorNameBuf};
10
11pub enum OperationVectors {
16 Decoded(NamedVectors<'static>),
17 Raw(NamedVectorBytesOwned),
18}
19
20pub enum PointMutation {
23 Replace {
26 vectors: OperationVectors,
27 payload: Payload,
28 },
29 Delete,
31 UpdateVectors(NamedVectors<'static>),
33 DeleteVectors(Vec<VectorNameBuf>),
35 SetPayload {
37 payload: Payload,
38 key: Option<JsonPath>,
39 },
40 OverwritePayload(Payload),
42 DeletePayload(Vec<PayloadKeyType>),
44 ClearPayload,
46}
47
48impl PointMutation {
49 fn discards_stored_point(&self) -> bool {
53 match self {
54 Self::Replace { .. } | Self::Delete => true,
55 Self::UpdateVectors(_)
56 | Self::DeleteVectors(_)
57 | Self::SetPayload { .. }
58 | Self::OverwritePayload(_)
59 | Self::DeletePayload(_)
60 | Self::ClearPayload => false,
61 }
62 }
63}
64
65pub struct PointUpdates {
67 version: SeqNumberType,
70 mutations: Vec<PointMutation>,
72}
73
74impl PointUpdates {
75 pub(super) fn new(version: SeqNumberType, mutation: PointMutation) -> Self {
76 Self {
77 version,
78 mutations: vec![mutation],
79 }
80 }
81
82 pub(super) fn push(&mut self, version: SeqNumberType, mutation: PointMutation) {
83 if mutation.discards_stored_point() {
84 self.mutations.clear();
85 }
86 self.version = self.version.max(version);
87 self.mutations.push(mutation);
88 }
89
90 pub fn version(&self) -> SeqNumberType {
92 self.version
93 }
94
95 pub fn needs_stored_point(&self) -> bool {
99 self.mutations
100 .first()
101 .is_none_or(|mutation| !mutation.discards_stored_point())
102 }
103
104 pub fn materialize(
111 self,
112 id: PointIdType,
113 stored: Option<StoredPoint>,
114 ) -> OperationResult<Option<FullyQualifiedPoint>> {
115 let Self { version, mutations } = self;
116
117 let mut exists = stored.is_some();
118 let (mut stored_vectors, mut payload) = match stored {
119 Some(stored) => {
120 let StoredPoint {
121 internal_id: _,
122 vectors,
123 payload,
124 } = stored;
125 (vectors, payload)
126 }
127 None => (NamedVectorBytesOwned::new(), Payload::default()),
128 };
129 let mut updated_vectors = NamedVectors::default();
133
134 for mutation in mutations {
135 match mutation {
136 PointMutation::Replace {
137 vectors,
138 payload: replacement,
139 } => {
140 exists = true;
141 stored_vectors.clear();
142 updated_vectors = NamedVectors::default();
143 match vectors {
144 OperationVectors::Decoded(vectors) => updated_vectors = vectors,
145 OperationVectors::Raw(vectors) => stored_vectors = vectors,
146 }
147 payload = replacement;
148 }
149 PointMutation::Delete => {
150 exists = false;
151 stored_vectors.clear();
152 updated_vectors = NamedVectors::default();
153 payload = Payload::default();
154 }
155 PointMutation::UpdateVectors(vectors) => {
156 if !exists {
157 return Err(OperationError::PointIdError {
158 missed_point_id: id,
159 });
160 }
161 updated_vectors.merge(vectors);
162 }
163 PointMutation::DeleteVectors(names) => {
164 for name in &names {
165 stored_vectors.retain(|(stored_name, _)| stored_name != name);
166 updated_vectors.remove_ref(name.as_str());
167 }
168 }
169 PointMutation::SetPayload {
170 payload: values,
171 key,
172 } => match key {
173 Some(key) => payload.merge_by_key(&values, &key),
174 None => payload.merge(&values),
175 },
176 PointMutation::OverwritePayload(values) => payload = values,
177 PointMutation::DeletePayload(keys) => {
178 for key in &keys {
179 payload.remove(key);
180 }
181 }
182 PointMutation::ClearPayload => payload = Payload::default(),
183 }
184 }
185
186 if !exists {
187 return Ok(None);
188 }
189
190 Ok(Some(FullyQualifiedPoint {
191 id,
192 version,
193 stored_vectors,
194 updated_vectors,
195 payload,
196 }))
197 }
198}