Submit a single synchronous read for `node_idx` and wait for it. Used as a fallback when `fetch_fp32` is called for a node that was never pre-fetched (e.g. the entry-point seed on first query).
(&mut self, node_idx: u32)
| 155 | /// Used as a fallback when `fetch_fp32` is called for a node that was |
| 156 | /// never pre-fetched (e.g. the entry-point seed on first query). |
| 157 | fn read_sync(&mut self, node_idx: u32) -> Option<Vec<f32>> { |
| 158 | let off = vector_offset(&self.layout, node_idx as u64); |
| 159 | let dim = self.layout.dim as usize; |
| 160 | let needed = dim * 4; |
| 161 | let buf_size = align_up(needed, ALIGNMENT); |
| 162 | |
| 163 | let mut buf = AlignedBuf::new(buf_size).ok()?; |
| 164 | let fd = io_uring::types::Fd(self.file.as_raw_fd()); |
| 165 | let op = io_uring::opcode::Read::new(fd, buf.as_mut_ptr(), buf_size as u32) |
| 166 | .offset(off) |
| 167 | .build() |
| 168 | .user_data(node_idx as u64); |
| 169 | |
| 170 | // SAFETY: `buf` outlives the SQE submission and the wait. |
| 171 | unsafe { |
| 172 | self.ring.submission().push(&op).ok()?; |
| 173 | } |
| 174 | self.ring.submit_and_wait(1).ok()?; |
| 175 | |
| 176 | let cqe = self.ring.completion().next()?; |
| 177 | if cqe.result() < needed as i32 { |
| 178 | return None; |
| 179 | } |
| 180 | |
| 181 | // SAFETY: io_uring wrote at least `needed` bytes into `buf`. |
| 182 | let floats = decode_f32_le(unsafe { buf.as_slice(needed) }, dim); |
| 183 | Some(floats) |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | impl NodeFetcher for IoUringNodeFetcher { |
no test coverage detected