MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / prefetch_batch

Method prefetch_batch

nodedb/src/data/vamana_fetcher.rs:197–243  ·  view source on GitHub ↗

Submit `IORING_OP_READ` SQEs for each index in `indices`. Indices that are already completed (from a prior prefetch), already in-flight, or cannot get a pool buffer are silently skipped — `fetch_fp32` will handle them via a sync fallback.

(&mut self, indices: &[u32])

Source from the content-addressed store, hash-verified

195 /// in-flight, or cannot get a pool buffer are silently skipped —
196 /// `fetch_fp32` will handle them via a sync fallback.
197 fn prefetch_batch(&mut self, indices: &[u32]) {
198 // Drain any already-completed CQEs to free pool slots.
199 self.drain_completions();
200
201 let dim = self.layout.dim as usize;
202 let needed = dim * 4;
203 let buf_size = align_up(needed, ALIGNMENT);
204 let fd = io_uring::types::Fd(self.file.as_raw_fd());
205
206 for &node_idx in indices {
207 // Skip: already completed, already in-flight.
208 if self.completed.contains_key(&node_idx) || self.pending.contains_key(&node_idx) {
209 continue;
210 }
211 // Skip: no free buffer.
212 let Some(slot) = self.free_bufs.pop() else {
213 continue;
214 };
215 // Grow pool buffer to required size if needed (shouldn't happen
216 // since pool is sized at open, but guard against it).
217 if self.buf_pool[slot].capacity() < buf_size {
218 self.free_bufs.push(slot);
219 continue;
220 }
221
222 let off = vector_offset(&self.layout, node_idx as u64);
223 let op =
224 io_uring::opcode::Read::new(fd, self.buf_pool[slot].as_mut_ptr(), buf_size as u32)
225 .offset(off)
226 .build()
227 .user_data(node_idx as u64);
228
229 // SAFETY: buf_pool[slot] outlives the SQE and completion.
230 // `self.pending` keeps the slot reserved until drain.
231 let pushed = unsafe { self.ring.submission().push(&op).is_ok() };
232 if pushed {
233 self.pending.insert(node_idx, slot);
234 self.in_flight += 1;
235 } else {
236 // SQ full — return the slot.
237 self.free_bufs.push(slot);
238 }
239 }
240
241 // Flush the submission queue to the kernel without waiting.
242 let _ = self.ring.submit();
243 }
244
245 fn fetch_fp32(&mut self, idx: u32) -> Option<Vec<f32>> {
246 // Drain any completions that arrived since last prefetch/fetch.

Callers 1

Calls 12

align_upFunction · 0.85
vector_offsetFunction · 0.85
drain_completionsMethod · 0.80
is_okMethod · 0.80
as_raw_fdMethod · 0.45
capacityMethod · 0.45
pushMethod · 0.45
buildMethod · 0.45
offsetMethod · 0.45
as_mut_ptrMethod · 0.45
insertMethod · 0.45
submitMethod · 0.45

Tested by 1