From 5519e8640af77da24809d3132a4ce917455f411c Mon Sep 17 00:00:00 2001 From: Felix Brendel Date: Sun, 20 Oct 2019 16:34:05 +0200 Subject: [PATCH] new for_hm macro --- hashmap.hpp | 180 ++++------------------------------------------------ 1 file changed, 13 insertions(+), 167 deletions(-) diff --git a/hashmap.hpp b/hashmap.hpp index 33008fc..2a7ebea 100644 --- a/hashmap.hpp +++ b/hashmap.hpp @@ -1,25 +1,18 @@ #pragma once + #include #include #include #include "types.hpp" - -// inline void print_hm(StringHashMap* hm) { - // for_str_hash_map(hm) { - // printf("index: %d desired-index: %llu key: %s hash: %llu value: %llu\n", i, (hm->data[i].hash % hm->current_capacity), (char*)key, hm->data[i].hash, (unsigned long long)value); - // } -// } - -#define __for_hm_generator(key_type, value_type, hm) \ - if (key_type key = 0); else \ - if (value_type value = 0); else \ - for(int index = 0; index < hm.current_capacity; ++index) \ - if (!((!hm.data[index].deleted) && \ - (key = hm.data[index].original) && \ +#define for_hash_map(hm) \ + if (decltype(hm.data[0].original) key = 0); else \ + if (decltype(hm.data[0].object) value = 0); else \ + for(int index = 0; index < hm.current_capacity; ++index) \ + if (!((!hm.data[index].deleted) && \ + (key = hm.data[index].original) && \ (value = hm.data[index].object))); else - template struct Hash_Map { int current_capacity; @@ -81,11 +74,12 @@ struct Hash_Map { } bool key_exists(key_type key) { - return get_index_of_living_cell_if_it_exists(key, hm_hash(key)) != -1; + return get_index_of_living_cell_if_it_exists(key, hm_hash((key_type)key)) != -1; } value_type get_object(key_type key) { - int index = get_index_of_living_cell_if_it_exists(key, hm_hash(key)); + + int index = get_index_of_living_cell_if_it_exists(key, hm_hash((key_type)key)); if (index != -1) { return data[index].object; } @@ -93,14 +87,14 @@ struct Hash_Map { } void delete_object(key_type key) { - int index = get_index_of_living_cell_if_it_exists(key, hm_hash(key)); + int index = get_index_of_living_cell_if_it_exists(key, hm_hash((key_type)key)); if (index != -1) { data[index].deleted = true; } } void set_object(key_type key, value_type obj) { - u64 hash_val = hm_hash(key); + u64 hash_val = hm_hash((key_type)key); int index = hash_val % current_capacity; /* if we the desired cell is just empty, write to it and done :) */ @@ -132,7 +126,7 @@ struct Hash_Map { } /* search for empty slot for new cell starting at desired index; */ /* preventing gotos using lambdas! */ - [&](){ + [&]{ for (int i = index; i < current_capacity; ++i) { if (!data[i].original || hm_objects_match(data[i].original, key)) @@ -160,151 +154,3 @@ struct Hash_Map { } }; - -// #define define_hash_map(type, name) \ -// bool hm_objects_match(type,type); \ -// u32 hm_hash(type); \ -// \ -// struct name##_Hash_Map_Cell { \ -// type original; \ -// u64 hash; \ -// bool deleted; \ -// void* object; \ -// }; \ -// \ -// struct name##_Hash_Map { \ -// int current_capacity; \ -// int cell_count; \ -// name##_Hash_Map_Cell* data; \ -// }; \ -// \ -// name##_Hash_Map* create_##name##_hashmap(int initial_capacity=8) { \ -// name##_Hash_Map* hm = new name##_Hash_Map; \ -// hm->current_capacity = initial_capacity; \ -// hm->cell_count = 0; \ -// /* set all data to nullptr */ \ -// hm->data = (name##_Hash_Map_Cell*)calloc(initial_capacity, sizeof(name##_Hash_Map_Cell)); \ -// /* printf("check: %s\n", hm->data[6].original_string); */ \ -// return hm; \ -// } \ -// \ -// int hm_get_index_of_living_cell_if_it_exists(name##_Hash_Map* hm, type key, u64 hash_val) { \ -// int index = hash_val % hm->current_capacity; \ -// name##_Hash_Map_Cell cell = hm->data[index]; \ -// /* test if cell exists at that index */ \ -// if (cell.original) { \ -// /* check if strings match */ \ -// if (hm_objects_match(key, cell.original)) { \ -// /* we found it, now check it it is deleted: */ \ -// if (cell.deleted) { \ -// /* we found it but it was deleted, we */ \ -// /* dont have to check for collisions then */ \ -// return -1; \ -// } else { \ -// /* we found it and it is not deleted */ \ -// return index; \ -// } \ -// } else { \ -// /* strings dont match, this means we have */ \ -// /* a collision. We just search forward */ \ -// for (int i = 0; i < hm->current_capacity; ++i) { \ -// int new_idx = (i + index) % hm->current_capacity; \ -// cell = hm->data[new_idx]; \ -// if (!cell.original) \ -// return -1; \ -// if (!hm_objects_match(key, cell.original)) \ -// continue; \ -// if (cell.deleted) \ -// continue; \ -// return new_idx; \ -// } \ -// /* not or only deleted cells found */ \ -// return -1; \ -// } \ -// } else { \ -// /* no cell exists at this index so the item was never in the */ \ -// /* hashmap. Either it would be there or be ther and 'deleted' */ \ -// /* or another item would be there and therefore a collistion */ \ -// /* would exist */ \ -// return -1; \ -// } \ -// } \ -// \ -// inline bool hm_key_exists(name##_Hash_Map* hm, type key) { \ -// return hm_get_index_of_living_cell_if_it_exists(hm, key, hm_hash(key)) != -1; \ -// } \ -// \ -// inline void* hm_get_object(name##_Hash_Map* hm, type key) { \ -// int index = hm_get_index_of_living_cell_if_it_exists(hm, key, hm_hash(key)); \ -// if (index != -1) { \ -// return hm->data[index].object; \ -// } \ -// return nullptr; \ -// } \ -// \ -// inline void hm_delete_object(name##_Hash_Map* hm, type key) { \ -// int index = hm_get_index_of_living_cell_if_it_exists(hm, key, hm_hash(key)); \ -// if (index != -1) { \ -// hm->data[index].deleted = true; \ -// } \ -// } \ -// \ -// void hm_set(name##_Hash_Map* hm, type key, void* obj) { \ -// u64 hash_val = hm_hash(key); \ -// int index = hash_val % hm->current_capacity; \ -// \ -// /* if we the desired cell is just empty, write to it and done :) */ \ -// if (!hm->data[index].original) { \ -// /* insert new cell into desired slot */ \ -// ++hm->cell_count; \ -// } else { \ -// if (hm_objects_match(key, hm->data[index].original)) { \ -// /* overwrite object with same key, dont increment cell */ \ -// /* count */ \ -// } else { \ -// /* collision, check resize */ \ -// ++hm->cell_count; \ -// if ((hm->cell_count*1.0f / hm->current_capacity) > 0.666f) { \ -// auto old_data = hm->data; \ -// hm->data = (name##_Hash_Map_Cell*)calloc(hm->current_capacity*4, sizeof(name##_Hash_Map_Cell)); \ -// hm->cell_count = 0; \ -// hm->current_capacity *= 4; \ -// \ -// /* insert all old items again */ \ -// for (int i = 0; i < hm->current_capacity/4; ++i) { \ -// auto cell = old_data[i]; \ -// if (cell.original) { \ -// hm_set(hm, cell.original, cell.object); \ -// } \ -// } \ -// free(old_data); \ -// index = hash_val % hm->current_capacity; \ -// } \ -// /* search for empty slot for new cell starting at desired index; */ \ -// /* preventing gotos using lambdas! */ \ -// [&](){ \ -// for (int i = index; i < hm->current_capacity; ++i) { \ -// if (!hm->data[i].original || \ -// hm_objects_match(hm->data[i].original, key)) \ -// { \ -// index = i; \ -// return; \ -// } \ -// } \ -// for (int i = 0; i < index; ++i) { \ -// if (!hm->data[i].original || \ -// hm_objects_match(hm->data[i].original, key)) \ -// { \ -// index = i; \ -// return; \ -// } \ -// } \ -// }(); \ -// } \ -// } \ -// \ -// hm->data[index].deleted = false; \ -// hm->data[index].original = key; \ -// hm->data[index].hash = hash_val; \ -// hm->data[index].object = obj; \ -// } \