35template <std::
size_t BlockSize,
int MaxNumBlocks>
37 Block blocks[MaxNumBlocks];
38 int current_block_index;
57 std::pair<std::size_t, MemoryNode*> best_fit(std::size_t bytes);
102 void deallocate(
void* ptr, std::size_t bytes);
124 return value & ~(3ull << 62);
147template <std::
size_t BlockSize,
int MaxNumBlocks>
148std::pair<std::size_t, MemoryNode*> BlocksContainer<BlockSize, MaxNumBlocks>::best_fit(
150 std::size_t best_block_index = std::numeric_limits<std::size_t>::max();
151 std::size_t best_size = std::numeric_limits<std::size_t>::max();
152 MemoryNode* best_node =
nullptr;
155 for (
int i = 0; i <= current_block_index; i++) {
156 MemoryNode* node = blocks[i].best_fit(bytes);
160 if (node_size < best_size) {
162 best_size = node_size;
163 best_block_index = i;
168 return {best_block_index, best_node};
182template <std::
size_t BlockSize,
int MaxNumBlocks>
184 current_block_index = 0;
185 blocks[current_block_index] = std::move(
Block(BlockSize));
209template <std::
size_t BlockSize,
int MaxNumBlocks>
212 throw std::invalid_argument(
"Bytes must be positive");
215 auto [index, node] = best_fit(bytes);
218 if (index == std::numeric_limits<std::size_t>::max()) {
220 if (current_block_index + 1 < MaxNumBlocks) {
221 current_block_index++;
222 blocks[current_block_index] = std::move(
Block(BlockSize));
223 index = current_block_index;
224 node = blocks[index].best_fit(bytes);
239 return blocks[index].allocate(bytes, node);
263template <std::
size_t BlockSize,
int MaxNumBlocks>
266 for (
int i = 0; i <= current_block_index; i++) {
268 void* block_start = blocks[i].get_head();
269 void* block_end = (
char*)block_start + BlockSize;
271 if (block_start <= ptr && ptr < block_end) {
272 blocks[i].deallocate(ptr, bytes);
284template <std::
size_t BlockSize,
int MaxNumBlocks>
286 logfile <<
"=================================================\n";
287 logfile <<
"BlocksContainer State:\n";
288 logfile <<
"Total Blocks: " << (current_block_index + 1) <<
"\n";
289 for (
int i = 0; i <= current_block_index; i++) {
290 logfile <<
"---------------- Block " << i <<
" ----------------\n";
291 blocks[i].log_block_state(logfile);
292 logfile <<
"---------------- End Block " << i <<
" ----------------\n";
294 logfile <<
"=================================================\n\n";
Memory block management with Red-Black tree based allocator.
#define RELEASE_MEMORY_VIA_MUNMAP(ptr, size)
Releases memory back to the operating system using munmap.
Definition Block.hpp:33
#define REQUEST_MEMORY_VIA_MMAP(size)
Allocates memory from the operating system using mmap.
Definition Block.hpp:24
Manages a contiguous memory block with RB-tree based allocation.
Definition Block.hpp:86
Manages multiple memory blocks for scalable allocation.
Definition BlocksContainer.hpp:36
BlocksContainer()
Default constructor - initializes container with no blocks.
Definition BlocksContainer.hpp:183
void deallocate(void *ptr, std::size_t bytes)
Deallocates previously allocated memory.
Definition BlocksContainer.hpp:264
void log_container_state(std::ofstream &logfile) const
Logs the current state of the container to a file.
Definition BlocksContainer.hpp:285
void * allocate(std::size_t bytes)
Allocates memory from the container.
Definition BlocksContainer.hpp:210
std::size_t get_actual_value(std::size_t value)
Helper function to extract actual size from encoded value.
Definition BlocksContainer.hpp:123