pub struct HyperbolicTreeTensor { /* private fields */ }Expand description
Hyperbolic Tree Tensor - core data structure.
Path access is hash-map cost; spatial queries go through the cell index. Nodes are embedded in the Poincare disk, and their positions are derived from tree shape rather than stored.
Path maps use DashMap for lock-free concurrent reads.
Implementations§
Source§impl HyperbolicTreeTensor
impl HyperbolicTreeTensor
Sourcepub fn insert_data_only(
&self,
path: &str,
value: Vec<u8>,
content_type: Option<String>,
) -> IntegrationResult<()>
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).
Sourcepub fn insert(
&self,
path: &str,
value: Vec<u8>,
content_type: Option<String>,
) -> IntegrationResult<()>
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.
Sourcepub fn insert_positioned(
&self,
path: &str,
value: Vec<u8>,
content_type: Option<String>,
child_index: u32,
) -> IntegrationResult<()>
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.
Sourcepub fn embed_existing(&self, path: &str) -> IntegrationResult<bool>
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.
Sourcepub fn get(&self, path: &str) -> IntegrationResult<CompressedNode>
pub fn get(&self, path: &str) -> IntegrationResult<CompressedNode>
Get a node by path (returns cloned value).
Sourcepub fn update_value(&self, path: &str, value: Vec<u8>) -> IntegrationResult<()>
pub fn update_value(&self, path: &str, value: Vec<u8>) -> IntegrationResult<()>
Update the value of a node at the specified path.
Sourcepub fn set_node_metadata(
&self,
path: &str,
key: &str,
value: &str,
) -> IntegrationResult<()>
pub fn set_node_metadata( &self, path: &str, key: &str, value: &str, ) -> IntegrationResult<()>
Set a metadata key-value pair on a node.
Sourcepub fn set_semantic(&self, path: &str, coords: Vec<u8>) -> IntegrationResult<()>
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).
Sourcepub fn get_semantic(&self, path: &str) -> IntegrationResult<Vec<u8>>
pub fn get_semantic(&self, path: &str) -> IntegrationResult<Vec<u8>>
Get semantic coordinates for a node (raw Q64.64 bytes).
Sourcepub fn delete(&self, path: &str) -> IntegrationResult<()>
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.
Sourcepub fn list_children(
&self,
path: &str,
) -> IntegrationResult<Vec<CompressedNode>>
pub fn list_children( &self, path: &str, ) -> IntegrationResult<Vec<CompressedNode>>
List children of a node at the specified path (cloned).
Sourcepub fn list_subtree(&self, path: &str) -> IntegrationResult<Vec<String>>
pub fn list_subtree(&self, path: &str) -> IntegrationResult<Vec<String>>
List all node paths under a specified path.
Sourcepub fn node_count(&self) -> usize
pub fn node_count(&self) -> usize
Get the number of nodes in the tree.
Sourcepub fn validate(&self) -> bool
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.
Sourcepub fn tensor_network(&self) -> &HyperbolicTensorNetwork
pub fn tensor_network(&self) -> &HyperbolicTensorNetwork
Get the underlying tensor network (for spatial queries).
Sourcepub fn path_for_id(&self, unique_id: &str) -> Option<String>
pub fn path_for_id(&self, unique_id: &str) -> Option<String>
Resolve a unique_id to a path.
Sourcepub fn position(&self, path: &str) -> IntegrationResult<HyperbolicPoint>
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.
Sourcepub fn path_ops(&self) -> &dyn PathOperations
pub fn path_ops(&self) -> &dyn PathOperations
Get the path operations.
Sourcepub fn nearest_neighbor_point(
&self,
query: &HyperbolicPoint,
) -> IntegrationResult<(String, FixedPoint)>
pub fn nearest_neighbor_point( &self, query: &HyperbolicPoint, ) -> IntegrationResult<(String, FixedPoint)>
Find the nearest stored node to an arbitrary Poincaré disk point.
Answered exactly by the cell index. Returns (path, hyperbolic_distance). Errors when the index holds nothing.
Sourcepub fn nearest_neighbor_point_k(
&self,
query: &HyperbolicPoint,
k: usize,
) -> IntegrationResult<Vec<(String, FixedPoint)>>
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.
k == 0 is a request for nothing and is answered with nothing — the
same as Self::find_nearest. Only an index that holds no nodes is an
error. Conflating the two used to make nearest_k(q, 0) report “no
nodes in tree” against a fully populated store, which is simply untrue.
Sourcepub fn find_nearest(
&self,
path: &str,
k: usize,
) -> IntegrationResult<Vec<(String, FixedPoint)>>
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.
Sourcepub fn nearest_semantic(
&self,
query_coords: &[u8],
k: usize,
dim_range: &Range<usize>,
) -> IntegrationResult<Vec<(String, FixedPoint)>>
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.
Sourcepub fn neighbors_semantic(
&self,
path: &str,
k: usize,
dim_range: &Range<usize>,
) -> IntegrationResult<Vec<(String, FixedPoint)>>
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.
Sourcepub fn find_in_radius(
&self,
path: &str,
radius: FixedPoint,
) -> IntegrationResult<Vec<(String, FixedPoint)>>
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.