pub trait FreshnessStorage: Send + Sync {
// Required methods
fn register_source<'life0, 'async_trait>(
&'life0 self,
session_id: Uuid,
reference: SourceReference,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn check_freshness<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
entry_id: &'life1 str,
file_hash: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = Result<FreshnessEntry>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn invalidate_source<'life0, 'life1, 'async_trait>(
&'life0 self,
file_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<u32>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_entries_by_source<'life0, 'life1, 'async_trait>(
&'life0 self,
file_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<SourceReference>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_stale_entries_by_source<'life0, 'life1, 'async_trait>(
&'life0 self,
file_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<StaleEntryInfo>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn register_symbol_dependencies<'life0, 'async_trait>(
&'life0 self,
from: SymbolId,
to_symbols: Vec<SymbolId>,
) -> Pin<Box<dyn Future<Output = Result<u32>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn cascade_invalidate<'life0, 'async_trait>(
&'life0 self,
changed: SymbolId,
new_ast_hash: Vec<u8>,
max_depth: u32,
) -> Pin<Box<dyn Future<Output = Result<CascadeInvalidateReport>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
// Provided methods
fn check_freshness_semantic<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
entry_id: &'life1 str,
file_hash: &'life2 [u8],
_ast_hash: Option<&'life3 [u8]>,
_symbol_name: Option<&'life4 str>,
) -> Pin<Box<dyn Future<Output = Result<FreshnessEntry>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait { ... }
fn check_freshness_batch<'life0, 'async_trait>(
&'life0 self,
entries: Vec<(String, Vec<u8>, Option<Vec<u8>>, Option<String>)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<FreshnessEntry>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
}Expand description
Storage trait for source freshness tracking.
This trait manages tracking where information in PCX originally came from, allowing efficient invalidation when the source files change.
Required Methods§
Sourcefn register_source<'life0, 'async_trait>(
&'life0 self,
session_id: Uuid,
reference: SourceReference,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn register_source<'life0, 'async_trait>(
&'life0 self,
session_id: Uuid,
reference: SourceReference,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Register or update a source reference for an entry
Sourcefn check_freshness<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
entry_id: &'life1 str,
file_hash: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = Result<FreshnessEntry>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn check_freshness<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
entry_id: &'life1 str,
file_hash: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = Result<FreshnessEntry>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Check if an entry’s stored hash matches the provided hash. When the stored entry has a FunctionScope with ast_hash, compares that instead of the file-level hash (semantic freshness).
Sourcefn invalidate_source<'life0, 'life1, 'async_trait>(
&'life0 self,
file_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<u32>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn invalidate_source<'life0, 'life1, 'async_trait>(
&'life0 self,
file_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<u32>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Invalidate (remove) a source reference, usually because the source changed or the entry is being deleted. Returns count of removed references.
Sourcefn get_entries_by_source<'life0, 'life1, 'async_trait>(
&'life0 self,
file_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<SourceReference>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_entries_by_source<'life0, 'life1, 'async_trait>(
&'life0 self,
file_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<SourceReference>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Get all entries associated with a specific file path
Sourcefn get_stale_entries_by_source<'life0, 'life1, 'async_trait>(
&'life0 self,
file_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<StaleEntryInfo>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_stale_entries_by_source<'life0, 'life1, 'async_trait>(
&'life0 self,
file_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<StaleEntryInfo>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Return entry_ids (plus symbol metadata) for all source_reference records that
are still marked stale (status=1) for the given file. Called by Axon after
register_source_batch to detect symbols that were deleted from the file
(they were marked stale by invalidate_source but never re-registered).
Sourcefn register_symbol_dependencies<'life0, 'async_trait>(
&'life0 self,
from: SymbolId,
to_symbols: Vec<SymbolId>,
) -> Pin<Box<dyn Future<Output = Result<u32>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn register_symbol_dependencies<'life0, 'async_trait>(
&'life0 self,
from: SymbolId,
to_symbols: Vec<SymbolId>,
) -> Pin<Box<dyn Future<Output = Result<u32>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Register symbol-level dependencies (e.g., fn foo depends on struct Bar). Used for cascade invalidation.
Sourcefn cascade_invalidate<'life0, 'async_trait>(
&'life0 self,
changed: SymbolId,
new_ast_hash: Vec<u8>,
max_depth: u32,
) -> Pin<Box<dyn Future<Output = Result<CascadeInvalidateReport>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn cascade_invalidate<'life0, 'async_trait>(
&'life0 self,
changed: SymbolId,
new_ast_hash: Vec<u8>,
max_depth: u32,
) -> Pin<Box<dyn Future<Output = Result<CascadeInvalidateReport>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Cascade invalidate: when a symbol changes, invalidate all entries whose symbols depend on it (transitively up to max_depth).
Provided Methods§
Sourcefn check_freshness_semantic<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
entry_id: &'life1 str,
file_hash: &'life2 [u8],
_ast_hash: Option<&'life3 [u8]>,
_symbol_name: Option<&'life4 str>,
) -> Pin<Box<dyn Future<Output = Result<FreshnessEntry>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
fn check_freshness_semantic<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
entry_id: &'life1 str,
file_hash: &'life2 [u8],
_ast_hash: Option<&'life3 [u8]>,
_symbol_name: Option<&'life4 str>,
) -> Pin<Box<dyn Future<Output = Result<FreshnessEntry>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
Semantic freshness check: compare ast_hash when available, fallback to file hash.
The ast_hash and symbol_name are optional — if provided and the stored entry
has a FunctionScope, ast_hash comparison is used instead of file-level hash.
Sourcefn check_freshness_batch<'life0, 'async_trait>(
&'life0 self,
entries: Vec<(String, Vec<u8>, Option<Vec<u8>>, Option<String>)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<FreshnessEntry>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn check_freshness_batch<'life0, 'async_trait>(
&'life0 self,
entries: Vec<(String, Vec<u8>, Option<Vec<u8>>, Option<String>)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<FreshnessEntry>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Batch freshness check: check multiple entries in a single storage round-trip.
Each element of entries is (entry_id, file_hash, ast_hash, symbol_name).
Returns one FreshnessEntry per input element, in the same order.
The default implementation loops over check_freshness_semantic calls.
Backends with native batch support (e.g., SurrealDB) should override this
with a single WHERE entry_id IN $ids query.