Commit
0858514ae8 enriched dns_qp_compact() to give callers more
control over how thoroughly the trie should be compacted.
In the DNS_QPGC_ALL case, if the trie is small it might be compacted
to a new position in the same memory chunk. In this situation it will
still be holding references to old leaf objects which have been
removed from the trie but will not be completely detached until the
chunk containing the references is freed.
This change resets the qp-trie allocator to a fresh chunk before a
DNS_QPGC_ALL compaction, so all the old memory chunks will be
evacuated and old leaf objects can be detached sooner.
return;
}
if (mode == DNS_QPGC_ALL) {
+ alloc_reset(qp);
qp->compact_all = true;
}
compact(qp);
static void
sqz_qp(void *qp) {
- dns_qp_compact(qp, true);
+ dns_qp_compact(qp, DNS_QPGC_ALL);
}
static isc_result_t
labels += name->labels;
names += 1;
}
- dns_qp_compact(qp, true);
+ dns_qp_compact(qp, DNS_QPGC_ALL);
size_t smallbytes = wirebytes + labels + names * sizeof(isc_refcount_t);
dns_qp_memusage_t memusage = dns_qp_memusage(qp);
args->absent++;
}
}
+ /*
+ * We would normally use DNS_QPGC_MAYBE, but here we do the
+ * fragmented check ourself so we can count compactions
+ */
if (dns_qp_memusage(qp).fragmented) {
- dns_qp_compact(qp, false);
+ dns_qp_compact(qp, DNS_QPGC_NOW);
args->compactions++;
}
dns_qpmulti_commit(args->multi, &qp);
item[i].present = true;
count++;
}
- dns_qp_compact(qp, true);
+ dns_qp_compact(qp, DNS_QPGC_ALL);
dns_qpmulti_commit(bctx->multi, &qp);
bctx->load_time = isc_time_monotonic() - start;