std.experimental.allocator.building_blocks.quantizer
- struct Quantizer(ParentAllocator, alias roundingFunction);
-
This allocator sits on top of
ParentAllocator
and quantizes allocation sizes, usually from arbitrary positive numbers to a small set of round numbers (e.g. powers of two, page sizes etc). This technique is commonly used to:- Preallocate more memory than requested such that later on, when reallocation is needed (e.g. to grow an array), expansion can be done quickly in place. Reallocation to smaller sizes is also fast (in-place) when the new size requested is within the same quantum as the existing size. Code that's reallocation-heavy can therefore benefit from fronting a generic allocator with a
Quantizer
. These advantages are present even ifParentAllocator
does not support reallocation at all. - Improve behavior of allocators sensitive to allocation sizes, such as
FreeList
andFreeTree
. Rounding allocation requests up makes for smaller free lists/trees at the cost of slack memory (internal fragmentation).
The following methods are forwarded to the parent allocator if present:allocateAll
,owns
,deallocateAll
,empty
.- Preconditions
-
roundingFunction
must satisfy three constraints. These are not enforced (save for the use ofassert
) for the sake of efficiency.
-
roundingFunction(n) >= n
for alln
of typesize_t
; -
roundingFunction
must be monotonically increasing, i.e.roundingFunction(n1) <= roundingFunction(n2)
for alln1 < n2
; -
roundingFunction
must benothrow
,@safe
,@nogc
andpure
, i.e. always return the same value for a givenn
.
- Examples:
-
import std.experimental.allocator.building_blocks.free_tree : FreeTree; import std.experimental.allocator.gc_allocator : GCAllocator; size_t roundUpToMultipleOf(size_t s, uint base) { auto rem = s % base; return rem ? s + base - rem : s; } // Quantize small allocations to a multiple of cache line, large ones to a // multiple of page size alias MyAlloc = Quantizer!( FreeTree!GCAllocator, n => roundUpToMultipleOf(n, n <= 16_384 ? 64 : 4096)); MyAlloc alloc; const buf = alloc.allocate(256); assert(buf.ptr);
- ParentAllocator parent;
-
The parent allocator. Depending on whether
ParentAllocator
holds state or not, this is a member variable or an alias forParentAllocator.instance
. - size_t goodAllocSize(size_t n);
-
Returns
roundingFunction(n)
. - enum auto alignment;
-
Alignment is identical to that of the parent.
- void[] allocate(size_t n);
-
Gets a larger buffer
buf
by callingparent.allocate(goodAllocSize(n))
. Ifbuf
isnull
, returnsnull
. Otherwise, returnsbuf[0 .. n]
. - void[] alignedAllocate(size_t n, uint a);
-
Defined only if
parent.alignedAllocate
exists and works similarly toallocate
by forwarding toparent.alignedAllocate(goodAllocSize(n), a)
. - bool expand(ref void[] b, size_t delta);
-
First checks whether there's enough slack memory preallocated for
b
by evaluatingb.length + delta <= goodAllocSize(b.length)
. If that's the case, expandsb
in place. Otherwise, attempts to useparent.expand
appropriately if present. - bool reallocate(ref void[] b, size_t s);
-
Expands or shrinks allocated block to an allocated size of
goodAllocSize(s)
. Expansion occurs in place under the conditions required byexpand
. Shrinking occurs in place ifgoodAllocSize(b.length) == goodAllocSize(s)
. - bool alignedReallocate(ref void[] b, size_t s, uint a);
-
Defined only if
ParentAllocator.alignedAllocate
exists. Expansion occurs in place under the conditions required byexpand
. Shrinking occurs in place ifgoodAllocSize(b.length) == goodAllocSize(s)
. - bool deallocate(void[] b);
-
Defined if
ParentAllocator.deallocate
exists and forwards toparent.deallocate(b.ptr[0 .. goodAllocSize(b.length)])
.
- Preallocate more memory than requested such that later on, when reallocation is needed (e.g. to grow an array), expansion can be done quickly in place. Reallocation to smaller sizes is also fast (in-place) when the new size requested is within the same quantum as the existing size. Code that's reallocation-heavy can therefore benefit from fronting a generic allocator with a
© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_experimental_allocator_building_blocks_quantizer.html