Commit 2843f5c8 authored by Jan Kadlec's avatar Jan Kadlec

changeset: Init structures, do not malloc, better init.

parent ed7b9eb3
......@@ -154,22 +154,20 @@ static int mark_removed_nsec3(changeset_t *out_ch,
if (zone_tree_is_empty(zone->nsec3_nodes)) {
return KNOT_EOK;
}
changeset_iter_t itt;
changeset_iter_rem(&itt, out_ch, false);
changeset_iter_t *itt = changeset_iter_rem(out_ch, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
knot_rrset_t rr = changeset_iter_next(itt);
knot_rrset_t rr = changeset_iter_next(&itt);
while (!knot_rrset_empty(&rr)) {
int ret = mark_nsec3(&rr, zone->nsec3_nodes);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return ret;
}
rr = changeset_iter_next(itt);
rr = changeset_iter_next(&itt);
}
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return KNOT_EOK;
}
......
......@@ -1353,24 +1353,21 @@ int knot_zone_sign_changeset(const zone_contents_t *zone,
if (args.signed_tree == NULL) {
return KNOT_ENOMEM;
}
// Sign all RRs that are in changeset, additions and removals
changeset_iter_t *itt = changeset_iter_all(in_ch, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
changeset_iter_t itt;
changeset_iter_all(&itt, in_ch, false);
knot_rrset_t rr = changeset_iter_next(itt);
knot_rrset_t rr = changeset_iter_next(&itt);
while (!knot_rrset_empty(&rr)) {
int ret = sign_changeset_wrap(&rr, &args);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return ret;
}
rr = changeset_iter_next(itt);
rr = changeset_iter_next(&itt);
}
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
knot_zone_clear_sorted_changes(args.signed_tree);
hattrie_free(args.signed_tree);
......@@ -1389,25 +1386,23 @@ int knot_zone_sign_nsecs_in_changeset(const knot_zone_keys_t *zone_keys,
assert(policy);
assert(changeset);
changeset_iter_t *itt = changeset_iter_add(changeset, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
changeset_iter_t itt;
changeset_iter_add(&itt, changeset, false);
knot_rrset_t rr = changeset_iter_next(itt);
knot_rrset_t rr = changeset_iter_next(&itt);
while (!knot_rrset_empty(&rr)) {
if (rr.type == KNOT_RRTYPE_NSEC ||
rr.type == KNOT_RRTYPE_NSEC3) {
int ret = add_missing_rrsigs(&rr, NULL, zone_keys,
policy, changeset);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return ret;
}
}
rr = changeset_iter_next(itt);
rr = changeset_iter_next(&itt);
}
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return 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. */
changeset_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. */
......@@ -86,18 +86,14 @@ static int ixfr_process_changeset(knot_pkt_t *pkt, const void *item,
/* Put REMOVE RRSets. */
if (ixfr->state == IXFR_DEL) {
if (ixfr->cur == NULL) {
ixfr->cur = changeset_iter_rem(chgset, false);
if (ixfr->cur == NULL) {
return KNOT_ENOMEM;
}
if (EMPTY_LIST(ixfr->cur.iters)) {
changeset_iter_rem(&ixfr->cur, chgset, false);
}
ret = ixfr_put_chg_part(pkt, ixfr, ixfr->cur);
ret = ixfr_put_chg_part(pkt, ixfr, &ixfr->cur);
if (ret != KNOT_EOK) {
return ret;
}
changeset_iter_free(ixfr->cur, NULL);
ixfr->cur = NULL;
changeset_iter_clear(&ixfr->cur);
ixfr->state = IXFR_SOA_ADD;
}
......@@ -110,18 +106,14 @@ static int ixfr_process_changeset(knot_pkt_t *pkt, const void *item,
/* Put REMOVE RRSets. */
if (ixfr->state == IXFR_ADD) {
if (ixfr->cur == NULL) {
ixfr->cur = changeset_iter_add(chgset, false);
if (ixfr->cur == NULL) {
return KNOT_ENOMEM;
}
if (EMPTY_LIST(ixfr->cur.iters)) {
changeset_iter_add(&ixfr->cur, chgset, false);
}
ret = ixfr_put_chg_part(pkt, ixfr, ixfr->cur);
ret = ixfr_put_chg_part(pkt, ixfr, &ixfr->cur);
if (ret != KNOT_EOK) {
return ret;
}
changeset_iter_free(ixfr->cur, NULL);
ixfr->cur = NULL;
changeset_iter_clear(&ixfr->cur);
ixfr->state = IXFR_SOA_DEL;
}
......@@ -188,8 +180,7 @@ static void ixfr_answer_cleanup(struct query_data *qdata)
mm_ctx_t *mm = qdata->mm;
ptrlist_free(&ixfr->proc.nodes, mm);
changeset_iter_free(ixfr->cur, NULL);
ixfr->cur = NULL;
changeset_iter_clear(&ixfr->cur);
changesets_free(&ixfr->changesets);
mm->free(qdata->ext);
......@@ -397,7 +388,7 @@ static int solve_soa_del(const knot_rrset_t *rr, struct ixfr_proc *proc)
static int solve_soa_add(const knot_rrset_t *rr, changeset_t *change, mm_ctx_t *mm)
{
assert(rr->type == KNOT_RRTYPE_SOA);
change->soa_to= knot_rrset_copy(rr, mm);
change->soa_to = knot_rrset_copy(rr, mm);
if (change->soa_to == NULL) {
return KNOT_ENOMEM;
}
......
......@@ -1026,22 +1026,19 @@ static int serialize_and_store_chgset(const changeset_t *chs,
return ret;
}
/* Serialize RRSets from the 'remove' section. */
changeset_iter_t *itt = changeset_iter_rem(chs, false);
if (itt == NULL) {
return ret;
}
changeset_iter_t itt;
changeset_iter_rem(&itt, chs, false);
knot_rrset_t rrset = changeset_iter_next(itt);
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);
changeset_iter_clear(&itt);
return ret;
}
rrset = changeset_iter_next(itt);
rrset = changeset_iter_next(&itt);
}
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
/* Serialize SOA 'to'. */
ret = rrset_write_to_mem(chs->soa_to, &entry, &max_size);
......@@ -1050,21 +1047,18 @@ static int serialize_and_store_chgset(const changeset_t *chs,
}
/* Serialize RRSets from the 'add' section. */
itt = changeset_iter_add(chs, false);
if (itt == NULL) {
return ret;
}
changeset_iter_add(&itt, chs, false);
rrset = changeset_iter_next(itt);
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);
changeset_iter_clear(&itt);
return ret;
}
rrset = changeset_iter_next(itt);
rrset = changeset_iter_next(&itt);
}
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return KNOT_EOK;
}
......
......@@ -76,22 +76,17 @@ 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_all(chgset, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
size_t soa_to_size = rrset_binary_size(chgset->soa_to);changeset_iter_t itt;
changeset_iter_all(&itt, chgset, false);
size_t change_size = 0;
knot_rrset_t rrset = changeset_iter_next(itt);
knot_rrset_t rrset = changeset_iter_next(&itt);
while (!knot_rrset_empty(&rrset)) {
change_size += rrset_binary_size(&rrset);
rrset = changeset_iter_next(itt);
rrset = changeset_iter_next(&itt);
}
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
*size = soa_from_size + soa_to_size + change_size;
......
......@@ -198,30 +198,28 @@ static int remove_rr(zone_node_t *node, const knot_rrset_t *rr,
/*! \brief Removes all RRs from changeset from zone contents. */
static int apply_remove(zone_contents_t *contents, changeset_t *chset)
{
changeset_iter_t *itt = changeset_iter_rem(chset, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
changeset_iter_t itt;
changeset_iter_rem(&itt, chset, false);
knot_rrset_t rr = changeset_iter_next(itt);
knot_rrset_t rr = changeset_iter_next(&itt);
while (!knot_rrset_empty(&rr)) {
// Find node for this owner
zone_node_t *node = zone_contents_find_node_for_rr(contents, &rr);
if (!can_remove(node, &rr)) {
// Nothing to remove from, skip.
rr = changeset_iter_next(itt);
rr = changeset_iter_next(&itt);
continue;
}
int ret = remove_rr(node, &rr, chset);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return ret;
}
rr = changeset_iter_next(itt);
rr = changeset_iter_next(&itt);
}
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return KNOT_EOK;
}
......@@ -275,28 +273,26 @@ static int add_rr(zone_node_t *node, const knot_rrset_t *rr,
static int apply_add(zone_contents_t *contents, changeset_t *chset,
bool master)
{
changeset_iter_t *itt = changeset_iter_add(chset, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
changeset_iter_t itt;
changeset_iter_add(&itt, chset, false);
knot_rrset_t rr = changeset_iter_next(itt);
knot_rrset_t rr = changeset_iter_next(&itt);
while(!knot_rrset_empty(&rr)) {
// Get or create node with this owner
zone_node_t *node = zone_contents_get_node_for_rr(contents, &rr);
if (node == NULL) {
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return KNOT_ENOMEM;
}
int ret = add_rr(node, &rr, chset, master);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return ret;
}
rr = changeset_iter_next(itt);
rr = changeset_iter_next(&itt);
}
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return KNOT_EOK;
}
......
......@@ -17,6 +17,7 @@
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdarg.h>
#include "knot/updates/changesets.h"
#include "libknot/common.h"
......@@ -79,14 +80,11 @@ bool changeset_empty(const changeset_t *ch)
if (ch->soa_to) {
return false;
}
changeset_iter_t itt;
changeset_iter_all(&itt, ch, false);
changeset_iter_t *itt = changeset_iter_all(ch ,false);
if (itt == NULL) {
return true;
}
knot_rrset_t rr = changeset_iter_next(itt);
changeset_iter_free(itt, NULL);
knot_rrset_t rr = changeset_iter_next(&itt);
changeset_iter_clear(&itt);
return knot_rrset_empty(&rr);
}
......@@ -96,19 +94,16 @@ size_t changeset_size(const changeset_t *ch)
if (ch == NULL) {
return 0;
}
changeset_iter_t *itt = changeset_iter_all(ch ,false);
if (itt == NULL) {
return 0;
}
changeset_iter_t itt;
changeset_iter_all(&itt, ch, false);
size_t size = 0;
knot_rrset_t rr = changeset_iter_next(itt);
knot_rrset_t rr = changeset_iter_next(&itt);
while(!knot_rrset_empty(&rr)) {
++size;
rr = changeset_iter_next(itt);
rr = changeset_iter_next(&itt);
}
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return size;
}
......@@ -116,35 +111,32 @@ size_t changeset_size(const changeset_t *ch)
int changeset_merge(changeset_t *ch1, changeset_t *ch2)
{
#warning slow slow slow slow
changeset_iter_t *itt = changeset_iter_add(ch2, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
changeset_iter_t itt;
changeset_iter_add(&itt, ch2, false);
knot_rrset_t rrset = changeset_iter_next(itt);
knot_rrset_t rrset = changeset_iter_next(&itt);
while (!knot_rrset_empty(&rrset)) {
int ret = changeset_add_rrset(ch1, &rrset);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return ret;
}
rrset = changeset_iter_next(itt);
rrset = changeset_iter_next(&itt);
}
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
itt = changeset_iter_add(ch2, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
changeset_iter_add(&itt, ch2, false);
rrset = changeset_iter_next(itt);
rrset = changeset_iter_next(&itt);
while (!knot_rrset_empty(&rrset)) {
int ret = changeset_rem_rrset(ch1, &rrset);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
return ret;
}
rrset = changeset_iter_next(itt);
rrset = changeset_iter_next(&itt);
}
changeset_iter_free(itt, NULL);
changeset_iter_clear(&itt);
// Use soa_to and serial from the second changeset
// soa_to from the first changeset is redundant, delete it
......@@ -203,85 +195,66 @@ void changesets_free(list_t *chgs)
}
}
static void cleanup_iter_list(list_t *l, mm_ctx_t *mm)
static void cleanup_iter_list(list_t *l)
{
ptrnode_t *n;
WALK_LIST_FIRST(n, *l) {
ptrnode_t *n, *nxt;
WALK_LIST_DELSAFE(n, nxt, *l) {
hattrie_iter_t *it = (hattrie_iter_t *)n->d;
hattrie_iter_free(it);
rem_node(&n->n);
mm_free(mm, n);
free(n);
}
init_list(l);
}
static changeset_iter_t *changeset_iter_begin(const changeset_t *ch, list_t *trie_l, bool sorted)
static int changeset_iter_init(changeset_iter_t *ch_it,
const changeset_t *ch, bool sorted, size_t tries, ...)
{
changeset_iter_t *ret = mm_alloc(ch->mm, sizeof(changeset_iter_t));
if (ret == NULL) {
ERR_ALLOC_FAILED;
return NULL;
}
memset(ret, 0, sizeof(*ret));
init_list(&ret->iters);
memset(ch_it, 0, sizeof(*ch_it));
init_list(&ch_it->iters);
ptrnode_t *n;
WALK_LIST(n, *trie_l) {
hattrie_t *t = (hattrie_t *)n->d;
va_list args;
va_start(args, tries);
for (size_t i = 0; i < tries; ++i) {
hattrie_t *t = va_arg(args, hattrie_t *);
if (t) {
if (sorted) {
hattrie_build_index(t);
}
hattrie_iter_t *it = hattrie_iter_begin(t, sorted);
if (it == NULL) {
cleanup_iter_list(&ret->iters, ch->mm);
mm_free(ch->mm, ret);
return NULL;
cleanup_iter_list(&ch_it->iters);
return KNOT_ENOMEM;
}
if (ptrlist_add(&ret->iters, it, NULL) == NULL) {
cleanup_iter_list(&ret->iters, ch->mm);
mm_free(ch->mm, ret);
return NULL;
if (ptrlist_add(&ch_it->iters, it, NULL) == NULL) {
cleanup_iter_list(&ch_it->iters);
return KNOT_ENOMEM;
}
}
}
return ret;
va_end(args);
return KNOT_EOK;
}
changeset_iter_t *changeset_iter_add(const changeset_t *ch, bool sorted)
int changeset_iter_add(changeset_iter_t *itt, const changeset_t *ch, bool sorted)
{
list_t tries;
init_list(&tries);
ptrlist_add(&tries, ch->add->nodes, NULL);
ptrlist_add(&tries, ch->add->nsec3_nodes, NULL);
changeset_iter_t *ret = changeset_iter_begin(ch, &tries, sorted);
ptrlist_free(&tries, NULL);
return ret;
return changeset_iter_init(itt, ch, sorted, 2,
ch->add->nodes, ch->add->nsec3_nodes);
}
changeset_iter_t *changeset_iter_rem(const changeset_t *ch, bool sorted)
int changeset_iter_rem(changeset_iter_t *itt, const changeset_t *ch, bool sorted)
{
list_t tries;
init_list(&tries);
ptrlist_add(&tries, ch->remove->nodes, NULL);
ptrlist_add(&tries, ch->remove->nsec3_nodes, NULL);
changeset_iter_t *ret = changeset_iter_begin(ch, &tries, sorted);
ptrlist_free(&tries, NULL);
return ret;
return changeset_iter_init(itt, ch, sorted, 2,
ch->remove->nodes, ch->remove->nsec3_nodes);
}
changeset_iter_t *changeset_iter_all(const changeset_t *ch, bool sorted)
int changeset_iter_all(changeset_iter_t *itt, const changeset_t *ch, bool sorted)
{
list_t tries;
init_list(&tries);
ptrlist_add(&tries, ch->add->nodes, NULL);
ptrlist_add(&tries, ch->add->nsec3_nodes, NULL);
ptrlist_add(&tries, ch->remove->nodes, NULL);
ptrlist_add(&tries, ch->remove->nsec3_nodes, NULL);
changeset_iter_t *ret = changeset_iter_begin(ch, &tries, sorted);
ptrlist_free(&tries, NULL);
return ret;
return changeset_iter_init(itt, ch, sorted, 4,
ch->add->nodes, ch->add->nsec3_nodes,
ch->remove->nodes, ch->remove->nsec3_nodes);
}
static void iter_next_node(changeset_iter_t *ch_it, hattrie_iter_t *t_it)
......@@ -349,11 +322,10 @@ knot_rrset_t changeset_iter_next(changeset_iter_t *it)
return rr;
}
void changeset_iter_free(changeset_iter_t *it, mm_ctx_t *mm)
void changeset_iter_clear(changeset_iter_t *it)
{
if (it) {
cleanup_iter_list(&it->iters, mm);
mm_free(mm, it);
cleanup_iter_list(&it->iters);
}
}
......@@ -94,22 +94,16 @@ bool changeset_empty(const changeset_t *ch);
*/
size_t changeset_size(const changeset_t *ch);
/*!
* \brief Frees the 'changesets' structure, including all its internal data.
*
* \param changesets Double pointer to changesets structure to be freed.
* \param mm Memory context used to allocate RRSets.
*/
void changesets_clear(list_t *chgs);
void changesets_free(list_t *chgs);
void changeset_clear(changeset_t *ch);
void changeset_free(changeset_t *ch);
int changeset_merge(changeset_t *ch1, changeset_t *ch2);
changeset_iter_t *changeset_iter_add(const changeset_t *ch, bool sorted);
changeset_iter_t *changeset_iter_rem(const changeset_t *ch, bool sorted);
changeset_iter_t *changeset_iter_all(const changeset_t *ch, bool sorted);
int changeset_iter_add(changeset_iter_t *itt, const changeset_t *ch, bool sorted);
int changeset_iter_rem(changeset_iter_t *itt, const changeset_t *ch, bool sorted);
int changeset_iter_all(changeset_iter_t *itt, const changeset_t *ch, bool sorted);
knot_rrset_t changeset_iter_next(changeset_iter_t *it);
void changeset_iter_free(changeset_iter_t *it, mm_ctx_t *mm);
void changeset_iter_clear(changeset_iter_t *it);
/*! @} */
......@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
ok(trav_ok, "changeset: add traversal");
iter = changeset_iter_next(it);
changeset_iter_free(it, NULL);
changeset_iter_clear(it, NULL);
ok(knot_rrset_empty(&iter), "changeset: traversal: skip non-terminals");
// Test remove traversal.
......@@ -97,7 +97,7 @@ int main(int argc, char *argv[])
iter = changeset_iter_next(it);
ok(knot_rrset_equal(&iter, apex_txt_rr, KNOT_RRSET_COMPARE_WHOLE),
"changeset: rem traversal");
changeset_iter_free(it, NULL);
changeset_iter_clear(it, NULL);
// Test all traversal - just count.
it = changeset_iter_all(ch, false);
......@@ -108,7 +108,7 @@ int main(int argc, char *argv[])
++size;
iter = changeset_iter_next(it);
}
changeset_iter_free(it, NULL);
changeset_iter_clear(it, NULL);
ok(size == 4, "changeset: iter all");
// Create new changeset.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment