#include "amduatd_fed_until.h" #include #include 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; }