diff --git a/arraylist.hpp b/arraylist.hpp index 1cfb27d..4884952 100644 --- a/arraylist.hpp +++ b/arraylist.hpp @@ -1,3 +1,6 @@ +#pragma once +#include + template struct Array_List { type* data; diff --git a/bucket_allocator.hpp b/bucket_allocator.hpp new file mode 100644 index 0000000..b9ee9ba --- /dev/null +++ b/bucket_allocator.hpp @@ -0,0 +1,96 @@ +#include "arraylist.hpp" + +template +class Bucket_Allocator { + int latest_bucket; + int next_index_in_latest_bucket; + int bucket_count; + int next_bucket_index; + + Array_List 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; + } +}; diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 diff --git a/test.cpp b/test.cpp index 97581c9..f097bb3 100644 --- a/test.cpp +++ b/test.cpp @@ -1,30 +1,36 @@ #define _CRT_SECURE_NO_WARNINGS #include -#include "profiler.hpp" -#include "macros.hpp" -#include "hashmap.hpp" -#include "arraylist.hpp" +#include "bucket_allocator.hpp" int main(int argc, char* argv[]) { - Array_List al; - al.append(10); - al.append(3); - al.append(1); + Bucket_Allocator ba; - printf("numbers: %d %d %d %d\n", al[0], al[1], al[2], al[3]); - al[2] = 1099; + int* a = ba.allocate(); + *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; }