Skip to content
GraphCommitChanges

GraphCommitChanges

Description

Apply all pending edge removals and node deletion marks.

Deleted slots remain reusable and future nodes may reuse their slot indices with fresh generations. Any deleted node id or GraphNode handle becomes invalid immediately after commit returns.

This deferred mutation model is meant for passes that need stable traversal first and destructive graph rewrites second.

Parameters

Name Direction Description
g in,out Graph to commit.

Success

Returns the count of pending removals applied (explicit edge removals plus node deletion marks; cascading edge cleanup from node deletion is not counted separately). live_count shrinks by the number of deleted nodes; edge_count shrinks accordingly; pending-delete count drops to 0. Freed slot indices are pushed onto the reuse list with incremented generations; previously-stored payloads have been torn down via copy_deinit (if configured). All previously-issued node ids and GraphNode handles for the deleted nodes are now stale.

Failure

Does not return - aborts via LOG_FATAL for an invalid graph (caller bug).

Usage example (Cross-references)

Usage examples (Cross-references)
    
    static bool test_graph_mark_delete_commit_and_reuse(void) {
        WriteFmt("Testing GraphMarkNodeForDeletion and GraphCommitChanges\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        bool result  = GraphContainsNode(&graph, b) && (graph.pending_delete_count == 1);
        u64  removed = GraphCommitChanges(&graph);
    
        result = result && (removed == 1);
        result      = result && !GraphNodeMarkedForDeletion(node);
        result      = result && !GraphUnmarkNodeForDeletion(node);
        result      = result && (GraphCommitChanges(&graph) == 0);
        result      = result && GraphContainsNode(&graph, a);
        result      = result && (GraphNodeCount(&graph) == 1);
        result      = result && !GraphMarkEdgeForRemoval(&graph, c, b);
    
        u64 committed = GraphCommitChanges(&graph);
    
        result = result && (committed == 2);
        result      = result && !GraphEdgeMarkedForRemoval(&graph, a, b);
        result      = result && !GraphUnmarkEdgeForRemoval(&graph, a, b);
        result      = result && (GraphCommitChanges(&graph) == 0);
        result      = result && GraphHasEdge(&graph, a, b);
        result      = result && (GraphEdgeCount(&graph) == 1);
        result      = result && !GraphEdgeMarkedForRemoval(&graph, a, b);
        result      = result && GraphEdgeMarkedForRemoval(&graph, a, c);
        result      = result && (GraphCommitChanges(&graph) == 1);
        result      = result && GraphHasEdge(&graph, a, b);
        result      = result && !GraphHasEdge(&graph, a, c);
        result      = result && (GraphPredecessorAt(&graph, a, 0) == a);
        result      = result && GraphMarkEdgeForRemoval(&graph, a, a);
        result      = result && (GraphCommitChanges(&graph) == 1);
        result      = result && (GraphEdgeCount(&graph) == 0);
        result      = result && (GraphOutDegree(&graph, a) == 0);
        result      = result && GraphEdgeMarkedForRemoval(&graph, a, b);
        result      = result && GraphNodeMarkedForDeletion(GraphGetNode(&graph, b));
        result      = result && (GraphCommitChanges(&graph) == 2);
        result      = result && !GraphContainsNode(&graph, b);
        result      = result && (GraphNodeCount(&graph) == 3);
    
        bool result = GraphMarkNodeForDeletion(GraphGetNode(&graph, b));
        result      = result && (GraphCommitChanges(&graph) == 1);
        result      = result && !GraphContainsNode(&graph, b);
    
        (void)GraphMarkNodeForDeletion(node);
        (void)GraphCommitChanges(&graph);
        (void)GraphNodeVisit(node);
Last updated on