Commit 35adb004 authored by Jan Kadlec's avatar Jan Kadlec

changesets: Partial port to changeset with tries.

parent b35c18d0
......@@ -58,7 +58,7 @@ int hattrie_apply_rev (hattrie_t*, int (*f)(value_t*,void*), void* d);
int hattrie_apply_rev_ahtable(hattrie_t* T, int (*f)(void*,void*), void* d);
/** Find the given key in the trie, inserting it if it does not exist, and
* returning a pointer to it's key.
* returning a pointer to its key.
*
* This pointer is not guaranteed to be valid after additional calls to
* hattrie_get, hattrie_del, hattrie_clear, or other functions that modifies the
......
......@@ -142,7 +142,7 @@ static int connect_nsec_nodes(zone_node_t *a, zone_node_t *b,
dbg_dnssec_detail("Adding new NSEC to changeset.\n");
// Add new NSEC to the changeset (no matter if old was removed)
return changeset_add_rrset(data->changeset, new_nsec, CHANGESET_ADD);
return changeset_add_rrset(data->changeset, new_nsec);
}
/* - API - iterations ------------------------------------------------------- */
......@@ -218,7 +218,7 @@ int knot_nsec_changeset_remove(const zone_node_t *n,
}
if (nsec) {
// update changeset
result = changeset_add_rrset(changeset, nsec, CHANGESET_REMOVE);
result = changeset_rem_rrset(changeset, nsec);
if (result != KNOT_EOK) {
knot_rrset_free(&nsec, NULL);
return result;
......@@ -251,8 +251,7 @@ int knot_nsec_changeset_remove(const zone_node_t *n,
}
// store RRSIG
result = changeset_add_rrset(changeset, synth_rrsigs,
CHANGESET_REMOVE);
result = changeset_rem_rrset(changeset, synth_rrsigs);
if (result != KNOT_EOK) {
knot_rrset_free(&synth_rrsigs, NULL);
return result;
......
......@@ -275,8 +275,7 @@ static int remove_expired_rrsigs(const knot_rrset_t *covered,
}
if (to_remove != NULL && result == KNOT_EOK) {
result = changeset_add_rrset(changeset, to_remove,
CHANGESET_REMOVE);
result = changeset_rem_rrset(changeset, to_remove);
}
if (to_remove != NULL && result != KNOT_EOK) {
......@@ -339,7 +338,7 @@ static int add_missing_rrsigs(const knot_rrset_t *covered,
}
if (to_add != NULL && result == KNOT_EOK) {
result = changeset_add_rrset(changeset, to_add, CHANGESET_ADD);
result = changeset_add_rrset(changeset, to_add);
}
if (to_add != NULL && result != KNOT_EOK) {
......@@ -377,7 +376,7 @@ static int remove_rrset_rrsigs(const knot_dname_t *owner, uint16_t type,
return KNOT_EOK;
}
ret = changeset_add_rrset(changeset, synth_rrsig, CHANGESET_REMOVE);
ret = changeset_rem_rrset(changeset, synth_rrsig);
if (ret != KNOT_EOK) {
knot_rrset_free(&synth_rrsig, NULL);
}
......@@ -476,8 +475,7 @@ static int remove_standalone_rrsigs(const zone_node_t *node,
knot_rrset_free(&to_remove, NULL);
return ret;
}
ret = changeset_add_rrset(changeset, to_remove,
CHANGESET_REMOVE);
ret = changeset_rem_rrset(changeset, to_remove);
if (ret != KNOT_EOK) {
knot_rrset_free(&to_remove, NULL);
return ret;
......@@ -802,8 +800,7 @@ static int remove_invalid_dnskeys(const knot_rrset_t *soa,
done:
if (to_remove != NULL && result == KNOT_EOK) {
result = changeset_add_rrset(changeset, to_remove,
CHANGESET_REMOVE);
result = changeset_rem_rrset(changeset, to_remove);
}
if (to_remove != NULL && result != KNOT_EOK) {
......@@ -883,7 +880,7 @@ static int add_missing_dnskeys(const knot_rrset_t *soa,
}
if (to_add != NULL && result == KNOT_EOK) {
result = changeset_add_rrset(changeset, to_add, CHANGESET_ADD);
result = changeset_add_rrset(changeset, to_add);
}
if (to_add != NULL && result != KNOT_EOK) {
......
......@@ -24,7 +24,7 @@ enum ixfr_states {
/*! \brief Extended structure for IXFR-in/IXFR-out processing. */
struct ixfr_proc {
struct xfr_proc proc; /* Generic transfer processing context. */
hattrie_iter_t *cur; /* Current changeset iteration state.*/
changeset_iter_t *cur; /* Current changeset iteration state.*/
int state; /* IXFR-in state. */
knot_rrset_t *final_soa; /* First SOA received via IXFR. */
list_t changesets; /* Processed changesets. */
......@@ -47,30 +47,19 @@ struct ixfr_proc {
return ret; \
}
static int ixfr_put_rrlist(knot_pkt_t *pkt, struct ixfr_proc *ixfr, list_t *list)
static int ixfr_put_chg_part(knot_pkt_t *pkt, struct ixfr_proc *ixfr, changeset_iter_t *itt)
{
assert(pkt);
assert(ixfr);
assert(list);
assert(itt);
hattrie_iter_begin()
/* If at the beginning, fetch first RR. */
int ret = KNOT_EOK;
if (ixfr->cur == NULL) {
ixfr->cur = HEAD(*list);
}
/* Now iterate until it hits the last one,
* this is done without for() loop because we can
* rejoin the iteration at any point. */
while(ixfr->cur->n.next) {
knot_rrset_t *rr = (knot_rrset_t *)ixfr->cur->d;
IXFR_SAFE_PUT(pkt, rr);
ixfr->cur = (ptrnode_t *)ixfr->cur->n.next;
knot_rrset_t rr = changeset_iter_next(itt);
int ret = KNOT_EOK; // Declaration for IXFR_SAFE_PUT macro
while(!knot_rrset_empty(&rr)) {
IXFR_SAFE_PUT(pkt, &rr);
rr = changeset_iter_next(itt);
}
ixfr->cur = NULL;
return ret;
}
......@@ -97,11 +86,18 @@ static int ixfr_process_changeset(knot_pkt_t *pkt, const void *item,
/* Put REMOVE RRSets. */
if (ixfr->state == IXFR_DEL) {
ret = ixfr_put_rrlist(pkt, ixfr, &chgset->remove);
if (ixfr->cur == NULL) {
ixfr->cur = changeset_iter_rem(chgset, false);
if (ixfr->cur == NULL) {
return KNOT_ENOMEM;
}
}
ret = ixfr_put_chg_part(pkt, ixfr, ixfr->cur);
if (ret != KNOT_EOK) {
return ret;
}
dbg_ns("%s: put 'REMOVE' RRs\n", __func__);
changeset_iter_free(ixfr->cur, NULL);
ixfr->cur = NULL;
ixfr->state = IXFR_SOA_ADD;
}
......@@ -114,11 +110,18 @@ static int ixfr_process_changeset(knot_pkt_t *pkt, const void *item,
/* Put REMOVE RRSets. */
if (ixfr->state == IXFR_ADD) {
ret = ixfr_put_rrlist(pkt, ixfr, &chgset->add);
if (ixfr->cur == NULL) {
ixfr->cur = changeset_iter_add(chgset, false);
if (ixfr->cur == NULL) {
return KNOT_ENOMEM;
}
}
ret = ixfr_put_chg_part(pkt, ixfr, ixfr->cur);
if (ret != KNOT_EOK) {
return ret;
}
dbg_ns("%s: put 'IXFR_ADD' RRs\n", __func__);
changeset_iter_free(ixfr->cur, NULL);
ixfr->cur = NULL;
ixfr->state = IXFR_SOA_DEL;
}
......@@ -147,8 +150,7 @@ static int ixfr_load_chsets(list_t *chgsets, const zone_t *zone,
return KNOT_EUPTODATE;
}
ret = journal_load_changesets(zone->conf->ixfr_db, chgsets,
serial_from, serial_to);
ret = journal_load_changesets(zone, chgsets, serial_from, serial_to);
if (ret != KNOT_EOK) {
changesets_free(chgsets, NULL);
}
......@@ -369,7 +371,7 @@ static int solve_soa_del(const knot_rrset_t *rr, struct ixfr_proc *proc)
}
// Create new changeset.
changeset_t *change = changeset_new(proc->mm);
changeset_t *change = changeset_new(proc->mm, proc->zone->name);
if (change == NULL) {
return KNOT_ENOMEM;
}
......@@ -400,32 +402,16 @@ static int solve_soa_add(const knot_rrset_t *rr, changeset_t *change, mm_ctx_t *
return KNOT_EOK;
}
/*! \brief Adds single RR into given section of changeset. */
static int add_part(const knot_rrset_t *rr, changeset_t *change, int part, mm_ctx_t *mm)
{
assert(rr->type != KNOT_RRTYPE_SOA);
knot_rrset_t *copy = knot_rrset_copy(rr, mm);
if (copy) {
int ret = changeset_add_rrset(change, copy, part);
if (ret != KNOT_EOK) {
return ret;
}
return KNOT_EOK;
} else {
return KNOT_ENOMEM;
}
}
/*! \brief Adds single RR into remove section of changeset. */
static int solve_del(const knot_rrset_t *rr, changeset_t *change, mm_ctx_t *mm)
{
return add_part(rr, change, CHANGESET_REMOVE, mm);
return changeset_rem_rrset(change, rr);
}
/*! \brief Adds single RR into add section of changeset. */
static int solve_add(const knot_rrset_t *rr, changeset_t *change, mm_ctx_t *mm)
{
return add_part(rr, change, CHANGESET_ADD, mm);
return changeset_add_rrset(change, rr);
}
/*! \brief Decides what the next IXFR-in state should be. */
......
......@@ -85,7 +85,7 @@ static int sign_update(zone_t *zone, const zone_contents_t *old_contents,
assert(ddns_ch != NULL);
changeset_t sec_ch;
changeset_init(&sec_ch, NULL);
changeset_init(&sec_ch, zone->name, NULL);
/*
* Check if the UPDATE changed DNSKEYs or NSEC3PARAM.
......@@ -150,7 +150,7 @@ static int process_authenticated(uint16_t *rcode, struct query_data *qdata)
// Create DDNS change
changeset_t ddns_ch;
changeset_init(&ddns_ch, NULL);
changeset_init(&ddns_ch, qdata->zone->name, NULL);
ret = ddns_process_update(zone, query, &ddns_ch, rcode);
if (ret != KNOT_EOK) {
......
......@@ -984,12 +984,10 @@ static int changesets_unpack(changeset_t *chs)
} else {
/* Remove RRSets. */
if (in_remove_section) {
ret = changeset_add_rrset(chs, rrset,
CHANGESET_REMOVE);
ret = changeset_rem_rrset(chs, rrset);
} else {
/* Add RRSets. */
ret = changeset_add_rrset(chs, rrset,
CHANGESET_ADD);
ret = changeset_add_rrset(chs, rrset);
}
}
}
......@@ -1021,14 +1019,21 @@ static int serialize_and_store_chgset(const changeset_t *chs,
}
/* Serialize RRSets from the 'remove' section. */
ptrnode_t *n;
WALK_LIST(n, chs->remove) {
knot_rrset_t *rrset = (knot_rrset_t *)n->d;
ret = rrset_write_to_mem(rrset, &entry, &max_size);
changeset_iter_t *itt = changeset_iter_rem(chs, false);
if (itt == NULL) {
return ret;
}
knot_rrset_t rrset = changeset_iter_next(itt);
while (!knot_rrset_empty(&rrset)) {
ret = rrset_write_to_mem(&rrset, &entry, &max_size);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
return ret;
}
rrset = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
/* Serialize SOA 'to'. */
ret = rrset_write_to_mem(chs->soa_to, &entry, &max_size);
......@@ -1037,14 +1042,21 @@ static int serialize_and_store_chgset(const changeset_t *chs,
}
/* Serialize RRSets from the 'add' section. */
WALK_LIST(n, chs->add) {
knot_rrset_t *rrset = (knot_rrset_t *)n->d;
ret = rrset_write_to_mem(rrset, &entry, &max_size);
itt = changeset_iter_add(chs, false);
if (itt == NULL) {
return ret;
}
rrset = changeset_iter_next(itt);
while (!knot_rrset_empty(&rrset)) {
ret = rrset_write_to_mem(&rrset, &entry, &max_size);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
return ret;
}
rrset = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
return KNOT_EOK;
}
......@@ -1085,9 +1097,9 @@ static int changeset_pack(const changeset_t *chs, journal_t *j)
}
/*! \brief Helper for iterating journal (this is temporary until #80) */
typedef int (*journal_apply_t)(journal_t *, journal_node_t *, void *);
typedef int (*journal_apply_t)(journal_t *, journal_node_t *, const zone_t *, list_t *);
static int journal_walk(const char *fn, uint32_t from, uint32_t to,
journal_apply_t cb, void *data)
journal_apply_t cb, const zone_t *zone, list_t *chgs)
{
/* Open journal for reading. */
journal_t *journal = journal_open(fn, FSLIMIT_INF);
......@@ -1116,7 +1128,7 @@ static int journal_walk(const char *fn, uint32_t from, uint32_t to,
}
/* Callback. */
ret = cb(journal, n, data);
ret = cb(journal, n, zone, chgs);
if (ret != KNOT_EOK) {
break;
}
......@@ -1130,11 +1142,9 @@ finish:
return ret;
}
static int load_changeset(journal_t *journal, journal_node_t *n, void *data)
static int load_changeset(journal_t *journal, journal_node_t *n, const zone_t *zone, list_t *chgs)
{
list_t *chgs = (list_t *)data;
changeset_t *ch = changeset_new(NULL);
changeset_t *ch = changeset_new(NULL, zone->name);
if (ch == NULL) {
return KNOT_ENOMEM;
}
......@@ -1159,10 +1169,10 @@ static int load_changeset(journal_t *journal, journal_node_t *n, void *data)
return KNOT_EOK;
}
int journal_load_changesets(const char *path, list_t *dst,
int journal_load_changesets(const zone_t *zone, list_t *dst,
uint32_t from, uint32_t to)
{
int ret = journal_walk(path, from, to, &load_changeset, dst);
int ret = journal_walk(zone->conf->ixfr_db, from, to, &load_changeset, zone, dst);
if (ret != KNOT_EOK) {
return ret;
}
......
......@@ -45,6 +45,7 @@
#include <pthread.h>
#include <stdbool.h>
#include "knot/updates/changesets.h"
#include "knot/zone/zone.h"
/*!
* \brief Journal entry flags.
......@@ -176,7 +177,7 @@ bool journal_exists(const char *path);
* \retval KNOT_ERANGE if given entry was not found.
* \return < KNOT_EOK on error.
*/
int journal_load_changesets(const char *path, list_t *dst,
int journal_load_changesets(const struct zone_t *zone, list_t *dst,
uint32_t from, uint32_t to);
/*!
......
......@@ -78,18 +78,32 @@ int changeset_binary_size(const changeset_t *chgset, size_t *size)
size_t soa_from_size = rrset_binary_size(chgset->soa_from);
size_t soa_to_size = rrset_binary_size(chgset->soa_to);
changeset_iter_t *itt = changeset_iter_rem(chgset, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
size_t remove_size = 0;
ptrnode_t *n;
WALK_LIST(n, chgset->remove) {
knot_rrset_t *rrset = (knot_rrset_t *)n->d;
remove_size += rrset_binary_size(rrset);
knot_rrset_t rrset = changeset_iter_next(itt);
while (!knot_rrset_empty(&rrset)) {
remove_size += rrset_binary_size(&rrset);
rrset = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
itt = changeset_iter_add(chgset, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
size_t add_size = 0;
WALK_LIST(n, chgset->add) {
knot_rrset_t *rrset = (knot_rrset_t *)n->d;
add_size += rrset_binary_size(rrset);
rrset = changeset_iter_next(itt);
while (!knot_rrset_empty(&rrset)) {
add_size += rrset_binary_size(&rrset);
rrset = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
*size = soa_from_size + soa_to_size + remove_size + add_size;
......
......@@ -27,22 +27,22 @@
#include "libknot/rrtype/soa.h"
#include "common/debug.h"
void changeset_init(changeset_t *ch, mm_ctx_t *mm)
void changeset_init(changeset_t *ch, const knot_dname_t *apex, mm_ctx_t *mm)
{
memset(ch, 0, sizeof(changeset_t));
ch->mm = mm;
// Init local lists
init_list(&ch->add);
init_list(&ch->remove);
// Init local changes
ch->add = zone_contents_new(apex);
ch->remove = zone_contents_new(apex);
// Init change lists
init_list(&ch->new_data);
init_list(&ch->old_data);
}
changeset_t *changeset_new(mm_ctx_t *mm)
changeset_t *changeset_new(mm_ctx_t *mm, const knot_dname_t *apex)
{
changeset_t *ret = mm_alloc(mm, sizeof(changeset_t));
if (ret == NULL) {
......@@ -50,24 +50,20 @@ changeset_t *changeset_new(mm_ctx_t *mm)
return NULL;
}
changeset_init(ret, mm);
changeset_init(ret, apex, mm);
return ret;
}
int changeset_add_rrset(changeset_t *ch, knot_rrset_t *rrset,
changeset_part_t part)
int changeset_add_rrset(changeset_t *ch, const knot_rrset_t *rrset)
{
if (part == CHANGESET_ADD) {
if (ptrlist_add(&ch->add, rrset, ch->mm) == NULL) {
return KNOT_ENOMEM;
}
} else {
if (ptrlist_add(&ch->remove, rrset, ch->mm) == NULL) {
return KNOT_ENOMEM;
}
}
zone_node_t *n;
return zone_contents_add_rr(ch->add, rrset, &n);
}
return KNOT_EOK;
int changeset_rem_rrset(changeset_t *ch, const knot_rrset_t *rrset)
{
zone_node_t *n;
return zone_contents_add_rr(ch->remove, rrset, &n);
}
bool changeset_empty(const changeset_t *ch)
......@@ -76,8 +72,8 @@ bool changeset_empty(const changeset_t *ch)
return true;
}
return (ch->soa_to == NULL &&
EMPTY_LIST(ch->add) && EMPTY_LIST(ch->remove));
return ch->soa_to == NULL &&
changeset_size(ch) == 0;
}
size_t changeset_size(const changeset_t *ch)
......@@ -86,46 +82,55 @@ size_t changeset_size(const changeset_t *ch)
return 0;
}
return list_size(&ch->add) + list_size(&ch->remove);
return hattrie_weight(ch->add->nodes) == 0 +
hattrie_weight(ch->add->nsec3_nodes) == 0 +
hattrie_weight(ch->remove->nodes) == 0 +
hattrie_weight(ch->remove->nsec3_nodes) == 0;
}
int changeset_apply(changeset_t *ch, changeset_part_t part,
int (*func)(knot_rrset_t *, void *), void *data)
int changeset_merge(changeset_t *ch1, changeset_t *ch2)
{
if (ch == NULL || func == NULL) {
return KNOT_EINVAL;
#warning slow slow slow slow
changeset_iter_t *itt = changeset_iter_add(ch2, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
ptrnode_t *n;
if (part == CHANGESET_ADD) {
WALK_LIST(n, ch->add) {
int res = func((knot_rrset_t *)n->d, data);
if (res != KNOT_EOK) {
return res;
}
}
} else if (part == CHANGESET_REMOVE) {
WALK_LIST(n, ch->remove) {
int res = func((knot_rrset_t *)n->d, data);
if (res != KNOT_EOK) {
return res;
}
knot_rrset_t rrset = changeset_iter_next(itt);
while (!knot_rrset_empty(&rrset)) {
zone_node_t *n;
int ret = zone_contents_add_rr(ch1->add, &rrset, &n);
UNUSED(n);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
}
rrset = changeset_iter_next(itt);
}
return KNOT_EOK;
}
changeset_iter_free(itt, NULL);
void changeset_merge(changeset_t *ch1, changeset_t *ch2)
{
// Connect lists in changesets together
add_tail_list(&ch1->add, &ch2->add);
add_tail_list(&ch1->remove, &ch2->remove);
itt = changeset_iter_add(ch2, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
rrset = changeset_iter_next(itt);
while (!knot_rrset_empty(&rrset)) {
zone_node_t *n;
int ret = zone_contents_add_rr(ch1->remove, &rrset, &n);
UNUSED(n);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
}
rrset = changeset_iter_next(itt);
}
// Use soa_to and serial from the second changeset
// soa_to from the first changeset is redundant, delete it
knot_rrset_free(&ch1->soa_to, NULL);
ch1->soa_to = ch2->soa_to;
return KNOT_EOK;
}
void changeset_clear(changeset_t *ch, mm_ctx_t *rr_mm)
......@@ -135,15 +140,8 @@ void changeset_clear(changeset_t *ch, mm_ctx_t *rr_mm)
}
// Delete RRSets in lists, in case there are any left
ptrnode_t *n, *nxt;
WALK_LIST_DELSAFE(n, nxt, ch->add) {
knot_rrset_free((knot_rrset_t **)&n->d, rr_mm);
mm_free(ch->mm, n);
}
WALK_LIST_DELSAFE(n, nxt, ch->remove) {
knot_rrset_free((knot_rrset_t **)&n->d, rr_mm);
mm_free(ch->mm, n);
}
zone_contents_deep_free(&ch->add);
zone_contents_deep_free(&ch->remove);
knot_rrset_free(&ch->soa_from, rr_mm);
knot_rrset_free(&ch->soa_to, rr_mm);
......@@ -162,16 +160,7 @@ void changesets_free(list_t *chgs, mm_ctx_t *rr_mm)
}
}
enum {
CHANGESET_NODE_DONE = -1,
};
typedef struct {
hattrie_iter_t *normal_it;
hattrie_iter_t *nsec3_it;
const zone_node_t *node;
int32_t node_pos;
} changeset_iter_t;
#define NODE_DONE -1
static changeset_iter_t *changeset_iter_begin(const changeset_t *ch, hattrie_t *tr,
hattrie_t *nsec3_tr, bool sorted)
......@@ -183,7 +172,7 @@ static changeset_iter_t *changeset_iter_begin(const changeset_t *ch, hattrie_t *
return NULL;
}
memset(ret, 0, sizeof(*ret));
ret->node_pos = CHANGESET_NODE_DONE;
ret->node_pos = NODE_DONE;
ret->normal_it = hattrie_iter_begin(tr, sorted);
ret->nsec3_it = hattrie_iter_begin(nsec3_tr, sorted);
......@@ -206,22 +195,21 @@ changeset_iter_t *changeset_iter_rem(const changeset_t *ch, bool sorted)
return changeset_iter_begin(ch, ch->remove->nodes, ch->remove->nsec3_nodes, sorted);
}
bool changeset_iter_finished(const changeset_iter_t *it)
{
return it->normal_it == NULL && it->nsec3_it == NULL;
}
void get_next_rr(knot_rrset_t *rr, changeset_iter_t *ch_it, hattrie_iter_t *t_it) // pun intented
static void get_next_rr(knot_rrset_t *rr, changeset_iter_t *ch_it, hattrie_iter_t *t_it) // pun intented
{
if (it->node_pos == CHANGESET_NODE_DONE) {
if (ch_it->node_pos == NODE_DONE) {
// Get next node.
if (it->node) {
if (ch_it->node) {
// Do not get next for very first node.
hattrie_iter_next(ch_it->normal_it);
}
if (hattrie_iter_finished(ch_it->normal_it)) {
hattrie_iter_free(&t_it->normal_it);
ch_it->normal_it = NULL;
if (hattrie_iter_finished(t_it)) {
if (t_it == ch_it->normal_it) {
ch_it->normal_it = NULL;
} else {
ch_it->nsec3_it = NULL;
}
hattrie_iter_free(t_it);
ch_it->node = NULL;
return;
}
......@@ -229,11 +217,11 @@ void get_next_rr(knot_rrset_t *rr, changeset_iter_t *ch_it, hattrie_iter_t *t_it
ch_it->node_pos = 0;
}
++it->node_pos;
++ch_it->node_pos;
if (ch_it->node_pos < ch_it->node->rrset_count) {
*rr = node_rrset_at(it->node, it->node_pos);
*rr = node_rrset_at(ch_it->node, ch_it->node_pos);
} else {
it->node_pos = CHANGESET_NODE_DONE;
ch_it->node_pos = NODE_DONE;
}
}
......@@ -244,7 +232,7 @@ knot_rrset_t changeset_iter_next(changeset_iter_t *it)
if (it->normal_it) {
get_next_rr(&ret, it, it->normal_it);
} else if (it->nsec3_it) {
get_next_rr(&ret, it, it->normal_it);
get_next_rr(&ret, it, it->nsec3_it);
}
return ret;
......@@ -252,14 +240,8 @@ knot_rrset_t changeset_iter_next(changeset_iter_t *it)
void changeset_iter_free(changeset_iter_t *it, mm_ctx_t *mm)
{
if (it->normal_it) {
hattrie_iter_free(it->normal_it);
}
if (it->nsec3_it) {
hattrie_iter_free(it->nsec3_it);
}
hattrie_iter_free(it->normal_it);
hattrie_iter_free(it->nsec3_it);
mm_free(mm, it);
}
......@@ -47,6 +47,13 @@ typedef struct changeset {
list_t new_data; /*!< New data, to be freed after failed update. */
} changeset_t;
typedef struct {
hattrie_iter_t *normal_it;
hattrie_iter_t *nsec3_it;
const zone_node_t *node;
int32_t node_pos;
} changeset_iter_t;
/*----------------------------------------------------------------------------*/
typedef enum {
......@@ -56,8 +63,8 @@ typedef enum {
/*----------------------------------------------------------------------------*/
changeset_t *changeset_new(mm_ctx_t *mm);
void changeset_init(changeset_t *ch, mm_ctx_t *mm);
changeset_t *changeset_new(mm_ctx_t *mm, const knot_dname_t *apex);
void changeset_init(changeset_t *ch, const knot_dname_t *apex, mm_ctx_t *mm);
/*!
* \brief Add RRSet to changeset. RRSet is either inserted to 'add' or to
......@@ -70,8 +77,8 @@ void changeset_init(changeset_t *ch, mm_ctx_t *mm);
* \retval KNOT_EOK on success.
* \retval Error code on failure.
*/
int changeset_add_rrset(changeset_t *ch, knot_rrset_t *rrset,
changeset_part_t part);
int changeset_add_rrset(changeset_t *ch, const knot_rrset_t *rrset);
int changeset_rem_rrset(changeset_t *ch, const knot_rrset_t *rrset);
/*!
* \brief Checks whether changeset is empty.
......@@ -95,25 +102,6 @@ bool changeset_empty(const changeset_t *ch);
*/