summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mcp/server.c4
-rw-r--r--src/mcp/tools/common/context.c1
-rw-r--r--src/mcp/tools/common/memory_index.c7
-rw-r--r--src/storage/store.c72
4 files changed, 77 insertions, 7 deletions
diff --git a/src/mcp/server.c b/src/mcp/server.c
index 498e9f4..a0ff436 100644
--- a/src/mcp/server.c
+++ b/src/mcp/server.c
@@ -30,10 +30,6 @@ tiny_convmem_server_run(FILE *input, FILE *output, tiny_store_t *store)
return 1;
}
status = mcpc_server_start(server);
- if (status != MCPC_EC_0)
- {
- fprintf(stderr, "mcpc server stopped with status %d\n", (int)status);
- }
tiny_mcp_tools_context_deactivate(context);
mcpc_server_close(server);
tiny_mcp_tools_context_free(context);
diff --git a/src/mcp/tools/common/context.c b/src/mcp/tools/common/context.c
index e833f70..bf59de9 100644
--- a/src/mcp/tools/common/context.c
+++ b/src/mcp/tools/common/context.c
@@ -1,5 +1,6 @@
#include "mcp/tools/common/context.h"
+#include <stdio.h>
#include <stdlib.h>
#include "base/allocator.h"
diff --git a/src/mcp/tools/common/memory_index.c b/src/mcp/tools/common/memory_index.c
index 36e430b..e3841e2 100644
--- a/src/mcp/tools/common/memory_index.c
+++ b/src/mcp/tools/common/memory_index.c
@@ -150,7 +150,12 @@ tiny_memory_index_build(const tiny_store_t *store)
{
const tiny_relation_t *value = &entry->message.metadata.relations[relation];
memory_bucket_t *target = find_bucket(index, value->message_id);
- if (!target || !add_incoming(target, position, value->type))
+ if (!target)
+ {
+ /* The relation target is missing (likely deleted during rebuild); skip it. */
+ continue;
+ }
+ if (!add_incoming(target, position, value->type))
{
tiny_memory_index_free(index);
return NULL;
diff --git a/src/storage/store.c b/src/storage/store.c
index 5701578..060c6f6 100644
--- a/src/storage/store.c
+++ b/src/storage/store.c
@@ -645,6 +645,72 @@ metadata_targets_valid(tiny_store_t *store, const char *self_id, const tiny_meta
return true;
}
+static bool
+prune_metadata_references(tiny_store_t *store, tiny_message_t *message)
+{
+ size_t index, write_index;
+ bool changed = false;
+ if (!store || !message)
+ {
+ return false;
+ }
+ /* Prune relations whose targets are deleted or missing. */
+ for (index = 0, write_index = 0; index < message->metadata.relation_count; ++index)
+ {
+ tiny_store_entry_t *target = find_entry(store, message->metadata.relations[index].message_id);
+ if (target && !target->deleted)
+ {
+ if (write_index != index)
+ {
+ message->metadata.relations[write_index] = message->metadata.relations[index];
+ }
+ write_index++;
+ }
+ else
+ {
+ changed = true;
+ }
+ }
+ if (changed)
+ {
+ message->metadata.relation_count = write_index;
+ if (write_index == 0)
+ {
+ free(message->metadata.relations);
+ message->metadata.relations = NULL;
+ }
+ }
+ /* Prune sources whose targets are deleted or missing. */
+ changed = false;
+ for (index = 0, write_index = 0; index < message->metadata.source_count; ++index)
+ {
+ tiny_store_entry_t *target = find_entry(store, message->metadata.source_message_ids[index]);
+ if (target && !target->deleted)
+ {
+ if (write_index != index)
+ {
+ message->metadata.source_message_ids[write_index]
+ = message->metadata.source_message_ids[index];
+ }
+ write_index++;
+ }
+ else
+ {
+ changed = true;
+ }
+ }
+ if (changed)
+ {
+ message->metadata.source_count = write_index;
+ if (write_index == 0)
+ {
+ free(message->metadata.source_message_ids);
+ message->metadata.source_message_ids = NULL;
+ }
+ }
+ return true;
+}
+
static tiny_store_status_t
prepare_update(tiny_store_t *store,
tiny_store_entry_t *entry,
@@ -1262,7 +1328,8 @@ write_snapshot(tiny_store_t *store)
{
unsigned char prefix[16], *payload = NULL;
uint32_t length = 0;
- if (!serialize_put(&store->entries[index].message, &payload, &length))
+ if (!prune_metadata_references(store, &store->entries[index].message)
+ || !serialize_put(&store->entries[index].message, &payload, &length))
{
ok = false;
break;
@@ -1773,7 +1840,8 @@ tiny_store_rebuild(tiny_store_t *store, tiny_rebuild_report_t *report)
{
unsigned char *payload = NULL;
uint32_t length = 0;
- if (!serialize_put(&store->entries[read_index].message, &payload, &length))
+ if (!prune_metadata_references(store, &store->entries[read_index].message)
+ || !serialize_put(&store->entries[read_index].message, &payload, &length))
{
status = TINY_STORE_NO_MEMORY;
break;