Skip to main content

uqa_storage/vector_index/retained/
canonical.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Borrow the existing retained corpus without copying its directory or coordinates at capture.
8
9use super::RetainedVectorIndex;
10use crate::{read_control::StorageReadControl, vector_index::VectorRead, StorageBackendResult};
11use uqa_core::{memory::BudgetedVec, DocId};
12
13impl VectorRead for RetainedVectorIndex {
14    fn corpus_fingerprint(
15        &self,
16        control: &StorageReadControl,
17    ) -> StorageBackendResult<Option<[u8; 32]>> {
18        self.check_control(control)?;
19        Ok(Some(self.fingerprint))
20    }
21    fn check_control(&self, control: &StorageReadControl) -> StorageBackendResult<()> {
22        self.control.check()?;
23        control.check()
24    }
25    fn dimensions(&self) -> u32 {
26        self.dimensions
27    }
28    fn next_document_after(
29        &self,
30        after: Option<DocId>,
31        control: &StorageReadControl,
32    ) -> StorageBackendResult<Option<DocId>> {
33        self.check_control(control)?;
34        let offset = self
35            .entries
36            .partition_point(|entry| after.is_some_and(|after| entry.0 <= after));
37        Ok(self.entries.get(offset).map(|entry| entry.0))
38    }
39    fn document_vector_count(
40        &self,
41        document: DocId,
42        control: &StorageReadControl,
43    ) -> StorageBackendResult<u64> {
44        self.check_control(control)?;
45        let start = self.entries.partition_point(|entry| entry.0 < document);
46        let end = self.entries.partition_point(|entry| entry.0 <= document);
47        Ok((end - start) as u64)
48    }
49    fn read_vector(
50        &self,
51        document: DocId,
52        ordinal: u32,
53        control: &StorageReadControl,
54    ) -> StorageBackendResult<Option<BudgetedVec<f32>>> {
55        self.check_control(control)?;
56        let Ok(position) = self
57            .entries
58            .binary_search_by_key(&(document, ordinal), |entry| (entry.0, entry.1))
59        else {
60            return Ok(None);
61        };
62        let mut vector = BudgetedVec::new(control.memory());
63        vector.reserve(self.entries[position].2.len())?;
64        for chunk in self.entries[position].2.chunks(1024) {
65            self.check_control(control)?;
66            vector.extend_from_slice(chunk)?;
67        }
68        self.check_control(control)?;
69        Ok(Some(vector))
70    }
71}