FreeList
(ParentAllocator, size_t minSize, size_t maxSize = minSize, Flag!"adaptive" adaptive = No.adaptive);min
() const;min
(size_tlow
);min
property is writable. Setting it must precede any allocation.size_tlow | new value formin |
Preconditionlow <= max, ormaxSize == chooseAtRuntime andmax has not yet been initialized. Also, no allocation has been yet done with this allocator.
Postconditionmin == low
max
() const;max
are rounded to max and forwarded to the parent allocator. When the block fitting the same constraint gets deallocated, it is put in the freelist with the allocated size assumed to bemax
.max
(size_thigh
);max
property is writable. Setting it must precede any allocation.size_thigh | new value formax |
Preconditionhigh >= min, orminSize == chooseAtRuntime andmin has not yet been initialized. Alsohigh >= (void*).sizeof. Also, no allocation has been yet done with this allocator.
Postconditionmax == high
parent
;alignment
= ParentAllocator.alignment
;goodAllocSize
(size_tbytes
);goodAllocSize
(bytes
). Otherwise, returnsmax for sizes in the interval[min, max], andparent.goodAllocSize
(bytes
) otherwise.PreconditionIf set at runtime,min and/ormax must be initialized appropriately.
Postconditionresult >= bytes
allocate
(size_tn
);n
is within[min, max] or if the free list is unchecked (minSize == 0 && maxSize == size_t.max), then the free list is consulted first. If not empty (hit), the block at the front of the free list is removed from the list and returned. Otherwise (miss), a new block ofmax bytes is allocated, truncated ton
bytes, and returned.size_tn | number of bytes to allocate |
PreconditionIf set at runtime,min and/ormax must be initialized appropriately.
Postconditionresult.length == bytes || result is null
deallocate
(void[]block
);block
.length is within[min, max] or if the free list is unchecked (minSize == 0 && maxSize == size_t.max), then inserts the block at the front of the free list. For all others, forwards to parent.deallocate ifParent.deallocate
is defined.void[]block | Block to deallocate. |
PreconditionIf set at runtime,min and/ormax must be initialized appropriately. The block must have been allocated with this freelist, and no dynamic changing ofmin ormax is allowed to occur between allocation and deallocation.
deallocateAll
();deallocateAll
. If so, forwards to it and resets the freelist.minimize
();ContiguousFreeList
(ParentAllocator, size_t minSize, size_t maxSize = minSize);ContiguousFreeList
's destructor (unlessParentAllocator isNullAllocator).ContiguousFreeList
has most advantages ofFreeList but fewerdisadvantages. It has better cache locality because items are closer to oneanother. It imposes less fragmentation on its parent allocator.The disadvantages ofContiguousFreeList
overFreeList are its payupfront model (as opposed toFreeList's pay-as-you-go approach), and ahard limit on the number of nodes in the list. Thus, a large number of long-lived objects may occupy the entire block, making it unavailable for servingallocations from the free list. However, an absolute cap on the free list sizemay be beneficial.The optionsminSize == unbounded andmaxSize == unbounded are notavailable forContiguousFreeList
.import std.experimental.allocator.building_blocks.allocator_list : AllocatorList;import std.experimental.allocator.gc_allocator : GCAllocator;import std.experimental.allocator.common : unbounded;alias ScalableFreeList = AllocatorList!((n) =>ContiguousFreeList!(GCAllocator, 0, unbounded)(4096));
parent
;alignment
;buffer
);parent
, ubyte[]buffer
);bytes
);parent
, size_tbytes
);bytes
, size_tmax
);parent
, size_tbytes
, size_tmax
);bytes
, size_tmin
, size_tmax
);parent
, size_tbytes
, size_tmin
, size_tmax
);ubyte[]buffer | Buffer to structure as a free list. IfParentAllocator is notNullAllocator, the buffer is assumed to be allocated byparent and will be freed in the destructor. |
ParentAllocatorparent | Parent allocator. For construction from stateless allocators, use theirinstance static member. |
size_tbytes | Bytes (not items) to be allocated for the free list. Memory will be allocated during construction and deallocated in the destructor. |
size_tmax | Maximum size eligible for freelisting. Construction with this parameter is defined only ifmaxSize == chooseAtRuntime ormaxSize == unbounded. |
size_tmin | Minimum size eligible for freelisting. Construction with this parameter is defined only ifminSize == chooseAtRuntime. If this condition is met and nomin parameter is present,min is initialized withmax . |
goodAllocSize
(size_tn
);n
is eligible for freelisting, returnsmax. Otherwise, returnsparent.goodAllocSize
(n
).PreconditionIf set at runtime,min and/ormax must be initialized appropriately.
Postconditionresult >= bytes
allocate
(size_tn
);n
bytes of memory. Ifn
is eligible for freelist and the freelist is not empty, pops the memory off the free list. In all other cases, uses the parent allocator.owns
(void[]b
);deallocate
(void[]b
);b
. If it's of eligible size, it's put on the free list. Otherwise, it's returned toparent.Preconditionb
has been allocated with this allocator, or is null.
deallocateAll
();empty
();SharedFreeList
(ParentAllocator, size_t minSize, size_t maxSize = minSize, size_t approxMaxNodes = unbounded);import std.experimental.allocator.common : chooseAtRuntime;import std.experimental.allocator.mallocator : Mallocator;sharedSharedFreeList!(Mallocator, chooseAtRuntime, chooseAtRuntime) a;a.setBounds(64, 128);writeln(a.max);// 128writeln(a.min);// 64
import std.experimental.allocator.common : chooseAtRuntime;import std.experimental.allocator.mallocator : Mallocator;sharedSharedFreeList!(Mallocator, 50, 50, chooseAtRuntime) a;// Set the maxSize first so setting the minSize doesn't throwa.approxMaxLength = 128;writeln(a.approxMaxLength);// 128a.approxMaxLength = 1024;writeln(a.approxMaxLength);// 1024a.approxMaxLength = 1;writeln(a.approxMaxLength);// 1
min
();min
(size_tnewMinSize
);max
();max
(size_tnewMaxSize
);setBounds
(size_tnewMin
, size_tnewMax
);approxMaxLength
() shared const;approxMaxLength
(size_tx
) shared;parent
;alignment
;goodAllocSize
(size_tbytes
) shared;owns
(const void[]b
) shared const;reallocate
(ref void[]b
, size_ts
) shared;allocate
(size_tbytes
) shared;deallocate
(void[]b
) shared;deallocateAll
() shared;minimize
() shared;