uqa_storage/key_value/diskann/
source.rs1use std::sync::Arc;
8
9use uqa_core::memory::{BudgetedVec, MemoryReservation};
10
11use crate::diskann_index::format::{DiskANNGeneration, PAGE_BYTES};
12use crate::diskann_index::pages::{
13 DiskANNPageSource, DiskANNPageVisitor, DiskANNReadCapabilities, DiskANNRecordKey,
14 DiskANNRecordVisitor,
15};
16use crate::key_value::KeyValueRead;
17use crate::read_control::StorageReadControl;
18use crate::StorageBackendResult;
19
20use super::keys::{Key, Keys, Kind, ROOT};
21use super::state::{fixed, State, STATE_BYTES};
22use super::{
23 invalid, read_data_identity, validate_session, DiskANNStageStatus, KeyValueDiskANNStore,
24};
25
26mod owned;
27mod selection;
28
29pub(super) const KEY_PAGE_LIMIT: usize = 64;
30
31pub struct KeyValueDiskANNSource {
33 pub(in crate::key_value::diskann) read: Arc<dyn KeyValueRead + Send + Sync>,
34 generation: DiskANNGeneration,
35 query_control: Option<StorageReadControl>,
36 _memory: MemoryReservation,
37}
38
39impl KeyValueDiskANNSource {
40 pub fn origin_reader(
42 &self,
43 maximum: usize,
44 control: &StorageReadControl,
45 ) -> StorageBackendResult<crate::diskann_index::pages::DiskANNOriginReader> {
46 self.check(control)?;
47 let source = Self::from_read(
48 self.read.clone(),
49 self.generation,
50 DiskANNStageStatus::Sealed,
51 self.query_control.as_ref(),
52 control,
53 )?;
54 crate::diskann_index::pages::DiskANNOriginReader::open(source, maximum, control)
55 }
56
57 pub(super) fn capture(
58 repository: &KeyValueDiskANNStore,
59 generation: DiskANNGeneration,
60 status: DiskANNStageStatus,
61 control: &StorageReadControl,
62 ) -> StorageBackendResult<Arc<Self>> {
63 control.check()?;
64 let mut state = None;
65 {
66 let _writer = repository.owner.writer.lock();
67 repository.idle(control)?;
68 repository.owner.store.with_read_view(&mut |read| {
69 state = super::staging::load_state(read, generation, control)?;
70 Ok(())
71 })?;
72 }
73 let state = state.ok_or_else(|| invalid("generation state is missing"))?;
74 if state.status != status
75 && !(status == DiskANNStageStatus::Sealed && state.status.is_complete())
76 {
77 return Err(invalid(
78 "generation has not reached the requested physical state",
79 ));
80 }
81 let lease = if matches!(
82 state.status,
83 DiskANNStageStatus::Published
84 | DiskANNStageStatus::Retired
85 | DiskANNStageStatus::Discarding
86 ) {
87 None
88 } else if matches!(state.owner, super::state::StageOwner::Legacy(_)) {
89 repository.resume_stage(generation, control)?.lease
90 } else {
91 Some(
92 repository
93 .acquire_owner(
94 state.owner,
95 crate::mvcc::ResourceLeaseRequest::Share,
96 control,
97 )?
98 .ok_or_else(|| invalid("generation recovery is still in progress"))?,
99 )
100 };
101 let store = {
102 let _writer = repository.owner.writer.lock();
103 repository.idle(control)?;
104 let retained = repository
105 .owner
106 .store
107 .open_retained_read_session(control.cancellation())?;
108 validate_session(&*repository.owner.store, &*retained)?;
109 retained
110 };
111 let mut read = None;
112 store.with_read_view(&mut |view| {
113 read = Some(view.retain(&[ROOT])?);
114 Ok(())
115 })?;
116 let mut read = read.ok_or_else(|| invalid("source did not expose a read view"))?;
117 if let Some(lease) = lease {
118 read = owned::OwnedRead::retain(read, lease, control)?;
119 }
120 Self::from_read(read, generation, status, None, control)
121 }
122
123 fn from_read(
124 read: Arc<dyn KeyValueRead + Send + Sync>,
125 generation: DiskANNGeneration,
126 status: DiskANNStageStatus,
127 original: Option<&StorageReadControl>,
128 control: &StorageReadControl,
129 ) -> StorageBackendResult<Arc<Self>> {
130 if let Some(original) = original {
131 original.check()?;
132 }
133 read.control().check()?;
134 control.check()?;
135 let memory = control.memory().reserve(std::mem::size_of::<Self>())?;
136 if read_data_identity(&*read, control)? != Some(generation.database()) {
137 return Err(invalid("source belongs to another data identity"));
138 }
139 let key = Keys::new(generation).key(Kind::State);
140 let state = fixed(control, |visit| {
141 read.visit_value_bounded(key.as_ref(), STATE_BYTES, control, visit)
142 })?
143 .map(State::decode)
144 .transpose()?
145 .ok_or_else(|| invalid("generation state is missing"))?;
146 if state.status != status
147 && !(status == DiskANNStageStatus::Sealed && state.status.is_complete())
148 {
149 return Err(invalid(
150 "generation has not reached the requested physical state",
151 ));
152 }
153 control.check()?;
154 Ok(Arc::new(Self {
155 read,
156 generation,
157 query_control: original.cloned(),
158 _memory: memory,
159 }))
160 }
161
162 pub(super) fn keys_after(
163 &self,
164 after: Option<&[u8]>,
165 control: &StorageReadControl,
166 ) -> StorageBackendResult<BudgetedVec<(Key, Kind)>> {
167 self.check(control)?;
168 let result = key_page(
169 &*self.read,
170 Keys::new(self.generation),
171 after,
172 KEY_PAGE_LIMIT,
173 control,
174 )?;
175 self.check(control)?;
176 Ok(result)
177 }
178
179 pub(super) fn value(
180 &self,
181 kind: Kind,
182 maximum: usize,
183 control: &StorageReadControl,
184 visit: &mut DiskANNRecordVisitor<'_>,
185 ) -> StorageBackendResult<()> {
186 self.check(control)?;
187 let key = Keys::new(self.generation).key(kind);
188 let mut seen = false;
189 let mut failure = None;
190 let source = self
191 .read
192 .visit_value_bounded(key.as_ref(), maximum, control, &mut |value| {
193 if failure.is_some() {
194 return Err(invalid("record visitor already failed"));
195 }
196 let outcome = (|| {
197 if seen {
198 return Err(invalid("record was returned more than once"));
199 }
200 seen = true;
201 let bytes = value.ok_or_else(|| invalid("generation record is missing"))?;
202 control.check_value_size(bytes.len(), maximum)?;
203 visit(bytes)
204 })();
205 if let Err(error) = outcome {
206 failure = Some(error);
207 return Err(invalid("record visitor rejected data"));
208 }
209 Ok(())
210 });
211 if let Some(error) = failure {
212 return Err(error);
213 }
214 source?;
215 if !seen {
216 return Err(invalid("record was not returned"));
217 }
218 self.check(control)
219 }
220
221 pub(in crate::key_value::diskann) fn check(
222 &self,
223 control: &StorageReadControl,
224 ) -> StorageBackendResult<()> {
225 if let Some(original) = &self.query_control {
226 original.check()?;
227 }
228 self.read.control().check()?;
229 control.check()
230 }
231}
232
233impl DiskANNPageSource for KeyValueDiskANNSource {
234 fn generation(&self) -> DiskANNGeneration {
235 self.generation
236 }
237 fn capabilities(&self) -> DiskANNReadCapabilities {
238 DiskANNReadCapabilities::new(32, 1).expect("fixed sequential read capability")
239 }
240 fn read_record(
241 &self,
242 key: DiskANNRecordKey,
243 max_bytes: usize,
244 control: &StorageReadControl,
245 visit: &mut DiskANNRecordVisitor<'_>,
246 ) -> StorageBackendResult<()> {
247 self.value(Kind::Record(key), max_bytes, control, visit)
248 }
249 fn read_graph_pages(
250 &self,
251 pages: &[u64],
252 control: &StorageReadControl,
253 visit: &mut DiskANNPageVisitor<'_>,
254 ) -> StorageBackendResult<()> {
255 self.check(control)?;
256 if pages.len() > self.capabilities().max_batch_pages()
257 || pages
258 .iter()
259 .enumerate()
260 .any(|(index, id)| pages[..index].contains(id))
261 {
262 return Err(invalid(
263 "page request exceeds its batch bound or repeats a page",
264 ));
265 }
266 for &id in pages {
267 self.value(Kind::Graph(id), PAGE_BYTES, control, &mut |bytes| {
268 if bytes.len() != PAGE_BYTES {
269 return Err(invalid("graph page length differs"));
270 }
271 visit(id, bytes)
272 })?;
273 }
274 self.check(control)
275 }
276}
277
278pub(super) fn key_page(
280 read: &dyn KeyValueRead,
281 keys: Keys,
282 after: Option<&[u8]>,
283 limit: usize,
284 control: &StorageReadControl,
285) -> StorageBackendResult<BudgetedVec<(Key, Kind)>> {
286 control.check()?;
287 let mut page = BudgetedVec::<(Key, Kind)>::new(control.memory());
288 let mut failure = None;
289 let source = read.visit_keys_after(keys.prefix(), after, limit, control, &mut |bytes| {
290 if failure.is_some() {
291 return Err(invalid("key visitor already failed"));
292 }
293 let outcome = (|| {
294 control.check()?;
295 let previous = page.last().map(|(key, _)| key.as_ref()).or(after);
296 if page.len() >= limit || previous.is_some_and(|previous| previous >= bytes) {
297 return Err(invalid("key page exceeds its bound or ordering"));
298 }
299 let kind = keys.decode(bytes)?;
300 page.push((keys.key(kind), kind))?;
301 Ok(())
302 })();
303 if let Err(error) = outcome {
304 failure = Some(error);
305 return Err(invalid("key visitor rejected data"));
306 }
307 Ok(())
308 });
309 if let Some(error) = failure {
310 return Err(error);
311 }
312 source?;
313 control.check()?;
314 Ok(page)
315}