pub struct HnswService { /* private fields */ }Expand description
Kernel service wrapping the HNSW vector store.
All mutable access to the inner HnswStore is serialized through a
Mutex. Atomic counters track insert and search operations for
observability without requiring the lock.
Implementations§
Source§impl HnswService
impl HnswService
Sourcepub fn new(config: HnswServiceConfig) -> Self
pub fn new(config: HnswServiceConfig) -> Self
Create a new service with the given configuration.
Sourcepub fn from_store(config: HnswServiceConfig, store: HnswStore) -> Self
pub fn from_store(config: HnswServiceConfig, store: HnswStore) -> Self
Wrap an existing HnswStore (e.g. after loading a snapshot).
Counters and epoch start at zero; callers that restore backend-level
epoch (e.g. crate::vector_hnsw::HnswBackend) set it separately.
Sourcepub fn snapshot_entries(&self) -> Vec<HnswEntry>
pub fn snapshot_entries(&self) -> Vec<HnswEntry>
Snapshot all stored entries for composite backend persistence.
Sourcepub fn ef_params(&self) -> (usize, usize)
pub fn ef_params(&self) -> (usize, usize)
Current (ef_search, ef_construction) used by the inner store.
Sourcepub fn delete(&self, id: &str) -> bool
pub fn delete(&self, id: &str) -> bool
Hard-delete an entry by string id. Returns true if it was present.
Sourcepub fn with_eml(config: HnswServiceConfig, eml_config: HnswEmlConfig) -> Self
pub fn with_eml(config: HnswServiceConfig, eml_config: HnswEmlConfig) -> Self
Create a new service with custom EML configuration.
Sourcepub fn set_chain_manager(&mut self, cm: Arc<ChainManager>)
pub fn set_chain_manager(&mut self, cm: Arc<ChainManager>)
Set the chain manager for exochain event logging.
Sourcepub fn set_governance_engine(&mut self, engine: Arc<GovernanceEngine>)
pub fn set_governance_engine(&mut self, engine: Arc<GovernanceEngine>)
Set the governance engine for gating destructive operations.
Sourcepub fn insert(&self, id: String, embedding: Vec<f32>, metadata: Value)
pub fn insert(&self, id: String, embedding: Vec<f32>, metadata: Value)
Insert an embedding with associated metadata (upsert semantics).
Sourcepub fn current_epoch(&self) -> u64
pub fn current_epoch(&self) -> u64
Return the current monotonic epoch.
Sourcepub fn search(&self, query: &[f32], top_k: usize) -> Vec<HnswSearchResult>
pub fn search(&self, query: &[f32], top_k: usize) -> Vec<HnswSearchResult>
Search for the top_k nearest embeddings to query.
When EML is enabled and trained, the beam width (ef_search) is adapted per-query and the rebuild model is consulted after each search. When a region → entry-node path table is available (WEFT-385 / HNSW-EML #4), search is guided through predicted entry nodes. Training data is recorded for continuous learning.
Sourcepub fn rebuild_path_table(&self)
pub fn rebuild_path_table(&self)
Explicitly rebuild the region → entry-node path table from the current store contents (WEFT-385).
Sourcepub fn path_table_ready(&self) -> bool
pub fn path_table_ready(&self) -> bool
Whether guided path prediction is active.
Sourcepub fn brute_force_topk(&self, query: &[f32], top_k: usize) -> Vec<String>
pub fn brute_force_topk(&self, query: &[f32], top_k: usize) -> Vec<String>
Brute-force ground-truth search for recall measurement.
Sourcepub fn measure_recall(&self, queries: &[Vec<f32>], top_k: usize) -> f64
pub fn measure_recall(&self, queries: &[Vec<f32>], top_k: usize) -> f64
Measure recall against brute-force and feed the EML rebuild model.
Sourcepub fn build_tiered(&self, top_k: usize) -> TieredSearch
pub fn build_tiered(&self, top_k: usize) -> TieredSearch
Build a tiered index from the current store contents.
Uses the EML distance model’s learned dimension ordering when
available, falling back to the first N dimensions otherwise.
The returned TieredSearch owns separate coarse/full indexes.
Sourcepub fn eml_status(&self) -> HnswEmlStatus
pub fn eml_status(&self) -> HnswEmlStatus
Borrow the EML manager (for status/benchmarking).
Sourcepub fn search_batch(
&self,
queries: &[&[f32]],
top_k: usize,
) -> Vec<Vec<HnswSearchResult>>
pub fn search_batch( &self, queries: &[&[f32]], top_k: usize, ) -> Vec<Vec<HnswSearchResult>>
Batch search: acquire the lock once, perform all queries, release.
This avoids per-query mutex acquisition overhead when processing multiple embeddings in a single tick (e.g., DEMOCRITUS loop).
Sourcepub fn insert_multi_key(
&self,
primary_id: String,
keys: &[MultiKey],
metadata: Value,
max_keys: usize,
)
pub fn insert_multi_key( &self, primary_id: String, keys: &[MultiKey], metadata: Value, max_keys: usize, )
Insert an entity with multiple search keys.
Each key generates a separate embedding entry in the store, all
sharing the same primary_id prefix. The stored ID has the form
"{primary_id}::{key_type}". This allows the entity to be found
via different query formulations (name, context, description, etc.).
Keys beyond max_keys are silently dropped.
Sourcepub fn search_dedup(&self, query: &[f32], top_k: usize) -> Vec<HnswSearchResult>
pub fn search_dedup(&self, query: &[f32], top_k: usize) -> Vec<HnswSearchResult>
Search with deduplication by primary entity ID.
Because multi-key insertion stores several embeddings for one entity,
a single query may match multiple keys of the same entity. This
method searches for top_k * 3 candidates, deduplicates by
stripping the "::key_type" suffix, and returns up to top_k
unique entities. The best (highest) score among duplicates is kept.
Sourcepub fn insert_count(&self) -> u64
pub fn insert_count(&self) -> u64
Total number of insert operations since service creation.
Sourcepub fn search_count(&self) -> u64
pub fn search_count(&self) -> u64
Total number of search operations since service creation.
Sourcepub fn clear(&self) -> Result<(), String>
pub fn clear(&self) -> Result<(), String>
Replace the inner store with a fresh, empty instance.
Useful for calibration cleanup. Counters are not reset.
Returns Err if the governance engine denies the bulk destruction.
Sourcepub fn config(&self) -> &HnswServiceConfig
pub fn config(&self) -> &HnswServiceConfig
Borrow the service configuration.
Sourcepub fn save_to_file(&self, path: &Path) -> Result<(), Error>
pub fn save_to_file(&self, path: &Path) -> Result<(), Error>
Persist the HNSW store to a JSON file.
Delegates to the underlying HnswStore::save. The HNSW index
graph is not serialized; it will be rebuilt on load.
Sourcepub fn load_from_file(path: &Path) -> Result<Self, Error>
pub fn load_from_file(path: &Path) -> Result<Self, Error>
Load an HNSW store from a JSON file and create a new service.
Delegates to HnswStore::load. The HNSW index is rebuilt
from the saved entries. Counters start at zero.
Note: chain logging for hnsw.load requires calling
[set_chain_manager] after construction; use
[load_from_file_logged] when a chain manager is available.
Sourcepub fn load_from_file_logged(
path: &Path,
cm: Arc<ChainManager>,
) -> Result<Self, Error>
pub fn load_from_file_logged( path: &Path, cm: Arc<ChainManager>, ) -> Result<Self, Error>
Load an HNSW store from a JSON file with chain logging.
Same as [load_from_file] but emits an hnsw.load chain event.
Source§impl HnswService
impl HnswService
Sourcepub fn insert_relationship(
&self,
stable_id: &str,
embedding: Vec<f32>,
metadata: Value,
)
pub fn insert_relationship( &self, stable_id: &str, embedding: Vec<f32>, metadata: Value, )
Insert a relationship (edge) embedding under rel::{stable_id}.
Metadata should include at least kind: "relationship" and the
edge endpoints so consumers can reconstruct the hit without a
separate graph lookup.
Sourcepub fn search_relationships(
&self,
query: &[f32],
top_k: usize,
) -> Vec<HnswSearchResult>
pub fn search_relationships( &self, query: &[f32], top_k: usize, ) -> Vec<HnswSearchResult>
Search and keep only relationship-prefixed hits (rel::).
Oversamples the underlying store so entity vectors do not starve edge results when both share one HNSW index.
Trait Implementations§
Source§impl Debug for HnswService
impl Debug for HnswService
Source§impl SystemService for HnswService
impl SystemService for HnswService
Source§fn service_type(&self) -> ServiceType
fn service_type(&self) -> ServiceType
Source§fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn Error + Send + Sync>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn start<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn Error + Send + Sync>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn stop<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn Error + Send + Sync>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn stop<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn Error + Send + Sync>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn health_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = HealthStatus> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn health_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = HealthStatus> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn health_detail(&self) -> Option<String>
fn health_detail(&self) -> Option<String>
Source§fn liveness_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ProbeResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn liveness_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ProbeResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn readiness_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ProbeResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn readiness_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ProbeResult> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Auto Trait Implementations§
impl !Freeze for HnswService
impl RefUnwindSafe for HnswService
impl Send for HnswService
impl Sync for HnswService
impl Unpin for HnswService
impl UnsafeUnpin for HnswService
impl UnwindSafe for HnswService
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more