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)
- In
Graph.c:16:
#define GRAPH_SLOT_MARKED ((u32)1u << 1)
static GraphNodeId graph_make_node_id(u32 index, u32 generation) {
return (((u64)generation) << 32) | (u64)index;
}- In
Graph.c:64:
}
static void graph_validate_node_id(const GenericGraph *graph, GraphNodeId node_id) {
u32 index;
u32 generation;- In
Graph.c:88:
}
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));- In
Graph.c:93:
}
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));- In
Graph.c:161:
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));- In
Graph.c:163:
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);- In
Graph.c:196:
}
static bool graph_neighbors_contains(const GraphNeighbors *neighbors, GraphNodeId node_id) {
size idx;- In
Graph.c:208:
}
static size graph_find_neighbor_index(const GraphNeighbors *neighbors, GraphNodeId node_id) {
size idx;- In
Graph.c:220:
}
static size graph_find_pending_edge_removal_index(const GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
size idx;- In
Graph.c:234:
}
static bool graph_remove_edge_now(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
GraphNeighbors *out_neighbors;
GraphNeighbors *in_neighbors;- In
Graph.c:252:
}
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;- In
Graph.c:253:
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;- In
Graph.c:258:
}
static size graph_remove_marked_outgoing_edges(GenericGraph *graph, GraphNodeId from) {
size removed = 0;
GraphNeighbors *neighbors = graph_out_neighbors_ptr(graph, from);- In
Graph.c:264:
while (idx < VecLen(neighbors)) {
GraphNodeId neighbor_id = VecAt(neighbors, idx);
const GenericGraphSlot *slot;- In
Graph.c:284:
}
static size graph_remove_all_outgoing_edges(GenericGraph *graph, GraphNodeId from) {
size removed = 0;
GraphNeighbors *neighbors = graph_out_neighbors_ptr(graph, from);- In
Graph.c:289:
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");- In
Graph.c:357:
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;- In
Graph.c:378:
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;- In
Graph.c:389:
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;- In
Graph.c:478:
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));- In
Graph.c:480:
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;- In
Graph.c:522:
}
GraphNodeId graph_push_node(GenericGraph *graph, const void *item_data, size item_size) {
GraphNodeId node_id;
GenericGraphSlot slot;- In
Graph.c:523:
GraphNodeId graph_push_node(GenericGraph *graph, const void *item_data, size item_size) {
GraphNodeId node_id;
GenericGraphSlot slot;
GenericGraphSlot *slot_ptr;- In
Graph.c:553:
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));- In
Graph.c:555:
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;- In
Graph.c:595:
)) {
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;- In
Graph.c:596:
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;
}- In
Graph.c:608:
}
GraphNodeId graph_push_node_owned(GenericGraph *graph, void *item_data, size item_size) {
GraphNodeId node_id;- In
Graph.c:609:
GraphNodeId graph_push_node_owned(GenericGraph *graph, void *item_data, size item_size) {
GraphNodeId node_id;
if (!graph || !item_data || !item_size) {- In
Graph.c:624:
}
bool graph_contains_node(GenericGraph *graph, GraphNodeId node_id) {
u32 index;
u32 generation;- In
Graph.c:646:
}
GraphNode graph_get_node(GenericGraph *graph, GraphNodeId node_id) {
GraphNode node;- In
Graph.c:657:
}
void *graph_node_ptr_at(GenericGraph *graph, GraphNodeId node_id) {
return graph_require_live_slot(graph, node_id)->data;
}- In
Graph.c:671:
}
GraphNeighbors *graph_out_neighbors_ptr(GenericGraph *graph, GraphNodeId node_id) {
return &graph_require_live_slot(graph, node_id)->out_neighbors;
}- In
Graph.c:675:
}
GraphNeighbors *graph_in_neighbors_ptr(GenericGraph *graph, GraphNodeId node_id) {
return &graph_require_live_slot(graph, node_id)->in_neighbors;
}- In
Graph.c:679:
}
size graph_out_degree(GenericGraph *graph, GraphNodeId node_id) {
return VecLen(graph_out_neighbors_ptr(graph, node_id));
}- In
Graph.c:683:
}
size graph_in_degree(GenericGraph *graph, GraphNodeId node_id) {
return VecLen(graph_in_neighbors_ptr(graph, node_id));
}- In
Graph.c:687:
}
GraphNodeId graph_neighbor_at(GenericGraph *graph, GraphNodeId from, size neighbor_idx) {
GraphNeighbors *neighbors;- In
Graph.c:701:
}
GraphNodeId graph_predecessor_at(GenericGraph *graph, GraphNodeId to, size predecessor_idx) {
GraphNeighbors *neighbors;- In
Graph.c:715:
}
bool graph_has_edge(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
GraphNeighbors *neighbors;- In
Graph.c:726:
}
bool graph_add_edge(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
GraphNeighbors *out_neighbors;
GraphNeighbors *in_neighbors;- In
Graph.c:743:
GENERIC_VEC(out_neighbors),
(const u8 *)&to,
sizeof(GraphNodeId),
VecLen(out_neighbors),
1- In
Graph.c:752:
GENERIC_VEC(in_neighbors),
(const u8 *)&from,
sizeof(GraphNodeId),
VecLen(in_neighbors),
1- In
Graph.c:756:
1
)) {
remove_range_vec(GENERIC_VEC(out_neighbors), NULL, sizeof(GraphNodeId), VecLen(out_neighbors) - 1, 1);
return false;
}- In
Graph.c:850:
}
bool graph_mark_edge_for_removal(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
GraphPendingEdgeRemoval pending;- In
Graph.c:876:
}
bool graph_edge_marked_for_removal(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
ValidateGraph(graph);
graph_validate_node_id(graph, from);- In
Graph.c:884:
}
bool graph_unmark_edge_for_removal(GenericGraph *graph, GraphNodeId from, GraphNodeId to) {
size idx;- In
Graph.c:922:
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);
}- In
Graph.c:930:
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);
}- In
Graph.c:1027:
while (iter->neighbor_index < VecLen(neighbors)) {
GraphNodeId neighbor_id = VecAt(neighbors, iter->neighbor_index);
iter->neighbor_index += 1;- In
Graph.c:1074:
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);
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);- In
Graph.Type.c:42:
IntGraph graph = GraphInit(&alloc);
GraphNodeId node_id = GraphAddNodeR(&graph, 11);
GraphNode node = GraphGetNode(&graph, node_id);- In
Graph.Ops.c:15:
IntGraph graph = GraphInit(&alloc);
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNode node = GraphGetNode(&graph, a);- In
Graph.Ops.c:41:
IntGraph graph = GraphInit(&alloc);
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);- In
Graph.Ops.c:42:
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);- In
Graph.Ops.c:43:
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);
GraphAddEdge(&graph, a, b);- In
Graph.Ops.c:68:
result = result && (GraphPredecessorAt(&graph, a, 0) == c);
GraphNodeId d = GraphAddNodeR(&graph, 40);
result = result && (GraphNodeIdIndex(d) == GraphNodeIdIndex(b));- In
Graph.Ops.c:88:
IntGraph graph = GraphInit(&alloc);
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNode node = GraphGetNode(&graph, a);- In
Graph.Ops.c:115:
IntGraph graph = GraphInit(&alloc);
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);- In
Graph.Ops.c:116:
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);- In
Graph.Ops.c:117:
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);
GraphAddEdge(&graph, a, b);- In
Graph.Ops.c:164:
IntGraph graph = GraphInit(&alloc);
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);- In
Graph.Ops.c:165:
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphAddEdge(&graph, a, b);- In
Graph.Ops.c:193:
IntGraph graph = GraphInit(&alloc);
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);- In
Graph.Ops.c:194:
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);- In
Graph.Ops.c:195:
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);
GraphAddEdge(&graph, a, b);- In
Graph.Ops.c:227:
IntGraph graph = GraphInit(&alloc);
GraphNodeId a = GraphAddNodeR(&graph, 10);
bool result = GraphAddEdge(&graph, a, a);- In
Graph.Ops.c:253:
IntGraph graph = GraphInit(&alloc);
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);- In
Graph.Ops.c:254:
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);
GraphNodeId d = GraphAddNodeR(&graph, 40);- In
Graph.Ops.c:255:
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);
GraphNodeId d = GraphAddNodeR(&graph, 40);- In
Graph.Ops.c:256:
GraphNodeId b = GraphAddNodeR(&graph, 20);
GraphNodeId c = GraphAddNodeR(&graph, 30);
GraphNodeId d = GraphAddNodeR(&graph, 40);
GraphAddEdge(&graph, a, b);- In
Graph.Ops.c:289:
IntGraph graph = GraphInit(&alloc);
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
u64 counts[2] = {0};- In
Graph.Ops.c:290:
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNodeId b = GraphAddNodeR(&graph, 20);
u64 counts[2] = {0};- In
Graph.Ops.c:300:
result = result && !GraphContainsNode(&graph, b);
GraphNodeId reused = GraphAddNodeR(&graph, 99);
result = result && (GraphNodeIdIndex(reused) == GraphNodeIdIndex(b));- In
Graph.Ops.c:324:
IntGraph graph = GraphInit(&alloc);
GraphNodeId a = GraphAddNodeR(&graph, 10);
GraphNode node = GraphGetNode(&graph, a);- In
Graph.Init.c:22:
bool result = VecCapacity(&graph.slots) >= 8;
GraphNodeId first_id = GraphAddNodeR(&graph, 10);
GraphNodeId second_id = GraphAddNodeR(&graph, 20);
GraphNodeId third_id = GraphAddNodeR(&graph, 30);- In
Graph.Init.c:23:
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);- In
Graph.Init.c:24:
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);- In
Graph.Init.c:81:
StrGraph graph = GraphInitWithDeepCopy(str_init_copy, str_deinit, &alloc);
Str name = StrInitFromZstr("alpha", &alloc);
GraphNodeId node_id;
GraphNode node;
Str *stored_name;- In
Graph.Init.c:105:
typedef Graph(Str) StrGraph;
StrGraph graph = GraphInitWithDeepCopy(NULL, str_deinit, &alloc);
GraphNodeId node_id;
GraphNode node;
Str *stored_name; 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);
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);- In
Type.h:37:
/// TAGS: Graph, Node, Id, Index
///
#define GraphNodeIdIndex(id) ((u32)((GraphNodeId)(id) & UINT32_MAX))
///
- In
Type.h:49:
/// TAGS: Graph, Node, Id, Generation
///
#define GraphNodeIdGeneration(id) ((u32)(((GraphNodeId)(id) >> 32) & UINT32_MAX))
///
- In
Type.h:65:
typedef struct {
void *_graph_;
GraphNodeId _id_;
} GraphNode;- In
Type.h:76:
/// TAGS: Graph, Edge, Neighbor, Vec
///
typedef Vec(GraphNodeId) GraphNeighbors;
///
- In
Type.h:116:
typedef struct {
GraphNodeId from;
GraphNodeId to;
} GraphPendingEdgeRemoval;- In
Type.h:117:
typedef struct {
GraphNodeId from;
GraphNodeId to;
} GraphPendingEdgeRemoval;
Last updated on