From: Evan Hunt Date: Tue, 25 Feb 2025 05:30:10 +0000 (-0800) Subject: save time when creating a slab from another slab X-Git-Tag: ondrej/lock-free-qpzone-reads-v1~28^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=94a96a7a0eaddd19261cec370188a51406d7b95c;p=thirdparty%2Fbind9.git save time when creating a slab from another slab the dns_rdataslab_fromrdataset() function creates a slab from an rdataset. if the source rdataset already uses a slab, then no processing is necessary; we can just copy the existing slab to a new location. --- diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index e4fce867bae..1aaafd0ba20 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -119,6 +119,24 @@ static bool rdataset_equals(const dns_rdataset_t *rdataset1, const dns_rdataset_t *rdataset2); +dns_rdatasetmethods_t dns_rdataslab_rdatasetmethods = { + .disassociate = rdataset_disassociate, + .first = rdataset_first, + .next = rdataset_next, + .current = rdataset_current, + .clone = rdataset_clone, + .count = rdataset_count, + .getnoqname = rdataset_getnoqname, + .getclosest = rdataset_getclosest, + .settrust = rdataset_settrust, + .expire = rdataset_expire, + .clearprefetch = rdataset_clearprefetch, + .setownercase = rdataset_setownercase, + .getownercase = rdataset_getownercase, + .getheader = rdataset_getheader, + .equals = rdataset_equals, +}; + /*% Note: the "const void *" are just to make qsort happy. */ static int compare_rdata(const void *p1, const void *p2) { @@ -136,7 +154,7 @@ makeslab(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region, dns_rdata_t *rdata = NULL; unsigned char *rawbuf = NULL; unsigned int headerlen = sizeof(dns_slabheader_t); - unsigned int buflen; + unsigned int buflen = headerlen + 2; isc_result_t result; unsigned int nitems; unsigned int nalloc; @@ -144,14 +162,28 @@ makeslab(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region, size_t i; size_t rdatasize; - buflen = headerlen + 2; + /* + * If the source rdataset is also a slab, we don't need + * to do anything special, just copy the whole slab to a + * new buffer. + */ + if (rdataset->methods == &dns_rdataslab_rdatasetmethods) { + dns_slabheader_t *header = dns_rdataset_getheader(rdataset); + buflen = dns_rdataslab_size(header); - nitems = dns_rdataset_count(rdataset); + rawbuf = isc_mem_get(mctx, buflen); + region->base = rawbuf; + region->length = buflen; + + memmove(rawbuf, header, buflen); + return ISC_R_SUCCESS; + } /* - * If there are no rdata then we can just need to allocate a header - * with zero a record count. + * If there are no rdata then we just need to allocate a header + * with a zero record count. */ + nitems = dns_rdataset_count(rdataset); if (nitems == 0) { if (rdataset->type != 0) { return ISC_R_FAILURE; @@ -160,8 +192,7 @@ makeslab(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region, region->base = rawbuf; region->length = buflen; rawbuf += headerlen; - *rawbuf++ = 0; - *rawbuf = 0; + put_uint16(rawbuf, 0); return ISC_R_SUCCESS; } @@ -269,9 +300,7 @@ makeslab(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region, region->base = rawbuf; region->length = buflen; - rawbuf += headerlen; - put_uint16(rawbuf, nitems); for (i = 0; i < nalloc; i++) { @@ -931,24 +960,6 @@ dns_slabheader_top(dns_slabheader_t *header) { return header; } -dns_rdatasetmethods_t dns_rdataslab_rdatasetmethods = { - .disassociate = rdataset_disassociate, - .first = rdataset_first, - .next = rdataset_next, - .current = rdataset_current, - .clone = rdataset_clone, - .count = rdataset_count, - .getnoqname = rdataset_getnoqname, - .getclosest = rdataset_getclosest, - .settrust = rdataset_settrust, - .expire = rdataset_expire, - .clearprefetch = rdataset_clearprefetch, - .setownercase = rdataset_setownercase, - .getownercase = rdataset_getownercase, - .getheader = rdataset_getheader, - .equals = rdataset_equals, -}; - /* Fixed RRSet helper macros */ #define DNS_RDATASET_LENGTH 2;