From 064885298f722f1fbdb2c501ad4c0a1dada09cb7 Mon Sep 17 00:00:00 2001 From: MrGeorgen Date: Fri, 7 Aug 2020 11:26:52 +0200 Subject: [PATCH] hashmap_put function --- CMakeLists.txt | 9 +-------- include/acl/array.h | 18 ++++++++++++++++-- include/acl/hashmap.h | 12 +++++++----- src/array.c | 28 ++++++---------------------- src/hashmap.c | 39 ++++++++++++++++++++++++++++++--------- 5 files changed, 60 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index af1c129..c8f5bf9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,12 +8,5 @@ if(CCACHE_PROGRAM) set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") endif() set( CMAKE_EXPORT_COMPILE_COMMANDS ON ) -set_property(TARGET acl PROPERTY C_STANDARD 11) -INCLUDE(TestBigEndian) -TEST_BIG_ENDIAN(IS_BIG_ENDIAN) -if(IS_BIG_ENDIAN) - add_compile_definitions(ACL_BIG_ENDIAN) -else() - add_compile_definitions(ACL_LITTLE_ENDIAN) -endif() +set_property(TARGET acl PROPERTY C_STANDARD 99) target_link_libraries(acl PRIVATE m) diff --git a/include/acl/array.h b/include/acl/array.h index b8c3ade..c66794e 100644 --- a/include/acl/array.h +++ b/include/acl/array.h @@ -1,10 +1,24 @@ #ifndef _acl_array_h #define _acl_array_h #include -size_t acl_arraylist_len(void *arraylist); +union acl_arraylist_meta { + double dummy_double; + long double dummy_long_double; + long long dummy_long_long; + void *dummy_ptr; + void (*dummy_func_ptr)(void); + struct { + size_t len; + size_t cap; + size_t sizeof_one_element; + }; +}; +inline size_t acl_arraylist_len(void *arraylist) { + return ((union acl_arraylist_meta*)arraylist - 1)->len; +} void acl_arraylist_free(void *arraylist); void* acl_arraylist_remove(void *arraylist_void, size_t index); void* acl_arraylist_create(size_t array_size, size_t sizeof_one_element); -void* acl_arraylist_append(void *arraylist_void, void *element_void); +void* acl_arraylist_append(void *arraylist_void, void *element); void* acl_arraylist_append_ptr(void *arraylist_void, void **append_element); #endif diff --git a/include/acl/hashmap.h b/include/acl/hashmap.h index 70c999c..58aed5b 100644 --- a/include/acl/hashmap.h +++ b/include/acl/hashmap.h @@ -1,15 +1,17 @@ #ifndef _acl_hashmap_h #define _acl_hashmap_h #include +#include +#define acl_hashmap_create(type, keyType, bucketCount) acl_hashmap_init(bucketCount, sizeof(struct{type c; type d;}), offsetof(struct{type c; type d;}, d), sizeof(keyType)); union acl_hashmap_meta { void *dummy_ptr; struct { - size_t bucketCount; + size_t bucketBits; size_t sizeOneElement; - size_t keyBits; + size_t keySize; + size_t offset; }; }; -/* set keySize to NULL for a dynamic keySize */ -union acl_hashmap_meta* acl_hashmap_create(size_t bucketCount, size_t sizeOneElement, size_t keySize); -void acl_hashmap_put(union acl_hashmap_meta *hashmap_meta, void *key, void *element); +union acl_hashmap_meta* acl_hashmap_init(size_t bucketCount, size_t sizeOneElement, size_t offset, size_t keySize); +void* acl_hashmap_put(union acl_hashmap_meta *hashmap_meta, void *key); #endif diff --git a/src/array.c b/src/array.c index 2e7157d..1b75ceb 100644 --- a/src/array.c +++ b/src/array.c @@ -4,21 +4,9 @@ #include #include -union arraylist_meta { - double dummy_double; - long double dummy_long_double; - long long dummy_long_long; - void *dummy_ptr; - void (*dummy_func_ptr)(void); - struct { - size_t len; - size_t cap; - size_t sizeof_one_element; - }; -}; - +size_t acl_arraylist_len(void *arraylist); void* acl_arraylist_create(size_t array_size, size_t sizeof_one_element) { - union arraylist_meta *arraylist_new = malloc(array_size * sizeof_one_element + sizeof*arraylist_new); + union acl_arraylist_meta *arraylist_new = malloc(array_size * sizeof_one_element + sizeof*arraylist_new); if(arraylist_new == NULL) return NULL; arraylist_new->len = array_size; arraylist_new->cap = array_size; @@ -28,14 +16,14 @@ void* acl_arraylist_create(size_t array_size, size_t sizeof_one_element) { void* acl_arraylist_append(void *arraylist_void, void *element) { void *element_append; - union arraylist_meta *arraylist = acl_arraylist_append_ptr(arraylist_void, &element_append); + union acl_arraylist_meta *arraylist = acl_arraylist_append_ptr(arraylist_void, &element_append); if(arraylist == NULL) return NULL; --arraylist; memcpy(element_append, element, arraylist->sizeof_one_element); return arraylist + 1; } void* acl_arraylist_append_ptr(void *arraylist_void, void **append_element) { - union arraylist_meta *arraylist = arraylist_void; + union acl_arraylist_meta *arraylist = arraylist_void; --arraylist; if(arraylist->len == arraylist->cap) { if(arraylist->len > 10) arraylist->cap = arraylist->len + 10; @@ -49,11 +37,11 @@ void* acl_arraylist_append_ptr(void *arraylist_void, void **append_element) { } void acl_arraylist_free(void *arraylist) { - free((union arraylist_meta*)arraylist-1); + free((union acl_arraylist_meta*)arraylist-1); } void* acl_arraylist_remove(void *arraylist_void, size_t index) { - union arraylist_meta *arraylist = (union arraylist_meta*)arraylist_void - 1; + union acl_arraylist_meta *arraylist = (union acl_arraylist_meta*)arraylist_void - 1; char *arraylist_char = arraylist_void; if(index != arraylist->len - 1) { memcpy(arraylist_char + arraylist->sizeof_one_element * index, arraylist_char + arraylist->sizeof_one_element * (arraylist->len - 1), arraylist->sizeof_one_element); @@ -65,7 +53,3 @@ void* acl_arraylist_remove(void *arraylist_void, size_t index) { } return arraylist; } - -size_t acl_arraylist_len(void *arraylist) { - return ((union arraylist_meta*)arraylist - 1)->len; -} diff --git a/src/hashmap.c b/src/hashmap.c index 00273a7..b9448bc 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -21,8 +21,17 @@ *hash_char ^= *i;\ }\ } +inline static void* acl_hashmap_elementFromBucketAndKey(void *bucket, void *key, union acl_hashmap_meta *hashmap_meta) { + char *i = bucket; + for(char *dest = bucket + acl_arraylist_len(bucket); i < dest; i += hashmap_meta->sizeOneElement) { + if(!memcmp(key, i, hashmap_meta->keySize)) { + return i + hashmap_meta->offset; + } + } + return NULL; +} -size_t acl_hash(void *data, size_t dataSize, size_t bucketBits) { +static size_t acl_hash(void *data, size_t dataSize, size_t bucketBits) { switch(dataSize) { case 1: return (uint8_t)(101u * *(uint8_t*)data >> (8 - bucketBits)); @@ -53,21 +62,33 @@ size_t acl_hash(void *data, size_t dataSize, size_t bucketBits) { } } -union acl_hashmap_meta* acl_hashmap_create(size_t bucketCount, size_t sizeOneElement, size_t keySize) { +union acl_hashmap_meta* acl_hashmap_init(size_t bucketCount, size_t sizeOneElement, size_t offset, size_t keySize) { union acl_hashmap_meta *hashmap_meta = malloc(sizeof *hashmap_meta + bucketCount * sizeof(void*)); - hashmap_meta->bucketCount = bucketCount; + hashmap_meta->bucketBits = log2(bucketCount); hashmap_meta->sizeOneElement = sizeOneElement; - hashmap_meta->keyBits = log2(keySize); + hashmap_meta->keySize = keySize; + hashmap_meta->offset = offset; void **hashmap_buckets = (void**)(hashmap_meta + 1); - for(size_t i; i < bucketCount; ++i) { + for(size_t i = 0; i < bucketCount; ++i) { hashmap_buckets[i] = acl_arraylist_create(0, sizeOneElement); + if(hashmap_buckets[i] == NULL) { + for(size_t j = 0; j < i; ++j) { + acl_arraylist_free(hashmap_buckets[j]); + } + return NULL; + } } return hashmap_meta; } -void acl_hashmap_put(union acl_hashmap_meta *hashmap_meta, void *key, void *element) { +void* acl_hashmap_put(union acl_hashmap_meta *hashmap_meta, void *key) { void **hashmap_buckets = (void**)(hashmap_meta + 1); - -} -int main() { + void *bucket = hashmap_buckets[acl_hash(key, hashmap_meta->keySize, hashmap_meta->bucketBits)]; + if(acl_hashmap_elementFromBucketAndKey(bucket, key, hashmap_meta) != NULL) return NULL; + void *elementKey; // pointer to the key inside the bucket + void *bucketTmp = acl_arraylist_append_ptr(bucket, &elementKey); + if(bucketTmp == NULL) return NULL; + bucket = bucketTmp; + memcpy(elementKey, key, hashmap_meta->keySize); + return (char*)elementKey + hashmap_meta->offset; }