Skip to main content

uqa_storage/read_only_snapshot/
vectors.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7use std::sync::Arc;
8
9use uqa_core::{DocId, PostingList};
10
11use crate::read_control::StorageReadControl;
12use crate::{StorageBackendResult, VectorIndex};
13
14use super::{read_only_error, ReadOnlySnapshot};
15
16impl<T: VectorIndex + ?Sized> ReadOnlySnapshot<T> {
17    /// Select query control for an already captured physical value. Cache owners bind each returned reader separately; nested readers preserve the first selected allowance and cancellation token.
18    pub fn with_vector_read_control(
19        mut self,
20        control: &StorageReadControl,
21    ) -> StorageBackendResult<Self> {
22        control.check()?;
23        if self.2.is_none() {
24            self.2 = Some(control.clone());
25        }
26        Ok(self)
27    }
28}
29
30impl<T: VectorIndex + ?Sized + 'static> VectorIndex for ReadOnlySnapshot<T> {
31    fn dimensions(&self) -> u32 {
32        self.0.dimensions()
33    }
34
35    fn index_kind(&self) -> &'static str {
36        self.0.index_kind()
37    }
38
39    fn add(&mut self, _doc_id: DocId, _vector: Vec<f32>) -> StorageBackendResult<()> {
40        Err(read_only_error())
41    }
42
43    fn add_many(&mut self, _doc_id: DocId, _vectors: Vec<Vec<f32>>) -> StorageBackendResult<()> {
44        Err(read_only_error())
45    }
46
47    fn delete(&mut self, _doc_id: DocId) -> StorageBackendResult<()> {
48        Err(read_only_error())
49    }
50
51    fn clear(&mut self) -> StorageBackendResult<()> {
52        Err(read_only_error())
53    }
54
55    fn search_knn(&self, query: &[f32], k: usize) -> StorageBackendResult<PostingList> {
56        match &self.2 {
57            Some(control) => self.0.search_knn_with_control(query, k, control),
58            None => self.0.search_knn(query, k),
59        }
60    }
61
62    fn search_threshold(&self, query: &[f32], threshold: f32) -> StorageBackendResult<PostingList> {
63        match &self.2 {
64            Some(control) => self
65                .0
66                .search_threshold_with_control(query, threshold, control),
67            None => self.0.search_threshold(query, threshold),
68        }
69    }
70
71    fn search_knn_with_control(
72        &self,
73        query: &[f32],
74        k: usize,
75        control: &StorageReadControl,
76    ) -> StorageBackendResult<PostingList> {
77        control.check()?;
78        if self.2.is_some() {
79            self.search_knn(query, k)
80        } else {
81            self.0.search_knn_with_control(query, k, control)
82        }
83    }
84
85    fn search_threshold_with_control(
86        &self,
87        query: &[f32],
88        threshold: f32,
89        control: &StorageReadControl,
90    ) -> StorageBackendResult<PostingList> {
91        control.check()?;
92        if self.2.is_some() {
93            self.search_threshold(query, threshold)
94        } else {
95            self.0
96                .search_threshold_with_control(query, threshold, control)
97        }
98    }
99
100    fn count(&self) -> StorageBackendResult<usize> {
101        if let Some(control) = &self.2 {
102            control.check()?;
103        }
104        self.0.count()
105    }
106
107    fn contains_document(&self, doc_id: DocId) -> StorageBackendResult<bool> {
108        if let Some(control) = &self.2 {
109            control.check()?;
110        }
111        self.0.contains_document(doc_id)
112    }
113
114    fn initialize(&mut self) -> StorageBackendResult<()> {
115        Err(read_only_error())
116    }
117
118    fn snapshot(&self) -> StorageBackendResult<Arc<dyn VectorIndex>> {
119        Ok(Arc::new(self.clone()))
120    }
121
122    fn snapshot_with_control(
123        &self,
124        control: &crate::read_control::StorageReadControl,
125    ) -> StorageBackendResult<Arc<dyn VectorIndex>> {
126        control.check()?;
127        if self.1.is_some() || self.2.is_some() {
128            return self.clone().with_vector_read_control(control)?.snapshot();
129        }
130        Ok(Arc::new(ReadOnlySnapshot::new(
131            self.0.snapshot_with_control(control)?,
132        )))
133    }
134}