stdx.allocator.building_blocks.allocator_list
-
Declaration
struct
AllocatorList
(Factory, BookkeepingAllocator = GCAllocator);
templateAllocatorList
(alias factoryFunction, BookkeepingAllocator = GCAllocator)Given an object factory of type
Factory
or a factory functionfactoryFunction
, and optionally alsoBookkeepingAllocator
as a supplemental allocator for bookkeeping,
creates an allocator that lazily creates as many allocators are needed for satisfying client allocation requests.AllocatorList
Discussion
An embedded list builds a most-recently-used strategy: the most recent allocators used in calls to either
allocate
,owns
(successful calls only), ordeallocate
are tried for new allocations in order of their most recent use. Thus, although core operations take in theory time for allocators in current use, in many workloads the factor is sublinear. Details of the actual strategy may change in future releases.
is primarily intended for coarse-grained handling of allocators, i.e. the number of allocators in the list is expected to be relatively small compared to the number of allocations handled by each allocator. However, the per-allocator overhead is small so usingAllocatorList
with a large number of allocators should be satisfactory as long as the most-recently-used strategy is fast enough for the application.AllocatorList
makes an effort to return allocated memory back when no longer used. It does so by destroying empty allocators. However, in order to avoid thrashing (excessive creation/destruction of allocators under certain use patterns), it keeps unused allocators for a while.AllocatorList
Parameters
factoryFunction
A function or template function (including function literals). New allocators are created by calling
factoryFunction(n)
with strictly positive numbersn
. Delegates that capture their enviroment are not created amid concerns regarding garbage creation for the environment. When the factory needs state, aFactory
object should be used.BookkeepingAllocator
Allocator used for storing bookkeeping data. The size of bookkeeping data is proportional to the number of allocators. If is , then is "ouroboros-style", i.e. it keeps the bookkeeping data in memory obtained from the allocators themselves. Note that for ouroboros-style management, the size passed to will be occasionally different from the size requested by client code.
Factory
Type of a factory object that returns new allocators on a need basis. For an object of type ,
sweatshop(n)
should return an allocator able to allocate at leastn
bytes (i.e.Factory
must defineopCall(size_t)
to return an allocator object). Usually the capacity of allocators created should be much larger than such that an allocator can be used for many subsequent allocations. is passed only to ensure the minimum necessary for the next allocation. The factory object is allowed to hold state, which will be stored inside
as a directAllocatorList
public
member calledfactory
.Examples
import std.algorithm.comparison : max; import stdx.allocator.building_blocks.free_list : ContiguousFreeList; import stdx.allocator.building_blocks.null_allocator : NullAllocator; import stdx.allocator.building_blocks.region : Region; import stdx.allocator.building_blocks.segregator : Segregator; import stdx.allocator.gc_allocator : GCAllocator; import stdx.allocator.mmap_allocator : MmapAllocator; // Ouroboros allocator list based upon 4MB regions, fetched directly from // mmap. All memory is released upon destruction. alias A1 = AllocatorList!((n) => Region!MmapAllocator(max(n, 1024 * 4096)), NullAllocator); // Allocator list based upon 4MB regions, fetched from the garbage // collector. All memory is released upon destruction. alias A2 = AllocatorList!((n) => Region!GCAllocator(max(n, 1024 * 4096))); // Ouroboros allocator list based upon 4MB regions, fetched from the garbage // collector. Memory is left to the collector. alias A3 = AllocatorList!( (n) => Region!NullAllocator(new ubyte[max(n, 1024 * 4096)]), NullAllocator); // Allocator list that creates one freelist for all objects alias A4 = Segregator!( 64, AllocatorList!( (n) => ContiguousFreeList!(NullAllocator, 0, 64)( cast(ubyte[])(GCAllocator.instance.allocate(4096)))), GCAllocator); A4 a; auto small = a.allocate(64); assert(small); a.deallocate(small); auto b1 = a.allocate(1024 * 8192); assert(b1 !is null); // still works due to overdimensioning b1 = a.allocate(1024 * 10); assert(b1.length == 1024 * 10);
-
Declaration
alias
Allocator
= typeof(Factory.init(1));Alias for
typeof(Factory()(1))
, i.e. the type of the individual allocators. -
Declaration
BookkeepingAllocator
bkalloc
;If is not , is defined and accessible.
-
Declaration
this(ref Factory
plant
);
this(Factoryplant
);Constructs an
AllocatorList
given a factory object. This constructor is defined only ifFactory
has state. -
Declaration
enum uint
alignment
;The
alignment
offered. -
Declaration
void[]
allocate
(size_ts
);Allocate a block of size . First tries to
allocate
from the existing list of already-created allocators. If neither can satisfy the request, creates a new allocator by calling and delegates the request to it. However, if the allocation fresh off a newly created allocator fails, subsequent calls to will not cause more calls to . -
Declaration
Ternary
owns
(void[]b
);Defined only if
Allocator
defines
. Tries each allocator in turn, in most-recently-used order. If the owner is found, it is moved to the front of the list as a side effect under the assumption it will be used soon.owns
Return Value
Ternary.yes
if one allocator was found to returnTernary.yes
,Ternary.no
if all component allocators returnedTernary.no
, andTernary.unknown
if no allocator returnedTernary.yes
and at least one returnedTernary.unknown
. -
Declaration
bool
expand
(ref void[]b
, size_tdelta
);Defined only if is defined. Finds the owner of and calls for it. The owner is not brought to the head of the list.
-
Declaration
bool
reallocate
(ref void[]b
, size_ts
);Defined only if is defined. Finds the owner of and calls for it. If that fails, calls the global , which allocates a new block and moves memory.
-
Declaration
bool
deallocate
(void[]b
);Defined if and are defined.
-
Declaration
bool
deallocateAll
();Defined only if and are defined.
-
Declaration
const Ternary
empty
();Returns
Ternary.yes
if no allocators are currently active,Ternary.no
otherwise. This methods never returnsTernary.unknown
.