amduat-api/src/amduatd_fed_until.c

241 lines
8 KiB
C
Raw Normal View History

#include "amduatd_fed_until.h"
#include <stdlib.h>
#include <string.h>
static void amduatd_fed_until_report_clear_cursor(
amduatd_fed_until_report_t *report) {
if (report == NULL) {
return;
}
if (report->cursor_ref_set) {
amduat_reference_free(&report->cursor_ref);
report->cursor_ref_set = false;
}
report->cursor_has_logseq = false;
report->cursor_logseq = 0u;
}
static void amduatd_fed_until_report_set_cursor(
amduatd_fed_until_report_t *report,
bool has_logseq,
uint64_t logseq,
bool has_ref,
amduat_reference_t ref) {
if (report == NULL) {
return;
}
amduatd_fed_until_report_clear_cursor(report);
if (has_logseq) {
report->cursor_has_logseq = true;
report->cursor_logseq = logseq;
}
if (has_ref) {
if (amduat_reference_clone(ref, &report->cursor_ref)) {
report->cursor_ref_set = true;
}
}
}
static void amduatd_fed_until_report_error(amduatd_fed_until_report_t *report,
const char *msg,
int remote_status) {
if (report == NULL || msg == NULL) {
return;
}
memset(report->error, 0, sizeof(report->error));
strncpy(report->error, msg, sizeof(report->error) - 1u);
report->remote_status = remote_status;
}
void amduatd_fed_until_report_init(amduatd_fed_until_report_t *report) {
if (report == NULL) {
return;
}
memset(report, 0, sizeof(*report));
report->cursor_ref = amduat_reference(0u, amduat_octets(NULL, 0u));
}
void amduatd_fed_until_report_free(amduatd_fed_until_report_t *report) {
if (report == NULL) {
return;
}
if (report->cursor_ref_set) {
amduat_reference_free(&report->cursor_ref);
}
memset(report, 0, sizeof(*report));
}
amduatd_fed_pull_apply_status_t amduatd_fed_pull_until(
amduat_asl_store_t *store,
amduat_asl_pointer_store_t *pointer_store,
const amduatd_space_t *effective_space,
const char *peer_key,
const char *remote_space_id,
uint64_t limit,
uint64_t max_rounds,
const amduatd_fed_cfg_t *fed_cfg,
const amduatd_fed_pull_transport_t *transport,
amduatd_fed_until_report_t *out_report) {
amduatd_fed_pull_apply_status_t status = AMDUATD_FED_PULL_APPLY_OK;
amduatd_fed_pull_apply_report_t round_report;
if (out_report == NULL) {
return AMDUATD_FED_PULL_APPLY_ERR_INVALID;
}
amduatd_fed_until_report_init(out_report);
out_report->peer_key = peer_key;
out_report->effective_space = effective_space;
out_report->limit = limit;
out_report->max_rounds = max_rounds;
if (store == NULL || pointer_store == NULL || peer_key == NULL ||
fed_cfg == NULL || transport == NULL || max_rounds == 0u) {
amduatd_fed_until_report_error(out_report, "invalid inputs", 0);
return AMDUATD_FED_PULL_APPLY_ERR_INVALID;
}
for (uint64_t round = 0u; round < max_rounds; ++round) {
amduatd_fed_pull_apply_report_init(&round_report);
status = amduatd_fed_pull_apply(store,
pointer_store,
effective_space,
peer_key,
remote_space_id,
limit,
fed_cfg,
transport,
&round_report);
out_report->rounds_executed++;
if (status != AMDUATD_FED_PULL_APPLY_OK) {
amduatd_fed_until_report_error(out_report,
round_report.error[0] != '\0'
? round_report.error
: "error",
round_report.remote_status);
amduatd_fed_pull_apply_report_free(&round_report);
return status;
}
out_report->total_records += round_report.applied_record_count;
out_report->total_artifacts += round_report.applied_artifact_count;
if (round_report.cursor_advanced) {
amduatd_fed_until_report_set_cursor(
out_report,
round_report.cursor_after_has_logseq,
round_report.cursor_after_logseq,
round_report.cursor_after_ref_set,
round_report.cursor_after_ref);
} else if (round_report.cursor_present) {
amduatd_fed_until_report_set_cursor(
out_report,
round_report.cursor_has_logseq,
round_report.cursor_logseq,
round_report.cursor_ref_set,
round_report.cursor_ref);
} else {
amduatd_fed_until_report_clear_cursor(out_report);
}
if (round_report.plan_record_count == 0u) {
out_report->caught_up = true;
amduatd_fed_pull_apply_report_free(&round_report);
return AMDUATD_FED_PULL_APPLY_OK;
}
amduatd_fed_pull_apply_report_free(&round_report);
}
out_report->caught_up = false;
return AMDUATD_FED_PULL_APPLY_OK;
}
amduatd_fed_push_apply_status_t amduatd_fed_push_until(
amduat_asl_store_t *store,
amduat_asl_pointer_store_t *pointer_store,
const amduatd_space_t *effective_space,
const char *peer_key,
const char *remote_space_id,
uint64_t limit,
uint64_t max_rounds,
const char *root_path,
const amduatd_fed_cfg_t *fed_cfg,
const amduatd_fed_push_transport_t *transport,
amduatd_fed_until_report_t *out_report) {
amduatd_fed_push_apply_status_t status = AMDUATD_FED_PUSH_APPLY_OK;
amduatd_fed_push_apply_report_t round_report;
if (out_report == NULL) {
return AMDUATD_FED_PUSH_APPLY_ERR_INVALID;
}
amduatd_fed_until_report_init(out_report);
out_report->peer_key = peer_key;
out_report->effective_space = effective_space;
out_report->limit = limit;
out_report->max_rounds = max_rounds;
if (store == NULL || pointer_store == NULL || peer_key == NULL ||
root_path == NULL || fed_cfg == NULL || transport == NULL ||
max_rounds == 0u) {
amduatd_fed_until_report_error(out_report, "invalid inputs", 0);
return AMDUATD_FED_PUSH_APPLY_ERR_INVALID;
}
for (uint64_t round = 0u; round < max_rounds; ++round) {
amduatd_fed_push_apply_report_init(&round_report);
status = amduatd_fed_push_apply(store,
pointer_store,
effective_space,
peer_key,
remote_space_id,
limit,
root_path,
fed_cfg,
transport,
&round_report);
out_report->rounds_executed++;
if (status != AMDUATD_FED_PUSH_APPLY_OK) {
amduatd_fed_until_report_error(out_report,
round_report.error[0] != '\0'
? round_report.error
: "error",
round_report.remote_status);
amduatd_fed_push_apply_report_free(&round_report);
return status;
}
out_report->total_records += round_report.sent_record_count;
out_report->total_artifacts += round_report.sent_artifact_count;
if (round_report.cursor_advanced) {
amduatd_fed_until_report_set_cursor(
out_report,
round_report.cursor_after_has_logseq,
round_report.cursor_after_logseq,
round_report.cursor_after_ref_set,
round_report.cursor_after_ref);
} else if (round_report.cursor_present) {
amduatd_fed_until_report_set_cursor(
out_report,
round_report.cursor_has_logseq,
round_report.cursor_logseq,
round_report.cursor_ref_set,
round_report.cursor_ref);
} else {
amduatd_fed_until_report_clear_cursor(out_report);
}
if (round_report.plan_record_count == 0u) {
out_report->caught_up = true;
amduatd_fed_push_apply_report_free(&round_report);
return AMDUATD_FED_PUSH_APPLY_OK;
}
amduatd_fed_push_apply_report_free(&round_report);
}
out_report->caught_up = false;
return AMDUATD_FED_PUSH_APPLY_OK;
}