Skip to main content

HyperbolicTreeTensor

Struct HyperbolicTreeTensor 

Source
pub struct HyperbolicTreeTensor { /* private fields */ }
Expand description

Hyperbolic Tree Tensor - core data structure.

Combines hyperbolic geometry, tensor networks, and geometric hashing: path access is hash-map cost, spatial queries use the bucketed VP-tree index. Nodes are embedded in the Poincare disk with spatial indexing for geometric queries.

Path maps use DashMap for lock-free concurrent reads.

Implementations§

Source§

impl HyperbolicTreeTensor

Source

pub fn new(config: HTTConfig) -> Self

Create a new Hyperbolic Tree Tensor.

Source

pub fn insert_data_only( &self, path: &str, value: Vec<u8>, content_type: Option<String>, ) -> IntegrationResult<()>

Insert a node without geometric embedding (data + semantic only).

Much faster than insert() — skips Sarkar embedding, VP-tree, power diagram, and point location grid. Use for bulk loading when spatial queries are not needed (semantic queries still work).

Source

pub fn insert( &self, path: &str, value: Vec<u8>, content_type: Option<String>, ) -> IntegrationResult<()>

Insert a node at the specified path.

Acquires a striped parent lock to serialize writes to the same parent while allowing parallel writes to different parents.

Source

pub fn insert_positioned( &self, path: &str, value: Vec<u8>, content_type: Option<String>, child_index: u32, ) -> IntegrationResult<()>

Insert a node with an explicit child_index for deterministic Sarkar reconstruction.

Same as insert() but passes the child_index through to the tensor network so the node gets the same geometric position regardless of insertion order.

Source

pub fn embed_existing(&self, path: &str) -> IntegrationResult<bool>

Upgrade a data-only node to a full geometric embedding, in place.

Data-only nodes (insert_data_only) live under a stub signature with no Poincaré position — semantic queries see them, spatial queries do not. This computes their Sarkar placement on demand: missing ancestors are embedded first (placement needs an embedded parent; recursion is bounded by the ~44/τ depth budget), then the node is re-registered under its position-derived signature with its identity preserved — key, value, user metadata, timestamps, and semantic coordinates all carry over.

Returns Ok(true) when this call performed the upgrade, Ok(false) when the node was already embedded (idempotent), NotFound for missing paths.

Concurrency: takes the same parent stripe lock as insert, so embeds serialize with sibling inserts and deletes; racing embeds of the same node resolve to one upgrade (double-checked under the lock). Readers never observe the node missing: the embedded replacement (with coordinates already copied) goes live in path_map before the data-only entry is retired — a concurrent semantic query may transiently see the key twice (same key, same coordinates) inside that window.

Geometric positions are derived state and are NOT persisted: the position depends on the sibling order at embed time, so it is deterministic for a fixed operation sequence but not stable across sessions. Callers re-embed after reopening a lazily-loaded store.

Source

pub fn get(&self, path: &str) -> IntegrationResult<CompressedNode>

Get a node by path (returns cloned value).

Source

pub fn update_value(&self, path: &str, value: Vec<u8>) -> IntegrationResult<()>

Update the value of a node at the specified path.

Source

pub fn set_node_metadata( &self, path: &str, key: &str, value: &str, ) -> IntegrationResult<()>

Set a metadata key-value pair on a node.

Source

pub fn set_semantic(&self, path: &str, coords: Vec<u8>) -> IntegrationResult<()>

Set semantic coordinates on a node (raw Q64.64 bytes, 16 bytes per dimension).

Source

pub fn get_semantic(&self, path: &str) -> IntegrationResult<Vec<u8>>

Get semantic coordinates for a node (raw Q64.64 bytes).

Source

pub fn delete(&self, path: &str) -> IntegrationResult<()>

Delete a node at the specified path.

A node with live children cannot be deleted (that would orphan them). The check and the removal run under two stripe locks — the node’s own (which blocks a concurrent insert of a child under it, closing the has-no-children TOCTOU) and its parent’s (which serializes the parent’s child-list mutation against sibling inserts/deletes). The two stripes are taken in canonical order, so this never deadlocks against a concurrent delete.

Source

pub fn list_children( &self, path: &str, ) -> IntegrationResult<Vec<CompressedNode>>

List children of a node at the specified path (cloned).

Source

pub fn list_subtree(&self, path: &str) -> IntegrationResult<Vec<String>>

List all node paths under a specified path.

Source

pub fn exists(&self, path: &str) -> bool

Check if a path exists.

Source

pub fn node_count(&self) -> usize

Get the number of nodes in the tree.

Source

pub fn stats(&self) -> HashMap<String, String>

Get tree statistics.

Source

pub fn validate(&self) -> bool

Validate the tree structure.

Checks all structural invariants: parent-child consistency, path_map ↔ id_to_path bidirectionality, and tensor network integrity.

Source

pub fn tensor_network(&self) -> &HyperbolicTensorNetwork

Get the underlying tensor network (for spatial queries).

Source

pub fn path_for_id(&self, unique_id: &str) -> Option<String>

Resolve a unique_id to a path.

Source

pub fn position(&self, path: &str) -> IntegrationResult<HyperbolicPoint>

The hyperbolic (Poincaré) position of a stored node.

Errors with NotFound for unknown paths and OperationFailed for data-only nodes, which have no geometric embedding.

Source

pub fn path_ops(&self) -> &dyn PathOperations

Get the path operations.

Source

pub fn nearest_neighbor_point( &self, query: &HyperbolicPoint, ) -> IntegrationResult<(String, FixedPoint)>

Find the nearest stored node to an arbitrary Poincaré disk point.

Uses the Nielsen power diagram grid for O(1) lookup. Returns (path, hyperbolic_distance).

Source

pub fn nearest_neighbor_point_k( &self, query: &HyperbolicPoint, k: usize, ) -> IntegrationResult<Vec<(String, FixedPoint)>>

Find the k nearest stored nodes to an arbitrary Poincaré disk point.

Returns (path, hyperbolic_distance) sorted by ascending distance.

Source

pub fn find_nearest( &self, path: &str, k: usize, ) -> IntegrationResult<Vec<(String, FixedPoint)>>

Find the k nearest stored nodes to the given path’s position in hyperbolic space. Returns paths sorted by ascending hyperbolic distance.

Source

pub fn nearest_semantic( &self, query_coords: &[u8], k: usize, dim_range: &Range<usize>, ) -> IntegrationResult<Vec<(String, FixedPoint)>>

Find the k nearest nodes by Euclidean distance across a dimensional slice of the semantic coordinate space.

query_coords: raw Q64.64 bytes representing the query point. k: number of results. dim_range: which dimensions to compare (e.g., 16..33 for category axes).

Returns (path, distance) sorted by distance ascending.

Source

pub fn neighbors_semantic( &self, path: &str, k: usize, dim_range: &Range<usize>, ) -> IntegrationResult<Vec<(String, FixedPoint)>>

Find the k nearest nodes to an existing node by semantic dimensional distance.

Convenience wrapper: reads the node’s semantic coordinates, then calls nearest_semantic. The queried node is excluded from results.

Source

pub fn find_in_radius( &self, path: &str, radius: FixedPoint, ) -> IntegrationResult<Vec<(String, FixedPoint)>>

Find all stored nodes within hyperbolic radius of the given path. Returns paths and their distances.

Trait Implementations§

Source§

impl Debug for HyperbolicTreeTensor

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> Same for T

Source§

type Output = T

Should always be Self
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.