Skip to main content

uqa_storage/sqlite/vector_index/hnsw/
lifecycle.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! `VectorIndex` lifecycle implementation for persistent HNSW.
8
9use std::sync::Arc;
10
11use uqa_core::{DocId, PostingList};
12
13use super::SQLiteHNSWIndex;
14use crate::vector_index::VectorIndex;
15use crate::StorageBackendResult;
16
17impl VectorIndex for SQLiteHNSWIndex {
18    fn dimensions(&self) -> u32 {
19        self.persistent.dimensions
20    }
21
22    fn index_kind(&self) -> &'static str {
23        "hnsw"
24    }
25
26    fn add(&mut self, doc_id: DocId, vector: Vec<f32>) -> StorageBackendResult<()> {
27        self.add_many(doc_id, vec![vector])
28    }
29
30    fn add_many(&mut self, doc_id: DocId, vectors: Vec<Vec<f32>>) -> StorageBackendResult<()> {
31        self.replace_document(doc_id, vectors)
32    }
33
34    fn delete(&mut self, doc_id: DocId) -> StorageBackendResult<()> {
35        self.delete_document(doc_id)
36    }
37
38    fn clear(&mut self) -> StorageBackendResult<()> {
39        self.clear_graph()
40    }
41
42    fn search_knn(&self, query: &[f32], k: usize) -> StorageBackendResult<PostingList> {
43        self.search_top_k(query, k)
44    }
45
46    fn search_threshold(&self, query: &[f32], threshold: f32) -> StorageBackendResult<PostingList> {
47        self.persistent.search_threshold(query, threshold)
48    }
49
50    fn count(&self) -> StorageBackendResult<usize> {
51        self.persistent.count()
52    }
53
54    fn initialize(&mut self) -> StorageBackendResult<()> {
55        self.initialize_graph()
56    }
57
58    fn snapshot(&self) -> StorageBackendResult<Arc<dyn VectorIndex>> {
59        if let Some(revision) = self.persisted_revision()? {
60            Ok(self.cached_graph_for_revision(revision)?)
61        } else if self.require_persisted_graph {
62            Err(super::mutation::missing_metadata(self))
63        } else {
64            self.persistent.snapshot()
65        }
66    }
67}