Skip to content

GraphNodeId

Description

Stable identifier used to refer to a graph node.

Node ids are opaque 64-bit values. Internally they pack a per-slot generation in the high 32 bits and a slot index in the low 32 bits.

A node id is stable only while that node remains live. After GraphCommitChanges deletes a node, any old id or handle referring to that slot becomes stale and must not be used with live-node access APIs.

Usage example (Cross-references)

Usage examples (Cross-references)
    /// TAGS: Graph, Node, Id, Index
    ///
    #define GraphNodeIdIndex(id) ((u32)((GraphNodeId)(id) & UINT32_MAX))
    
    ///
    /// TAGS: Graph, Node, Id, Generation
    ///
    #define GraphNodeIdGeneration(id) ((u32)(((GraphNodeId)(id) >> 32) & UINT32_MAX))
    
    ///
    typedef struct {
        void       *_graph_;
        GraphNodeId _id_;
    } GraphNode;
    /// TAGS: Graph, Edge, Neighbor, Vec
    ///
    typedef Vec(GraphNodeId) GraphNeighbors;
    
    ///
    
    typedef struct {
        GraphNodeId from;
        GraphNodeId to;
    } GraphPendingEdgeRemoval;
    typedef struct {
        GraphNodeId from;
        GraphNodeId to;
    } GraphPendingEdgeRemoval;
    #define GRAPH_SLOT_MARKED   ((u32)1u << 1)
    
    static GraphNodeId graph_make_node_id(u32 index, u32 generation) {
        return (((u64)generation) << 32) | (u64)index;
    }
    }
    
    static void graph_validate_node_id(const GenericGraph *graph, GraphNodeId node_id) {
        u32                     index;
        u32                     generation;
    }
    
    static GenericGraphSlot *graph_require_live_slot(GenericGraph *graph, GraphNodeId node_id) {
        graph_validate_node_id(graph, node_id);
        return graph_slot_ptr_raw(graph, GraphNodeIdIndex(node_id));
    }
    
    static const GenericGraphSlot *graph_require_live_slot_const(const GenericGraph *graph, GraphNodeId node_id) {
        graph_validate_node_id(graph, node_id);
        return graph_slot_ptr_const_raw(graph, GraphNodeIdIndex(node_id));
        slot->data = NULL;
    
        deinit_vec(GENERIC_VEC(&slot->out_neighbors), sizeof(GraphNodeId));
        slot->out_neighbors = VecInitT(slot->out_neighbors, graph->allocator);
        deinit_vec(GENERIC_VEC(&slot->in_neighbors), sizeof(GraphNodeId));
        deinit_vec(GENERIC_VEC(&slot->out_neighbors), sizeof(GraphNodeId));
        slot->out_neighbors = VecInitT(slot->out_neighbors, graph->allocator);
        deinit_vec(GENERIC_VEC(&slot->in_neighbors), sizeof(GraphNodeId));
        slot->in_neighbors = VecInitT(slot->in_neighbors, graph->allocator);
    }
    
    static bool graph_neighbors_contains(const GraphNeighbors *neighbors, GraphNodeId node_id) {
        size idx;
    }
    
    static size graph_find_neighbor_index(const GraphNeighbors *neighbors, GraphNodeId node_id) {
        size idx;
    }
    
    static size graph_find_pending_edge_removal_index(const GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
        size idx;
    }
    
    static bool graph_remove_edge_now(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
        GraphNeighbors *out_neighbors;
        GraphNeighbors *in_neighbors;
        }
    
        remove_range_vec(GENERIC_VEC(out_neighbors), NULL, sizeof(GraphNodeId), out_idx, 1);
        remove_range_vec(GENERIC_VEC(in_neighbors), NULL, sizeof(GraphNodeId), in_idx, 1);
        graph->edge_count -= 1;
    
        remove_range_vec(GENERIC_VEC(out_neighbors), NULL, sizeof(GraphNodeId), out_idx, 1);
        remove_range_vec(GENERIC_VEC(in_neighbors), NULL, sizeof(GraphNodeId), in_idx, 1);
        graph->edge_count -= 1;
        return true;
    }
    
    static size graph_remove_marked_outgoing_edges(GenericGraph *graph, GraphNodeId from) {
        size            removed   = 0;
        GraphNeighbors *neighbors = graph_out_neighbors_ptr(graph, from);
    
        while (idx < VecLen(neighbors)) {
            GraphNodeId             neighbor_id = VecAt(neighbors, idx);
            const GenericGraphSlot *slot;
    }
    
    static size graph_remove_all_outgoing_edges(GenericGraph *graph, GraphNodeId from) {
        size            removed   = 0;
        GraphNeighbors *neighbors = graph_out_neighbors_ptr(graph, from);
    
        while (VecLen(neighbors)) {
            GraphNodeId to = VecLast(neighbors);
            if (!graph_remove_edge_now(graph, from, to)) {
                LOG_FATAL("Graph failed to remove outgoing edge during node deletion");
        for (slot_index = 0; slot_index < VecLen(&graph->slots); slot_index++) {
            const GenericGraphSlot *slot    = VecPtrAt((GraphSlots *)&graph->slots, slot_index);
            GraphNodeId             self_id = graph_make_node_id((u32)slot_index, slot->generation);
            u64                     neighbor_i;
    
                for (neighbor_i = 0; neighbor_i < VecLen(&slot->out_neighbors); neighbor_i++) {
                    GraphNodeId             neighbor_id = VecAt(&slot->out_neighbors, neighbor_i);
                    const GenericGraphSlot *target_slot;
    
                for (neighbor_i = 0; neighbor_i < VecLen(&slot->in_neighbors); neighbor_i++) {
                    GraphNodeId             predecessor_id = VecAt(&slot->in_neighbors, neighbor_i);
                    const GenericGraphSlot *source_slot;
                graph_release_slot(graph, slot, item_size);
            } else {
                deinit_vec(GENERIC_VEC(&slot->out_neighbors), sizeof(GraphNodeId));
                slot->out_neighbors = VecInitT(slot->out_neighbors, graph->allocator);
                deinit_vec(GENERIC_VEC(&slot->in_neighbors), sizeof(GraphNodeId));
                deinit_vec(GENERIC_VEC(&slot->out_neighbors), sizeof(GraphNodeId));
                slot->out_neighbors = VecInitT(slot->out_neighbors, graph->allocator);
                deinit_vec(GENERIC_VEC(&slot->in_neighbors), sizeof(GraphNodeId));
                slot->in_neighbors = VecInitT(slot->in_neighbors, graph->allocator);
                slot->visit_count  = 0;
    }
    
    GraphNodeId graph_push_node(GenericGraph *graph, const void *item_data, size item_size) {
        GraphNodeId       node_id;
        GenericGraphSlot  slot;
    
    GraphNodeId graph_push_node(GenericGraph *graph, const void *item_data, size item_size) {
        GraphNodeId       node_id;
        GenericGraphSlot  slot;
        GenericGraphSlot *slot_ptr;
                graph_free_node_data(graph, slot_ptr->data, item_size);
                slot_ptr->data = NULL;
                deinit_vec(GENERIC_VEC(&slot_ptr->out_neighbors), sizeof(GraphNodeId));
                slot_ptr->out_neighbors = VecInitT(slot_ptr->out_neighbors, graph->allocator);
                deinit_vec(GENERIC_VEC(&slot_ptr->in_neighbors), sizeof(GraphNodeId));
                deinit_vec(GENERIC_VEC(&slot_ptr->out_neighbors), sizeof(GraphNodeId));
                slot_ptr->out_neighbors = VecInitT(slot_ptr->out_neighbors, graph->allocator);
                deinit_vec(GENERIC_VEC(&slot_ptr->in_neighbors), sizeof(GraphNodeId));
                slot_ptr->in_neighbors = VecInitT(slot_ptr->in_neighbors, graph->allocator);
                slot_ptr->visit_count  = 0;
            )) {
            graph_free_node_data(graph, slot.data, item_size);
            deinit_vec(GENERIC_VEC(&slot.out_neighbors), sizeof(GraphNodeId));
            deinit_vec(GENERIC_VEC(&slot.in_neighbors), sizeof(GraphNodeId));
            return 0;
            graph_free_node_data(graph, slot.data, item_size);
            deinit_vec(GENERIC_VEC(&slot.out_neighbors), sizeof(GraphNodeId));
            deinit_vec(GENERIC_VEC(&slot.in_neighbors), sizeof(GraphNodeId));
            return 0;
        }
    }
    
    GraphNodeId graph_push_node_owned(GenericGraph *graph, void *item_data, size item_size) {
        GraphNodeId node_id;
    
    GraphNodeId graph_push_node_owned(GenericGraph *graph, void *item_data, size item_size) {
        GraphNodeId node_id;
    
        if (!graph || !item_data || !item_size) {
    }
    
    bool graph_contains_node(GenericGraph *graph, GraphNodeId node_id) {
        u32               index;
        u32               generation;
    }
    
    GraphNode graph_get_node(GenericGraph *graph, GraphNodeId node_id) {
        GraphNode node;
    }
    
    void *graph_node_ptr_at(GenericGraph *graph, GraphNodeId node_id) {
        return graph_require_live_slot(graph, node_id)->data;
    }
    }
    
    GraphNeighbors *graph_out_neighbors_ptr(GenericGraph *graph, GraphNodeId node_id) {
        return &graph_require_live_slot(graph, node_id)->out_neighbors;
    }
    }
    
    GraphNeighbors *graph_in_neighbors_ptr(GenericGraph *graph, GraphNodeId node_id) {
        return &graph_require_live_slot(graph, node_id)->in_neighbors;
    }
    }
    
    size graph_out_degree(GenericGraph *graph, GraphNodeId node_id) {
        return VecLen(graph_out_neighbors_ptr(graph, node_id));
    }
    }
    
    size graph_in_degree(GenericGraph *graph, GraphNodeId node_id) {
        return VecLen(graph_in_neighbors_ptr(graph, node_id));
    }
    }
    
    GraphNodeId graph_neighbor_at(GenericGraph *graph, GraphNodeId from, size neighbor_idx) {
        GraphNeighbors *neighbors;
    }
    
    GraphNodeId graph_predecessor_at(GenericGraph *graph, GraphNodeId to, size predecessor_idx) {
        GraphNeighbors *neighbors;
    }
    
    bool graph_has_edge(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
        GraphNeighbors *neighbors;
    }
    
    bool graph_add_edge(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
        GraphNeighbors *out_neighbors;
        GraphNeighbors *in_neighbors;
                GENERIC_VEC(out_neighbors),
                (const u8 *)&to,
                sizeof(GraphNodeId),
                VecLen(out_neighbors),
                1
                GENERIC_VEC(in_neighbors),
                (const u8 *)&from,
                sizeof(GraphNodeId),
                VecLen(in_neighbors),
                1
                1
            )) {
            remove_range_vec(GENERIC_VEC(out_neighbors), NULL, sizeof(GraphNodeId), VecLen(out_neighbors) - 1, 1);
            return false;
        }
    }
    
    bool graph_mark_edge_for_removal(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
        GraphPendingEdgeRemoval pending;
    }
    
    bool graph_edge_marked_for_removal(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
        ValidateGraph(graph);
        graph_validate_node_id(graph, from);
    }
    
    bool graph_unmark_edge_for_removal(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
        size idx;
            GenericGraphSlot *slot = VecPtrAt(&graph->slots, slot_index);
            if (graph_slot_is_occupied(slot) && graph_slot_is_marked(slot)) {
                GraphNodeId marked_id = graph_make_node_id((u32)slot_index, slot->generation);
                (void)graph_remove_all_outgoing_edges(graph, marked_id);
            }
            GenericGraphSlot *slot = VecPtrAt(&graph->slots, slot_index);
            if (graph_slot_is_occupied(slot) && !graph_slot_is_marked(slot)) {
                GraphNodeId live_id = graph_make_node_id((u32)slot_index, slot->generation);
                (void)graph_remove_marked_outgoing_edges(graph, live_id);
            }
    
        while (iter->neighbor_index < VecLen(neighbors)) {
            GraphNodeId neighbor_id  = VecAt(neighbors, iter->neighbor_index);
            iter->neighbor_index    += 1;
    
        while (iter->predecessor_index < VecLen(neighbors)) {
            GraphNodeId predecessor_id  = VecAt(neighbors, iter->predecessor_index);
            iter->predecessor_index    += 1;
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a    = GraphAddNodeR(&graph, 10);
        GraphNode   node = GraphGetNode(&graph, a);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphAddEdge(&graph, a, b);
        result = result && (GraphPredecessorAt(&graph, a, 0) == c);
    
        GraphNodeId d = GraphAddNodeR(&graph, 40);
    
        result = result && (GraphNodeIdIndex(d) == GraphNodeIdIndex(b));
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a    = GraphAddNodeR(&graph, 10);
        GraphNode   node = GraphGetNode(&graph, a);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
    
        bool result = GraphAddEdge(&graph, a, a);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId d = GraphAddNodeR(&graph, 40);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId d = GraphAddNodeR(&graph, 40);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId d = GraphAddNodeR(&graph, 40);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a         = GraphAddNodeR(&graph, 10);
        GraphNodeId b         = GraphAddNodeR(&graph, 20);
        u64         counts[2] = {0};
    
        GraphNodeId a         = GraphAddNodeR(&graph, 10);
        GraphNodeId b         = GraphAddNodeR(&graph, 20);
        u64         counts[2] = {0};
        result      = result && !GraphContainsNode(&graph, b);
    
        GraphNodeId reused = GraphAddNodeR(&graph, 99);
    
        result = result && (GraphNodeIdIndex(reused) == GraphNodeIdIndex(b));
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a    = GraphAddNodeR(&graph, 10);
        GraphNode   node = GraphGetNode(&graph, a);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        // a.out = [c, b] -- the kept edge (a->c) comes first, the edge to the
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        // Delete b so its slot is free at the time GraphClear walks it.
        // A valid op after clear runs ValidateGraph; on the mutant the pre-free
        // slot carries a bogus visit_count and validation aborts here.
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        result        = result && GraphContainsNode(&graph, c);
        result        = result && (GraphNodeCount(&graph) == 1);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
        // Valid op runs ValidateGraph; on the mutant free_indices is over-long and
        // slot accounting is inconsistent, so validation aborts before this runs.
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        result        = result && GraphContainsNode(&graph, c);
        result        = result && (GraphNodeCount(&graph) == 1);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphAddEdge(&graph, a, c);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        (void)GraphMarkNodeForDeletion(GraphGetNode(&graph, a));
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        (void)GraphMarkNodeForDeletion(GraphGetNode(&graph, b));
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        (void)GraphMarkNodeForDeletion(GraphGetNode(&graph, a));
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        (void)GraphMarkNodeForDeletion(GraphGetNode(&graph, b));
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        // a.out = [b]; b.in = [a]; the buffers physically hold those ids.
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        (void)b;
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        (void)b;
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        (void)b;
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        (void)b;
    
        bool        result            = VecCapacity(&graph.slots) >= 8;
        GraphNodeId first_id          = GraphAddNodeR(&graph, 10);
        GraphNodeId second_id         = GraphAddNodeR(&graph, 20);
        GraphNodeId third_id          = GraphAddNodeR(&graph, 30);
        bool        result            = VecCapacity(&graph.slots) >= 8;
        GraphNodeId first_id          = GraphAddNodeR(&graph, 10);
        GraphNodeId second_id         = GraphAddNodeR(&graph, 20);
        GraphNodeId third_id          = GraphAddNodeR(&graph, 30);
        u64         slot_count        = VecLen(&graph.slots);
        GraphNodeId first_id          = GraphAddNodeR(&graph, 10);
        GraphNodeId second_id         = GraphAddNodeR(&graph, 20);
        GraphNodeId third_id          = GraphAddNodeR(&graph, 30);
        u64         slot_count        = VecLen(&graph.slots);
        size        slot_capacity     = VecCapacity(&graph.slots);
        StrGraph    graph = GraphInitWithDeepCopy(str_init_copy, str_deinit, &alloc);
        Str         name  = StrInitFromZstr("alpha", &alloc);
        GraphNodeId node_id;
        GraphNode   node;
        Str        *stored_name;
        typedef Graph(Str) StrGraph;
        StrGraph    graph = GraphInitWithDeepCopy(NULL, str_deinit, &alloc);
        GraphNodeId node_id;
        GraphNode   node;
        Str        *stored_name;
        IntGraph graph = GraphInit(&dbg);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphAddEdge(&graph, a, b);
        int      shared = 7;
    
        GraphNodeId id0 = GraphAddNodeL(&graph, owned);
        GraphNodeId id1 = GraphAddNodeR(&graph, shared);
    
        GraphNodeId id0 = GraphAddNodeL(&graph, owned);
        GraphNodeId id1 = GraphAddNodeR(&graph, shared);
    
        bool result = GraphNodeIdIndex(id0) == 0 && GraphNodeIdGeneration(id0) == 1 && GraphNodeIdIndex(id1) == 1;
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
    
        bool result = GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
    
        bool result = GraphAddEdge(&graph, a, a);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
    
        u64         old_epoch = GraphMutationEpoch(&graph);
        GraphNodeId reused    = GraphAddNodeR(&graph, 99);
    
        bool result = (GraphNodeIdIndex(reused) == GraphNodeIdIndex(b));
        IntGraph graph = GraphInitWithDeepCopy(flaky_int_copy, NULL, &alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
    
        g_fail_copy           = true;
        GraphNodeId failed_id = GraphAddNodeR(&graph, 30);
        g_fail_copy           = false;
        g_fail_copy           = false;
    
        GraphNodeId reused = GraphAddNodeR(&graph, 40);
    
        bool result = (failed_id == 0);
        IntGraph graph = GraphInitWithDeepCopy(flaky_int_copy, NULL, &alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        (void)GraphMarkNodeForDeletion(GraphGetNode(&graph, b));
    
        g_fail_copy           = true;
        GraphNodeId failed_id = GraphAddNodeR(&graph, 42);
        g_fail_copy           = false;
        IntGraph graph = GraphInitWithDeepCopy(flaky_int_copy, NULL, &dbg);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
    
        g_fail_copy           = true;
        GraphNodeId failed_id = GraphAddNodeR(&graph, 30); // reuses b's slot, copy fails
        g_fail_copy           = false;
    
    // Fetch the type-erased slot for a node id (slots vec is shared-layout).
    static GenericGraphSlot *mutant_slot(void *graph_handle, GraphNodeId id) {
        GenericGraph *g = GENERIC_GRAPH(graph_handle);
        return (GenericGraphSlot *)VecPtrAt(&g->slots, GraphNodeIdIndex(id));
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId node_id = GraphAddNodeR(&graph, 11);
        GraphNode   node    = GraphGetNode(&graph, node_id);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
        // validator (sets the validated bit), so the next ValidateGraph walks the
        // slots and recomputes marked_count.
        GraphNodeId d = GraphAddNodeR(&graph, 40);
        (void)d;
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphAddEdge(&graph, b, a);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphAddEdge(&graph, b, a);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        (void)GraphMarkNodeForDeletion(GraphGetNode(&graph, b));
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a; // a keeps slot 0 occupied; only b is deleted to seed free_indices.
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a; // a keeps slot 0 occupied; only b is deleted to seed free_indices.
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        (void)GraphMarkNodeForDeletion(GraphGetNode(&graph, b));
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId d = GraphAddNodeR(&graph, 40);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId d = GraphAddNodeR(&graph, 40);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId d = GraphAddNodeR(&graph, 40);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId d = GraphAddNodeR(&graph, 40);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId d = GraphAddNodeR(&graph, 40);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId d = GraphAddNodeR(&graph, 40);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        (void)GraphAddEdge(&graph, a, b);
    
    static u64 node_id_hash(const void *data, u32 size) {
        u64 x = *(const GraphNodeId *)data;
        (void)size;
    
    static i32 node_id_compare(const void *lhs, const void *rhs) {
        GraphNodeId a = *(const GraphNodeId *)lhs;
        GraphNodeId b = *(const GraphNodeId *)rhs;
        return (a > b) - (a < b);
    static i32 node_id_compare(const void *lhs, const void *rhs) {
        GraphNodeId a = *(const GraphNodeId *)lhs;
        GraphNodeId b = *(const GraphNodeId *)rhs;
        return (a > b) - (a < b);
    }
    
    typedef Graph(Str) CityGraph;
    typedef Map(Str, GraphNodeId) CityIndex;
    
    static GraphNodeId city_add_intersection(CityGraph *graph, CityIndex *index, const Str *name, DefaultAllocator *alloc) {
    typedef Map(Str, GraphNodeId) CityIndex;
    
    static GraphNodeId city_add_intersection(CityGraph *graph, CityIndex *index, const Str *name, DefaultAllocator *alloc) {
        GraphNodeId id = GraphAddNodeR(graph, StrInitFromCstr(StrBegin(name), StrLen(name), alloc));
    
    static GraphNodeId city_add_intersection(CityGraph *graph, CityIndex *index, const Str *name, DefaultAllocator *alloc) {
        GraphNodeId id = GraphAddNodeR(graph, StrInitFromCstr(StrBegin(name), StrLen(name), alloc));
    
        Str key_copy = StrInitFromCstr(StrBegin(name), StrLen(name), alloc);
    }
    
    static bool city_reachable_from(GraphNode node, GraphNodeId goal_id) {
        if (GraphNodeVisitCount(node) > 0) {
            return false;
    
    static bool city_reachable(CityGraph *graph, CityIndex *index, const Str *from, const Str *to) {
        GraphNodeId *from_id = MapGetFirstPtr(index, *from);
        GraphNodeId *to_id   = MapGetFirstPtr(index, *to);
    static bool city_reachable(CityGraph *graph, CityIndex *index, const Str *from, const Str *to) {
        GraphNodeId *from_id = MapGetFirstPtr(index, *from);
        GraphNodeId *to_id   = MapGetFirstPtr(index, *to);
    
        if (!from_id || !to_id) {
        Str s_unknown = StrInitFromZstr("Unknown", &alloc);
    
        GraphNodeId alpha = city_add_intersection(&graph, &index, &s_alpha, &alloc);
        GraphNodeId beta  = city_add_intersection(&graph, &index, &s_beta, &alloc);
        GraphNodeId gamma = city_add_intersection(&graph, &index, &s_gamma, &alloc);
    
        GraphNodeId alpha = city_add_intersection(&graph, &index, &s_alpha, &alloc);
        GraphNodeId beta  = city_add_intersection(&graph, &index, &s_beta, &alloc);
        GraphNodeId gamma = city_add_intersection(&graph, &index, &s_gamma, &alloc);
        GraphNodeId delta = city_add_intersection(&graph, &index, &s_delta, &alloc);
        GraphNodeId alpha = city_add_intersection(&graph, &index, &s_alpha, &alloc);
        GraphNodeId beta  = city_add_intersection(&graph, &index, &s_beta, &alloc);
        GraphNodeId gamma = city_add_intersection(&graph, &index, &s_gamma, &alloc);
        GraphNodeId delta = city_add_intersection(&graph, &index, &s_delta, &alloc);
        GraphNodeId echo  = city_add_intersection(&graph, &index, &s_echo, &alloc);
        GraphNodeId beta  = city_add_intersection(&graph, &index, &s_beta, &alloc);
        GraphNodeId gamma = city_add_intersection(&graph, &index, &s_gamma, &alloc);
        GraphNodeId delta = city_add_intersection(&graph, &index, &s_delta, &alloc);
        GraphNodeId echo  = city_add_intersection(&graph, &index, &s_echo, &alloc);
        GraphNodeId gamma = city_add_intersection(&graph, &index, &s_gamma, &alloc);
        GraphNodeId delta = city_add_intersection(&graph, &index, &s_delta, &alloc);
        GraphNodeId echo  = city_add_intersection(&graph, &index, &s_echo, &alloc);
    
        GraphAddEdge(&graph, alpha, beta);
    
        typedef Graph(int) IntGraph;
        typedef Map(GraphNodeId, u64) CountMap;
    
        IntGraph graph  = GraphInit(&alloc);
        CountMap counts = MapInit(node_id_hash, node_id_compare, &alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId d = GraphAddNodeR(&graph, 4);
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId d = GraphAddNodeR(&graph, 4);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId d = GraphAddNodeR(&graph, 4);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId d = GraphAddNodeR(&graph, 4);
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId d = GraphAddNodeR(&graph, 4);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId d = GraphAddNodeR(&graph, 4);
    
        GraphAddEdge(&graph, a, d);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
    
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId d = GraphAddNodeR(&graph, 4);
        GraphNodeId a = GraphAddNodeR(&graph, 1);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId d = GraphAddNodeR(&graph, 4);
        GraphNodeId b = GraphAddNodeR(&graph, 2);
        GraphNodeId c = GraphAddNodeR(&graph, 3);
        GraphNodeId d = GraphAddNodeR(&graph, 4);
    
        GraphAddEdge(&graph, a, c);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        (void)a;
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        (void)a;
        (void)c;
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphAddEdge(&graph, a, b);
        // without bumping the mutation epoch or re-flagging the validated bit.
        GenericGraphSlot *slot_a = (GenericGraphSlot *)VecPtrAt(&GENERIC_GRAPH(&graph)->slots, GraphNodeIdIndex(a));
        GraphNodeId      *entry  = VecPtrAt(&slot_a->out_neighbors, 0);
        *entry                   = (GraphNodeId)GraphNodeIdIndex(b);
        GenericGraphSlot *slot_a = (GenericGraphSlot *)VecPtrAt(&GENERIC_GRAPH(&graph)->slots, GraphNodeIdIndex(a));
        GraphNodeId      *entry  = VecPtrAt(&slot_a->out_neighbors, 0);
        *entry                   = (GraphNodeId)GraphNodeIdIndex(b);
    
        GraphNode out = {0};
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphAddEdge(&graph, a, b);
        // is 0, leaving the epoch and validated bit untouched.
        GenericGraphSlot *slot_b = (GenericGraphSlot *)VecPtrAt(&GENERIC_GRAPH(&graph)->slots, GraphNodeIdIndex(b));
        GraphNodeId      *entry  = VecPtrAt(&slot_b->in_neighbors, 0);
        *entry                   = (GraphNodeId)GraphNodeIdIndex(a);
        GenericGraphSlot *slot_b = (GenericGraphSlot *)VecPtrAt(&GENERIC_GRAPH(&graph)->slots, GraphNodeIdIndex(b));
        GraphNodeId      *entry  = VecPtrAt(&slot_b->in_neighbors, 0);
        *entry                   = (GraphNodeId)GraphNodeIdIndex(a);
    
        GraphNode out = {0};
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
    
        // Capture a handle, then delete + commit + reuse a's slot so the captured
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
    // GraphNodeId is a u64 laid out as (generation << 32) | index -- see
    // GraphNodeIdIndex / GraphNodeIdGeneration in Graph/Type.h.
    static GraphNodeId make_raw_node_id(u32 index, u32 generation) {
        return ((GraphNodeId)generation << 32) | (GraphNodeId)index;
    }
    // GraphNodeIdIndex / GraphNodeIdGeneration in Graph/Type.h.
    static GraphNodeId make_raw_node_id(u32 index, u32 generation) {
        return ((GraphNodeId)generation << 32) | (GraphNodeId)index;
    }
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNode   node_b;
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        GraphNodeId c = GraphAddNodeR(&graph, 30);
        GraphNode   node_b;
        GraphAddEdge(&graph, a, b);
        ZstrGraph graph = GraphInit(&alloc);
    
        GraphNodeId red   = GraphAddNodeR(&graph, "red");
        GraphNodeId green = GraphAddNodeR(&graph, "green");
        GraphNodeId blue  = GraphAddNodeR(&graph, "blue");
    
        GraphNodeId red   = GraphAddNodeR(&graph, "red");
        GraphNodeId green = GraphAddNodeR(&graph, "green");
        GraphNodeId blue  = GraphAddNodeR(&graph, "blue");
        GraphNodeId red   = GraphAddNodeR(&graph, "red");
        GraphNodeId green = GraphAddNodeR(&graph, "green");
        GraphNodeId blue  = GraphAddNodeR(&graph, "blue");
    
        GraphAddEdge(&graph, red, green);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphAddEdge(&graph, a, b);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
    
        bool result = GraphContainsNode(&graph, a);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
    
        bool result = GraphContainsNode(&graph, a);
        // generation. Real code: slot is unoccupied => not contained. Mutant:
        // occupancy term forced truthy + generation matches => wrongly contained.
        GraphNodeId free_slot_id = make_raw_node_id(GraphNodeIdIndex(a), GraphNodeIdGeneration(a) + 1);
        result                   = result && !GraphContainsNode(&graph, free_slot_id);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
        GraphNodeId b = GraphAddNodeR(&graph, 20);
        (void)a;
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
    
        (void)GraphMarkNodeForDeletion(GraphGetNode(&graph, a));
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
    
        // index 5 does not exist; generation 1 is otherwise plausible.
    
        // index 5 does not exist; generation 1 is otherwise plausible.
        GraphNodeId bogus_to = make_raw_node_id(5, 1);
    
        (void)GraphHasEdge(&graph, a, bogus_to);
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
    
        (void)GraphMarkNodeForDeletion(GraphGetNode(&graph, a));
        IntGraph graph = GraphInit(&alloc);
    
        GraphNodeId a = GraphAddNodeR(&graph, 10);
    
        (void)GraphMarkNodeForDeletion(GraphGetNode(&graph, a));
        // id with that exact generation: index in bounds, generation nonzero and
        // matching, slot unoccupied -> only the occupancy guard rejects it.
        GraphNodeId free_match = make_raw_node_id(GraphNodeIdIndex(a), GraphNodeIdGeneration(a) + 1);
    
        (void)GraphGetNode(&graph, free_match);
Last updated on