Struct TemporalGraphIndex

Source
pub struct TemporalGraphIndex<D: DistanceMetric> {
    inner: TemporalHnsw<D>,
    edges: TemporalEdgeLayer,
    typed_edges: TypedEdgeStore,
}
Expand description

Temporal Graph Index: HNSW with temporal successor/predecessor edges.

Wraps TemporalHnsw (untouched) with a TemporalEdgeLayer for causal navigation and hybrid search.

Fields§

§inner: TemporalHnsw<D>

The underlying spatiotemporal HNSW index.

§edges: TemporalEdgeLayer

Temporal edge layer (successor/predecessor per entity).

§typed_edges: TypedEdgeStore

Typed relational edges (RFC-013 Part B).

Implementations§

Source§

impl<D: DistanceMetric + Clone> TemporalGraphIndex<D>

Source

pub fn new(config: HnswConfig, metric: D) -> Self

Create a new empty temporal graph index.

Source

pub fn from_temporal_hnsw(inner: TemporalHnsw<D>) -> Self

Create from an existing TemporalHnsw (migration path).

Rebuilds the temporal edge layer from the entity_index.

Source

pub fn insert(&mut self, entity_id: u64, timestamp: i64, vector: &[f32]) -> u32

Insert a temporal point.

Source

pub fn insert_with_reward( &mut self, entity_id: u64, timestamp: i64, vector: &[f32], reward: f32, ) -> u32

Insert a temporal point with an outcome reward.

Source

pub fn search( &self, query: &[f32], k: usize, filter: TemporalFilter, alpha: f32, query_timestamp: i64, ) -> Vec<(u32, f32)>

Standard search (delegates to inner TemporalHnsw).

Causal search: semantic search + temporal edge context.

Phase 1: Standard HNSW search. Phase 2: For each result, walk temporal edges to get what happened before and after.

Answers: “Find similar entities, and show me what happened to them next.”

Hybrid search: beam search exploring both semantic AND temporal edges.

At each step of the beam search on level 0, when visiting a node, also adds its temporal neighbors to the candidate set with a distance penalty controlled by beta.

  • beta = 0.0: pure semantic HNSW (ignores temporal edges)
  • beta = 1.0: always follow temporal edges (aggressive temporal exploration)
Source

pub fn inner(&self) -> &TemporalHnsw<D>

Access the underlying TemporalHnsw.

Source

pub fn edges(&self) -> &TemporalEdgeLayer

Access the temporal edge layer.

Source

pub fn trajectory( &self, entity_id: u64, filter: TemporalFilter, ) -> Vec<(i64, u32)>

Get trajectory for an entity.

Source

pub fn vector(&self, node_id: u32) -> &[f32]

Get vector by node ID.

Source

pub fn entity_id(&self, node_id: u32) -> u64

Get entity ID by node ID.

Source

pub fn timestamp(&self, node_id: u32) -> i64

Get timestamp by node ID.

Source

pub fn len(&self) -> usize

Total number of points.

Source

pub fn is_empty(&self) -> bool

Whether empty.

Source

pub fn inner_mut(&mut self) -> &mut TemporalHnsw<D>

Mutable access to the underlying TemporalHnsw.

Source

pub fn config(&self) -> &HnswConfig

Get HNSW config.

Source

pub fn set_ef_construction(&mut self, ef: usize)

Set ef_construction at runtime.

Set ef_search at runtime.

Source

pub fn enable_scalar_quantization(&mut self, min_val: f32, max_val: f32)

Enable scalar quantization.

Source

pub fn disable_scalar_quantization(&mut self)

Disable scalar quantization.

Source

pub fn search_with_recency( &self, query: &[f32], k: usize, filter: TemporalFilter, alpha: f32, query_timestamp: i64, recency_lambda: f32, recency_weight: f32, ) -> Vec<(u32, f32)>

Search with recency bias and normalized distances.

Source

pub fn reward(&self, node_id: u32) -> f32

Get the reward for a node.

Source

pub fn set_reward(&mut self, node_id: u32, reward: f32)

Set the reward for a node retroactively.

Source

pub fn search_with_reward( &self, query: &[f32], k: usize, filter: TemporalFilter, alpha: f32, query_timestamp: i64, min_reward: f32, ) -> Vec<(u32, f32)>

Search with reward pre-filtering.

Source

pub fn compute_centroid(&self) -> Option<Vec<f32>>

Compute the centroid of all vectors.

Source

pub fn set_centroid(&mut self, centroid: Vec<f32>)

Set centroid for anisotropy correction.

Source

pub fn clear_centroid(&mut self)

Clear centroid.

Source

pub fn centroid(&self) -> Option<&[f32]>

Get current centroid.

Source

pub fn centered_vector(&self, vec: &[f32]) -> Vec<f32>

Center a vector by subtracting the centroid.

Source

pub fn regions(&self, level: usize) -> Vec<(u32, Vec<f32>, usize)>

Get semantic regions at a given HNSW level.

Source

pub fn region_assignments( &self, level: usize, filter: TemporalFilter, ) -> HashMap<u32, Vec<(u64, i64)>>

O(N) single-pass region assignments.

Source

pub fn region_trajectory( &self, entity_id: u64, level: usize, window_days: i64, alpha: f32, ) -> Vec<(i64, Vec<f32>)>

Smoothed region distribution trajectory for an entity.

Source

pub fn typed_edges(&self) -> &TypedEdgeStore

Access the typed edge store.

Source

pub fn typed_edges_mut(&mut self) -> &mut TypedEdgeStore

Mutable access to the typed edge store.

Source

pub fn add_typed_edge( &mut self, source: u32, target: u32, edge_type: EdgeType, weight: f32, )

Add a typed edge between two nodes.

Source

pub fn success_score(&self, node_id: u32) -> f32

Get the success score of a node based on typed edges.

Uses Beta prior: P(success) = (1 + n_success) / (2 + n_total).

Source

pub fn save(&self, dir: &Path) -> Result<()>

Save to directory (index + temporal edges + typed edges).

Source

pub fn load(dir: &Path, metric: D) -> Result<Self>

Load from directory.

Search with Bayesian multi-factor scoring.

Pipeline:

  1. HNSW over-fetch 4k candidates
  2. Compute features per candidate (similarity, recency, reward, success_score, region)
  3. Bayesian rerank using weights
  4. Return top-k

This integrates typed edges (success_score), reward annotations, recency, and region membership into a single scored retrieval.

Source

pub fn assign_region(&self, vector: &[f32], level: usize) -> Option<u32>

Assign a vector to a region at a given HNSW level.

Search for episodes with similar trajectory SHAPE (not just similar state).

Uses path signatures to compare the agent’s recent trajectory against stored episodes. Returns episodes whose trajectory shape is most similar, regardless of where in embedding space they are.

This enables “lateral thinking”: finding episodes that MOVED similarly, not just episodes that WERE in a similar position.

Returns (entity_id, signature_distance, trajectory_length). Search for episodes with similar trajectory SHAPE (not just similar state).

Uses path signatures to compare the agent’s recent trajectory against stored episodes. Returns episodes whose trajectory shape is most similar.

This enables “lateral thinking”: finding episodes that MOVED similarly, not just episodes that WERE in a similar position.

Returns (entity_id, signature_distance, trajectory_length).

Trait Implementations§

Source§

impl<D: DistanceMetric + Clone> TemporalIndexAccess for TemporalGraphIndex<D>

Source§

fn search_raw( &self, query: &[f32], k: usize, filter: TemporalFilter, alpha: f32, query_timestamp: i64, ) -> Vec<(u32, f32)>

Search with temporal filtering, returning (node_id, score) pairs.
Source§

fn trajectory(&self, entity_id: u64, filter: TemporalFilter) -> Vec<(i64, u32)>

Retrieve trajectory for an entity: (timestamp, node_id) pairs.
Source§

fn vector(&self, node_id: u32) -> Vec<f32>

Get the vector for a node. Returns owned vec for thread safety.
Source§

fn entity_id(&self, node_id: u32) -> u64

Get the entity_id for a node.
Source§

fn timestamp(&self, node_id: u32) -> i64

Get the timestamp for a node.
Source§

fn len(&self) -> usize

Number of points in the index.
Source§

fn is_empty(&self) -> bool

Whether the index is empty.
Source§

fn regions(&self, _level: usize) -> Vec<(u32, Vec<f32>, usize)>

Get semantic regions at a given HNSW level (RFC-004). Returns (hub_node_id, hub_vector, n_assigned) per region.
Source§

fn region_members( &self, _region_hub: u32, _level: usize, _filter: TemporalFilter, ) -> Vec<(u32, u64, i64)>

Get points belonging to a specific region, optionally time-filtered (RFC-005). Returns (node_id, entity_id, timestamp) per member.
Source§

fn region_assignments( &self, _level: usize, _filter: TemporalFilter, ) -> HashMap<u32, Vec<(u64, i64)>>

Assign all nodes to regions in a single O(N) pass, optionally time-filtered. Returns HashMap<hub_id, Vec<(entity_id, timestamp)>>.
Source§

fn region_trajectory( &self, _entity_id: u64, _level: usize, _window_days: i64, _alpha: f32, ) -> Vec<(i64, Vec<f32>)>

Smoothed region-distribution trajectory for an entity (RFC-004).
Source§

fn metadata(&self, _node_id: u32) -> HashMap<String, String>

Get metadata for a node. Returns empty map if not available.
Source§

fn search_with_metadata( &self, query: &[f32], k: usize, filter: TemporalFilter, alpha: f32, query_timestamp: i64, metadata_filter: &MetadataFilter, ) -> Vec<(u32, f32)>

Search with metadata filtering (post-filter on search results). Default: ignores metadata filter and delegates to search_raw.

Auto Trait Implementations§

§

impl<D> Freeze for TemporalGraphIndex<D>
where D: Freeze,

§

impl<D> RefUnwindSafe for TemporalGraphIndex<D>
where D: RefUnwindSafe,

§

impl<D> Send for TemporalGraphIndex<D>

§

impl<D> Sync for TemporalGraphIndex<D>

§

impl<D> Unpin for TemporalGraphIndex<D>
where D: Unpin,

§

impl<D> UnwindSafe for TemporalGraphIndex<D>
where D: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> TemporalSearch for T

Source§

fn search_raw( &self, query: &[f32], k: usize, filter: TemporalFilter, alpha: f32, query_timestamp: i64, ) -> Vec<(u32, f32)>

Search with temporal filtering, returning (node_id, score) pairs.
Source§

impl<T> TrajectoryAccess for T

Source§

fn trajectory(&self, entity_id: u64, filter: TemporalFilter) -> Vec<(i64, u32)>

Retrieve trajectory for an entity: (timestamp, node_id) pairs.
Source§

fn vector(&self, node_id: u32) -> Vec<f32>

Get the vector for a node. Returns owned vec for thread safety.
Source§

fn entity_id(&self, node_id: u32) -> u64

Get the entity_id for a node.
Source§

fn timestamp(&self, node_id: u32) -> i64

Get the timestamp for a node.
Source§

fn len(&self) -> usize

Number of points in the index.
Source§

fn is_empty(&self) -> bool

Whether the index is empty.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V