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 DenseVectorQuantization::Binary => {
53 for (i, &b) in raw.iter().enumerate().take(num_floats) {
56 out[i] = b as f32;
57 }
58 }
59 }
60}
61
62pub struct FlatVectorData;
75
76impl FlatVectorData {
77 pub fn write_binary_header(
79 dim: usize,
80 num_vectors: usize,
81 quant: DenseVectorQuantization,
82 writer: &mut dyn std::io::Write,
83 ) -> std::io::Result<()> {
84 writer.write_all(&FLAT_BINARY_MAGIC.to_le_bytes())?;
85 writer.write_all(&(dim as u32).to_le_bytes())?;
86 writer.write_all(&(num_vectors as u32).to_le_bytes())?;
87 writer.write_all(&[quant.tag(), 0, 0, 0])?; Ok(())
89 }
90
91 pub fn serialized_binary_size(
93 dim: usize,
94 num_vectors: usize,
95 quant: DenseVectorQuantization,
96 ) -> usize {
97 let bytes_per_vector = match quant {
98 DenseVectorQuantization::Binary => dim.div_ceil(8),
99 _ => dim * quant.element_size(),
100 };
101 FLAT_BINARY_HEADER_SIZE + num_vectors * bytes_per_vector + num_vectors * DOC_ID_ENTRY_SIZE
102 }
103
104 pub fn serialize_binary_from_flat_streaming(
109 dim: usize,
110 flat_vectors: &[f32],
111 doc_ids: &[(u32, u16)],
112 quant: DenseVectorQuantization,
113 writer: &mut dyn std::io::Write,
114 ) -> std::io::Result<()> {
115 let num_vectors = doc_ids.len();
116 Self::write_binary_header(dim, num_vectors, quant, writer)?;
117
118 match quant {
119 DenseVectorQuantization::F32 => {
120 let bytes: &[u8] = unsafe {
121 std::slice::from_raw_parts(
122 flat_vectors.as_ptr() as *const u8,
123 std::mem::size_of_val(flat_vectors),
124 )
125 };
126 writer.write_all(bytes)?;
127 }
128 DenseVectorQuantization::F16 => {
129 let mut buf = vec![0u16; dim];
130 for v in flat_vectors.chunks_exact(dim) {
131 batch_f32_to_f16(v, &mut buf);
132 let bytes: &[u8] =
133 unsafe { std::slice::from_raw_parts(buf.as_ptr() as *const u8, dim * 2) };
134 writer.write_all(bytes)?;
135 }
136 }
137 DenseVectorQuantization::UInt8 => {
138 let mut buf = vec![0u8; dim];
139 for v in flat_vectors.chunks_exact(dim) {
140 batch_f32_to_u8(v, &mut buf);
141 writer.write_all(&buf)?;
142 }
143 }
144 DenseVectorQuantization::Binary => {
145 unreachable!("Binary quantization should use serialize_binary_from_bits_streaming");
147 }
148 }
149
150 for &(doc_id, ordinal) in doc_ids {
151 writer.write_all(&doc_id.to_le_bytes())?;
152 writer.write_all(&ordinal.to_le_bytes())?;
153 }
154
155 Ok(())
156 }
157
158 pub fn serialize_binary_from_bits_streaming(
163 dim_bits: usize,
164 packed_vectors: &[u8],
165 doc_ids: &[(u32, u16)],
166 writer: &mut dyn std::io::Write,
167 ) -> std::io::Result<()> {
168 let num_vectors = doc_ids.len();
169 let byte_len = dim_bits.div_ceil(8);
170 debug_assert_eq!(packed_vectors.len(), num_vectors * byte_len);
171
172 Self::write_binary_header(
173 dim_bits,
174 num_vectors,
175 DenseVectorQuantization::Binary,
176 writer,
177 )?;
178 writer.write_all(packed_vectors)?;
179
180 for &(doc_id, ordinal) in doc_ids {
181 writer.write_all(&doc_id.to_le_bytes())?;
182 writer.write_all(&ordinal.to_le_bytes())?;
183 }
184
185 Ok(())
186 }
187
188 pub fn write_raw_vector_bytes(
192 raw_bytes: &[u8],
193 writer: &mut dyn std::io::Write,
194 ) -> std::io::Result<()> {
195 writer.write_all(raw_bytes)
196 }
197}
198
199#[derive(Debug, Clone)]
211pub struct LazyFlatVectorData {
212 pub dim: usize,
214 pub num_vectors: usize,
216 pub quantization: DenseVectorQuantization,
218 doc_ids_bytes: OwnedBytes,
220 handle: FileHandle,
222 vectors_offset: u64,
224 vbs: usize,
226}
227
228impl LazyFlatVectorData {
229 pub async fn open(handle: FileHandle) -> io::Result<Self> {
234 let header = handle
236 .read_bytes_range(0..FLAT_BINARY_HEADER_SIZE as u64)
237 .await?;
238 let hdr = header.as_slice();
239
240 let magic = u32::from_le_bytes([hdr[0], hdr[1], hdr[2], hdr[3]]);
241 if magic != FLAT_BINARY_MAGIC {
242 return Err(io::Error::new(
243 io::ErrorKind::InvalidData,
244 "Invalid FlatVectorData binary magic",
245 ));
246 }
247
248 let dim = u32::from_le_bytes([hdr[4], hdr[5], hdr[6], hdr[7]]) as usize;
249 let num_vectors = u32::from_le_bytes([hdr[8], hdr[9], hdr[10], hdr[11]]) as usize;
250 let quantization = DenseVectorQuantization::from_tag(hdr[12]).ok_or_else(|| {
251 io::Error::new(
252 io::ErrorKind::InvalidData,
253 format!("Unknown quantization tag: {}", hdr[12]),
254 )
255 })?;
256 let vbs = if quantization == DenseVectorQuantization::Binary {
258 dim.div_ceil(8)
259 } else {
260 dim * quantization.element_size()
261 };
262 let vectors_byte_len = num_vectors * vbs;
263 let doc_ids_start = (FLAT_BINARY_HEADER_SIZE + vectors_byte_len) as u64;
264 let doc_ids_byte_len = (num_vectors * DOC_ID_ENTRY_SIZE) as u64;
265
266 let doc_ids_bytes = handle
267 .read_bytes_range(doc_ids_start..doc_ids_start + doc_ids_byte_len)
268 .await?;
269
270 Ok(Self {
271 dim,
272 num_vectors,
273 quantization,
274 doc_ids_bytes,
275 handle,
276 vectors_offset: FLAT_BINARY_HEADER_SIZE as u64,
277 vbs,
278 })
279 }
280
281 pub async fn read_vector_into(&self, idx: usize, out: &mut [f32]) -> io::Result<()> {
286 debug_assert!(out.len() >= self.dim);
287 let vbs = self.vector_byte_size();
288 let byte_offset = self.vectors_offset + (idx * vbs) as u64;
289 let bytes = self
290 .handle
291 .read_bytes_range(byte_offset..byte_offset + vbs as u64)
292 .await?;
293 let raw = bytes.as_slice();
294
295 dequantize_raw(raw, self.quantization, self.dim, out);
296 Ok(())
297 }
298
299 pub async fn get_vector(&self, idx: usize) -> io::Result<Vec<f32>> {
301 let mut vector = vec![0f32; self.dim];
302 self.read_vector_into(idx, &mut vector).await?;
303 Ok(vector)
304 }
305
306 pub async fn read_vector_raw_into(&self, idx: usize, out: &mut [u8]) -> io::Result<()> {
311 let vbs = self.vector_byte_size();
312 debug_assert!(out.len() >= vbs);
313 let byte_offset = self.vectors_offset + (idx * vbs) as u64;
314 let bytes = self
315 .handle
316 .read_bytes_range(byte_offset..byte_offset + vbs as u64)
317 .await?;
318 out[..vbs].copy_from_slice(bytes.as_slice());
319 Ok(())
320 }
321
322 pub async fn read_vectors_batch(
328 &self,
329 start_idx: usize,
330 count: usize,
331 ) -> io::Result<OwnedBytes> {
332 debug_assert!(start_idx + count <= self.num_vectors);
333 let vbs = self.vector_byte_size();
334 let byte_offset = self.vectors_offset + (start_idx * vbs) as u64;
335 let byte_len = (count * vbs) as u64;
336 self.handle
337 .read_bytes_range(byte_offset..byte_offset + byte_len)
338 .await
339 }
340
341 #[cfg(feature = "sync")]
343 pub fn read_vector_raw_into_sync(&self, idx: usize, out: &mut [u8]) -> io::Result<()> {
344 let vbs = self.vector_byte_size();
345 debug_assert!(out.len() >= vbs);
346 let byte_offset = self.vectors_offset + (idx * vbs) as u64;
347 let bytes = self
348 .handle
349 .read_bytes_range_sync(byte_offset..byte_offset + vbs as u64)?;
350 out[..vbs].copy_from_slice(bytes.as_slice());
351 Ok(())
352 }
353
354 #[cfg(feature = "sync")]
356 pub fn read_vectors_batch_sync(
357 &self,
358 start_idx: usize,
359 count: usize,
360 ) -> io::Result<OwnedBytes> {
361 debug_assert!(start_idx + count <= self.num_vectors);
362 let vbs = self.vector_byte_size();
363 let byte_offset = self.vectors_offset + (start_idx * vbs) as u64;
364 let byte_len = (count * vbs) as u64;
365 self.handle
366 .read_bytes_range_sync(byte_offset..byte_offset + byte_len)
367 }
368
369 pub fn flat_indexes_for_doc_range(&self, doc_id: u32) -> (usize, usize) {
375 let n = self.num_vectors;
376 let start = {
377 let mut lo = 0usize;
378 let mut hi = n;
379 while lo < hi {
380 let mid = lo + (hi - lo) / 2;
381 if self.doc_id_at(mid) < doc_id {
382 lo = mid + 1;
383 } else {
384 hi = mid;
385 }
386 }
387 lo
388 };
389 let mut count = 0;
390 let mut i = start;
391 while i < n && self.doc_id_at(i) == doc_id {
392 count += 1;
393 i += 1;
394 }
395 (start, count)
396 }
397
398 pub fn flat_indexes_for_doc(&self, doc_id: u32) -> (usize, Vec<(u32, u16)>) {
405 let n = self.num_vectors;
406 let start = {
408 let mut lo = 0usize;
409 let mut hi = n;
410 while lo < hi {
411 let mid = lo + (hi - lo) / 2;
412 if self.doc_id_at(mid) < doc_id {
413 lo = mid + 1;
414 } else {
415 hi = mid;
416 }
417 }
418 lo
419 };
420 let mut entries = Vec::new();
422 let mut i = start;
423 while i < n {
424 let (did, ord) = self.get_doc_id(i);
425 if did != doc_id {
426 break;
427 }
428 entries.push((did, ord));
429 i += 1;
430 }
431 (start, entries)
432 }
433
434 #[inline]
436 fn doc_id_at(&self, idx: usize) -> u32 {
437 let off = idx * DOC_ID_ENTRY_SIZE;
438 let d = &self.doc_ids_bytes[off..];
439 u32::from_le_bytes([d[0], d[1], d[2], d[3]])
440 }
441
442 #[inline]
444 pub fn get_doc_id(&self, idx: usize) -> (u32, u16) {
445 let off = idx * DOC_ID_ENTRY_SIZE;
446 let d = &self.doc_ids_bytes[off..];
447 let doc_id = u32::from_le_bytes([d[0], d[1], d[2], d[3]]);
448 let ordinal = u16::from_le_bytes([d[4], d[5]]);
449 (doc_id, ordinal)
450 }
451
452 #[inline]
454 pub fn vector_byte_size(&self) -> usize {
455 self.vbs
456 }
457
458 pub fn vector_bytes_len(&self) -> u64 {
460 (self.num_vectors as u64) * (self.vector_byte_size() as u64)
461 }
462
463 pub fn vectors_byte_offset(&self) -> u64 {
465 self.vectors_offset
466 }
467
468 pub fn handle(&self) -> &FileHandle {
470 &self.handle
471 }
472
473 pub fn estimated_memory_bytes(&self) -> usize {
475 size_of::<Self>() + size_of::<OwnedBytes>()
476 }
477}
478
479#[derive(Debug, Clone, Serialize, Deserialize)]
484pub struct IVFRaBitQIndexData {
485 pub index: crate::structures::IVFRaBitQIndex,
486 pub codebook: crate::structures::RaBitQCodebook,
487}
488
489impl IVFRaBitQIndexData {
490 pub fn to_bytes(&self) -> std::io::Result<Vec<u8>> {
491 bincode::serde::encode_to_vec(self, bincode::config::standard())
492 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
493 }
494
495 pub fn from_bytes(data: &[u8]) -> std::io::Result<Self> {
496 bincode::serde::decode_from_slice(data, bincode::config::standard())
497 .map(|(v, _)| v)
498 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
499 }
500}
501
502#[derive(Debug, Clone, Serialize, Deserialize)]
507pub struct ScaNNIndexData {
508 pub index: crate::structures::IVFPQIndex,
509 pub codebook: crate::structures::PQCodebook,
510}
511
512impl ScaNNIndexData {
513 pub fn to_bytes(&self) -> std::io::Result<Vec<u8>> {
514 bincode::serde::encode_to_vec(self, bincode::config::standard())
515 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
516 }
517
518 pub fn from_bytes(data: &[u8]) -> std::io::Result<Self> {
519 bincode::serde::decode_from_slice(data, bincode::config::standard())
520 .map(|(v, _)| v)
521 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
522 }
523}