Report a bug If you spot a problem with this page, click here to create a Bugzilla issue. Improve this page Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone.
- struct AllocatorList(Factory, BookkeepingAllocator = GCAllocator);
template AllocatorList(alias factoryFunction, BookkeepingAllocator = GCAllocator)
- Given an object factory of type Factory or a factory function factoryFunction, and optionally also BookkeepingAllocator as a supplemental allocator for bookkeeping, AllocatorList creates an allocator that lazily creates as many allocators are needed for satisfying client allocation requests.An embedded list builds a most-recently-used strategy: the most recent allocators used in calls to either allocate, owns (successful calls only), or deallocate are tried for new allocations in order of their most recent use. Thus, although core operations take in theory Ο(k) time for k allocators in current use, in many workloads the factor is sublinear. Details of the actual strategy may change in future releases. AllocatorList 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 using AllocatorList 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.Parameters:Examples:
import std.algorithm : max; import std.experimental.allocator.building_blocks.region : Region; import std.experimental.allocator.mmap_allocator : MmapAllocator; import std.experimental.allocator.building_blocks.segregator : Segregator; import std.experimental.allocator.building_blocks.free_list : ContiguousFreeList; // 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 void[max(n, 1024 * 4096)]), NullAllocator); // Allocator list that creates one freelist for all objects alias A4 = Segregator!( 64, AllocatorList!( (n) => ContiguousFreeList!(NullAllocator, 0, 64)( 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);
- alias Allocator = typeof(Factory.init(1));
- Alias for typeof(Factory()(1)), i.e. the type of the individual allocators.
- BookkeepingAllocator bkalloc;
- this(ref Factory plant);
- Constructs an AllocatorList given a factory object. This constructor is defined only if Factory has state.
- enum uint alignment;
- void allocate(size_t s);
- Allocate a block of size s. First tries to allocate from the existing list of already-created allocators. If neither can satisfy the request, creates a new allocator by calling make(s) and delegates the request to it. However, if the allocation fresh off a newly created allocator fails, subsequent calls to allocate will not cause more calls to make.
- Ternary owns(void b);
- Defined only if Allocator defines owns. 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.Returns:Ternary.yes if one allocator was found to return Ternary.yes, Ternary.no if all component allocators returned Ternary.no, and Ternary.unknown if no allocator returned Ternary.yes and at least one returned Ternary.unknown.
- bool expand(ref void b, size_t delta);
- bool reallocate(ref void b, size_t s);
- bool deallocate(void b);
- bool deallocateAll();
- const Ternary empty();
- Returns Ternary.yes if no allocators are currently active, Ternary.no otherwise. This methods never returns Ternary.unknown.