Region

A Region allocator allocates memory straight from one contiguous chunk. There is no deallocation, and once the region is full, allocation requests return null. Therefore, Regions are often used (a) in conjunction with more sophisticated allocators; or (b) for batch-style very fast allocations that deallocate everything at once.

The region only stores three pointers, corresponding to the current position in the store and the limits. One allocation entails rounding up the allocation size for alignment purposes, bumping the current pointer, and comparing it against the limit.

Region deallocates the chunk of memory during destruction.

The minAlign parameter establishes alignment. If minAlign > 1, the sizes of all allocation requests are rounded up to a multiple of minAlign. Applications aiming at maximum speed may want to choose minAlign = 1 and control alignment externally.

Constructors

this
this(ubyte[] store)
this(size_t n)
this(ParentAllocator parent, size_t n)

Constructs a region backed by a user-provided store. Assumes the memory was allocated with ParentAllocator.

Destructor

~this
~this()

If ParentAllocator defines deallocate, the region defines a destructor that uses ParentAllocator.deallocate to free the memory chunk.

Members

Aliases

alignment
alias alignment = minAlign

Alignment offered.

Functions

alignedAllocate
void[] alignedAllocate(size_t n, uint a)

Allocates n bytes of memory aligned at alignment a.

allocate
void[] allocate(size_t n)

Allocates n bytes of memory. The shortest path involves an alignment adjustment (if alignment > 1), an increment, and a comparison.

allocateAll
void[] allocateAll()

Allocates and returns all memory available to this region.

available
size_t available()

Nonstandard property that returns bytes available for allocation.

deallocate
bool deallocate(void[] b)

Deallocates b. This works only if b was obtained as the last call to allocate; otherwise (i.e. another allocation has occurred since) it does nothing.

deallocateAll
bool deallocateAll()

Deallocates all memory allocated by this region, which can be subsequently reused for new allocations.

empty
Ternary empty()

Returns Ternary.yes if no memory has been allocated in this region, Ternary.no otherwise. (Never returns Ternary.unknown.)

expand
bool expand(void[] b, size_t delta)

Expands an allocated block in place. Expansion will succeed only if the block is the last allocated. Defined only if growDownwards is No.growDownwards.

goodAllocSize
size_t goodAllocSize(size_t n)

Rounds the given size to a multiple of the alignment

owns
Ternary owns(void[] b)

Queries whether b has been allocated with this region.

Variables

parent
ParentAllocator parent;

The parent allocator. Depending on whether ParentAllocator holds state or not, this is a member variable or an alias for ParentAllocator.instance.

Examples

import std.algorithm.comparison : max;
import std.experimental.allocator.building_blocks.allocator_list
    : AllocatorList;
import std.experimental.allocator.mallocator : Mallocator;
import std.typecons : Ternary;
// Create a scalable list of regions. Each gets at least 1MB at a time by
// using malloc.
auto batchAllocator = AllocatorList!(
    (size_t n) => Region!Mallocator(max(n, 1024 * 1024))
)();
assert(batchAllocator.empty ==  Ternary.yes);
auto b = batchAllocator.allocate(101);
assert(b.length == 101);
assert(batchAllocator.empty ==  Ternary.no);
// This will cause a second allocation
b = batchAllocator.allocate(2 * 1024 * 1024);
assert(b.length == 2 * 1024 * 1024);
// Destructor will free the memory

Meta