diff --git a/lib/dns/diff.c b/lib/dns/diff.c index 24e1634ca1..f251f32860 100644 --- a/lib/dns/diff.c +++ b/lib/dns/diff.c @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -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,17 +136,19 @@ 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(dns_diff_t *diff, dns_name_t *new_name) { +dns_diff_is_boundary(const dns_diff_t *diff, dns_name_t *new_name) { if (ISC_LIST_EMPTY(diff->tuples)) { return false; } @@ -153,6 +157,11 @@ dns_diff_is_boundary(dns_diff_t *diff, dns_name_t *new_name) { 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 @@ -181,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 { @@ -193,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; } } @@ -264,7 +277,7 @@ 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; @@ -504,19 +517,19 @@ 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; @@ -652,7 +665,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; diff --git a/lib/dns/include/dns/diff.h b/lib/dns/include/dns/diff.h index 7db727ae07..fa5fbd0c56 100644 --- a/lib/dns/include/dns/diff.h +++ b/lib/dns/include/dns/diff.h @@ -27,6 +27,7 @@ *** Imports ***/ +#include #include #include @@ -97,6 +98,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. */ @@ -195,7 +197,10 @@ dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuple); */ bool -dns_diff_is_boundary(dns_diff_t *diff, dns_name_t *new_name); +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); @@ -221,9 +226,9 @@ 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'. * @@ -242,7 +247,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 @@ -254,7 +259,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 diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 7d12e6b1e1..8022a9d989 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -131,7 +131,6 @@ struct dns_xfrin { dns_db_t *db; dns_dbversion_t *ver; dns_diff_t diff; /*%< Pending database changes */ - int difflen; /*%< Number of pending tuples */ /* Diff queue */ bool diff_running; @@ -284,7 +283,6 @@ axfr_init(dns_xfrin_t *xfr) { isc_result_t result; atomic_store(&xfr->is_ixfr, false); - xfr->difflen = 0; if (xfr->db != NULL) { dns_db_detach(&xfr->db); @@ -316,7 +314,7 @@ 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 (xfr->difflen > 128 && dns_diff_is_boundary(&xfr->diff, name)) { + 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, @@ -327,7 +325,6 @@ axfr_putdata(dns_xfrin_t *xfr, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_difftuple_create(xfr->diff.mctx, op, name, ttl, rdata, &tuple); dns_diff_append(&xfr->diff, &tuple); - xfr->difflen += 1; result = ISC_R_SUCCESS; failure: @@ -362,7 +359,6 @@ axfr_apply(void *arg) { failure: dns_diff_clear(&xfr->diff); - xfr->difflen = 0; work->result = result; } @@ -1111,8 +1107,6 @@ xfrin_reset(dns_xfrin_t *xfr) { } dns_diff_clear(&xfr->diff); - xfr->difflen = 0; - xfr->ixfr.diffs = 0; if (xfr->ixfr.journal != NULL) {