mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
Incrementally apply AXFR transfer
Reintroduce logic to apply diffs when the number of pending tuples is
above 128. The previous strategy of accumulating all the tuples and
pushing them at the end leads to excessive memory consumption during
transfer.
This effectively reverts half of e3892805d6
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <isc/buffer.h>
|
||||
@@ -123,6 +124,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
|
||||
@@ -133,15 +135,37 @@ 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) {
|
||||
REQUIRE(DNS_DIFF_VALID(diff));
|
||||
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) {
|
||||
REQUIRE(DNS_DIFF_VALID(diff));
|
||||
REQUIRE(DNS_NAME_VALID(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) {
|
||||
REQUIRE(DNS_DIFF_VALID(diff));
|
||||
return diff->size;
|
||||
}
|
||||
|
||||
/* XXX this is O(N) */
|
||||
|
||||
void
|
||||
@@ -170,6 +194,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 {
|
||||
@@ -182,6 +209,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;
|
||||
}
|
||||
}
|
||||
@@ -253,7 +281,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;
|
||||
@@ -493,19 +522,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;
|
||||
|
||||
@@ -641,7 +671,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;
|
||||
|
Reference in New Issue
Block a user