2025-12-21 08:44:04 +01:00
|
|
|
#include "amduat/tgk/store.h"
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
static void amduat_tgk_store_reference_free(amduat_reference_t *ref) {
|
|
|
|
|
if (ref == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
free((void *)ref->digest.data);
|
|
|
|
|
ref->digest.data = NULL;
|
|
|
|
|
ref->digest.len = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void amduat_tgk_store_init(amduat_tgk_store_t *store,
|
|
|
|
|
amduat_tgk_store_config_t config,
|
|
|
|
|
amduat_tgk_store_ops_t ops,
|
|
|
|
|
void *ctx) {
|
|
|
|
|
if (store == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
store->config = config;
|
|
|
|
|
store->ops = ops;
|
|
|
|
|
store->ctx = ctx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool amduat_tgk_store_get_config(amduat_tgk_store_t *store,
|
|
|
|
|
amduat_tgk_store_config_t *out_config) {
|
|
|
|
|
if (store == NULL || store->ops.get_config == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return store->ops.get_config(store->ctx, out_config);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-21 21:09:01 +01:00
|
|
|
bool amduat_tgk_store_snapshot_id(amduat_tgk_store_t *store,
|
|
|
|
|
amduat_tgk_snapshot_id_t *out_id) {
|
|
|
|
|
if (store == NULL || store->ops.snapshot_id == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return store->ops.snapshot_id(store->ctx, out_id);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-21 08:44:04 +01:00
|
|
|
amduat_tgk_graph_error_t amduat_tgk_store_resolve_edge(
|
|
|
|
|
amduat_tgk_store_t *store,
|
|
|
|
|
amduat_reference_t ref,
|
|
|
|
|
amduat_tgk_edge_body_t *out_body) {
|
|
|
|
|
if (store == NULL || store->ops.resolve_edge == NULL) {
|
|
|
|
|
return GS_ERR_UNSUPPORTED;
|
|
|
|
|
}
|
|
|
|
|
return store->ops.resolve_edge(store->ctx, ref, out_body);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool amduat_tgk_store_edges_from(amduat_tgk_store_t *store,
|
|
|
|
|
amduat_reference_t node,
|
|
|
|
|
amduat_tgk_edge_type_filter_t type_filter,
|
|
|
|
|
amduat_tgk_graph_edge_view_list_t *out_edges) {
|
|
|
|
|
if (store == NULL || store->ops.edges_from == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return store->ops.edges_from(store->ctx, node, type_filter, out_edges);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool amduat_tgk_store_edges_to(amduat_tgk_store_t *store,
|
|
|
|
|
amduat_reference_t node,
|
|
|
|
|
amduat_tgk_edge_type_filter_t type_filter,
|
|
|
|
|
amduat_tgk_graph_edge_view_list_t *out_edges) {
|
|
|
|
|
if (store == NULL || store->ops.edges_to == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return store->ops.edges_to(store->ctx, node, type_filter, out_edges);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool amduat_tgk_store_edges_incident(
|
|
|
|
|
amduat_tgk_store_t *store,
|
|
|
|
|
amduat_reference_t node,
|
|
|
|
|
amduat_tgk_edge_type_filter_t type_filter,
|
|
|
|
|
amduat_tgk_graph_edge_view_list_t *out_edges) {
|
|
|
|
|
if (store == NULL || store->ops.edges_incident == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return store->ops.edges_incident(store->ctx, node, type_filter, out_edges);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool amduat_tgk_store_scan_edges(amduat_tgk_store_t *store,
|
|
|
|
|
amduat_tgk_edge_type_filter_t type_filter,
|
|
|
|
|
amduat_octets_t page_token,
|
|
|
|
|
bool has_page_token,
|
|
|
|
|
amduat_tgk_graph_scan_result_t *out_scan) {
|
|
|
|
|
if (store == NULL || store->ops.scan_edges == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return store->ops.scan_edges(store->ctx, type_filter, page_token,
|
|
|
|
|
has_page_token, out_scan);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool amduat_tgk_store_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) {
|
|
|
|
|
if (store == NULL || store->ops.neighbors == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return store->ops.neighbors(store->ctx, node, type_filter, direction,
|
|
|
|
|
out_nodes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void amduat_tgk_graph_edge_view_list_free(
|
|
|
|
|
amduat_tgk_graph_edge_view_list_t *list) {
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
if (list == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (list->edges == NULL) {
|
|
|
|
|
list->len = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for (i = 0; i < list->len; ++i) {
|
|
|
|
|
amduat_tgk_store_reference_free(&list->edges[i].edge_ref);
|
|
|
|
|
amduat_tgk_edge_body_free(&list->edges[i].body);
|
|
|
|
|
}
|
|
|
|
|
free(list->edges);
|
|
|
|
|
list->edges = NULL;
|
|
|
|
|
list->len = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void amduat_tgk_node_list_free(amduat_tgk_node_list_t *list) {
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
if (list == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (list->nodes == NULL) {
|
|
|
|
|
list->len = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for (i = 0; i < list->len; ++i) {
|
|
|
|
|
amduat_tgk_store_reference_free(&list->nodes[i]);
|
|
|
|
|
}
|
|
|
|
|
free(list->nodes);
|
|
|
|
|
list->nodes = NULL;
|
|
|
|
|
list->len = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void amduat_tgk_graph_scan_result_free(amduat_tgk_graph_scan_result_t *scan) {
|
|
|
|
|
if (scan == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
amduat_tgk_graph_edge_view_list_free(&scan->edges);
|
|
|
|
|
free((void *)scan->next_page_token.data);
|
|
|
|
|
scan->next_page_token.data = NULL;
|
|
|
|
|
scan->next_page_token.len = 0;
|
|
|
|
|
scan->has_next_page = false;
|
|
|
|
|
}
|