Implemented identity-domain validation and duplicate EdgeRef detection in the in‑memory TGK store

This commit is contained in:
Carl Niklas Rydberg 2025-12-21 20:21:34 +01:00
parent 8f3282bbce
commit c298481025

View file

@ -5,21 +5,47 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static bool amduat_tgk_store_mem_id_space_valid(
amduat_tgk_id_space_config_t id_space) {
size_t i;
size_t j;
if (id_space.domains_len != 0 && id_space.domains == NULL) {
return false;
}
for (i = 0; i < id_space.domains_len; ++i) {
for (j = i + 1; j < id_space.domains_len; ++j) {
if (id_space.domains[i].hash_id == id_space.domains[j].hash_id) {
return false;
}
}
}
return true;
}
static bool amduat_tgk_store_mem_hash_id_supported( static bool amduat_tgk_store_mem_hash_id_supported(
const amduat_tgk_store_mem_t *mem, const amduat_tgk_store_mem_t *mem,
amduat_hash_id_t hash_id) { amduat_hash_id_t hash_id) {
size_t i; size_t i;
bool found = false;
if (mem == NULL) { if (mem == NULL) {
return false; return false;
} }
if (mem->config.id_space.domains_len != 0 &&
mem->config.id_space.domains == NULL) {
return false;
}
for (i = 0; i < mem->config.id_space.domains_len; ++i) { for (i = 0; i < mem->config.id_space.domains_len; ++i) {
if (mem->config.id_space.domains[i].hash_id == hash_id) { if (mem->config.id_space.domains[i].hash_id == hash_id) {
return true; if (found) {
}
}
return false; return false;
} }
found = true;
}
}
return found;
}
static bool amduat_tgk_store_mem_edge_tag_supported( static bool amduat_tgk_store_mem_edge_tag_supported(
const amduat_tgk_store_mem_t *mem, const amduat_tgk_store_mem_t *mem,
@ -91,6 +117,15 @@ static bool amduat_tgk_store_mem_type_filter_match(
return false; return false;
} }
static bool amduat_tgk_store_mem_artifact_eq(amduat_artifact_t a,
amduat_artifact_t b) {
if ((a.bytes.len != 0 && a.bytes.data == NULL) ||
(b.bytes.len != 0 && b.bytes.data == NULL)) {
return false;
}
return amduat_artifact_eq(a, b);
}
static bool amduat_tgk_store_mem_node_in_list( static bool amduat_tgk_store_mem_node_in_list(
amduat_reference_t node, amduat_reference_t node,
const amduat_reference_t *list, const amduat_reference_t *list,
@ -260,18 +295,59 @@ static bool amduat_tgk_store_mem_edge_view_clone(
static const amduat_tgk_store_mem_artifact_t * static const amduat_tgk_store_mem_artifact_t *
amduat_tgk_store_mem_lookup_artifact(const amduat_tgk_store_mem_t *mem, amduat_tgk_store_mem_lookup_artifact(const amduat_tgk_store_mem_t *mem,
amduat_reference_t ref) { amduat_reference_t ref,
bool *out_conflict) {
const amduat_tgk_store_mem_artifact_t *found = NULL;
size_t i; size_t i;
if (out_conflict != NULL) {
*out_conflict = false;
}
if (mem == NULL) { if (mem == NULL) {
return NULL; return NULL;
} }
for (i = 0; i < mem->artifacts_len; ++i) { for (i = 0; i < mem->artifacts_len; ++i) {
if (amduat_reference_eq(mem->artifacts[i].ref, ref)) { if (!amduat_reference_eq(mem->artifacts[i].ref, ref)) {
return &mem->artifacts[i]; continue;
}
if (found == NULL) {
found = &mem->artifacts[i];
continue;
}
if (!amduat_tgk_store_mem_artifact_eq(found->artifact,
mem->artifacts[i].artifact)) {
if (out_conflict != NULL) {
*out_conflict = true;
}
return found;
} }
} }
return NULL; return found;
}
static bool amduat_tgk_store_mem_check_duplicate_artifact(
const amduat_tgk_store_mem_artifact_t *artifacts,
size_t index,
bool *out_duplicate) {
size_t i;
if (out_duplicate != NULL) {
*out_duplicate = false;
}
for (i = 0; i < index; ++i) {
if (!amduat_reference_eq(artifacts[i].ref, artifacts[index].ref)) {
continue;
}
if (!amduat_tgk_store_mem_artifact_eq(artifacts[i].artifact,
artifacts[index].artifact)) {
return false;
}
if (out_duplicate != NULL) {
*out_duplicate = true;
}
return true;
}
return true;
} }
static amduat_tgk_graph_error_t amduat_tgk_store_mem_decode_edge( static amduat_tgk_graph_error_t amduat_tgk_store_mem_decode_edge(
@ -456,6 +532,7 @@ static amduat_tgk_graph_error_t amduat_tgk_store_mem_resolve_edge(
amduat_tgk_edge_body_t *out_body) { amduat_tgk_edge_body_t *out_body) {
amduat_tgk_store_mem_t *mem = (amduat_tgk_store_mem_t *)ctx; amduat_tgk_store_mem_t *mem = (amduat_tgk_store_mem_t *)ctx;
const amduat_tgk_store_mem_artifact_t *entry; const amduat_tgk_store_mem_artifact_t *entry;
bool conflict = false;
if (out_body != NULL) { if (out_body != NULL) {
memset(out_body, 0, sizeof(*out_body)); memset(out_body, 0, sizeof(*out_body));
@ -466,7 +543,10 @@ static amduat_tgk_graph_error_t amduat_tgk_store_mem_resolve_edge(
if (!amduat_tgk_store_mem_hash_id_supported(mem, ref.hash_id)) { if (!amduat_tgk_store_mem_hash_id_supported(mem, ref.hash_id)) {
return GS_ERR_UNSUPPORTED; return GS_ERR_UNSUPPORTED;
} }
entry = amduat_tgk_store_mem_lookup_artifact(mem, ref); entry = amduat_tgk_store_mem_lookup_artifact(mem, ref, &conflict);
if (conflict) {
return GS_ERR_INTEGRITY;
}
if (entry == NULL) { if (entry == NULL) {
return GS_ERR_ARTIFACT_ERROR; return GS_ERR_ARTIFACT_ERROR;
} }
@ -657,6 +737,9 @@ bool amduat_tgk_store_mem_init(amduat_tgk_store_mem_t *mem,
mem->edges = NULL; mem->edges = NULL;
mem->edges_len = 0; mem->edges_len = 0;
if (!amduat_tgk_store_mem_id_space_valid(config.id_space)) {
return false;
}
if (config.tgk_profiles.encodings_len != 0 && if (config.tgk_profiles.encodings_len != 0 &&
config.tgk_profiles.encodings == NULL) { config.tgk_profiles.encodings == NULL) {
return false; return false;
@ -685,7 +768,15 @@ bool amduat_tgk_store_mem_init(amduat_tgk_store_mem_t *mem,
amduat_tgk_edge_body_t body; amduat_tgk_edge_body_t body;
amduat_tgk_graph_error_t err; amduat_tgk_graph_error_t err;
const amduat_tgk_store_mem_artifact_t *entry = &artifacts[i]; const amduat_tgk_store_mem_artifact_t *entry = &artifacts[i];
bool duplicate = false;
if (!amduat_tgk_store_mem_check_duplicate_artifact(artifacts, i,
&duplicate)) {
goto cleanup;
}
if (duplicate) {
continue;
}
if (!amduat_tgk_store_mem_hash_id_supported(mem, entry->ref.hash_id)) { if (!amduat_tgk_store_mem_hash_id_supported(mem, entry->ref.hash_id)) {
continue; continue;
} }