nodedb_fts/index/writer/state.rs
1// SPDX-License-Identifier: Apache-2.0
2
3//! Index state, construction, and backend access.
4
5use crate::{
6 backend::FtsBackend,
7 lsm::memtable::{Memtable, MemtableConfig},
8 posting::Bm25Params,
9};
10use nodedb_mem::MemoryGovernor;
11use std::sync::{Arc, atomic::AtomicU64};
12
13/// Full-text search index generic over storage backend.
14///
15/// Indexing, search, and highlighting use the [`FtsBackend`] storage contract.
16///
17/// Writes accumulate in an in-memory `Memtable`, one state per index.
18/// Threshold-triggered flushing writes each index's postings to an
19/// immutable segment of that index through the backend.
20/// Queries merge the active memtable with stored segments.
21/// The backend determines segment durability.
22///
23/// [`MemoryGovernor`] enforces per-engine memory budgets on large
24/// allocations (compaction, segment merge, query term collection).
25pub struct FtsIndex<B: FtsBackend> {
26 pub(crate) backend: B,
27 pub(crate) bm25_params: Bm25Params,
28 pub(crate) memtable: Memtable,
29 /// Monotonic segment ID counter.
30 pub(super) next_segment_id: AtomicU64,
31 /// Memory governor for budget enforcement.
32 pub(crate) governor: Arc<MemoryGovernor>,
33}
34
35impl<B: FtsBackend> FtsIndex<B> {
36 /// Create a new FTS index with the given backend, default BM25 params, and a memory governor.
37 pub fn new(backend: B, governor: Arc<MemoryGovernor>) -> Self {
38 Self {
39 backend,
40 bm25_params: Bm25Params::default(),
41 memtable: Memtable::new(MemtableConfig::default()),
42 next_segment_id: AtomicU64::new(1),
43 governor,
44 }
45 }
46
47 /// Create a new FTS index with custom BM25 parameters and a memory governor.
48 pub fn with_params(backend: B, params: Bm25Params, governor: Arc<MemoryGovernor>) -> Self {
49 Self {
50 bm25_params: params,
51 ..Self::new(backend, governor)
52 }
53 }
54
55 /// Create a new FTS index whose memtable spills at `memtable` thresholds.
56 /// Unreachable thresholds keep every posting in the memtable.
57 pub fn with_memtable_config(
58 backend: B,
59 memtable: MemtableConfig,
60 governor: Arc<MemoryGovernor>,
61 ) -> Self {
62 Self {
63 memtable: Memtable::new(memtable),
64 ..Self::new(backend, governor)
65 }
66 }
67
68 /// Create a new FTS index with custom BM25 parameters whose memtable
69 /// spills at `memtable` thresholds.
70 pub fn with_config(
71 backend: B,
72 params: Bm25Params,
73 memtable: MemtableConfig,
74 governor: Arc<MemoryGovernor>,
75 ) -> Self {
76 Self {
77 bm25_params: params,
78 memtable: Memtable::new(memtable),
79 ..Self::new(backend, governor)
80 }
81 }
82
83 /// Access the underlying backend.
84 pub fn backend(&self) -> &B {
85 &self.backend
86 }
87
88 /// Mutable access to the underlying backend.
89 pub fn backend_mut(&mut self) -> &mut B {
90 &mut self.backend
91 }
92
93 /// Access the active memtable (for LSM query merging).
94 pub fn memtable(&self) -> &Memtable {
95 &self.memtable
96 }
97}