pub struct GraphTransaction<'a, T> { /* private fields */ }Expand description
Tracks reversible changes to a Graph<T> and provides commit/rollback.
Usage:
- Mutate via
push(...),attach(...),detach(...),change_direction(...). - Call
commit(),commit_with(...), ortry_commit()to finalize. - On invalid commit, the graph is rolled back and you receive
replaysteps you can pass toreplay(...)in a fresh transaction.
Implementations§
Source§impl<'a, T> GraphTransaction<'a, T>
impl<'a, T> GraphTransaction<'a, T>
pub fn new(graph: &'a mut Graph<T>) -> Self
Sourcepub fn commit(self) -> TransactionResult<T>
pub fn commit(self) -> TransactionResult<T>
Finalize the transaction:
- Marks cycles (
set_cycles()). - Validates with
Graph<T>: Valid. - If valid, returns
Valid(steps). - If invalid, rolls back and returns
Invalid(steps, replay).
Sourcepub fn commit_with(
self,
validator: impl Fn(&Graph<T>) -> bool,
) -> TransactionResult<T>
pub fn commit_with( self, validator: impl Fn(&Graph<T>) -> bool, ) -> TransactionResult<T>
Like commit(), but also requires validator(&Graph<T>) to pass.
This is useful for domain-specific acceptance checks in addition to structural validity.
Sourcepub fn try_commit(self) -> TransactionResult<T>
pub fn try_commit(self) -> TransactionResult<T>
Attempt to commit the transaction, repairing invalid nodes if possible.
- Calls
repair_invalid_nodes()up toMAX_REPAIR_ATTEMPTStimes.
Note: This may produce different graphs on each call due to possible random repairs.
Sourcepub fn push(&mut self, node: impl Into<GraphNode<T>>) -> usize
pub fn push(&mut self, node: impl Into<GraphNode<T>>) -> usize
Append a node to the graph and record the change. Returns the new node’s index.
Sourcepub fn attach(&mut self, from: usize, to: usize)
pub fn attach(&mut self, from: usize, to: usize)
Create an edge from from to to and record the change.
Sourcepub fn detach(&mut self, from: usize, to: usize)
pub fn detach(&mut self, from: usize, to: usize)
Remove an edge from from to to and record the change.
Sourcepub fn change_direction(&mut self, index: usize, direction: Direction)
pub fn change_direction(&mut self, index: usize, direction: Direction)
Change the direction of the node at index if it differs from its current direction.
Records the previous direction so the change can be rolled back or replayed.
Sourcepub fn rollback(self) -> Vec<ReplayStep<T>>
pub fn rollback(self) -> Vec<ReplayStep<T>>
Undo all recorded changes in reverse order, mutating the graph back to its original state.
Returns a sequence of ReplaySteps that can be fed to replay(...) on a new transaction
to re-apply the same operational effects.
Sourcepub fn replay(&mut self, steps: Vec<ReplayStep<T>>)
pub fn replay(&mut self, steps: Vec<ReplayStep<T>>)
Apply ReplaySteps (typically from a prior rollback()) to this transaction/graph.
Steps are recorded as normal mutations (so they can be committed or rolled back again).
Sourcepub fn set_cycles(&mut self)
pub fn set_cycles(&mut self)
Mark cycle participation for nodes touched in this transaction:
- Nodes without cycles are set to
Direction::Forward. - Nodes in cycles (via
get_cycles(idx)) are set toDirection::Backward.
Sourcepub fn get_insertion_steps(
&self,
source_idx: usize,
target_idx: usize,
new_node_idx: usize,
rand: &mut RdRand<'_>,
) -> Vec<InsertStep>
pub fn get_insertion_steps( &self, source_idx: usize, target_idx: usize, new_node_idx: usize, rand: &mut RdRand<'_>, ) -> Vec<InsertStep>
Compute the steps needed to insert new_node_idx between source_idx and target_idx.
Behavior:
- If
new_nodehasArity::Zeroandtargetis not locked, connectnew_node -> target. - If
sourceis anEdge, re-route its single outgoing throughnew_node. - If
targetis anEdgeor is locked, detach one incoming and rewire vianew_node. - Otherwise connect
source -> new_node -> target.
Sourcepub fn random_source_node(&self, rand: &mut RdRand<'_>) -> Option<&GraphNode<T>>
pub fn random_source_node(&self, rand: &mut RdRand<'_>) -> Option<&GraphNode<T>>
The below functions are used to get random nodes from the graph. These are useful for creating connections between nodes. Neither of these functions will return an edge node. This is because edge nodes are not valid source or target nodes for connections as they only allow one incoming and one outgoing connection, thus they can’t be used to create new connections. Instead, edge nodes are used to represent the weights of the connections
Get a random node that can be used as a source node for a connection. A source node can be either an input or a vertex node.
Sourcepub fn random_target_node(&self, rand: &mut RdRand<'_>) -> Option<&GraphNode<T>>
pub fn random_target_node(&self, rand: &mut RdRand<'_>) -> Option<&GraphNode<T>>
Get a random node that can be used as a target node for a connection. A target node can be either an output or a vertex node.