| @@ -1,13 +1,14 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include "types.hpp" | |||||
| template <typename type> | template <typename type> | ||||
| struct Array_List { | struct Array_List { | ||||
| type* data; | type* data; | ||||
| int length; | |||||
| int next_index; | |||||
| u32 length; | |||||
| u32 next_index; | |||||
| void alloc(int initial_capacity = 16) { | |||||
| void alloc(u32 initial_capacity = 16) { | |||||
| data = (type*)malloc(initial_capacity * sizeof(type)); | data = (type*)malloc(initial_capacity * sizeof(type)); | ||||
| next_index = 0; | next_index = 0; | ||||
| length = initial_capacity; | length = initial_capacity; | ||||
| @@ -24,7 +25,7 @@ struct Array_List { | |||||
| ret.next_index = next_index; | ret.next_index = next_index; | ||||
| ret.data = (type*)malloc(length * sizeof(type)); | ret.data = (type*)malloc(length * sizeof(type)); | ||||
| for (int i = 0; i < next_index; ++i) { | |||||
| for (u32 i = 0; i < next_index; ++i) { | |||||
| ret.data[i] = data[i]; | ret.data[i] = data[i]; | ||||
| } | } | ||||
| return ret; | return ret; | ||||
| @@ -38,7 +39,7 @@ struct Array_List { | |||||
| return data+(next_index); | return data+(next_index); | ||||
| } | } | ||||
| void remove_index(int index) { | |||||
| void remove_index(u32 index) { | |||||
| data[index] = data[--next_index]; | data[index] = data[--next_index]; | ||||
| } | } | ||||
| @@ -51,19 +52,19 @@ struct Array_List { | |||||
| next_index++; | next_index++; | ||||
| } | } | ||||
| void reserve(unsigned int count) { | |||||
| if (next_index+count >= (unsigned int)length) { | |||||
| void reserve(u32 count) { | |||||
| if (next_index+count >= (u32)length) { | |||||
| length *= 2; | length *= 2; | ||||
| data = (type*)realloc(data, length * sizeof(type)); | data = (type*)realloc(data, length * sizeof(type)); | ||||
| } | } | ||||
| } | } | ||||
| type& operator[](int index) { | |||||
| type& operator[](u32 index) { | |||||
| return data[index]; | return data[index]; | ||||
| } | } | ||||
| void _merge(int start, int mid, int end) { | |||||
| int start2 = mid + 1; | |||||
| void _merge(u32 start, u32 mid, u32 end) { | |||||
| u32 start2 = mid + 1; | |||||
| /* If the direct merge is already sorted */ | /* If the direct merge is already sorted */ | ||||
| if ((size_t)data[mid] <= (size_t)data[start2]) { | if ((size_t)data[mid] <= (size_t)data[start2]) { | ||||
| @@ -77,7 +78,7 @@ struct Array_List { | |||||
| } | } | ||||
| else { | else { | ||||
| type value = data[start2]; | type value = data[start2]; | ||||
| int index = start2; | |||||
| u32 index = start2; | |||||
| /* Shift all the elements between element 1; element 2, right by 1. */ | /* Shift all the elements between element 1; element 2, right by 1. */ | ||||
| while (index != start) { | while (index != start) { | ||||
| @@ -94,7 +95,7 @@ struct Array_List { | |||||
| } | } | ||||
| } | } | ||||
| void sort(int left=-1, int right=-1) { | |||||
| void sort(s32 left=-1, s32 right=-1) { | |||||
| if (left == -1) { | if (left == -1) { | ||||
| if (next_index == 0) | if (next_index == 0) | ||||
| return; | return; | ||||
| @@ -104,7 +105,7 @@ struct Array_List { | |||||
| return; | return; | ||||
| } | } | ||||
| int middle = left + (right-left) / 2; | |||||
| u32 middle = left + (right-left) / 2; | |||||
| sort(left, middle); | sort(left, middle); | ||||
| sort(middle+1, right); | sort(middle+1, right); | ||||
| @@ -112,7 +113,7 @@ struct Array_List { | |||||
| _merge(left, middle, right); | _merge(left, middle, right); | ||||
| } | } | ||||
| int sorted_find(type elem, int left=-1, int right=-1) { | |||||
| u32 sorted_find(type elem, s32 left=-1, s32 right=-1) { | |||||
| if (left == -1) { | if (left == -1) { | ||||
| return sorted_find(elem, 0, next_index - 1); | return sorted_find(elem, 0, next_index - 1); | ||||
| } else if (left == right) { | } else if (left == right) { | ||||
| @@ -122,7 +123,7 @@ struct Array_List { | |||||
| } else if (right < left) | } else if (right < left) | ||||
| return -1; | return -1; | ||||
| int middle = left + (right-left) / 2; | |||||
| u32 middle = left + (right-left) / 2; | |||||
| if ((size_t)data[middle] < (size_t)elem) | if ((size_t)data[middle] < (size_t)elem) | ||||
| return sorted_find(elem, middle+1, right); | return sorted_find(elem, middle+1, right); | ||||
| @@ -1,11 +1,12 @@ | |||||
| #include "arraylist.hpp" | #include "arraylist.hpp" | ||||
| #include "types.hpp" | |||||
| template <typename type> | template <typename type> | ||||
| class Bucket_Allocator { | class Bucket_Allocator { | ||||
| unsigned int next_index_in_latest_bucket; | |||||
| unsigned int next_bucket_index; | |||||
| unsigned int bucket_count; | |||||
| unsigned int bucket_size; | |||||
| u32 next_index_in_latest_bucket; | |||||
| u32 next_bucket_index; | |||||
| u32 bucket_count; | |||||
| u32 bucket_size; | |||||
| Array_List<type*> free_list; | Array_List<type*> free_list; | ||||
| type** buckets; | type** buckets; | ||||
| @@ -26,7 +27,7 @@ class Bucket_Allocator { | |||||
| buckets[next_bucket_index] = (type*)malloc(bucket_size * sizeof(type)); | buckets[next_bucket_index] = (type*)malloc(bucket_size * sizeof(type)); | ||||
| } | } | ||||
| void increment_pointers(int amount = 1) { | |||||
| void increment_pointers(s32 amount = 1) { | |||||
| next_index_in_latest_bucket += amount; | next_index_in_latest_bucket += amount; | ||||
| if (next_index_in_latest_bucket >= bucket_size) { | if (next_index_in_latest_bucket >= bucket_size) { | ||||
| jump_to_next_bucket(); | jump_to_next_bucket(); | ||||
| @@ -34,7 +35,7 @@ class Bucket_Allocator { | |||||
| } | } | ||||
| public: | public: | ||||
| void alloc(unsigned int bucket_size, unsigned int initial_bucket_count) { | |||||
| void alloc(u32 bucket_size, u32 initial_bucket_count) { | |||||
| this->free_list.alloc(); | this->free_list.alloc(); | ||||
| this->bucket_size = bucket_size; | this->bucket_size = bucket_size; | ||||
| next_index_in_latest_bucket = 0; | next_index_in_latest_bucket = 0; | ||||
| @@ -46,7 +47,7 @@ public: | |||||
| } | } | ||||
| void dealloc() { | void dealloc() { | ||||
| for (unsigned int i = 0; i <= next_bucket_index; ++i) { | |||||
| for (u32 i = 0; i <= next_bucket_index; ++i) { | |||||
| free(buckets[i]); | free(buckets[i]); | ||||
| } | } | ||||
| this->free_list.dealloc(); | this->free_list.dealloc(); | ||||
| @@ -57,21 +58,21 @@ public: | |||||
| void for_each(proc p) { | void for_each(proc p) { | ||||
| free_list.sort(); | free_list.sort(); | ||||
| type* val; | type* val; | ||||
| for (unsigned int i = 0; i < next_bucket_index; ++i) { | |||||
| for (unsigned int j = 0; j < bucket_size; ++j) { | |||||
| for (u32 i = 0; i < next_bucket_index; ++i) { | |||||
| for (u32 j = 0; j < bucket_size; ++j) { | |||||
| val = buckets[i]+j; | val = buckets[i]+j; | ||||
| if (free_list.sorted_find(val) == -1) | if (free_list.sorted_find(val) == -1) | ||||
| p(val); | p(val); | ||||
| } | } | ||||
| } | } | ||||
| for (unsigned int j = 0; j < next_index_in_latest_bucket; ++j) { | |||||
| for (u32 j = 0; j < next_index_in_latest_bucket; ++j) { | |||||
| val = buckets[next_bucket_index]+j; | val = buckets[next_bucket_index]+j; | ||||
| if (free_list.sorted_find(val) == -1) | if (free_list.sorted_find(val) == -1) | ||||
| p(val); | p(val); | ||||
| } | } | ||||
| } | } | ||||
| type* allocate(unsigned int amount = 1) { | |||||
| type* allocate(u32 amount = 1) { | |||||
| type* ret; | type* ret; | ||||
| if (amount == 0) return nullptr; | if (amount == 0) return nullptr; | ||||
| if (amount == 1) { | if (amount == 1) { | ||||
| @@ -9,15 +9,15 @@ | |||||
| #define for_hash_map(hm) \ | #define for_hash_map(hm) \ | ||||
| if (decltype((hm).data[0].original) key = 0); else \ | if (decltype((hm).data[0].original) key = 0); else \ | ||||
| if (decltype((hm).data[0].object) value = 0); else \ | if (decltype((hm).data[0].object) value = 0); else \ | ||||
| for(int index = 0; index < (hm).current_capacity; ++index) \ | |||||
| for(u32 index = 0; index < (hm).current_capacity; ++index) \ | |||||
| if (!((!(hm).data[index].deleted) && \ | if (!((!(hm).data[index].deleted) && \ | ||||
| (key = (hm).data[index].original) && \ | (key = (hm).data[index].original) && \ | ||||
| (value = (hm).data[index].object))); else | (value = (hm).data[index].object))); else | ||||
| template <typename key_type, typename value_type> | template <typename key_type, typename value_type> | ||||
| struct Hash_Map { | struct Hash_Map { | ||||
| int current_capacity; | |||||
| int cell_count; | |||||
| u32 current_capacity; | |||||
| u32 cell_count; | |||||
| struct HM_Cell { | struct HM_Cell { | ||||
| key_type original; | key_type original; | ||||
| u64 hash; | u64 hash; | ||||
| @@ -25,7 +25,7 @@ struct Hash_Map { | |||||
| value_type object; | value_type object; | ||||
| }* data; | }* data; | ||||
| void alloc(int initial_capacity = 8) { | |||||
| void alloc(u32 initial_capacity = 8) { | |||||
| current_capacity = initial_capacity; | current_capacity = initial_capacity; | ||||
| cell_count = 0; | cell_count = 0; | ||||
| data = (HM_Cell*)calloc(initial_capacity, sizeof(HM_Cell)); | data = (HM_Cell*)calloc(initial_capacity, sizeof(HM_Cell)); | ||||
| @@ -36,9 +36,9 @@ struct Hash_Map { | |||||
| data = nullptr; | data = nullptr; | ||||
| } | } | ||||
| int get_index_of_living_cell_if_it_exists(key_type key, u64 hash_val) { | |||||
| // int index = hash_val & (current_capacity - 1); | |||||
| int index = hash_val % current_capacity; | |||||
| s32 get_index_of_living_cell_if_it_exists(key_type key, u64 hash_val) { | |||||
| // s32 index = hash_val & (current_capacity - 1); | |||||
| s32 index = hash_val % current_capacity; | |||||
| HM_Cell cell = data[index]; | HM_Cell cell = data[index]; | ||||
| /* test if cell exists at that index */ | /* test if cell exists at that index */ | ||||
| if (cell.original) { | if (cell.original) { | ||||
| @@ -56,8 +56,8 @@ struct Hash_Map { | |||||
| } else { | } else { | ||||
| /* strings dont match, this means we have */ | /* strings dont match, this means we have */ | ||||
| /* a collision. We just search forward */ | /* a collision. We just search forward */ | ||||
| for (int i = 0; i < current_capacity; ++i) { | |||||
| int new_idx = (i + index) % current_capacity; | |||||
| for (u32 i = 0; i < current_capacity; ++i) { | |||||
| u32 new_idx = (i + index) % current_capacity; | |||||
| cell = data[new_idx]; | cell = data[new_idx]; | ||||
| if (!cell.original) | if (!cell.original) | ||||
| return -1; | return -1; | ||||
| @@ -84,7 +84,7 @@ struct Hash_Map { | |||||
| } | } | ||||
| key_type search_key_to_object(value_type v) { | key_type search_key_to_object(value_type v) { | ||||
| for (int i = 0; i < current_capacity; ++i) { | |||||
| for (u32 i = 0; i < current_capacity; ++i) { | |||||
| if (data[i].object == v && !data[i].deleted) | if (data[i].object == v && !data[i].deleted) | ||||
| return data[i].original; | return data[i].original; | ||||
| } | } | ||||
| @@ -94,7 +94,9 @@ struct Hash_Map { | |||||
| Array_List<key_type> get_all_keys() { | Array_List<key_type> get_all_keys() { | ||||
| Array_List<key_type> ret; | Array_List<key_type> ret; | ||||
| ret.alloc(); | ret.alloc(); | ||||
| for (int i = 0; i < current_capacity; ++i) { | |||||
| // QUESTION(Felix): Does it make sense to | |||||
| // ret.reserve(this->cell_count)? | |||||
| for (u32 i = 0; i < current_capacity; ++i) { | |||||
| if (data[i].original && !data[i].deleted) | if (data[i].original && !data[i].deleted) | ||||
| ret.append(data[i].original); | ret.append(data[i].original); | ||||
| } | } | ||||
| @@ -102,7 +104,7 @@ struct Hash_Map { | |||||
| } | } | ||||
| value_type get_object(key_type key) { | value_type get_object(key_type key) { | ||||
| int index = get_index_of_living_cell_if_it_exists(key, hm_hash((key_type)key)); | |||||
| s32 index = get_index_of_living_cell_if_it_exists(key, hm_hash((key_type)key)); | |||||
| if (index != -1) { | if (index != -1) { | ||||
| return data[index].object; | return data[index].object; | ||||
| } | } | ||||
| @@ -110,14 +112,14 @@ struct Hash_Map { | |||||
| } | } | ||||
| void delete_object(key_type key) { | void delete_object(key_type key) { | ||||
| int index = get_index_of_living_cell_if_it_exists(key, hm_hash((key_type)key)); | |||||
| s32 index = get_index_of_living_cell_if_it_exists(key, hm_hash((key_type)key)); | |||||
| if (index != -1) { | if (index != -1) { | ||||
| data[index].deleted = true; | data[index].deleted = true; | ||||
| } | } | ||||
| } | } | ||||
| void set_object(key_type key, value_type obj, u64 hash_val) { | void set_object(key_type key, value_type obj, u64 hash_val) { | ||||
| int index = hash_val % current_capacity; | |||||
| u32 index = hash_val % current_capacity; | |||||
| /* if we the desired cell is just empty, write to it and done :) */ | /* if we the desired cell is just empty, write to it and done :) */ | ||||
| if (!data[index].original) { | if (!data[index].original) { | ||||
| @@ -137,7 +139,7 @@ struct Hash_Map { | |||||
| current_capacity *= 4; | current_capacity *= 4; | ||||
| /* insert all old items again */ | /* insert all old items again */ | ||||
| for (int i = 0; i < current_capacity/4; ++i) { | |||||
| for (u32 i = 0; i < current_capacity/4; ++i) { | |||||
| auto cell = old_data[i]; | auto cell = old_data[i]; | ||||
| if (cell.original) { | if (cell.original) { | ||||
| set_object(cell.original, cell.object, cell.hash); | set_object(cell.original, cell.object, cell.hash); | ||||
| @@ -149,7 +151,7 @@ struct Hash_Map { | |||||
| /* search for empty slot for new cell starting at desired index; */ | /* search for empty slot for new cell starting at desired index; */ | ||||
| /* preventing gotos using lambdas! */ | /* preventing gotos using lambdas! */ | ||||
| [&]{ | [&]{ | ||||
| for (int i = index; i < current_capacity; ++i) { | |||||
| for (u32 i = index; i < current_capacity; ++i) { | |||||
| if (!data[i].original || | if (!data[i].original || | ||||
| hm_objects_match(data[i].original, key)) | hm_objects_match(data[i].original, key)) | ||||
| { | { | ||||
| @@ -157,7 +159,7 @@ struct Hash_Map { | |||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| for (int i = 0; i < index; ++i) { | |||||
| for (u32 i = 0; i < index; ++i) { | |||||
| if (!data[i].original || | if (!data[i].original || | ||||
| hm_objects_match(data[i].original, key)) | hm_objects_match(data[i].original, key)) | ||||
| { | { | ||||
| @@ -1,10 +1,11 @@ | |||||
| #define _CRT_SECURE_NO_WARNINGS | #define _CRT_SECURE_NO_WARNINGS | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include "./types.hpp" | |||||
| #include "./hooks.hpp" | #include "./hooks.hpp" | ||||
| Hook h; | Hook h; | ||||
| int main(int argc, char* argv[]) { | |||||
| s32 main(s32 argc, char* argv[]) { | |||||
| printf("Hello world"); | printf("Hello world"); | ||||
| system_shutdown_hook << [] { | system_shutdown_hook << [] { | ||||
| printf("Goodbye world\n"); | printf("Goodbye world\n"); | ||||