Compare commits

...

5 Commits

Author SHA1 Message Date
alessio
97460c9929 Better size testing 2024-11-08 10:57:22 +01:00
alessio
44c18b62fb Add test for diff size change 2024-11-07 21:25:54 +01:00
alessio
5d0d537b31 Apply clang-format 2024-11-07 13:45:11 +01:00
alessio
5d00cd48a8 Encapsulate diff size 2024-11-07 13:13:29 +01:00
alessio
ccb7e3ecd5 Chunk work synchronously 2024-11-07 12:26:22 +01:00
5 changed files with 168 additions and 10 deletions

View File

@@ -15,6 +15,7 @@
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <isc/buffer.h>
@@ -124,6 +125,7 @@ dns_diff_init(isc_mem_t *mctx, dns_diff_t *diff) {
diff->mctx = mctx;
ISC_LIST_INIT(diff->tuples);
diff->magic = DNS_DIFF_MAGIC;
diff->size = 0;
}
void
@@ -134,15 +136,32 @@ dns_diff_clear(dns_diff_t *diff) {
ISC_LIST_UNLINK(diff->tuples, t, link);
dns_difftuple_free(&t);
}
diff->size = 0;
ENSURE(ISC_LIST_EMPTY(diff->tuples));
}
void
dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuplep) {
ISC_LIST_APPEND(diff->tuples, *tuplep, link);
diff->size += 1;
*tuplep = NULL;
}
bool
dns_diff_is_boundary(const dns_diff_t *diff, dns_name_t *new_name) {
if (ISC_LIST_EMPTY(diff->tuples)) {
return false;
}
dns_difftuple_t *tail = ISC_LIST_TAIL(diff->tuples);
return !dns_name_caseequal(&tail->name, new_name);
}
size_t
dns_diff_size(const dns_diff_t *diff) {
return diff->size;
}
/* XXX this is O(N) */
void
@@ -171,6 +190,9 @@ dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuplep) {
ot->ttl == (*tuplep)->ttl)
{
ISC_LIST_UNLINK(diff->tuples, ot, link);
INSIST(diff->size > 0);
diff->size -= 1;
if ((*tuplep)->op == ot->op) {
UNEXPECTED_ERROR("unexpected non-minimal diff");
} else {
@@ -183,6 +205,7 @@ dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuplep) {
if (*tuplep != NULL) {
ISC_LIST_APPEND(diff->tuples, *tuplep, link);
diff->size += 1;
*tuplep = NULL;
}
}
@@ -254,7 +277,8 @@ optotext(dns_diffop_t op) {
}
static isc_result_t
diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver, bool warn) {
diff_apply(const dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
bool warn) {
dns_difftuple_t *t;
dns_dbnode_t *node = NULL;
isc_result_t result;
@@ -494,19 +518,20 @@ failure:
}
isc_result_t
dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) {
dns_diff_apply(const dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) {
return (diff_apply(diff, db, ver, true));
}
isc_result_t
dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver) {
dns_diff_applysilently(const dns_diff_t *diff, dns_db_t *db,
dns_dbversion_t *ver) {
return (diff_apply(diff, db, ver, false));
}
/* XXX this duplicates lots of code in diff_apply(). */
isc_result_t
dns_diff_load(dns_diff_t *diff, dns_rdatacallbacks_t *callbacks) {
dns_diff_load(const dns_diff_t *diff, dns_rdatacallbacks_t *callbacks) {
dns_difftuple_t *t;
isc_result_t result;
@@ -642,7 +667,7 @@ diff_tuple_tordataset(dns_difftuple_t *t, dns_rdata_t *rdata,
}
isc_result_t
dns_diff_print(dns_diff_t *diff, FILE *file) {
dns_diff_print(const dns_diff_t *diff, FILE *file) {
isc_result_t result;
dns_difftuple_t *t;
char *mem = NULL;

View File

@@ -27,6 +27,8 @@
*** Imports
***/
#include <stddef.h>
#include <isc/lang.h>
#include <isc/magic.h>
@@ -97,6 +99,7 @@ struct dns_diff {
unsigned int magic;
isc_mem_t *mctx;
dns_difftuplelist_t tuples;
size_t size;
};
/* Type of comparison function for sorting diffs. */
@@ -194,6 +197,12 @@ dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuple);
*\li The tuple has been freed, or will be freed when the diff is cleared.
*/
bool
dns_diff_is_boundary(const dns_diff_t *diff, dns_name_t *new_name);
size_t
dns_diff_size(const dns_diff_t *diff);
void
dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuple);
/*%<
@@ -218,9 +227,10 @@ dns_diff_sort(dns_diff_t *diff, dns_diff_compare_func *compare);
*/
isc_result_t
dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
dns_diff_apply(const dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
isc_result_t
dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
dns_diff_applysilently(const dns_diff_t *diff, dns_db_t *db,
dns_dbversion_t *ver);
/*%<
* Apply 'diff' to the database 'db'.
*
@@ -239,7 +249,7 @@ dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver);
*/
isc_result_t
dns_diff_load(dns_diff_t *diff, dns_rdatacallbacks_t *callbacks);
dns_diff_load(const dns_diff_t *diff, dns_rdatacallbacks_t *callbacks);
/*%<
* Like dns_diff_apply, but for use when loading a new database
* instead of modifying an existing one. This bypasses the
@@ -251,7 +261,7 @@ dns_diff_load(dns_diff_t *diff, dns_rdatacallbacks_t *callbacks);
*/
isc_result_t
dns_diff_print(dns_diff_t *diff, FILE *file);
dns_diff_print(const dns_diff_t *diff, FILE *file);
/*%<
* Print the differences to 'file' or if 'file' is NULL via the

View File

@@ -300,6 +300,9 @@ failure:
return (result);
}
static void
axfr_apply(void *arg);
static isc_result_t
axfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
dns_rdata_t *rdata) {
@@ -312,8 +315,20 @@ axfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
}
CHECK(dns_zone_checknames(xfr->zone, name, rdata));
if (dns_diff_size(&xfr->diff) > 128 &&
dns_diff_is_boundary(&xfr->diff, name))
{
xfrin_work_t work = (xfrin_work_t){
.xfr = xfr,
.result = ISC_R_UNSET,
};
axfr_apply((void *)&work);
CHECK(work.result);
}
dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata, &tuple);
dns_diff_append(&xfr->diff, &tuple);
result = ISC_R_SUCCESS;
failure:
return (result);
@@ -1095,7 +1110,6 @@ xfrin_reset(dns_xfrin_t *xfr) {
}
dns_diff_clear(&xfr->diff);
xfr->ixfr.diffs = 0;
if (xfr->ixfr.journal != NULL) {

View File

@@ -24,6 +24,7 @@ check_PROGRAMS = \
dbdiff_test \
dbiterator_test \
dbversion_test \
diff_test \
dispatch_test \
dns64_test \
dst_test \

108
tests/dns/diff_test.c Normal file
View File

@@ -0,0 +1,108 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <setjmp.h>
#include <unistd.h>
#include "isc/list.h"
#define UNIT_TESTING
#include <cmocka.h>
#include <dns/diff.h>
#include <tests/dns.h>
unsigned char data_1[] = "\006name_1";
unsigned char offsets_1[] = { 0, 7 };
dns_name_t name_1 = DNS_NAME_INITABSOLUTE(data_1, offsets_1);
unsigned char data_2[] = "\006name_2";
unsigned char offsets_2[] = { 0, 7 };
dns_name_t name_2 = DNS_NAME_INITABSOLUTE(data_2, offsets_2);
unsigned char data_3[] = "\006name_3";
unsigned char offsets_3[] = { 0, 7 };
dns_name_t name_3 = DNS_NAME_INITABSOLUTE(data_3, offsets_3);
unsigned char data_dup[] = "\006name_1";
unsigned char offsets_dup[] = {0, 7};
dns_name_t name_dup = DNS_NAME_INITABSOLUTE(data_dup, offsets_dup);
unsigned char data_nodup[] = "\006name_1";
unsigned char offsets_nodup[] = {0, 7};
dns_name_t name_nodup = DNS_NAME_INITABSOLUTE(data_nodup, offsets_nodup);
dns_rdata_t rdata_1 = DNS_RDATA_INIT;
dns_rdata_t rdata_2 = DNS_RDATA_INIT;
dns_rdata_t rdata_3 = DNS_RDATA_INIT;
dns_rdata_t rdata_dup = DNS_RDATA_INIT;
dns_rdata_t rdata_nodup = DNS_RDATA_INIT;
static size_t count_elements(const dns_diff_t *diff) {
dns_difftuple_t *ot = NULL;
size_t count = 0;
for (ot = ISC_LIST_HEAD(diff->tuples); ot != NULL; ot = ISC_LIST_NEXT(ot, link)) {
++count;
}
return count;
}
ISC_RUN_TEST_IMPL(dns_diff_size) {
dns_diff_t diff;
dns_diff_init(mctx, &diff);
assert_true(dns_diff_size(&diff) == 0);
dns_difftuple_t *tup_1 = NULL, *tup_2 = NULL, *tup_3 = NULL;
dns_difftuple_create(mctx, DNS_DIFFOP_ADD, &name_1, 1, &rdata_1, &tup_1);
dns_difftuple_create(mctx, DNS_DIFFOP_DEL, &name_2, 1, &rdata_2, &tup_2);
dns_difftuple_create(mctx, DNS_DIFFOP_DEL, &name_3, 1, &rdata_3, &tup_3);
dns_difftuple_t *tup_dup = NULL, *tup_nodup = NULL;
dns_difftuple_create(mctx, DNS_DIFFOP_DEL, &name_dup, 1, &rdata_dup, &tup_dup);
dns_difftuple_create(mctx, DNS_DIFFOP_ADD, &name_nodup, 1, &rdata_nodup, &tup_nodup);
(void)tup_dup;
(void)tup_nodup;
dns_diff_append(&diff, &tup_1);
assert_true(dns_diff_size(&diff) == 1);
assert_true(dns_diff_size(&diff) == count_elements(&diff));
dns_diff_append(&diff, &tup_2);
assert_true(dns_diff_size(&diff) == 2);
assert_true(dns_diff_size(&diff) == count_elements(&diff));
dns_diff_appendminimal(&diff, &tup_dup);
assert_true(dns_diff_size(&diff) == 1);
assert_true(dns_diff_size(&diff) == count_elements(&diff));
dns_diff_append(&diff, &tup_3);
assert_true(dns_diff_size(&diff) == 2);
assert_true(dns_diff_size(&diff) == count_elements(&diff));
dns_diff_appendminimal(&diff, &tup_nodup);
assert_true(dns_diff_size(&diff) == 3);
assert_true(dns_diff_size(&diff) == count_elements(&diff));
dns_diff_clear(&diff);
assert_true(dns_diff_size(&diff) == 0);
assert_true(dns_diff_size(&diff) == count_elements(&diff));
dns_difftuple_t* to_clear[] = {tup_1, tup_2, tup_3, tup_dup, tup_nodup};
size_t to_clear_size = sizeof(to_clear) / sizeof(*to_clear);
for (size_t idx = 0; idx < to_clear_size; ++idx) {
if (to_clear[idx] != NULL) {
printf("Tuple %zu is not null\n", idx);
dns_difftuple_free(&to_clear[idx]);
}
}
}
ISC_TEST_LIST_START
ISC_TEST_ENTRY(dns_diff_size)
ISC_TEST_LIST_END
ISC_TEST_MAIN