module ecs.block_allocator; import ecs.manager; import ecs.std; struct BlockAllocator { private uint block_size; private uint blocks_in_allocation; struct BlockPointers { void*[32] blocks; uint numberof = 0; BlockPointers* next_pointers = null; } void* next_block = null; BlockPointers* pointers = null; void* getBlock() nothrow @nogc { if (next_block is null) allocBlock(); void* ret = next_block; next_block = *cast(void**) next_block; return ret; } void freeBlock(void* block) nothrow @nogc { *cast(void**)block = next_block; next_block = block; } private void allocBlock() nothrow @nogc { next_block = cast(void*) Mallocator.alignAlloc( block_size * blocks_in_allocation, block_size); if(pointers is null)pointers = Mallocator.make!BlockPointers; if(pointers.numberof >= 32) { BlockPointers* new_pointers = Mallocator.make!BlockPointers; new_pointers.next_pointers = pointers; pointers = new_pointers; } pointers.blocks[pointers.numberof++] = next_block; foreach (i; 0 .. blocks_in_allocation - 1) { void** pointer = cast(void**)(next_block + i * block_size); *pointer = next_block + (i + 1) * block_size; } void** pointer = cast(void**)( next_block + (blocks_in_allocation - 1) * block_size); *pointer = null; } void freeMemory() nothrow @nogc { while(pointers) { foreach(i;0..pointers.numberof) { Mallocator.alignDispose(pointers.blocks[i]); } BlockPointers* next_pointers = pointers.next_pointers; Mallocator.dispose(pointers); pointers = next_pointers; } } }