Struct std.experimental.allocator.building_blocks.bitmapped_block.BitmappedBlock
BitmappedBlock implements a simple heap consisting of one contiguous area
of memory organized in blocks, each of size theBlockSize. A block is a unit
of allocation. A bitmap serves as bookkeeping data, more precisely one bit per
block indicating whether that block is currently allocated or not.
						
				struct BitmappedBlock(ulong theBlockSize, uint theAlignment = platformAlignment, ParentAllocator, Flag!("multiblock") f = Yes
				Passing NullAllocator as ParentAllocator (the default) means user code
manages allocation of the memory block from the outside; in that case
BitmappedBlock must be constructed with a ubyte[] preallocated block and
has no responsibility regarding the lifetime of its support underlying storage.
If another allocator type is passed, BitmappedBlock defines a destructor that
uses the parent allocator to release the memory block. That makes the combination of AllocatorList,
BitmappedBlock, and a back-end allocator such as MmapAllocator
a simple and scalable solution for memory allocation.
There are advantages to storing bookkeeping data separated from the payload
(as opposed to e.g. using AffixAllocator to store metadata together with
each allocation). The layout is more compact (overhead is one bit per block),
searching for a free block during allocation enjoys better cache locality, and
deallocation does not touch memory around the payload being deallocated (which
is often cold).
Allocation requests are handled on a first-fit basis. Although linear in
complexity, allocation is in practice fast because of the compact bookkeeping
representation, use of simple and fast bitwise routines, and caching of the
first available block position. A known issue with this general approach is
fragmentation, partially mitigated by coalescing. Since BitmappedBlock does
not need to maintain the allocated size, freeing memory implicitly coalesces
free blocks together. Also, tuning blockSize has a considerable impact on
both internal and external fragmentation.
If the last template parameter is set to No, the allocator will only serve
allocations which require at most theBlockSize. The BitmappedBlock has a specialized
implementation for single-block allocations which allows for greater performance,
at the cost of not being able to allocate more than one block at a time.
The size of each block can be selected either during compilation or at run
time. Statically-known block sizes are frequent in practice and yield slightly
better performance. To choose a block size statically, pass it as the blockSize
parameter as in BitmappedBlock!(4096). To choose a block
size parameter, use BitmappedBlock!(chooseAtRuntime) and pass the
block size to the constructor.
Constructors
| Name | Description | 
|---|---|
| this(data) | Constructs a block allocator given a hunk of memory, or a desired capacity
        in bytes. 
 | 
Fields
| Name | Type | Description | 
|---|---|---|
| parent | ParentAllocator | The parent allocator. Depending on whether ParentAllocatorholds state
        or not, this is a member variable or an alias forParentAllocator. | 
Methods
| Name | Description | 
|---|---|
| alignedAllocate(n, a) | Allocates a block with specified alignment a. The alignment must be a
        power of 2. Ifa <= alignment, function forwards toallocate.
        Otherwise, it attempts to overallocate and then adjust the result for
        proper alignment. In the worst case the slack memory is around two blocks. | 
| alignedReallocate(b, newSize, a) | Reallocates a block previously allocated with alignedAllocate. Contractions do not occur in place. | 
| allocate(s) | Allocates sbytes of memory and returns it, ornullif memory
        could not be allocated. | 
| allocateAll() | If the BitmappedBlockobject is empty (has no active allocation), allocates
        all memory within and returns a slice to it. Otherwise, returnsnull(i.e. no attempt is made to allocate the largest available block). | 
| allocateFresh(s) | Allocates s bytes of memory and returns it, or nullif memory could not be allocated.allocateFreshbehaves just like allocate, the only difference being that this always
        returns unused(fresh) memory. Although there may still be available space in theBitmappedBlock,allocateFreshcould still return null, because all the available blocks have been previously deallocated. | 
| deallocate(b) | Deallocates a block previously allocated with this allocator. | 
| deallocateAll() | Forcibly deallocates all memory allocated by this allocator, making it
        available for further allocations. Does not return memory to ParentAllocator. | 
| empty() | Returns Ternaryif no memory is currently allocated with this
        allocator, otherwiseTernary. This method never returnsTernary. | 
| expand(b, delta) | Expands in place a buffer previously allocated by BitmappedBlock.
        If instantiated withNo, the expansion fails if the new length
        exceedstheBlockSize. | 
| goodAllocSize(n) | Returns the actual bytes allocated when nbytes are requested, i.e.n. | 
| owns(b) | Returns Ternaryifbbelongs to theBitmappedBlockobject,Ternaryotherwise. Never returnsTernary. (This
        method is somewhat tolerant in that accepts an interior slice.) | 
| reallocate(b, newSize) | Reallocates a previously-allocated block. Contractions occur in place. | 
Aliases
| Name | Description | 
|---|---|
| alignment | The alignment offered is user-configurable statically through parameter theAlignment, defaulted toplatformAlignment. | 
| blockSize | If blockSize == chooseAtRuntime,BitmappedBlockoffers a read/write
        propertyblockSize. It must be set before any use of the allocator.
        Otherwise (i.e.theBlockSizeis a legit constant),blockSizeis
        an alias fortheBlockSize. Whether constant or variable, must also be
        a multiple ofalignment. This constraint isasserted statically
        and dynamically. | 
Parameters
| Name | Description | 
|---|---|
| theBlockSize | the length of a block, which must be a multiple of theAlignment | 
| theAlignment | alignment of each block | 
| ParentAllocator | allocator from which the BitmappedBlockwill draw memory.
        If set toNullAllocator, the storage must be passed via the constructor | 
| f | Yesto support allocations spanning across multiple blocks andNoto support single block allocations.
        Although limited by single block allocations,Nowill generally
        provide higher performance. | 
Example
// Create a block allocator on top of a 10KB stack region.
import stdExample
import stdExample
import std