From 8f3282bbce3354b800742fd411e12b18489dc9c1 Mon Sep 17 00:00:00 2001 From: Carl Niklas Rydberg Date: Sun, 21 Dec 2025 20:16:46 +0100 Subject: [PATCH] =?UTF-8?q?Updated=20TGK/PROV=20to=20no=20longer=20hard?= =?UTF-8?q?=E2=80=91require=20neighbors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tgk_stack/prov/prov.c | 83 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/src/tgk_stack/prov/prov.c b/src/tgk_stack/prov/prov.c index bfbc137..dfe7adb 100644 --- a/src/tgk_stack/prov/prov.c +++ b/src/tgk_stack/prov/prov.c @@ -283,6 +283,84 @@ static void amduat_tgk_prov_reference_list_free(amduat_reference_t *nodes, free(nodes); } +static bool amduat_tgk_prov_collect_neighbors( + amduat_tgk_store_t *store, + amduat_reference_t node, + amduat_tgk_edge_type_filter_t type_filter, + amduat_tgk_graph_direction_t direction, + amduat_tgk_node_list_t *out_nodes) { + amduat_reference_t *nodes = NULL; + size_t nodes_len = 0; + size_t nodes_cap = 0; + amduat_tgk_graph_edge_view_list_t edges = {0}; + size_t i; + size_t j; + + if (store == NULL || out_nodes == NULL) { + return false; + } + out_nodes->nodes = NULL; + out_nodes->len = 0; + + if (store->ops.neighbors != NULL) { + return store->ops.neighbors(store->ctx, node, type_filter, direction, + out_nodes); + } + + if (direction == AMDUAT_TGK_GRAPH_DIR_OUT || + direction == AMDUAT_TGK_GRAPH_DIR_BOTH) { + if (!amduat_tgk_store_edges_from(store, node, type_filter, &edges)) { + goto cleanup; + } + for (i = 0; i < edges.len; ++i) { + const amduat_tgk_edge_body_t *body = &edges.edges[i].body; + for (j = 0; j < body->to_len; ++j) { + if (!amduat_tgk_prov_node_set_add(body->to[j], &nodes, &nodes_len, + &nodes_cap)) { + amduat_tgk_graph_edge_view_list_free(&edges); + goto cleanup; + } + } + } + amduat_tgk_graph_edge_view_list_free(&edges); + edges.edges = NULL; + edges.len = 0; + } + + if (direction == AMDUAT_TGK_GRAPH_DIR_IN || + direction == AMDUAT_TGK_GRAPH_DIR_BOTH) { + if (!amduat_tgk_store_edges_to(store, node, type_filter, &edges)) { + goto cleanup; + } + for (i = 0; i < edges.len; ++i) { + const amduat_tgk_edge_body_t *body = &edges.edges[i].body; + for (j = 0; j < body->from_len; ++j) { + if (!amduat_tgk_prov_node_set_add(body->from[j], &nodes, &nodes_len, + &nodes_cap)) { + amduat_tgk_graph_edge_view_list_free(&edges); + goto cleanup; + } + } + } + amduat_tgk_graph_edge_view_list_free(&edges); + edges.edges = NULL; + edges.len = 0; + } + + if (nodes_len > 1) { + qsort(nodes, nodes_len, sizeof(*nodes), amduat_tgk_prov_ref_ptr_cmp); + } + + out_nodes->nodes = nodes; + out_nodes->len = nodes_len; + return true; + +cleanup: + amduat_tgk_graph_edge_view_list_free(&edges); + amduat_tgk_prov_reference_list_free(nodes, nodes_len); + return false; +} + static bool amduat_tgk_prov_edge_body_clone(const amduat_tgk_edge_body_t *src, amduat_tgk_edge_body_t *dst) { size_t i; @@ -471,8 +549,9 @@ static bool amduat_tgk_prov_build_depth_entries( neighbors.nodes = NULL; neighbors.len = 0; - if (!amduat_tgk_store_neighbors(store, builder.entries[index].node, - query.type_filter, dir, &neighbors)) { + if (!amduat_tgk_prov_collect_neighbors(store, builder.entries[index].node, + query.type_filter, dir, + &neighbors)) { amduat_tgk_node_list_free(&neighbors); goto cleanup; }