1use std::io;
4use std::mem::size_of;
5
6use serde::{Deserialize, Serialize};
7
8use crate::directories::{FileHandle, OwnedBytes};
9use crate::dsl::DenseVectorQuantization;
10use crate::segment::format::{DOC_ID_ENTRY_SIZE, FLAT_BINARY_HEADER_SIZE, FLAT_BINARY_MAGIC};
11use crate::structures::simd::{batch_f32_to_f16, batch_f32_to_u8, f16_to_f32, u8_to_f32};
12
13#[inline]
19pub fn dequantize_raw(
20 raw: &[u8],
21 quant: DenseVectorQuantization,
22 num_floats: usize,
23 out: &mut [f32],
24) {
25 debug_assert!(out.len() >= num_floats);
26 match quant {
27 DenseVectorQuantization::F32 => {
28 debug_assert!(
29 (raw.as_ptr() as usize).is_multiple_of(std::mem::align_of::<f32>()),
30 "f32 vector data not 4-byte aligned"
31 );
32 out[..num_floats].copy_from_slice(unsafe {
33 std::slice::from_raw_parts(raw.as_ptr() as *const f32, num_floats)
34 });
35 }
36 DenseVectorQuantization::F16 => {
37 debug_assert!(
38 (raw.as_ptr() as usize).is_multiple_of(std::mem::align_of::<u16>()),
39 "f16 vector data not 2-byte aligned"
40 );
41 let f16_slice =
42 unsafe { std::slice::from_raw_parts(raw.as_ptr() as *const u16, num_floats) };
43 for (i, &h) in f16_slice.iter().enumerate() {
44 out[i] = f16_to_f32(h);
45 }
46 }
47 DenseVectorQuantization::UInt8 => {
48 for (i, &b) in raw.iter().enumerate().take(num_floats) {
49 out[i] = u8_to_f32(b);
50 }
51 }
52 }
53}
54
55pub struct FlatVectorData;
68
69impl FlatVectorData {
70 pub fn write_binary_header(
72 dim: usize,
73 num_vectors: usize,
74 quant: DenseVectorQuantization,
75 writer: &mut dyn std::io::Write,
76 ) -> std::io::Result<()> {
77 writer.write_all(&FLAT_BINARY_MAGIC.to_le_bytes())?;
78 writer.write_all(&(dim as u32).to_le_bytes())?;
79 writer.write_all(&(num_vectors as u32).to_le_bytes())?;
80 writer.write_all(&[quant.tag(), 0, 0, 0])?; Ok(())
82 }
83
84 pub fn serialized_binary_size(
86 dim: usize,
87 num_vectors: usize,
88 quant: DenseVectorQuantization,
89 ) -> usize {
90 FLAT_BINARY_HEADER_SIZE
91 + num_vectors * dim * quant.element_size()
92 + num_vectors * DOC_ID_ENTRY_SIZE
93 }
94
95 pub fn serialize_binary_from_flat_streaming(
100 dim: usize,
101 flat_vectors: &[f32],
102 doc_ids: &[(u32, u16)],
103 quant: DenseVectorQuantization,
104 writer: &mut dyn std::io::Write,
105 ) -> std::io::Result<()> {
106 let num_vectors = doc_ids.len();
107 Self::write_binary_header(dim, num_vectors, quant, writer)?;
108
109 match quant {
110 DenseVectorQuantization::F32 => {
111 let bytes: &[u8] = unsafe {
112 std::slice::from_raw_parts(
113 flat_vectors.as_ptr() as *const u8,
114 std::mem::size_of_val(flat_vectors),
115 )
116 };
117 writer.write_all(bytes)?;
118 }
119 DenseVectorQuantization::F16 => {
120 let mut buf = vec![0u16; dim];
121 for v in flat_vectors.chunks_exact(dim) {
122 batch_f32_to_f16(v, &mut buf);
123 let bytes: &[u8] =
124 unsafe { std::slice::from_raw_parts(buf.as_ptr() as *const u8, dim * 2) };
125 writer.write_all(bytes)?;
126 }
127 }
128 DenseVectorQuantization::UInt8 => {
129 let mut buf = vec![0u8; dim];
130 for v in flat_vectors.chunks_exact(dim) {
131 batch_f32_to_u8(v, &mut buf);
132 writer.write_all(&buf)?;
133 }
134 }
135 }
136
137 for &(doc_id, ordinal) in doc_ids {
138 writer.write_all(&doc_id.to_le_bytes())?;
139 writer.write_all(&ordinal.to_le_bytes())?;
140 }
141
142 Ok(())
143 }
144
145 pub fn write_raw_vector_bytes(
149 raw_bytes: &[u8],
150 writer: &mut dyn std::io::Write,
151 ) -> std::io::Result<()> {
152 writer.write_all(raw_bytes)
153 }
154}
155
156#[derive(Debug, Clone)]
168pub struct LazyFlatVectorData {
169 pub dim: usize,
171 pub num_vectors: usize,
173 pub quantization: DenseVectorQuantization,
175 doc_ids_bytes: OwnedBytes,
177 handle: FileHandle,
179 vectors_offset: u64,
181 element_size: usize,
183}
184
185impl LazyFlatVectorData {
186 pub async fn open(handle: FileHandle) -> io::Result<Self> {
191 let header = handle
193 .read_bytes_range(0..FLAT_BINARY_HEADER_SIZE as u64)
194 .await?;
195 let hdr = header.as_slice();
196
197 let magic = u32::from_le_bytes([hdr[0], hdr[1], hdr[2], hdr[3]]);
198 if magic != FLAT_BINARY_MAGIC {
199 return Err(io::Error::new(
200 io::ErrorKind::InvalidData,
201 "Invalid FlatVectorData binary magic",
202 ));
203 }
204
205 let dim = u32::from_le_bytes([hdr[4], hdr[5], hdr[6], hdr[7]]) as usize;
206 let num_vectors = u32::from_le_bytes([hdr[8], hdr[9], hdr[10], hdr[11]]) as usize;
207 let quantization = DenseVectorQuantization::from_tag(hdr[12]).ok_or_else(|| {
208 io::Error::new(
209 io::ErrorKind::InvalidData,
210 format!("Unknown quantization tag: {}", hdr[12]),
211 )
212 })?;
213 let element_size = quantization.element_size();
214
215 let vectors_byte_len = num_vectors * dim * element_size;
217 let doc_ids_start = (FLAT_BINARY_HEADER_SIZE + vectors_byte_len) as u64;
218 let doc_ids_byte_len = (num_vectors * DOC_ID_ENTRY_SIZE) as u64;
219
220 let doc_ids_bytes = handle
221 .read_bytes_range(doc_ids_start..doc_ids_start + doc_ids_byte_len)
222 .await?;
223
224 Ok(Self {
225 dim,
226 num_vectors,
227 quantization,
228 doc_ids_bytes,
229 handle,
230 vectors_offset: FLAT_BINARY_HEADER_SIZE as u64,
231 element_size,
232 })
233 }
234
235 pub async fn read_vector_into(&self, idx: usize, out: &mut [f32]) -> io::Result<()> {
240 debug_assert!(out.len() >= self.dim);
241 let vec_byte_len = self.dim * self.element_size;
242 let byte_offset = self.vectors_offset + (idx * vec_byte_len) as u64;
243 let bytes = self
244 .handle
245 .read_bytes_range(byte_offset..byte_offset + vec_byte_len as u64)
246 .await?;
247 let raw = bytes.as_slice();
248
249 dequantize_raw(raw, self.quantization, self.dim, out);
250 Ok(())
251 }
252
253 pub async fn get_vector(&self, idx: usize) -> io::Result<Vec<f32>> {
255 let mut vector = vec![0f32; self.dim];
256 self.read_vector_into(idx, &mut vector).await?;
257 Ok(vector)
258 }
259
260 pub async fn read_vector_raw_into(&self, idx: usize, out: &mut [u8]) -> io::Result<()> {
265 let vbs = self.vector_byte_size();
266 debug_assert!(out.len() >= vbs);
267 let byte_offset = self.vectors_offset + (idx * vbs) as u64;
268 let bytes = self
269 .handle
270 .read_bytes_range(byte_offset..byte_offset + vbs as u64)
271 .await?;
272 out[..vbs].copy_from_slice(bytes.as_slice());
273 Ok(())
274 }
275
276 pub async fn read_vectors_batch(
282 &self,
283 start_idx: usize,
284 count: usize,
285 ) -> io::Result<OwnedBytes> {
286 debug_assert!(start_idx + count <= self.num_vectors);
287 let vec_byte_len = self.dim * self.element_size;
288 let byte_offset = self.vectors_offset + (start_idx * vec_byte_len) as u64;
289 let byte_len = (count * vec_byte_len) as u64;
290 self.handle
291 .read_bytes_range(byte_offset..byte_offset + byte_len)
292 .await
293 }
294
295 #[cfg(feature = "sync")]
297 pub fn read_vector_raw_into_sync(&self, idx: usize, out: &mut [u8]) -> io::Result<()> {
298 let vbs = self.vector_byte_size();
299 debug_assert!(out.len() >= vbs);
300 let byte_offset = self.vectors_offset + (idx * vbs) as u64;
301 let bytes = self
302 .handle
303 .read_bytes_range_sync(byte_offset..byte_offset + vbs as u64)?;
304 out[..vbs].copy_from_slice(bytes.as_slice());
305 Ok(())
306 }
307
308 #[cfg(feature = "sync")]
310 pub fn read_vectors_batch_sync(
311 &self,
312 start_idx: usize,
313 count: usize,
314 ) -> io::Result<OwnedBytes> {
315 debug_assert!(start_idx + count <= self.num_vectors);
316 let vec_byte_len = self.dim * self.element_size;
317 let byte_offset = self.vectors_offset + (start_idx * vec_byte_len) as u64;
318 let byte_len = (count * vec_byte_len) as u64;
319 self.handle
320 .read_bytes_range_sync(byte_offset..byte_offset + byte_len)
321 }
322
323 pub fn flat_indexes_for_doc_range(&self, doc_id: u32) -> (usize, usize) {
329 let n = self.num_vectors;
330 let start = {
331 let mut lo = 0usize;
332 let mut hi = n;
333 while lo < hi {
334 let mid = lo + (hi - lo) / 2;
335 if self.doc_id_at(mid) < doc_id {
336 lo = mid + 1;
337 } else {
338 hi = mid;
339 }
340 }
341 lo
342 };
343 let mut count = 0;
344 let mut i = start;
345 while i < n && self.doc_id_at(i) == doc_id {
346 count += 1;
347 i += 1;
348 }
349 (start, count)
350 }
351
352 pub fn flat_indexes_for_doc(&self, doc_id: u32) -> (usize, Vec<(u32, u16)>) {
359 let n = self.num_vectors;
360 let start = {
362 let mut lo = 0usize;
363 let mut hi = n;
364 while lo < hi {
365 let mid = lo + (hi - lo) / 2;
366 if self.doc_id_at(mid) < doc_id {
367 lo = mid + 1;
368 } else {
369 hi = mid;
370 }
371 }
372 lo
373 };
374 let mut entries = Vec::new();
376 let mut i = start;
377 while i < n {
378 let (did, ord) = self.get_doc_id(i);
379 if did != doc_id {
380 break;
381 }
382 entries.push((did, ord));
383 i += 1;
384 }
385 (start, entries)
386 }
387
388 #[inline]
390 fn doc_id_at(&self, idx: usize) -> u32 {
391 let off = idx * DOC_ID_ENTRY_SIZE;
392 let d = &self.doc_ids_bytes[off..];
393 u32::from_le_bytes([d[0], d[1], d[2], d[3]])
394 }
395
396 #[inline]
398 pub fn get_doc_id(&self, idx: usize) -> (u32, u16) {
399 let off = idx * DOC_ID_ENTRY_SIZE;
400 let d = &self.doc_ids_bytes[off..];
401 let doc_id = u32::from_le_bytes([d[0], d[1], d[2], d[3]]);
402 let ordinal = u16::from_le_bytes([d[4], d[5]]);
403 (doc_id, ordinal)
404 }
405
406 #[inline]
408 pub fn vector_byte_size(&self) -> usize {
409 self.dim * self.element_size
410 }
411
412 pub fn vector_bytes_len(&self) -> u64 {
414 (self.num_vectors as u64) * (self.vector_byte_size() as u64)
415 }
416
417 pub fn vectors_byte_offset(&self) -> u64 {
419 self.vectors_offset
420 }
421
422 pub fn handle(&self) -> &FileHandle {
424 &self.handle
425 }
426
427 pub fn estimated_memory_bytes(&self) -> usize {
429 size_of::<Self>() + size_of::<OwnedBytes>()
430 }
431}
432
433#[derive(Debug, Clone, Serialize, Deserialize)]
438pub struct IVFRaBitQIndexData {
439 pub index: crate::structures::IVFRaBitQIndex,
440 pub codebook: crate::structures::RaBitQCodebook,
441}
442
443impl IVFRaBitQIndexData {
444 pub fn to_bytes(&self) -> std::io::Result<Vec<u8>> {
445 bincode::serde::encode_to_vec(self, bincode::config::standard())
446 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
447 }
448
449 pub fn from_bytes(data: &[u8]) -> std::io::Result<Self> {
450 bincode::serde::decode_from_slice(data, bincode::config::standard())
451 .map(|(v, _)| v)
452 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
453 }
454}
455
456#[derive(Debug, Clone, Serialize, Deserialize)]
461pub struct ScaNNIndexData {
462 pub index: crate::structures::IVFPQIndex,
463 pub codebook: crate::structures::PQCodebook,
464}
465
466impl ScaNNIndexData {
467 pub fn to_bytes(&self) -> std::io::Result<Vec<u8>> {
468 bincode::serde::encode_to_vec(self, bincode::config::standard())
469 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
470 }
471
472 pub fn from_bytes(data: &[u8]) -> std::io::Result<Self> {
473 bincode::serde::decode_from_slice(data, bincode::config::standard())
474 .map(|(v, _)| v)
475 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
476 }
477}