Build SQ8 quantized data for an HNSW index. Returns `None` when there are too few live vectors for stable min/max calibration.
(index: &HnswIndex)
| 50 | /// Returns `None` when there are too few live vectors for stable |
| 51 | /// min/max calibration. |
| 52 | pub fn build_sq8_for_index(index: &HnswIndex) -> Option<(Sq8Codec, Vec<u8>)> { |
| 53 | if index.live_count() < 1000 { |
| 54 | return None; |
| 55 | } |
| 56 | let dim = index.dim(); |
| 57 | let n = index.len(); |
| 58 | |
| 59 | let mut refs: Vec<&[f32]> = Vec::with_capacity(n); |
| 60 | for i in 0..n { |
| 61 | if !index.is_deleted(i as u32) |
| 62 | && let Some(v) = index.get_vector(i as u32) |
| 63 | { |
| 64 | refs.push(v); |
| 65 | } |
| 66 | } |
| 67 | if refs.is_empty() { |
| 68 | return None; |
| 69 | } |
| 70 | |
| 71 | let codec = Sq8Codec::calibrate(&refs, dim); |
| 72 | |
| 73 | let mut data = Vec::with_capacity(dim * n); |
| 74 | for i in 0..n { |
| 75 | if let Some(v) = index.get_vector(i as u32) { |
| 76 | data.extend(codec.quantize(v)); |
| 77 | } else { |
| 78 | data.extend(vec![0u8; dim]); |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | Some((codec, data)) |
| 83 | } |
| 84 | |
| 85 | /// Train a PQ codec from a built HNSW index's live vectors. |
| 86 | pub fn build_pq_for_index(index: &HnswIndex, pq_m: usize) -> Option<(PqCodec, Vec<u8>)> { |
nothing calls this directly
no test coverage detected