Skip to main content

nodedb_fts/backend/
traits.rs

1use crate::posting::Posting;
2
3/// Storage backend abstraction for the full-text search engine.
4///
5/// Origin implements this with redb (persistent). Lite implements with
6/// in-memory HashMap. All scoring, BMW, compression, and analysis logic
7/// works identically over any backend.
8///
9/// Write methods take `&self` (not `&mut self`) because:
10/// - Redb provides transactional isolation internally — concurrent writes
11///   are safe through redb's MVCC.
12/// - MemoryBackend uses interior mutability (`RefCell`) to match the same
13///   trait signature, keeping the trait uniform.
14pub trait FtsBackend {
15    /// Error type for backend operations.
16    type Error: std::fmt::Display;
17
18    /// Read the posting list for a term in a collection.
19    fn read_postings(&self, collection: &str, term: &str) -> Result<Vec<Posting>, Self::Error>;
20
21    /// Write/replace the posting list for a term in a collection.
22    fn write_postings(
23        &self,
24        collection: &str,
25        term: &str,
26        postings: &[Posting],
27    ) -> Result<(), Self::Error>;
28
29    /// Remove a term's posting list entirely.
30    fn remove_postings(&self, collection: &str, term: &str) -> Result<(), Self::Error>;
31
32    /// Read the document length (token count) for a document.
33    fn read_doc_length(&self, collection: &str, doc_id: &str) -> Result<Option<u32>, Self::Error>;
34
35    /// Write/replace the document length for a document.
36    fn write_doc_length(
37        &self,
38        collection: &str,
39        doc_id: &str,
40        length: u32,
41    ) -> Result<(), Self::Error>;
42
43    /// Remove a document's length entry.
44    fn remove_doc_length(&self, collection: &str, doc_id: &str) -> Result<(), Self::Error>;
45
46    /// Get all term keys for a collection (for fuzzy matching).
47    /// Returns terms without the collection prefix.
48    fn collection_terms(&self, collection: &str) -> Result<Vec<String>, Self::Error>;
49
50    /// Get total document count and sum of all document lengths for a collection.
51    /// Returns `(doc_count, total_token_sum)`.
52    ///
53    /// Implementations should maintain these incrementally for O(1) lookup.
54    fn collection_stats(&self, collection: &str) -> Result<(u32, u64), Self::Error>;
55
56    /// Increment collection stats after indexing a document.
57    /// `doc_len` is the number of tokens in the newly indexed document.
58    fn increment_stats(&self, collection: &str, doc_len: u32) -> Result<(), Self::Error>;
59
60    /// Decrement collection stats after removing a document.
61    /// `doc_len` is the token count of the removed document.
62    fn decrement_stats(&self, collection: &str, doc_len: u32) -> Result<(), Self::Error>;
63
64    /// Read a metadata blob by key (e.g., "docmap:{collection}", "fieldnorms:{collection}").
65    fn read_meta(&self, key: &str) -> Result<Option<Vec<u8>>, Self::Error>;
66
67    /// Write a metadata blob by key.
68    fn write_meta(&self, key: &str, value: &[u8]) -> Result<(), Self::Error>;
69
70    /// Write a segment blob. Key format: "{collection}:seg:{segment_id}".
71    fn write_segment(&self, key: &str, data: &[u8]) -> Result<(), Self::Error>;
72
73    /// Read a segment blob. Returns None if not found.
74    fn read_segment(&self, key: &str) -> Result<Option<Vec<u8>>, Self::Error>;
75
76    /// List all segment keys for a collection (prefix "{collection}:seg:").
77    fn list_segments(&self, collection: &str) -> Result<Vec<String>, Self::Error>;
78
79    /// Remove a segment blob.
80    fn remove_segment(&self, key: &str) -> Result<(), Self::Error>;
81
82    /// Remove all entries for a collection prefix. Returns count of removed entries.
83    fn purge_collection(&self, collection: &str) -> Result<usize, Self::Error>;
84}