Commit 23424e14 authored by Jan Kadlec's avatar Jan Kadlec

changeset: Smarted iteration, copypasta removed.

parent 94eadac1
......@@ -1393,8 +1393,8 @@ int knot_zone_sign_changeset(const zone_contents_t *zone,
return KNOT_ENOMEM;
}
// Sign all RRs that are new in changeset
changeset_iter_t *itt = changeset_iter_add(in_ch, false);
// 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;
}
......@@ -1409,23 +1409,6 @@ int knot_zone_sign_changeset(const zone_contents_t *zone,
rr = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
itt = changeset_iter_rem(in_ch, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
#warning too much copypasta
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);
return ret;
}
rr = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
knot_zone_clear_sorted_changes(args.signed_tree);
hattrie_free(args.signed_tree);
......
......@@ -79,33 +79,21 @@ int changeset_binary_size(const changeset_t *chgset, size_t *size)
size_t soa_to_size = rrset_binary_size(chgset->soa_to);
changeset_iter_t *itt = changeset_iter_rem(chgset, false);
changeset_iter_t *itt = changeset_iter_all(chgset, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
size_t remove_size = 0;
size_t change_size = 0;
knot_rrset_t rrset = changeset_iter_next(itt);
while (!knot_rrset_empty(&rrset)) {
remove_size += rrset_binary_size(&rrset);
change_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;
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;
*size = soa_from_size + soa_to_size + change_size;
return KNOT_EOK;
}
......
......@@ -162,35 +162,43 @@ void changesets_free(list_t *chgs, mm_ctx_t *rr_mm)
}
}
#define NODE_DONE -1
void cleanup_iter_list(list_t *l)
{
ptrnode_t *n;
WALK_LIST_FIRST(n, *l) {
hattrie_iter_t *it = (hattrie_iter_t *)n->d;
hattrie_iter_free(it);
rem_node(&n->n);
}
}
static changeset_iter_t *changeset_iter_begin(const changeset_t *ch, hattrie_t *tr,
hattrie_t *nsec3_tr, bool sorted)
static changeset_iter_t *changeset_iter_begin(const changeset_t *ch, list_t *trie_l, bool sorted)
{
#warning emptiness check
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));
ret->node_pos = NODE_DONE;
ret->normal_it = hattrie_iter_begin(tr, sorted);
if (ret->normal_it == NULL) {
mm_free(ch->mm, ret);
return NULL;
}
if (nsec3_tr) {
ret->nsec3_it = hattrie_iter_begin(nsec3_tr, sorted);
if (ret->nsec3_it == NULL) {
hattrie_iter_free(ret->normal_it);
mm_free(ch->mm, ret);
return NULL;
memset(ret, 0, sizeof(*ret));
init_list(&ret->iters);
ptrnode_t *n;
WALK_LIST(n, *trie_l) {
hattrie_t *t = (hattrie_t *)n->d;
if (t) {
hattrie_iter_t *it = hattrie_iter_begin(t, sorted);
if (it == NULL) {
cleanup_iter_list(&ret->iters);
mm_free(ch->mm, ret);
return NULL;
}
if (ptrlist_add(&ret->iters, it, NULL) == NULL) {
cleanup_iter_list(&ret->iters);
mm_free(ch->mm, ret);
return NULL;
}
}
} else {
ret->nsec3_it = NULL;
}
return ret;
......@@ -198,72 +206,105 @@ static changeset_iter_t *changeset_iter_begin(const changeset_t *ch, hattrie_t *
changeset_iter_t *changeset_iter_add(const changeset_t *ch, bool sorted)
{
return changeset_iter_begin(ch, ch->add->nodes, ch->add->nsec3_nodes, 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;
}
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);
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;
}
static void get_next_rr(knot_rrset_t *rr, changeset_iter_t *ch_it, hattrie_iter_t **t_it) // pun intented
changeset_iter_t *changeset_iter_all(const changeset_t *ch, bool sorted)
{
#warning get rid of recursion
if (ch_it->node_pos == NODE_DONE) {
// Get next node.
if (ch_it->node) {
// Do not get next for very first node.
hattrie_iter_next(*t_it);
}
if (hattrie_iter_finished(*t_it)) {
hattrie_iter_free(*t_it);
*t_it = NULL;
ch_it->node = NULL;
ch_it->node_pos = NODE_DONE;
return;
}
ch_it->node = (zone_node_t *)*hattrie_iter_val(*t_it);
if (ch_it->node->rrset_count == 0) {
get_next_rr(rr, ch_it, t_it);
}
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;
}
static void iter_next_node(changeset_iter_t *ch_it, hattrie_iter_t *t_it)
{
// Get next node, but not for the very first call.
if (ch_it->node) {
hattrie_iter_next(t_it);
}
if (hattrie_iter_finished(t_it)) {
ch_it->node = NULL;
return;
}
ch_it->node = (zone_node_t *)*hattrie_iter_val(t_it);
while (ch_it->node->rrset_count == 0 && !hattrie_iter_finished(t_it)) {
// Skip empty non-terminals.
hattrie_iter_next(t_it);
ch_it->node = (zone_node_t *)*hattrie_iter_val(t_it);
}
if (hattrie_iter_finished(t_it)) {
ch_it->node = NULL;
return;
}
ch_it->node_pos = 0;
}
static knot_rrset_t get_next_rr(changeset_iter_t *ch_it, hattrie_iter_t *t_it) // pun intented
{
if (ch_it->node == NULL || ch_it->node_pos == ch_it->node->rrset_count) {
iter_next_node(ch_it, t_it);
if (ch_it->node == NULL) {
return;
assert(hattrie_iter_finished(t_it));
knot_rrset_t rr;
knot_rrset_init_empty(&rr);
return rr;
}
}
assert(ch_it->node);
if (ch_it->node_pos < ch_it->node->rrset_count) {
*rr = node_rrset_at(ch_it->node, ch_it->node_pos);
++ch_it->node_pos;
} else {
// Node is done, get next.
ch_it->node_pos = NODE_DONE;
get_next_rr(rr, ch_it, t_it);
}
assert(!knot_rrset_empty(rr));
return node_rrset_at(ch_it->node, ch_it->node_pos++);
}
knot_rrset_t changeset_iter_next(changeset_iter_t *it)
{
knot_rrset_t ret;
knot_rrset_init_empty(&ret);
if (it->normal_it) {
get_next_rr(&ret, it, &it->normal_it);
} else if (it->nsec3_it) {
get_next_rr(&ret, it, &it->nsec3_it);
ptrnode_t *n = NULL;
knot_rrset_t rr;
knot_rrset_init_empty(&rr);
WALK_LIST(n, it->iters) {
hattrie_iter_t *t_it = (hattrie_iter_t *)n->d;
if (hattrie_iter_finished(t_it)) {
continue;
}
rr = get_next_rr(it, t_it);
if (!knot_rrset_empty(&rr)) {
// Got valid RRSet.
return rr;
}
}
return ret;
return rr;
}
void changeset_iter_free(changeset_iter_t *it, mm_ctx_t *mm)
{
if (it) {
hattrie_iter_free(it->normal_it);
hattrie_iter_free(it->nsec3_it);
cleanup_iter_list(&it->iters);
mm_free(mm, it);
}
}
......
......@@ -48,8 +48,7 @@ typedef struct changeset {
} changeset_t;
typedef struct {
hattrie_iter_t *normal_it;
hattrie_iter_t *nsec3_it;
list_t iters;
const zone_node_t *node;
int32_t node_pos;
} changeset_iter_t;
......@@ -114,6 +113,7 @@ void changeset_clear(changeset_t *ch, mm_ctx_t *rr_mm);
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);
knot_rrset_t changeset_iter_next(changeset_iter_t *it);
void changeset_iter_free(changeset_iter_t *it, mm_ctx_t *mm);
......
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