added bucket allocator

This commit is contained in:
Felix Brendel
2019-10-21 22:37:58 +02:00
parent 6b3c2e157e
commit a20539587c
4 changed files with 122 additions and 17 deletions
+3
View File
@@ -1,3 +1,6 @@
#pragma once
#include <stdlib.h>
template <typename type> template <typename type>
struct Array_List { struct Array_List {
type* data; type* data;
+96
View File
@@ -0,0 +1,96 @@
#include "arraylist.hpp"
template <typename type, unsigned int bucket_size>
class Bucket_Allocator {
int latest_bucket;
int next_index_in_latest_bucket;
int bucket_count;
int next_bucket_index;
Array_List<type*> free_list;
type** buckets;
void expand() {
// realloc time
buckets = (type**)realloc(buckets, bucket_count * 2 * sizeof(type*));
for (int i = bucket_count; i < bucket_count * 2; ++i) {
buckets[i] = (type*)malloc(bucket_size * sizeof(type));
}
bucket_count *= 2;
}
void jump_to_next_bucket() {
next_index_in_latest_bucket = 0;
++next_bucket_index;
if (next_bucket_index >= bucket_count) {
expand();
}
}
void increment_pointers(int amount = 1) {
next_index_in_latest_bucket += amount;
if (next_index_in_latest_bucket >= bucket_size) {
jump_to_next_bucket();
}
}
public:
Bucket_Allocator(unsigned int initial_bucket_count = 1) {
latest_bucket = 0;
next_index_in_latest_bucket = 0;
next_bucket_index = 0;
bucket_count = initial_bucket_count;
buckets = (type**)malloc(bucket_count * sizeof(type*));
for (int i = 0; i < bucket_count; ++i) {
buckets[i] = (type*)malloc(bucket_size * sizeof(type));
}
}
~Bucket_Allocator() {
for (int i = 0; i < bucket_count; ++i) {
free(buckets[i]);
}
::free(buckets);
}
type* allocate(unsigned int amount = 1) {
type* ret;
if (amount == 0) return nullptr;
if (amount == 1) {
if (free_list.next_index != 0) {
return free_list.data[--free_list.next_index];
}
ret = buckets[next_bucket_index]+next_index_in_latest_bucket;
increment_pointers(1);
return ret;
}
if (amount > bucket_size)
return nullptr;
if ((bucket_size - next_index_in_latest_bucket) >= 4) {
// if the current bucket is ahs enough free space
ret = buckets[next_bucket_index]+(next_index_in_latest_bucket);
increment_pointers(amount);
return ret;
} else {
// the current bucket does not have enough free space
// add all remainding slots to free list
while (next_index_in_latest_bucket < bucket_size) {
free_list.append(buckets[next_bucket_index]+next_index_in_latest_bucket);
++next_index_in_latest_bucket;
}
jump_to_next_bucket();
return allocate(amount);
}
}
void free(type* obj) {
free_list.append(obj);
}
void reset() {
latest_bucket = 0;
next_index_in_latest_bucket = 0;
next_bucket_index = 0;
}
};
Regular → Executable
View File
+23 -17
View File
@@ -1,30 +1,36 @@
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> #include <stdio.h>
#include "profiler.hpp" #include "bucket_allocator.hpp"
#include "macros.hpp"
#include "hashmap.hpp"
#include "arraylist.hpp"
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
Array_List<int> al; Bucket_Allocator<int, 3> ba;
al.append(10);
al.append(3);
al.append(1);
printf("numbers: %d %d %d %d\n", al[0], al[1], al[2], al[3]); int* a = ba.allocate();
al[2] = 1099; *a = 1;
printf("%d\n", *a);
printf("numbers: %d %d %d %d\n", al[0], al[1], al[2], al[3]); ba.free(a);
al.sort(); int* b = ba.allocate();
*b = 2;
printf("%d\n", *b);
printf("numbers: %d %d %d %d\n", al[0], al[1], al[2], al[3]); int* c = ba.allocate();
*c = 3;
printf("%d\n", *c);
printf("sortedfind (10): %d\n", al.sorted_find(10)); int* d = ba.allocate();
*d = 4;
printf("%d\n", *d);
int* e = ba.allocate();
*e = 5;
printf("%d\n", *e);
int* f = ba.allocate();
*f = 6;
printf("%d\n", *f);
for (auto num : al) {
printf("- %d\n", num);
}
return 0; return 0;
} }