Skip to content

GraphNode

Description

Opaque node handle used by traversal helpers.

This carries the owning graph pointer plus the stable node id. Users typically obtain it from GraphGetNode, GraphForeachNode, or GraphNodeForeachNeighbor.

The handle is meant for active traversal and graph-aware node access. Long-lived external state should usually be stored separately, keyed by GraphNodeGetId(node) or by application data held in the node payload.

Usage example (Cross-references)

Usage examples (Cross-references)
    }
    
    static GraphNode graph_validate_node_handle(GraphNode node) {
        GenericGraph *graph;
    }
    
    GraphNode graph_get_node(GenericGraph *graph, GraphNodeId node_id) {
        GraphNode node;
    
    GraphNode graph_get_node(GenericGraph *graph, GraphNodeId node_id) {
        GraphNode node;
    
        ValidateGraph(graph);
    }
    
    void *graph_node_data_ptr_checked(GenericGraph *graph, GraphNode node) {
        GraphNode validated = graph_validate_node_handle(node);
    
    void *graph_node_data_ptr_checked(GenericGraph *graph, GraphNode node) {
        GraphNode validated = graph_validate_node_handle(node);
    
        if (GENERIC_GRAPH(validated.__graph) != graph) {
    }
    
    u64 graph_node_visit(GraphNode node) {
        GenericGraph     *graph;
        GenericGraphSlot *slot;
    }
    
    void graph_node_unvisit(GraphNode node) {
        GenericGraph     *graph;
        GenericGraphSlot *slot;
    }
    
    u64 graph_node_visit_count(GraphNode node) {
        GenericGraph           *graph;
        const GenericGraphSlot *slot;
    }
    
    bool graph_node_visited(GraphNode node) {
        return graph_node_visit_count(node) > 0;
    }
    }
    
    bool graph_mark_node_for_deletion(GraphNode node) {
        GenericGraph     *graph;
        GenericGraphSlot *slot;
    }
    
    bool graph_node_marked_for_deletion(GraphNode node) {
        GenericGraph           *graph;
        const GenericGraphSlot *slot;
    }
    
    bool graph_unmark_node_for_deletion(GraphNode node) {
        GenericGraph     *graph;
        GenericGraphSlot *slot;
    }
    
    bool graph_node_iter_next(GenericGraphNodeIter *iter, GraphNode *out_node) {
        if (!iter || !out_node) {
            LOG_FATAL("invalid arguments");
    }
    
    GenericGraphNeighborIter graph_neighbor_iter_begin(GraphNode node) {
        GenericGraphNeighborIter iter;
        GenericGraph            *graph;
    }
    
    bool graph_neighbor_iter_next(GenericGraphNeighborIter *iter, GraphNode *out_node) {
        GraphNeighbors *neighbors;
    }
    
    GenericGraphPredecessorIter graph_predecessor_iter_begin(GraphNode node) {
        GenericGraphPredecessorIter iter;
        GenericGraph               *graph;
    }
    
    bool graph_predecessor_iter_next(GenericGraphPredecessorIter *iter, GraphNode *out_node) {
        GraphNeighbors *neighbors;
    }
    
    static bool city_reachable_from(GraphNode node, GraphNodeId goal_id) {
        if (GraphNodeVisitCount(node) > 0) {
            return false;
    
        GraphNodeId a    = GraphAddNodeR(&graph, 10);
        GraphNode   node = GraphGetNode(&graph, a);
    
        bool result = !GraphNodeVisited(node) && (GraphNodeVisitCount(node) == 0);
    
        GraphNodeId a    = GraphAddNodeR(&graph, 10);
        GraphNode   node = GraphGetNode(&graph, a);
    
        bool result = !GraphNodeMarkedForDeletion(node);
    
    static bool test_graph_stale_node_handle_after_commit_deadend(void) {
        WriteFmt("Testing stale GraphNode handle after commit (should abort)\n");
    
        typedef Graph(int) IntGraph;
    
        GraphNodeId a    = GraphAddNodeR(&graph, 10);
        GraphNode   node = GraphGetNode(&graph, a);
    
        (void)GraphMarkNodeForDeletion(node);
        Str        name  = StrInitFromZstr("alpha");
        GraphNodeId node_id;
        GraphNode   node;
        Str        *stored_name;
    
        GraphNodeId node_id = GraphAddNodeR(&graph, 11);
        GraphNode   node    = GraphGetNode(&graph, node_id);
    
        bool result = graph.alignment == 32 && GraphNodeIdIndex(node_id) == 0 && GraphNodeIdGeneration(node_id) == 1;
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNode   node_b;
        GraphAddEdge(&graph, a, b);
        GraphAddEdge(&graph, a, c);
        IntGraph graph_a = GraphInit();
        IntGraph graph_b = GraphInit();
        GraphNode node   = GraphGetNode(&graph_a, GraphAddNodeR(&graph_a, 10));
    
        (void)GraphNodeData(&graph_b, node);
                for (GenericGraphNodeIter UNPL(iter) = graph_node_iter_begin(GENERIC_GRAPH(UNPL(pg))); UNPL(iter).graph;  \
                     UNPL(iter).graph = NULL)                                                                              \
                    for (GraphNode node = {0}; graph_node_iter_next(&UNPL(iter), &node);)
    
    ///
    ///
    #define GraphNodeForeachNeighbor(node, neighbor)                                                                       \
        for (GraphNode UNPL(src_node) = (node); UNPL(src_node).__graph; UNPL(src_node).__graph = NULL)                    \
            for (GenericGraphNeighborIter UNPL(iter) = graph_neighbor_iter_begin(UNPL(src_node)); UNPL(iter).graph;       \
                 UNPL(iter).graph = NULL)                                                                                  \
            for (GenericGraphNeighborIter UNPL(iter) = graph_neighbor_iter_begin(UNPL(src_node)); UNPL(iter).graph;       \
                 UNPL(iter).graph = NULL)                                                                                  \
                for (GraphNode neighbor = {0}; graph_neighbor_iter_next(&UNPL(iter), &neighbor);)
    
    ///
    ///
    #define GraphNodeForeachPredecessor(node, predecessor)                                                                \
        for (GraphNode UNPL(dst_node) = (node); UNPL(dst_node).__graph; UNPL(dst_node).__graph = NULL)                   \
            for (GenericGraphPredecessorIter UNPL(iter) = graph_predecessor_iter_begin(UNPL(dst_node));                  \
                 UNPL(iter).graph;                                                                                        \
                 UNPL(iter).graph;                                                                                        \
                 UNPL(iter).graph = NULL)                                                                                 \
                for (GraphNode predecessor = {0}; graph_predecessor_iter_next(&UNPL(iter), &predecessor);)
    
    #endif // MISRA_STD_CONTAINER_GRAPH_FOREACH_H
        void       *__graph;
        GraphNodeId __id;
    } GraphNode;
    
    ///
Last updated on