diff --git a/src/libknot/rrset.c b/src/libknot/rrset.c index e7e7391eb3fa138dc619f9e55f0c5742adcd0a45..2aba0770798fc9bea03a4be94be10952842e99ea 100644 --- a/src/libknot/rrset.c +++ b/src/libknot/rrset.c @@ -1225,154 +1225,53 @@ int knot_rrset_merge(void **r1, void **r2) int knot_rrset_merge_no_dupl(void **r1, void **r2) { - // TODO! - return knot_rrset_merge(r1, r2); -} -// if (r1 == NULL || r2 == NULL) { -// dbg_rrset("rrset: merge_no_dupl: NULL arguments."); -// return KNOT_EINVAL; -// } - -// knot_rrset_t *rrset1 = (knot_rrset_t *)(*r1); -// knot_rrset_t *rrset2 = (knot_rrset_t *)(*r2); -// if (rrset1 == NULL || rrset2 == NULL) { -// dbg_rrset("rrset: merge_no_dupl: NULL arguments."); -// return KNOT_EINVAL; -// } - + if (r1 == NULL || r2 == NULL) { + dbg_rrset("rrset: merge_no_dupl: NULL arguments."); + return KNOT_EINVAL; + } -//dbg_rrset_exec_detail( -// char *name = knot_dname_to_str(rrset1->owner); -// dbg_rrset_detail("rrset: merge_no_dupl: Merging %s.\n", name); -// free(name); -//); + knot_rrset_t *rrset1 = (knot_rrset_t *)(*r1); + knot_rrset_t *rrset2 = (knot_rrset_t *)(*r2); + if (rrset1 == NULL || rrset2 == NULL) { + dbg_rrset("rrset: merge_no_dupl: NULL arguments."); + return KNOT_EINVAL; + } -// if ((knot_dname_compare(rrset1->owner, rrset2->owner) != 0) -// || rrset1->rclass != rrset2->rclass -// || rrset1->type != rrset2->type) { -// dbg_rrset("rrset: merge_no_dupl: Trying to merge " -// "different RRs.\n"); -// return KNOT_EINVAL; -// } +dbg_rrset_exec_detail( + char *name = knot_dname_to_str(rrset1->owner); + dbg_rrset_detail("rrset: merge_no_dupl: Merging %s.\n", name); + free(name); +); -// knot_rdata_t *walk2 = rrset2->rdata; - -// // no RDATA in RRSet 1 -// if (rrset1->rdata == NULL && rrset2->rdata != NULL) { -// /* -// * This function has to assure that there are no duplicates in -// * second RRSet's list. This can be done by putting a first -// * item from the second list as a first item of the first list -// * and then simply continuing with inserting items from second -// * list to the first one. -// * -// * However, we must store pointer to second item in the second -// * list, as the 'next' pointer of the first item will be altered -// */ - -// // Store pointer to the second item in RRSet2 RDATA so that -// // we later start from this item. -// walk2 = knot_rrset_rdata_get_next(rrset2, walk2); -// assert(walk2 == rrset2->rdata->next || walk2 == NULL); - -// // Connect the first item from second list to the first list. -// rrset1->rdata = rrset2->rdata; -// // Close the cyclic list (by pointing to itself). -// rrset1->rdata->next = rrset1->rdata; -// } else if (rrset2->rdata == NULL) { -// return KNOT_EOK; -// } + if ((knot_dname_compare(rrset1->owner, rrset2->owner) != 0) + || rrset1->rclass != rrset2->rclass + || rrset1->type != rrset2->type) { + dbg_rrset("rrset: merge_no_dupl: Trying to merge " + "different RRs.\n"); + return KNOT_EINVAL; + } -// /* -// * Check that rrset1 does not contain any rdata from rrset2, if so -// * such RDATA shall not be inserted. -// */ + /* For each item in second RRSet, make sure it is not duplicated. */ + for (uint16_t i = 0; i < rrset2->rdata_count; i++) { + int duplicated = 0; + /* Compare with all RRs in the first RRSet. */ + for (uint16_t j = 0; j < rrset1->rdata_count && !duplicated; + j++) { + duplicated = !rrset_rdata_compare_one(rrset2, rrset1, + i, j, + rrset1->type); + } + + if (!duplicated) { + // This index goes to merged RRSet. + knot_rrset_add_rdata(rrset1, + rrset_rdata_pointer(rrset2, i), + rrset_rdata_item_size(rrset2, i)); + } + } -// /* Get last RDATA from first rrset, we'll need it for insertion. */ -// knot_rdata_t *insert_after = rrset1->rdata; -// while (insert_after->next != rrset1->rdata) { -// dbg_rrset_detail("rrset: merge_dupl: first rrset rdata: %p.\n", -// insert_after); -// insert_after = insert_after->next; -// } -// assert(insert_after->next == rrset1->rdata); - -// while (walk2 != NULL) { -// knot_rdata_t *walk1 = rrset1->rdata; -// char dupl = 0; -// while ((walk1 != NULL) && -// !dupl) { -// const knot_rrtype_descriptor_t *desc = -// knot_rrtype_descriptor_by_type(rrset1->type); -// assert(desc); -// /* If walk1 and walk2 are equal, do not insert. */ -// dupl = !knot_rdata_compare(walk1, walk2, -// desc->wireformat); -// walk1 = knot_rrset_rdata_get_next(rrset1, walk1); -// dbg_rrset_detail("rrset: merge_dupl: next item: %p.\n", -// walk1); -// } -// if (!dupl) { -// dbg_rrset_detail("rrset: merge_dupl: Inserting " -// "unique item (%p).\n", -// walk2); -// knot_rdata_t *tmp = walk2; -// /* -// * We need to move this, insertion -// * will corrupt pointers. -// */ -// walk2 = knot_rrset_rdata_get_next(rrset2, walk2); -// /* Insert this item at the end of first list. */ -// tmp->next = insert_after->next; -// insert_after->next = tmp; -// insert_after = tmp; -// /*!< \todo This message has to be removed after bugfix. */ -// dbg_rrset_detail("rrset: merge_no_dupl: Insert after=%p" -// ", tmp=%p, tmp->next=%p, " -// " rrset1->rdata=%p" -// "\n", -// insert_after, tmp, tmp->next, -// rrset1->rdata); -// assert(tmp->next == rrset1->rdata); -// } else { -// dbg_rrset_detail("rrset: merge_dupl: Skipping and " -// "freeing duplicated item " -// "of type: %s (%p).\n", -// knot_rrtype_to_string(rrset1->type), -// walk2); -// /* -// * Not freeing this item will result in a leak. -// * Since this operation destroys the second -// * list, we have to free the item here. -// */ -// knot_rdata_t *tmp = walk2; -// dbg_rrset_detail("rrset: merge_dupl: freeing: %p.\n", -// tmp); -// walk2 = knot_rrset_rdata_get_next(rrset2, walk2); -// knot_rdata_deep_free(&tmp, rrset1->type, 1); -// assert(tmp == NULL); -// /* Maybe caller should be warned about this. */ -// } -// } -// assert(walk2 == NULL); -//dbg_rrset_exec_detail( -// dbg_rrset_detail("rrset: merge_dupl: RDATA after merge:\n "); -// knot_rdata_t *walk1 = rrset1->rdata; -// while (walk1 != NULL) { -// dbg_rrset_detail("%p ->\n", walk1); -// walk1 = knot_rrset_rdata_get_next(rrset1, walk1); -// } -// dbg_rrset_detail("rrset: merge_dupl: RDATA after merge: r1:%p r2: %p\n", -// rrset1->rdata, rrset2->rdata); -//); -// /* -// * Since there is a possibility of corrupted list for second RRSet, it -// * is safer to set its list to NULL, so that it cannot be used. -// */ -// rrset2->rdata = NULL; - -// return KNOT_EOK; -//} + return KNOT_EOK; +} /*----------------------------------------------------------------------------*/