pub struct Graph { /* private fields */ }Expand description
Graph storage for all nodes in the database
The graph is an in-memory hash map that stores nodes by their soul (unique identifier). It provides thread-safe access and automatic conflict resolution when merging updates.
§Thread Safety
Graph is thread-safe and uses parking_lot::RwLock for concurrent access.
Multiple threads can read simultaneously, or a single thread can write exclusively.
§Conflict Resolution
When merging nodes, the graph uses the HAM algorithm:
- Compare state timestamps for each property
- Higher state wins
- Merge non-conflicting properties
§Example
use gun::graph::Graph;
use gun::state::Node;
let graph = Graph::new();
let node = Node::with_soul("user_123".to_string());
graph.put("user_123", node)?;
if let Some(loaded_node) = graph.get("user_123") {
println!("Found node: {:?}", loaded_node);
}Implementations§
Source§impl Graph
impl Graph
Sourcepub fn all_nodes(&self) -> HashMap<String, Node>
pub fn all_nodes(&self) -> HashMap<String, Node>
Get a copy of all nodes in the graph (for debugging/testing)
Warning: This clones all nodes, which can be expensive for large graphs. Only use this for debugging or small datasets.
§Returns
A HashMap mapping soul to node for all nodes in the graph.
Sourcepub fn merge(
&self,
soul: &str,
incoming: &Node,
state_fn: impl Fn() -> f64,
) -> GunResult<Node>
pub fn merge( &self, soul: &str, incoming: &Node, state_fn: impl Fn() -> f64, ) -> GunResult<Node>
Merge a node into the graph with automatic conflict resolution
This method implements the HAM (Hypothetical Amnesia Machine) algorithm:
- If the node doesn’t exist, it’s inserted
- If the node exists, properties are merged based on state timestamps
- Higher state always wins in conflicts
- Non-conflicting properties are preserved
§Arguments
soul- The unique identifier for the nodeincoming- The node to merge instate_fn- Function that generates the current state timestamp
§Returns
The merged node after conflict resolution.
§Example
use gun::graph::Graph;
use gun::state::{Node, State};
use serde_json::json;
let graph = Graph::new();
let state = State::new();
let mut node1 = Node::with_soul("user_123".to_string());
node1.data.insert("name".to_string(), json!("Alice"));
let merged = graph.merge("user_123", &node1, || state.next())?;