From 5f876866330d56b055b97358a966a78530b806b6 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Thu, 15 May 2025 12:20:45 -0500 Subject: [PATCH 01/33] fix(stack): fixed reallocation size in push function --- Src/Core/Stack.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Src/Core/Stack.c b/Src/Core/Stack.c index 916ff04..bcec7c3 100644 --- a/Src/Core/Stack.c +++ b/Src/Core/Stack.c @@ -76,7 +76,7 @@ FledastyError fledasty_stack_push(FledastyStack *current_stack, void *value) { if (current_stack->size == current_stack->capacity) { current_stack->capacity += current_stack->capacity; - current_stack->buffer = (unsigned char*)hallocy_realloc(current_stack->buffer, current_stack->capacity); + current_stack->buffer = (unsigned char*)hallocy_realloc(current_stack->buffer, current_stack->capacity * current_stack->element_byte_size); if (current_stack->buffer == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; @@ -102,10 +102,8 @@ void *fledasty_stack_pop(FledastyStack *current_stack) { return NULL; } - void *value_address = current_stack->buffer + ((current_stack->size - 1) * current_stack->element_byte_size); current_stack->size -= 1; - - return value_address; + return current_stack->buffer + (current_stack->size * current_stack->element_byte_size); } FledastyError fledasty_stack_clear(FledastyStack *current_stack) { -- 2.39.5 From f7ac0e519257c5484ac7eba9a9d606818cdca769 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Thu, 15 May 2025 12:28:54 -0500 Subject: [PATCH 02/33] feat(stack): implemented schrink to fit function --- Include/Fledasty/Core/Stack.h | 1 + Src/Core/Stack.c | 21 +++++++++++++++++++++ Tests/Main.c | 3 +++ 3 files changed, 25 insertions(+) diff --git a/Include/Fledasty/Core/Stack.h b/Include/Fledasty/Core/Stack.h index cbee423..268b297 100644 --- a/Include/Fledasty/Core/Stack.h +++ b/Include/Fledasty/Core/Stack.h @@ -43,6 +43,7 @@ void *fledasty_stack_peek(const FledastyStack *current_stack); void *fledasty_stack_pop(FledastyStack *current_stack); FledastyError fledasty_stack_clear(FledastyStack *current_stack); +FledastyError fledasty_stack_shrink_to_fit(FledastyStack *current_stack); static inline bool fledasty_stack_is_empty(const FledastyStack *current_stack) { return current_stack == NULL || current_stack->size == 0; } diff --git a/Src/Core/Stack.c b/Src/Core/Stack.c index bcec7c3..3a6bcf6 100644 --- a/Src/Core/Stack.c +++ b/Src/Core/Stack.c @@ -21,6 +21,7 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Core/Stack.h" +#include "Fledasty/Utils/Error.h" #include #include @@ -114,3 +115,23 @@ FledastyError fledasty_stack_clear(FledastyStack *current_stack) { current_stack->size = 0; return FLEDASTY_ERROR_NONE; } + +FledastyError fledasty_stack_shrink_to_fit(FledastyStack *current_stack) { + if (current_stack == NULL) { + return FLEDASTY_ERROR_INVALID_POINTER; + } + + current_stack->capacity = (current_stack->size == 0) ? 10 : current_stack->size; + unsigned char *shrinked_buffer = (unsigned char*)hallocy_malloc(current_stack->capacity); + if (shrinked_buffer == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + hallocy_copy_memory(shrinked_buffer, current_stack->buffer, current_stack->size); + if (hallocy_free(current_stack->buffer) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + current_stack->buffer = shrinked_buffer; + return FLEDASTY_ERROR_NONE; +} diff --git a/Tests/Main.c b/Tests/Main.c index 963c553..9c10342 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -61,6 +61,9 @@ int main() { fledasty_stack_push(&test_stack, &i); } + fledasty_stack_shrink_to_fit(&test_stack); + printf("Stack schrinked to fit %s\n", (test_stack.capacity == test_stack.size) ? "succeeded" : "failed"); + int *peeked_stack_data = (int*)fledasty_stack_peek(&test_stack); printf("Stack peeked: %d\n", *peeked_stack_data); -- 2.39.5 From 06cc29916058bad5be5b904f0ddbe47054b5ede9 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Thu, 15 May 2025 12:33:07 -0500 Subject: [PATCH 03/33] perf(queue): improved peek function by inlining it --- Include/Fledasty/Core/Queue.h | 2 +- Src/Core/Queue.c | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/Include/Fledasty/Core/Queue.h b/Include/Fledasty/Core/Queue.h index ab9f472..0821a74 100644 --- a/Include/Fledasty/Core/Queue.h +++ b/Include/Fledasty/Core/Queue.h @@ -40,11 +40,11 @@ FledastyError fledasty_queue_initialize(FledastyQueue *new_queue, void *values, FledastyError fledasty_queue_destroy(FledastyQueue *current_queue); FledastyError fledasty_queue_push(FledastyQueue *current_queue, void *value); -void *fledasty_queue_peek(const FledastyQueue *current_queue); void *fledasty_queue_pop(FledastyQueue *current_queue); FledastyError fledasty_queue_clear(FledastyQueue *current_queue); +static inline void *fledasty_queue_peek(const FledastyQueue *current_queue) { return (current_queue == NULL) ? NULL : current_queue->buffer + (current_queue->head * current_queue->element_byte_size); } static inline bool fledasty_queue_is_empty(const FledastyQueue *current_queue) { return current_queue == NULL || current_queue->size == 0; } #endif diff --git a/Src/Core/Queue.c b/Src/Core/Queue.c index 1fc4686..f0e55fc 100644 --- a/Src/Core/Queue.c +++ b/Src/Core/Queue.c @@ -54,7 +54,6 @@ FledastyError fledasty_queue_initialize(FledastyQueue *new_queue, void *values, } new_queue->tail = new_queue->size; - return FLEDASTY_ERROR_NONE; } @@ -102,14 +101,6 @@ FledastyError fledasty_queue_push(FledastyQueue *current_queue, void *value) { return FLEDASTY_ERROR_NONE; } -void *fledasty_queue_peek(const FledastyQueue *current_queue) { - if (current_queue == NULL) { - return NULL; - } - - return current_queue->buffer + (current_queue->head * current_queue->element_byte_size); -} - void *fledasty_queue_pop(FledastyQueue *current_queue) { if (current_queue == NULL || current_queue->size == 0) { return NULL; -- 2.39.5 From 349268068bc0162bd8067ee14df69829fcc6a521 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Thu, 15 May 2025 12:34:03 -0500 Subject: [PATCH 04/33] perf(stack): improved peek function by inlining it --- Include/Fledasty/Core/Stack.h | 2 +- Src/Core/Stack.c | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/Include/Fledasty/Core/Stack.h b/Include/Fledasty/Core/Stack.h index 268b297..5286d82 100644 --- a/Include/Fledasty/Core/Stack.h +++ b/Include/Fledasty/Core/Stack.h @@ -39,12 +39,12 @@ FledastyError fledasty_stack_initialize(FledastyStack *new_stack, void *values, FledastyError fledasty_stack_destroy(FledastyStack *current_stack); FledastyError fledasty_stack_push(FledastyStack *current_stack, void *value); -void *fledasty_stack_peek(const FledastyStack *current_stack); void *fledasty_stack_pop(FledastyStack *current_stack); FledastyError fledasty_stack_clear(FledastyStack *current_stack); FledastyError fledasty_stack_shrink_to_fit(FledastyStack *current_stack); +static inline void *fledasty_stack_peek(const FledastyStack *current_stack) { (current_stack == NULL) ? NULL : current_stack->buffer + ((current_stack->size - 1) * current_stack->element_byte_size); } static inline bool fledasty_stack_is_empty(const FledastyStack *current_stack) { return current_stack == NULL || current_stack->size == 0; } #endif diff --git a/Src/Core/Stack.c b/Src/Core/Stack.c index 3a6bcf6..d8ec35c 100644 --- a/Src/Core/Stack.c +++ b/Src/Core/Stack.c @@ -90,14 +90,6 @@ FledastyError fledasty_stack_push(FledastyStack *current_stack, void *value) { return FLEDASTY_ERROR_NONE; } -void *fledasty_stack_peek(const FledastyStack *current_stack) { - if (current_stack == NULL) { - return NULL; - } - - return current_stack->buffer + ((current_stack->size - 1) * current_stack->element_byte_size); -} - void *fledasty_stack_pop(FledastyStack *current_stack) { if (current_stack == NULL) { return NULL; -- 2.39.5 From ca59eec627e375d502a33176870e16f33b3830ce Mon Sep 17 00:00:00 2001 From: Mineplay Date: Thu, 15 May 2025 13:03:03 -0500 Subject: [PATCH 05/33] feat(queue): implemented schrink to fit function --- Include/Fledasty/Core/Queue.h | 1 + Include/Fledasty/Core/Stack.h | 2 +- Src/Core/Queue.c | 48 ++++++++++++++++++++++++++++++++--- Src/Core/Stack.c | 4 +-- Tests/Main.c | 4 +++ 5 files changed, 52 insertions(+), 7 deletions(-) diff --git a/Include/Fledasty/Core/Queue.h b/Include/Fledasty/Core/Queue.h index 0821a74..21ba5fa 100644 --- a/Include/Fledasty/Core/Queue.h +++ b/Include/Fledasty/Core/Queue.h @@ -43,6 +43,7 @@ FledastyError fledasty_queue_push(FledastyQueue *current_queue, void *value); void *fledasty_queue_pop(FledastyQueue *current_queue); FledastyError fledasty_queue_clear(FledastyQueue *current_queue); +FledastyError fledasty_queue_shrink_to_fit(FledastyQueue *current_queue); static inline void *fledasty_queue_peek(const FledastyQueue *current_queue) { return (current_queue == NULL) ? NULL : current_queue->buffer + (current_queue->head * current_queue->element_byte_size); } static inline bool fledasty_queue_is_empty(const FledastyQueue *current_queue) { return current_queue == NULL || current_queue->size == 0; } diff --git a/Include/Fledasty/Core/Stack.h b/Include/Fledasty/Core/Stack.h index 5286d82..3db1132 100644 --- a/Include/Fledasty/Core/Stack.h +++ b/Include/Fledasty/Core/Stack.h @@ -44,7 +44,7 @@ void *fledasty_stack_pop(FledastyStack *current_stack); FledastyError fledasty_stack_clear(FledastyStack *current_stack); FledastyError fledasty_stack_shrink_to_fit(FledastyStack *current_stack); -static inline void *fledasty_stack_peek(const FledastyStack *current_stack) { (current_stack == NULL) ? NULL : current_stack->buffer + ((current_stack->size - 1) * current_stack->element_byte_size); } +static inline void *fledasty_stack_peek(const FledastyStack *current_stack) { return (current_stack == NULL) ? NULL : current_stack->buffer + ((current_stack->size - 1) * current_stack->element_byte_size); } static inline bool fledasty_stack_is_empty(const FledastyStack *current_stack) { return current_stack == NULL || current_stack->size == 0; } #endif diff --git a/Src/Core/Queue.c b/Src/Core/Queue.c index f0e55fc..5070b4b 100644 --- a/Src/Core/Queue.c +++ b/Src/Core/Queue.c @@ -21,6 +21,7 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Core/Queue.h" +#include "Fledasty/Utils/Error.h" #include #include @@ -84,10 +85,17 @@ FledastyError fledasty_queue_push(FledastyQueue *current_queue, void *value) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - size_t head_length = current_queue->size - current_queue->head; - size_t new_head = current_queue->capacity - head_length; - hallocy_move_memory(current_queue->buffer + (new_head * current_queue->element_byte_size), current_queue->buffer + (current_queue->head * current_queue->element_byte_size), head_length * current_queue->element_byte_size); - current_queue->head = new_head; + if (current_queue->tail < current_queue->head) { + size_t head_size = (current_queue->size - current_queue->tail) * current_queue->element_byte_size; + + hallocy_move_memory(current_queue->buffer, current_queue->buffer + (current_queue->head * current_queue->element_byte_size), head_size); + hallocy_move_memory(current_queue->buffer + head_size, current_queue->buffer, current_queue->tail * current_queue->element_byte_size); + } else { + hallocy_move_memory(current_queue->buffer, current_queue->buffer + (current_queue->head * current_queue->element_byte_size), current_queue->size * current_queue->element_byte_size); + } + + current_queue->head = 0; + current_queue->tail = current_queue->size; } hallocy_copy_memory(current_queue->buffer + (current_queue->tail * current_queue->element_byte_size), value, current_queue->element_byte_size); @@ -125,3 +133,35 @@ FledastyError fledasty_queue_clear(FledastyQueue *current_queue) { current_queue->size = 0; return FLEDASTY_ERROR_NONE; } + +FledastyError fledasty_queue_shrink_to_fit(FledastyQueue *current_queue) { + if (current_queue == NULL) { + return FLEDASTY_ERROR_INVALID_POINTER; + } + + size_t new_capacity = (current_queue->size == 0) ? 10 : current_queue->size; + unsigned char *shrinked_buffer = (unsigned char*)hallocy_malloc(new_capacity); + if (shrinked_buffer == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + if (current_queue->tail < current_queue->head) { + size_t head_size = (current_queue->size - current_queue->tail) * current_queue->element_byte_size; + + hallocy_copy_memory(shrinked_buffer, current_queue->buffer + (current_queue->head * current_queue->element_byte_size), head_size); + hallocy_copy_memory(shrinked_buffer + head_size, current_queue->buffer, current_queue->tail * current_queue->element_byte_size); + } else { + hallocy_copy_memory(shrinked_buffer, current_queue->buffer + (current_queue->head * current_queue->element_byte_size), current_queue->size * current_queue->element_byte_size); + } + + if (hallocy_free(current_queue->buffer) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + current_queue->head = 0; + current_queue->tail = current_queue->size; + current_queue->capacity = new_capacity; + current_queue->buffer = shrinked_buffer; + + return FLEDASTY_ERROR_NONE; +} diff --git a/Src/Core/Stack.c b/Src/Core/Stack.c index d8ec35c..6b9096b 100644 --- a/Src/Core/Stack.c +++ b/Src/Core/Stack.c @@ -114,12 +114,12 @@ FledastyError fledasty_stack_shrink_to_fit(FledastyStack *current_stack) { } current_stack->capacity = (current_stack->size == 0) ? 10 : current_stack->size; - unsigned char *shrinked_buffer = (unsigned char*)hallocy_malloc(current_stack->capacity); + unsigned char *shrinked_buffer = (unsigned char*)hallocy_malloc(current_stack->capacity * current_stack->element_byte_size); if (shrinked_buffer == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - hallocy_copy_memory(shrinked_buffer, current_stack->buffer, current_stack->size); + hallocy_copy_memory(shrinked_buffer, current_stack->buffer, current_stack->size * current_stack->element_byte_size); if (hallocy_free(current_stack->buffer) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } diff --git a/Tests/Main.c b/Tests/Main.c index 9c10342..1d21f87 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -39,6 +39,10 @@ int main() { fledasty_queue_push(&test_queue, &i); } + fledasty_queue_shrink_to_fit(&test_queue); + printf("Queue schrinked to fit %s\n", (test_queue.capacity == test_queue.size) ? "succeeded" : "failed"); + int test = 0; + fledasty_queue_push(&test_queue, &test); int *peeked_queue_data = (int*)fledasty_queue_peek(&test_queue); printf("Queue peeked: %d\n", *peeked_queue_data); -- 2.39.5 From 4cfd56bcea0551ef0d0b205edc83f01e540d06a6 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Thu, 15 May 2025 13:53:02 -0500 Subject: [PATCH 06/33] refactor(linked list): improved allocation error handling --- Src/Core/LinkedList.c | 92 ++++++++++++++++++++++++++++++++----------- Src/Core/Queue.c | 5 +-- Src/Core/Stack.c | 3 +- 3 files changed, 73 insertions(+), 27 deletions(-) diff --git a/Src/Core/LinkedList.c b/Src/Core/LinkedList.c index 76d90e1..905d5b9 100644 --- a/Src/Core/LinkedList.c +++ b/Src/Core/LinkedList.c @@ -22,6 +22,7 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Core/LinkedList.h" +#include "Fledasty/Utils/Error.h" #include #include @@ -41,14 +42,30 @@ FledastyError fledasty_linked_list_initialize(FledastyLinkedList *new_linked_lis new_linked_list->size = values_size; new_linked_list->start = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); + if (new_linked_list->start == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_linked_list->start->value = hallocy_malloc(new_linked_list->element_byte_size); + if (new_linked_list->start->value == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + hallocy_copy_memory(new_linked_list->start->value, values, new_linked_list->element_byte_size); new_linked_list->start->next = NULL; FledastyLinkedListNode *last_node = new_linked_list->start; for (size_t index = new_linked_list->element_byte_size; index < new_linked_list->size * new_linked_list->element_byte_size; index += new_linked_list->element_byte_size) { FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_node->value = hallocy_malloc(new_linked_list->element_byte_size); + if (new_node->value == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + hallocy_copy_memory(new_node->value, (unsigned char*)values + index, new_linked_list->element_byte_size); new_node->next = NULL; @@ -73,13 +90,11 @@ FledastyError fledasty_linked_list_destroy(FledastyLinkedList *current_linked_li previous_node = current_node; current_node = current_node->next; - HallocyError result = hallocy_free(previous_node->value); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(previous_node->value) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - result = hallocy_free(previous_node); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } } @@ -93,8 +108,15 @@ FledastyError fledasty_linked_list_append(FledastyLinkedList *current_linked_lis } FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_node->value = hallocy_malloc(current_linked_list->element_byte_size); + if (new_node->value == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); new_node->next = NULL; @@ -115,10 +137,16 @@ FledastyError fledasty_linked_list_insert_at_index(FledastyLinkedList *current_l } FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - - new_node->value = hallocy_malloc(current_linked_list->element_byte_size); - hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_node->value = hallocy_malloc(current_linked_list->element_byte_size); + if (new_node->value == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); if (index == 0) { new_node->next = current_linked_list->start; current_linked_list->start = new_node; @@ -157,10 +185,16 @@ FledastyError fledasty_linked_list_insert_before_value(FledastyLinkedList *curre } FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - - new_node->value = hallocy_malloc(current_linked_list->element_byte_size); - hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_node->value = hallocy_malloc(current_linked_list->element_byte_size); + if (new_node->value == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); if (previous_node == NULL) { new_node->next = current_linked_list->start; current_linked_list->start = new_node; @@ -188,10 +222,16 @@ FledastyError fledasty_linked_list_insert_after_value(FledastyLinkedList *curren } FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - - new_node->value = hallocy_malloc(current_linked_list->element_byte_size); - hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_node->value = hallocy_malloc(current_linked_list->element_byte_size); + if (new_node->value == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); if (current_node == current_linked_list->end) { new_node->next = NULL; @@ -232,8 +272,13 @@ FledastyError fledasty_linked_list_remove_at_index(FledastyLinkedList *current_l previous_node->next = current_node->next; } - hallocy_free(current_node->value); - hallocy_free(current_node); + if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } current_linked_list->size -= 1; return FLEDASTY_ERROR_NONE; @@ -265,8 +310,13 @@ FledastyError fledasty_linked_list_remove_value(FledastyLinkedList *current_link previous_node->next = current_node->next; } - hallocy_free(current_node->value); - hallocy_free(current_node); + if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } current_linked_list->size -= 1; return FLEDASTY_ERROR_NONE; @@ -283,13 +333,11 @@ FledastyError fledasty_linked_list_clear(FledastyLinkedList *current_linked_list previous_node = current_node; current_node = current_node->next; - HallocyError result = hallocy_free(previous_node->value); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(previous_node->value) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - result = hallocy_free(previous_node); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } } diff --git a/Src/Core/Queue.c b/Src/Core/Queue.c index 5070b4b..6b28ffd 100644 --- a/Src/Core/Queue.c +++ b/Src/Core/Queue.c @@ -63,8 +63,7 @@ FledastyError fledasty_queue_destroy(FledastyQueue *current_queue) { return FLEDASTY_ERROR_INVALID_POINTER; } - HallocyError result = hallocy_free(current_queue->buffer); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(current_queue->buffer) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -79,8 +78,8 @@ FledastyError fledasty_queue_push(FledastyQueue *current_queue, void *value) { if (current_queue->size == current_queue->capacity) { current_queue->capacity += current_queue->capacity; - current_queue->buffer = (unsigned char*)hallocy_realloc(current_queue->buffer, current_queue->capacity * current_queue->element_byte_size); + current_queue->buffer = (unsigned char*)hallocy_realloc(current_queue->buffer, current_queue->capacity * current_queue->element_byte_size); if (current_queue->buffer == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } diff --git a/Src/Core/Stack.c b/Src/Core/Stack.c index 6b9096b..30e2058 100644 --- a/Src/Core/Stack.c +++ b/Src/Core/Stack.c @@ -61,8 +61,7 @@ FledastyError fledasty_stack_destroy(FledastyStack *current_stack) { return FLEDASTY_ERROR_INVALID_POINTER; } - HallocyError result = hallocy_free(current_stack->buffer); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(current_stack->buffer) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } -- 2.39.5 From 8dd77f8e39799ef219c6724f1df64f5d613d6e1f Mon Sep 17 00:00:00 2001 From: Mineplay Date: Mon, 19 May 2025 03:21:11 -0500 Subject: [PATCH 07/33] fix(linked list): fixed memory leaks that happen when failed allocation error is thrown --- Src/Core/LinkedList.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/Src/Core/LinkedList.c b/Src/Core/LinkedList.c index 905d5b9..b24c426 100644 --- a/Src/Core/LinkedList.c +++ b/Src/Core/LinkedList.c @@ -48,6 +48,7 @@ FledastyError fledasty_linked_list_initialize(FledastyLinkedList *new_linked_lis new_linked_list->start->value = hallocy_malloc(new_linked_list->element_byte_size); if (new_linked_list->start->value == NULL) { + hallocy_free(new_linked_list->start); return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -58,11 +59,33 @@ FledastyError fledasty_linked_list_initialize(FledastyLinkedList *new_linked_lis for (size_t index = new_linked_list->element_byte_size; index < new_linked_list->size * new_linked_list->element_byte_size; index += new_linked_list->element_byte_size) { FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); if (new_node == NULL) { + FledastyLinkedListNode *previous_node = NULL; + FledastyLinkedListNode *current_node = new_linked_list->start; + while (current_node != NULL) { + previous_node = current_node; + current_node = current_node->next; + + hallocy_free(previous_node->value); + hallocy_free(previous_node); + } + return FLEDASTY_ERROR_FAILED_ALLOCATION; } new_node->value = hallocy_malloc(new_linked_list->element_byte_size); if (new_node->value == NULL) { + hallocy_free(new_node); + + FledastyLinkedListNode *previous_node = NULL; + FledastyLinkedListNode *current_node = new_linked_list->start; + while (current_node != NULL) { + previous_node = current_node; + current_node = current_node->next; + + hallocy_free(previous_node->value); + hallocy_free(previous_node); + } + return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -114,6 +137,7 @@ FledastyError fledasty_linked_list_append(FledastyLinkedList *current_linked_lis new_node->value = hallocy_malloc(current_linked_list->element_byte_size); if (new_node->value == NULL) { + hallocy_free(new_node); return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -143,6 +167,7 @@ FledastyError fledasty_linked_list_insert_at_index(FledastyLinkedList *current_l new_node->value = hallocy_malloc(current_linked_list->element_byte_size); if (new_node->value == NULL) { + hallocy_free(new_node); return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -191,6 +216,7 @@ FledastyError fledasty_linked_list_insert_before_value(FledastyLinkedList *curre new_node->value = hallocy_malloc(current_linked_list->element_byte_size); if (new_node->value == NULL) { + hallocy_free(new_node); return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -228,6 +254,7 @@ FledastyError fledasty_linked_list_insert_after_value(FledastyLinkedList *curren new_node->value = hallocy_malloc(current_linked_list->element_byte_size); if (new_node->value == NULL) { + hallocy_free(new_node); return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -262,7 +289,7 @@ FledastyError fledasty_linked_list_remove_at_index(FledastyLinkedList *current_l current_node = current_node->next; } - if (current_node->next == NULL) { + if (current_node == current_linked_list->end) { current_linked_list->end = previous_node; } @@ -300,7 +327,7 @@ FledastyError fledasty_linked_list_remove_value(FledastyLinkedList *current_link return FLEDASTY_ERROR_VALUE_NOT_FOUND; } - if (current_node->next == NULL) { + if (current_node == current_linked_list->end) { current_linked_list->end = previous_node; } -- 2.39.5 From 827723e7251fb503739cd94c0699240518aeb881 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Mon, 19 May 2025 03:56:43 -0500 Subject: [PATCH 08/33] refactor(data structures): removed unused includes --- Include/Fledasty/Core/DoublyLinkedList.h | 2 +- Src/Core/DynamicArray.c | 1 - Src/Core/LinkedList.c | 3 +-- Src/Core/Queue.c | 1 - Src/Core/Stack.c | 1 - Src/Strings/UTF8String.c | 1 - 6 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Include/Fledasty/Core/DoublyLinkedList.h b/Include/Fledasty/Core/DoublyLinkedList.h index f5ac708..5cdb667 100644 --- a/Include/Fledasty/Core/DoublyLinkedList.h +++ b/Include/Fledasty/Core/DoublyLinkedList.h @@ -57,4 +57,4 @@ FledastyError fledasty_doubly_linked_list_clear(FledastyDoublyLinkedList *curren bool fledasty_doubly_linked_list_has_value(const FledastyDoublyLinkedList *current_doubly_linked_list, void *value); static inline bool fledasty_doubly_linked_list_is_empty(const FledastyDoublyLinkedList *current_doubly_linked_list) { return current_doubly_linked_list == NULL || current_doubly_linked_list->size == 0; } -#endif \ No newline at end of file +#endif diff --git a/Src/Core/DynamicArray.c b/Src/Core/DynamicArray.c index e7e6f7c..462496d 100644 --- a/Src/Core/DynamicArray.c +++ b/Src/Core/DynamicArray.c @@ -22,7 +22,6 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Core/DynamicArray.h" -#include "Fledasty/Utils/Error.h" #include #include diff --git a/Src/Core/LinkedList.c b/Src/Core/LinkedList.c index b24c426..42919e7 100644 --- a/Src/Core/LinkedList.c +++ b/Src/Core/LinkedList.c @@ -22,7 +22,6 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Core/LinkedList.h" -#include "Fledasty/Utils/Error.h" #include #include @@ -68,7 +67,7 @@ FledastyError fledasty_linked_list_initialize(FledastyLinkedList *new_linked_lis hallocy_free(previous_node->value); hallocy_free(previous_node); } - + return FLEDASTY_ERROR_FAILED_ALLOCATION; } diff --git a/Src/Core/Queue.c b/Src/Core/Queue.c index 6b28ffd..d3d05d7 100644 --- a/Src/Core/Queue.c +++ b/Src/Core/Queue.c @@ -21,7 +21,6 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Core/Queue.h" -#include "Fledasty/Utils/Error.h" #include #include diff --git a/Src/Core/Stack.c b/Src/Core/Stack.c index 30e2058..cde42a2 100644 --- a/Src/Core/Stack.c +++ b/Src/Core/Stack.c @@ -21,7 +21,6 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Core/Stack.h" -#include "Fledasty/Utils/Error.h" #include #include diff --git a/Src/Strings/UTF8String.c b/Src/Strings/UTF8String.c index 31697ce..3d18f49 100644 --- a/Src/Strings/UTF8String.c +++ b/Src/Strings/UTF8String.c @@ -24,7 +24,6 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Strings/UTF8String.h" -#include "Fledasty/Utils/Error.h" #include #include -- 2.39.5 From 4134d55492a3f1f3d2ab3299a1ed94783306dadd Mon Sep 17 00:00:00 2001 From: Mineplay Date: Tue, 20 May 2025 05:23:25 -0500 Subject: [PATCH 09/33] refactor(doubly linked list): improved allocation error handling --- Src/Core/DoublyLinkedList.c | 110 ++++++++++++++++++++++++++++++------ 1 file changed, 93 insertions(+), 17 deletions(-) diff --git a/Src/Core/DoublyLinkedList.c b/Src/Core/DoublyLinkedList.c index 0c06d23..f7e07ee 100644 --- a/Src/Core/DoublyLinkedList.c +++ b/Src/Core/DoublyLinkedList.c @@ -41,16 +41,54 @@ FledastyError fledasty_doubly_linked_list_initialize(FledastyDoublyLinkedList *n new_doubly_linked_list->size = values_size; new_doubly_linked_list->start = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); + if (new_doubly_linked_list->start == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_doubly_linked_list->start->value = hallocy_malloc(new_doubly_linked_list->element_byte_size); + if (new_doubly_linked_list->start->value == NULL) { + hallocy_free(new_doubly_linked_list->start); + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + hallocy_copy_memory(new_doubly_linked_list->start->value, values, new_doubly_linked_list->element_byte_size); new_doubly_linked_list->start->previous = NULL; new_doubly_linked_list->start->next = NULL; - FledastyDoublyLinkedListNode *last_node = new_doubly_linked_list->start; for (size_t index = new_doubly_linked_list->element_byte_size; index < new_doubly_linked_list->size * new_doubly_linked_list->element_byte_size; index += new_doubly_linked_list->element_byte_size) { FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); + if (new_node == NULL) { + FledastyDoublyLinkedListNode *previous_node = NULL; + FledastyDoublyLinkedListNode *current_node = new_doubly_linked_list->start; + while (current_node != NULL) { + previous_node = current_node; + current_node = current_node->next; + + hallocy_free(previous_node->value); + hallocy_free(previous_node); + } + + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_node->value = hallocy_malloc(new_doubly_linked_list->element_byte_size); + if (new_node->value == NULL) { + hallocy_free(new_node); + + FledastyDoublyLinkedListNode *previous_node = NULL; + FledastyDoublyLinkedListNode *current_node = new_doubly_linked_list->start; + while (current_node != NULL) { + previous_node = current_node; + current_node = current_node->next; + + hallocy_free(previous_node->value); + hallocy_free(previous_node); + } + + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + hallocy_copy_memory(new_node->value, (unsigned char*)values + index, new_doubly_linked_list->element_byte_size); new_node->previous = last_node; @@ -77,13 +115,11 @@ FledastyError fledasty_doubly_list_destroy(FledastyDoublyLinkedList *current_dou previous_node = current_node; current_node = current_node->next; - HallocyError result = hallocy_free(previous_node->value); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(previous_node->value) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - result = hallocy_free(previous_node); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } } @@ -97,8 +133,16 @@ FledastyError fledasty_doubly_linked_list_append(FledastyDoublyLinkedList *curre } FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); + if (new_node->value == NULL) { + hallocy_free(new_node); + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); new_node->previous = current_doubly_linked_list->end; @@ -121,8 +165,16 @@ FledastyError fledasty_doubly_linked_list_insert_at_index(FledastyDoublyLinkedLi } FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); + if (new_node->value) { + hallocy_free(new_node); + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); if (index == 0) { @@ -177,8 +229,16 @@ FledastyError fledasty_doubly_linked_list_insert_before_value(FledastyDoublyLink } FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); + if (new_node->value == NULL) { + hallocy_free(new_node); + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); if (current_node->previous == NULL) { @@ -214,8 +274,16 @@ FledastyError fledasty_doubly_linked_list_insert_after_value(FledastyDoublyLinke } FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); + if (new_node->value == NULL) { + hallocy_free(new_node); + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); if (current_node == current_doubly_linked_list->end) { @@ -273,8 +341,13 @@ FledastyError fledasty_doubly_linked_list_remove_at_index(FledastyDoublyLinkedLi } } - hallocy_free(current_node->value); - hallocy_free(current_node); + if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } current_doubly_linked_list->size -= 1; return FLEDASTY_ERROR_NONE; @@ -309,8 +382,13 @@ FledastyError fledasty_doubly_linked_list_remove_value(FledastyDoublyLinkedList } } - hallocy_free(current_node->value); - hallocy_free(current_node); + if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } current_doubly_linked_list->size -= 1; return FLEDASTY_ERROR_NONE; @@ -327,13 +405,11 @@ FledastyError fledasty_doubly_linked_list_clear(FledastyDoublyLinkedList *curren previous_node = current_node; current_node = current_node->next; - HallocyError result = hallocy_free(previous_node->value); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(previous_node->value) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - result = hallocy_free(previous_node); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } } -- 2.39.5 From 18c7f70fca5cee82b55ea2595a6af6b673aa7e12 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Tue, 20 May 2025 07:07:04 -0500 Subject: [PATCH 10/33] refactor(doubly linked list): changed method used for freeing memory on error --- Src/Core/DoublyLinkedList.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Src/Core/DoublyLinkedList.c b/Src/Core/DoublyLinkedList.c index f7e07ee..5669073 100644 --- a/Src/Core/DoublyLinkedList.c +++ b/Src/Core/DoublyLinkedList.c @@ -26,7 +26,7 @@ #include #include #include - +#include FledastyError fledasty_doubly_linked_list_initialize(FledastyDoublyLinkedList *new_doubly_linked_list, void *values, const size_t values_size, const size_t element_byte_size) { if (new_doubly_linked_list == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; @@ -55,20 +55,22 @@ FledastyError fledasty_doubly_linked_list_initialize(FledastyDoublyLinkedList *n new_doubly_linked_list->start->previous = NULL; new_doubly_linked_list->start->next = NULL; + FledastyDoublyLinkedListNode *last_node = new_doubly_linked_list->start; for (size_t index = new_doubly_linked_list->element_byte_size; index < new_doubly_linked_list->size * new_doubly_linked_list->element_byte_size; index += new_doubly_linked_list->element_byte_size) { FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); if (new_node == NULL) { - FledastyDoublyLinkedListNode *previous_node = NULL; FledastyDoublyLinkedListNode *current_node = new_doubly_linked_list->start; - while (current_node != NULL) { - previous_node = current_node; + while (current_node->next != NULL) { current_node = current_node->next; - hallocy_free(previous_node->value); - hallocy_free(previous_node); + hallocy_free(current_node->previous->value); + hallocy_free(current_node->previous); } + hallocy_free(current_node->value); + hallocy_free(current_node); + return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -76,16 +78,17 @@ FledastyError fledasty_doubly_linked_list_initialize(FledastyDoublyLinkedList *n if (new_node->value == NULL) { hallocy_free(new_node); - FledastyDoublyLinkedListNode *previous_node = NULL; FledastyDoublyLinkedListNode *current_node = new_doubly_linked_list->start; - while (current_node != NULL) { - previous_node = current_node; + while (current_node->next != NULL) { current_node = current_node->next; - hallocy_free(previous_node->value); - hallocy_free(previous_node); + hallocy_free(current_node->previous->value); + hallocy_free(current_node); } + hallocy_free(current_node->value); + hallocy_free(current_node); + return FLEDASTY_ERROR_FAILED_ALLOCATION; } -- 2.39.5 From 31e9953bf7fef35b405966a71c1046ffffe38081 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Thu, 22 May 2025 17:54:22 -0500 Subject: [PATCH 11/33] perf(doubly linked list): made small improvements in performance when searching for values in a function --- Src/Core/DoublyLinkedList.c | 214 ++++++++++++++++++------------------ 1 file changed, 104 insertions(+), 110 deletions(-) diff --git a/Src/Core/DoublyLinkedList.c b/Src/Core/DoublyLinkedList.c index 5669073..8a55a33 100644 --- a/Src/Core/DoublyLinkedList.c +++ b/Src/Core/DoublyLinkedList.c @@ -26,7 +26,7 @@ #include #include #include -#include + FledastyError fledasty_doubly_linked_list_initialize(FledastyDoublyLinkedList *new_doubly_linked_list, void *values, const size_t values_size, const size_t element_byte_size) { if (new_doubly_linked_list == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; @@ -223,43 +223,43 @@ FledastyError fledasty_doubly_linked_list_insert_before_value(FledastyDoublyLink } FledastyDoublyLinkedListNode *current_node = current_doubly_linked_list->start; - while (current_node != NULL && !hallocy_compare_memory(current_node->value, before_value, current_doubly_linked_list->element_byte_size)) { + while (current_node != NULL) { + if (hallocy_compare_memory(current_node->value, before_value, current_doubly_linked_list->element_byte_size)) { + FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); + if (new_node->value == NULL) { + hallocy_free(new_node); + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); + + if (current_node->previous == NULL) { + new_node->previous = NULL; + new_node->next = current_doubly_linked_list->start; + + current_doubly_linked_list->start->previous = new_node; + current_doubly_linked_list->start = new_node; + } else { + new_node->previous = current_node->previous; + new_node->next = current_node; + + current_node->previous->next = new_node; + current_node->previous = new_node; + } + + current_doubly_linked_list->size += 1; + return FLEDASTY_ERROR_NONE; + } + current_node = current_node->next; } - if (current_node == NULL) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); - - if (current_node->previous == NULL) { - new_node->previous = NULL; - new_node->next = current_doubly_linked_list->start; - - current_doubly_linked_list->start->previous = new_node; - current_doubly_linked_list->start = new_node; - } else { - new_node->previous = current_node->previous; - new_node->next = current_node; - - current_node->previous->next = new_node; - current_node->previous = new_node; - } - - current_doubly_linked_list->size += 1; - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } FledastyError fledasty_doubly_linked_list_insert_after_value(FledastyDoublyLinkedList *current_doubly_linked_list, void *after_value, void *value) { @@ -268,43 +268,43 @@ FledastyError fledasty_doubly_linked_list_insert_after_value(FledastyDoublyLinke } FledastyDoublyLinkedListNode *current_node = current_doubly_linked_list->start; - while (current_node != NULL && !hallocy_compare_memory(current_node->value, after_value, current_doubly_linked_list->element_byte_size)) { + while (current_node != NULL) { + if (hallocy_compare_memory(current_node->value, after_value, current_doubly_linked_list->element_byte_size)) { + FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); + if (new_node->value == NULL) { + hallocy_free(new_node); + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); + + if (current_node == current_doubly_linked_list->end) { + new_node->next = NULL; + new_node->previous = current_doubly_linked_list->end; + + current_doubly_linked_list->end->next = new_node; + current_doubly_linked_list->end = new_node; + } else { + new_node->previous = current_node; + new_node->next = current_node->next; + + current_node->next->previous = new_node; + current_node->next = new_node; + } + + current_doubly_linked_list->size += 1; + return FLEDASTY_ERROR_NONE; + } + current_node = current_node->next; } - if (current_node == NULL) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); - - if (current_node == current_doubly_linked_list->end) { - new_node->next = NULL; - new_node->previous = current_doubly_linked_list->end; - - current_doubly_linked_list->end->next = new_node; - current_doubly_linked_list->end = new_node; - } else { - new_node->previous = current_node; - new_node->next = current_node->next; - - current_node->next->previous = new_node; - current_node->next = new_node; - } - - current_doubly_linked_list->size += 1; - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } FledastyError fledasty_doubly_linked_list_remove_at_index(FledastyDoublyLinkedList *current_doubly_linked_list, const size_t index) { @@ -329,19 +329,16 @@ FledastyError fledasty_doubly_linked_list_remove_at_index(FledastyDoublyLinkedLi } } - if (current_node->previous == NULL) { + if (current_node == current_doubly_linked_list->start) { current_doubly_linked_list->start = current_node->next; - current_doubly_linked_list->start->previous = NULL; - if (current_node->next == NULL) { - current_doubly_linked_list->end = current_node->previous; - } } else { current_node->previous->next = current_node->next; - if (current_node->next == NULL) { - current_doubly_linked_list->end = current_node->previous; - } else { - current_node->next->previous = current_node->previous; - } + } + + if (current_node == current_doubly_linked_list->end) { + current_doubly_linked_list->end = current_node->previous; + } else { + current_node->next->previous = current_node->previous; } if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { @@ -362,39 +359,36 @@ FledastyError fledasty_doubly_linked_list_remove_value(FledastyDoublyLinkedList } FledastyDoublyLinkedListNode *current_node = current_doubly_linked_list->start; - while (current_node != NULL && !hallocy_compare_memory(current_node->value, value, current_doubly_linked_list->element_byte_size)) { + while (current_node != NULL) { + if (hallocy_compare_memory(current_node->value, value, current_doubly_linked_list->element_byte_size)) { + if (current_node == current_doubly_linked_list->start) { + current_doubly_linked_list->start = current_node->next; + } else { + current_node->previous->next = current_node->next; + } + + if (current_node == current_doubly_linked_list->end) { + current_doubly_linked_list->end = current_node->previous; + } else { + current_node->next->previous = current_node->previous; + } + + if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + current_doubly_linked_list->size -= 1; + return FLEDASTY_ERROR_NONE; + } + current_node = current_node->next; } - if (current_node == NULL) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - if (current_node->previous == NULL) { - current_doubly_linked_list->start = current_node->next; - current_doubly_linked_list->start->previous = NULL; - if (current_node->next == NULL) { - current_doubly_linked_list->end = current_node->previous; - } - } else { - current_node->previous->next = current_node->next; - if (current_node->next == NULL) { - current_doubly_linked_list->end = current_node->previous; - } else { - current_node->next->previous = current_node->previous; - } - } - - if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_doubly_linked_list->size -= 1; - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } FledastyError fledasty_doubly_linked_list_clear(FledastyDoublyLinkedList *current_doubly_linked_list) { @@ -417,10 +411,10 @@ FledastyError fledasty_doubly_linked_list_clear(FledastyDoublyLinkedList *curren } } - current_doubly_linked_list->size = 0; current_doubly_linked_list->start = NULL; current_doubly_linked_list->end = NULL; + current_doubly_linked_list->size = 0; return FLEDASTY_ERROR_NONE; } -- 2.39.5 From b43b5c550d4c0693ac7a76aef60af967a4c1bb30 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Thu, 22 May 2025 17:58:01 -0500 Subject: [PATCH 12/33] perf(linked list): made same improvements to searching for value as in doubly linked list --- Src/Core/LinkedList.c | 166 +++++++++++++++++++++--------------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/Src/Core/LinkedList.c b/Src/Core/LinkedList.c index 42919e7..609658c 100644 --- a/Src/Core/LinkedList.c +++ b/Src/Core/LinkedList.c @@ -199,37 +199,37 @@ FledastyError fledasty_linked_list_insert_before_value(FledastyLinkedList *curre FledastyLinkedListNode *previous_node = NULL; FledastyLinkedListNode *current_node = current_linked_list->start; - while (current_node != NULL && !hallocy_compare_memory(current_node->value, before_value, current_linked_list->element_byte_size)) { + while (current_node != NULL) { + if (hallocy_compare_memory(current_node->value, before_value, current_linked_list->element_byte_size)) { + FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + new_node->value = hallocy_malloc(current_linked_list->element_byte_size); + if (new_node->value == NULL) { + hallocy_free(new_node); + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); + if (previous_node == NULL) { + new_node->next = current_linked_list->start; + current_linked_list->start = new_node; + } else { + new_node->next = current_node; + previous_node->next = new_node; + } + + current_linked_list->size += 1; + return FLEDASTY_ERROR_NONE; + } + previous_node = current_node; current_node = current_node->next; } - - if (current_node == NULL) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); - if (previous_node == NULL) { - new_node->next = current_linked_list->start; - current_linked_list->start = new_node; - } else { - new_node->next = current_node; - previous_node->next = new_node; - } - - current_linked_list->size += 1; - return FLEDASTY_ERROR_NONE; + + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } FledastyError fledasty_linked_list_insert_after_value(FledastyLinkedList *current_linked_list, void *after_value, void *value) { @@ -238,38 +238,38 @@ FledastyError fledasty_linked_list_insert_after_value(FledastyLinkedList *curren } FledastyLinkedListNode *current_node = current_linked_list->start; - while (current_node != NULL && !hallocy_compare_memory(current_node->value, after_value, current_linked_list->element_byte_size)) { + while (current_node != NULL) { + if (hallocy_compare_memory(current_node->value, after_value, current_linked_list->element_byte_size)) { + FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); + if (new_node == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + new_node->value = hallocy_malloc(current_linked_list->element_byte_size); + if (new_node->value == NULL) { + hallocy_free(new_node); + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); + if (current_node == current_linked_list->end) { + new_node->next = NULL; + + current_linked_list->end->next = new_node; + current_linked_list->end = new_node; + } else { + new_node->next = current_node->next; + current_node->next = new_node; + } + + current_linked_list->size += 1; + return FLEDASTY_ERROR_NONE; + } + current_node = current_node->next; } - if (current_node == NULL) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); - if (current_node == current_linked_list->end) { - new_node->next = NULL; - - current_linked_list->end->next = new_node; - current_linked_list->end = new_node; - } else { - new_node->next = current_node->next; - current_node->next = new_node; - } - - current_linked_list->size += 1; - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } FledastyError fledasty_linked_list_remove_at_index(FledastyLinkedList *current_linked_list, const size_t index) { @@ -317,35 +317,35 @@ FledastyError fledasty_linked_list_remove_value(FledastyLinkedList *current_link FledastyLinkedListNode *previous_node = NULL; FledastyLinkedListNode *current_node = current_linked_list->start; - while (current_node != NULL && !hallocy_compare_memory(current_node->value, value, current_linked_list->element_byte_size)) { + while (current_node != NULL) { + if (hallocy_compare_memory(current_node->value, value, current_linked_list->element_byte_size)) { + if (current_node == current_linked_list->end) { + current_linked_list->end = previous_node; + } + + if (previous_node == NULL) { + current_linked_list->start = current_node->next; + } else { + previous_node->next = current_node->next; + } + + if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + current_linked_list->size -= 1; + return FLEDASTY_ERROR_NONE; + } + previous_node = current_node; current_node = current_node->next; } - if (current_node == NULL) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - if (current_node == current_linked_list->end) { - current_linked_list->end = previous_node; - } - - if (previous_node == NULL) { - current_linked_list->start = current_node->next; - } else { - previous_node->next = current_node->next; - } - - if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_linked_list->size -= 1; - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } FledastyError fledasty_linked_list_clear(FledastyLinkedList *current_linked_list) { @@ -368,10 +368,10 @@ FledastyError fledasty_linked_list_clear(FledastyLinkedList *current_linked_list } } - current_linked_list->size = 0; current_linked_list->start = NULL; current_linked_list->end = NULL; + current_linked_list->size = 0; return FLEDASTY_ERROR_NONE; } -- 2.39.5 From a0cca7f696ddfa6d9923e8d7ea9a2599a615604d Mon Sep 17 00:00:00 2001 From: Mineplay Date: Fri, 23 May 2025 08:42:34 -0500 Subject: [PATCH 13/33] feat(dynamic array): implemented shrink to fit function --- Include/Fledasty/Core/DynamicArray.h | 1 + Src/Core/DynamicArray.c | 21 +++++++++++++++++++++ Tests/Main.c | 3 +++ 3 files changed, 25 insertions(+) diff --git a/Include/Fledasty/Core/DynamicArray.h b/Include/Fledasty/Core/DynamicArray.h index a58098a..df7d978 100644 --- a/Include/Fledasty/Core/DynamicArray.h +++ b/Include/Fledasty/Core/DynamicArray.h @@ -51,6 +51,7 @@ FledastyError fledasty_dynamic_array_remove_at_index(FledastyDynamicArray *curre FledastyError fledasty_dynamic_array_remove_value(FledastyDynamicArray *current_dynamic_array, void *value); FledastyError fledasty_dynamic_array_clear(FledastyDynamicArray *current_dynamic_array); +FledastyError fledasty_dynamic_array_shrink_to_fit(FledastyDynamicArray *current_dynamic_array); bool fledasty_dynamic_array_has_value(const FledastyDynamicArray *current_dynamic_array, void *value); inline static bool fledasty_dynamic_array_is_empty(const FledastyDynamicArray *current_dynamic_array) { return current_dynamic_array == NULL || current_dynamic_array->size == 0; } diff --git a/Src/Core/DynamicArray.c b/Src/Core/DynamicArray.c index 462496d..01dc88d 100644 --- a/Src/Core/DynamicArray.c +++ b/Src/Core/DynamicArray.c @@ -22,6 +22,7 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Core/DynamicArray.h" +#include "Fledasty/Utils/Error.h" #include #include @@ -229,6 +230,26 @@ FledastyError fledasty_dynamic_array_clear(FledastyDynamicArray *current_dynamic return FLEDASTY_ERROR_NONE; } +FledastyError fledasty_dynamic_array_shrink_to_fit(FledastyDynamicArray *current_dynamic_array) { + if (current_dynamic_array == NULL) { + return FLEDASTY_ERROR_INVALID_POINTER; + } + + current_dynamic_array->capacity = (current_dynamic_array->size == 0) ? 10 : current_dynamic_array->size; + unsigned char *shrinked_buffer = (unsigned char*)hallocy_malloc(current_dynamic_array->capacity * current_dynamic_array->element_byte_size); + if (shrinked_buffer == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + hallocy_copy_memory(shrinked_buffer, current_dynamic_array->buffer, current_dynamic_array->size * current_dynamic_array->element_byte_size); + if (hallocy_free(current_dynamic_array->buffer) != HALLOCY_ERROR_NONE) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + current_dynamic_array->buffer = shrinked_buffer; + return FLEDASTY_ERROR_NONE; +} + bool fledasty_dynamic_array_has_value(const FledastyDynamicArray *current_dynamic_array, void *value) { if (current_dynamic_array == NULL) { return false; diff --git a/Tests/Main.c b/Tests/Main.c index 1d21f87..fba8285 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -89,6 +89,9 @@ int main() { fledasty_dynamic_array_append(&test_dynamic_array, &i); } + fledasty_dynamic_array_shrink_to_fit(&test_dynamic_array); + printf("Dynamic array schrinked to fit %s\n", (test_dynamic_array.capacity == test_dynamic_array.size) ? "succeeded" : "failed"); + int insert_value = 18; fledasty_dynamic_array_insert_at_index(&test_dynamic_array, 1, &insert_value); -- 2.39.5 From 81f1c7d7ca5df22320945026fdf880e23974fdbe Mon Sep 17 00:00:00 2001 From: Mineplay Date: Fri, 23 May 2025 17:24:39 -0500 Subject: [PATCH 14/33] refactor(dynamic array): improved error handeling for allocating and freeing memory --- Src/Core/DynamicArray.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Src/Core/DynamicArray.c b/Src/Core/DynamicArray.c index 01dc88d..6692c32 100644 --- a/Src/Core/DynamicArray.c +++ b/Src/Core/DynamicArray.c @@ -62,8 +62,7 @@ FledastyError fledasty_dynamic_array_destroy(FledastyDynamicArray *current_dynam return FLEDASTY_ERROR_INVALID_POINTER; } - HallocyError result = hallocy_free(current_dynamic_array->buffer); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(current_dynamic_array->buffer) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -79,6 +78,10 @@ FledastyError fledasty_dynamic_array_append(FledastyDynamicArray *current_dynami if (current_dynamic_array->size == current_dynamic_array->capacity) { current_dynamic_array->capacity += current_dynamic_array->capacity; current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); + + if (current_dynamic_array->buffer == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } } hallocy_copy_memory(current_dynamic_array->buffer + (current_dynamic_array->size * current_dynamic_array->element_byte_size), value, current_dynamic_array->element_byte_size); -- 2.39.5 From fe84e39ac7f5a853613b5660c49fd119af014764 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Fri, 23 May 2025 17:27:56 -0500 Subject: [PATCH 15/33] perf(dynamic array): made small improvements in performance when searching for values in a function --- Src/Core/DynamicArray.c | 97 ++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/Src/Core/DynamicArray.c b/Src/Core/DynamicArray.c index 6692c32..bce2953 100644 --- a/Src/Core/DynamicArray.c +++ b/Src/Core/DynamicArray.c @@ -22,7 +22,6 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Core/DynamicArray.h" -#include "Fledasty/Utils/Error.h" #include #include @@ -123,28 +122,28 @@ FledastyError fledasty_dynamic_array_insert_before_value(FledastyDynamicArray *c size_t byte_index = 0; size_t byte_size = current_dynamic_array->size * current_dynamic_array->element_byte_size; - while (byte_index < byte_size && !hallocy_compare_memory(current_dynamic_array->buffer + byte_index, before_value, current_dynamic_array->element_byte_size)) { + while (byte_index < byte_size) { + if (hallocy_compare_memory(current_dynamic_array->buffer + byte_index, before_value, current_dynamic_array->element_byte_size)) { + if (current_dynamic_array->size == current_dynamic_array->capacity) { + current_dynamic_array->capacity += current_dynamic_array->capacity; + current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); + + if (current_dynamic_array->buffer == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + } + + hallocy_move_memory(current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), current_dynamic_array->buffer + byte_index, byte_size - byte_index); + hallocy_copy_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size); + current_dynamic_array->size += 1; + + return FLEDASTY_ERROR_NONE; + } + byte_index += current_dynamic_array->element_byte_size; } - if (byte_index == byte_size) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - if (current_dynamic_array->size == current_dynamic_array->capacity) { - current_dynamic_array->capacity += current_dynamic_array->capacity; - current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - - if (current_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - hallocy_move_memory(current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), current_dynamic_array->buffer + byte_index, byte_size - byte_index); - hallocy_copy_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size); - current_dynamic_array->size += 1; - - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } FledastyError fledasty_dynamic_array_insert_after_value(FledastyDynamicArray *current_dynamic_array, void *after_value, void *value) { @@ -154,29 +153,29 @@ FledastyError fledasty_dynamic_array_insert_after_value(FledastyDynamicArray *cu size_t byte_index = 0; size_t byte_size = current_dynamic_array->size * current_dynamic_array->element_byte_size; - while (byte_index < byte_size && !hallocy_compare_memory(current_dynamic_array->buffer + byte_index, after_value, current_dynamic_array->element_byte_size)) { + while (byte_index < byte_size) { + if (hallocy_compare_memory(current_dynamic_array->buffer + byte_index, after_value, current_dynamic_array->element_byte_size)) { + if (current_dynamic_array->size == current_dynamic_array->capacity) { + current_dynamic_array->capacity += current_dynamic_array->capacity; + current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); + + if (current_dynamic_array->buffer == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + } + + byte_index += current_dynamic_array->element_byte_size; + hallocy_move_memory(current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), current_dynamic_array->buffer + byte_index, byte_size - byte_index); + hallocy_copy_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size); + current_dynamic_array->size += 1; + + return FLEDASTY_ERROR_NONE; + } + byte_index += current_dynamic_array->element_byte_size; } - if (byte_index == byte_size) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - if (current_dynamic_array->size == current_dynamic_array->capacity) { - current_dynamic_array->capacity += current_dynamic_array->capacity; - current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - - if (current_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - byte_index += current_dynamic_array->element_byte_size; - hallocy_move_memory(current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), current_dynamic_array->buffer + byte_index, byte_size - byte_index); - hallocy_copy_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size); - current_dynamic_array->size += 1; - - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } void *fledasty_dynamic_array_get(const FledastyDynamicArray *current_dynamic_array, const size_t index) { @@ -210,18 +209,18 @@ FledastyError fledasty_dynamic_array_remove_value(FledastyDynamicArray *current_ size_t byte_index = 0; size_t byte_size = current_dynamic_array->size * current_dynamic_array->element_byte_size; - while (byte_index < byte_size && !hallocy_compare_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size)) { + while (byte_index < byte_size) { + if (hallocy_compare_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size)) { + hallocy_copy_memory(current_dynamic_array->buffer + byte_index, current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), byte_size - (byte_index + current_dynamic_array->element_byte_size)); + current_dynamic_array->size -= 1; + + return FLEDASTY_ERROR_NONE; + } + byte_index += current_dynamic_array->element_byte_size; } - if (byte_index == byte_size) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - hallocy_copy_memory(current_dynamic_array->buffer + byte_index, current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), byte_size - (byte_index + current_dynamic_array->element_byte_size)); - current_dynamic_array->size -= 1; - - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } FledastyError fledasty_dynamic_array_clear(FledastyDynamicArray *current_dynamic_array) { -- 2.39.5 From 892388c2183faaa145caa5bde64921f57fd2dfeb Mon Sep 17 00:00:00 2001 From: Mineplay Date: Fri, 23 May 2025 17:35:50 -0500 Subject: [PATCH 16/33] refactor(hash table): added const to some function parameters --- Include/Fledasty/Core/HashTable.h | 4 ++-- Src/Core/HashTable.c | 2 +- Tests/Main.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Include/Fledasty/Core/HashTable.h b/Include/Fledasty/Core/HashTable.h index e1d0b30..ab26d1e 100644 --- a/Include/Fledasty/Core/HashTable.h +++ b/Include/Fledasty/Core/HashTable.h @@ -40,10 +40,10 @@ typedef struct { size_t key_byte_size, value_byte_size; FledastyDynamicArray *Table; - size_t (*hash_function)(void *key); + size_t (*hash_function)(const void *key); } FledastyHashTable; -FledastyError fledasty_hash_table_initialize(FledastyHashTable *new_hash_table, size_t key_byte_size, size_t value_byte_size, size_t (*hash_function)(void *key)); +FledastyError fledasty_hash_table_initialize(FledastyHashTable *new_hash_table, const size_t key_byte_size, const size_t value_byte_size, size_t (*hash_function)(const void *key)); FledastyError fledasty_hash_table_destroy(FledastyHashTable *current_hash_table); FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, void *key, void *value); diff --git a/Src/Core/HashTable.c b/Src/Core/HashTable.c index 8e92a31..aacf83a 100644 --- a/Src/Core/HashTable.c +++ b/Src/Core/HashTable.c @@ -28,7 +28,7 @@ static const int FLEDASTY_HASH_TABLE_SIZE_THRESHOLD = 75; -FledastyError fledasty_hash_table_initialize(FledastyHashTable *new_hash_table, size_t key_byte_size, size_t value_byte_size, size_t (*hash_function)(void *key)) { +FledastyError fledasty_hash_table_initialize(FledastyHashTable *new_hash_table, const size_t key_byte_size, const size_t value_byte_size, size_t (*hash_function)(const void *key)) { if (new_hash_table == NULL || hash_function == NULL) { return FLEDASTY_ERROR_INVALID_POINTER; } diff --git a/Tests/Main.c b/Tests/Main.c index fba8285..4ce0f77 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -29,7 +29,7 @@ #include #include -static inline size_t integer_hash_function(void *key) { return *(size_t*)key; } +static inline size_t integer_hash_function(const void *key) { return *(size_t*)key; } int main() { FledastyQueue test_queue; -- 2.39.5 From fc5f731397371d4cd08d3db4ddc89566690be5bd Mon Sep 17 00:00:00 2001 From: Mineplay Date: Fri, 23 May 2025 17:42:37 -0500 Subject: [PATCH 17/33] refactor(hash table): improved error checks --- Src/Core/HashTable.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/Src/Core/HashTable.c b/Src/Core/HashTable.c index aacf83a..57894a6 100644 --- a/Src/Core/HashTable.c +++ b/Src/Core/HashTable.c @@ -53,11 +53,13 @@ FledastyError fledasty_hash_table_destroy(FledastyHashTable *current_hash_table) } for (size_t i = 0; i < current_hash_table->capacity; i += 1) { - fledasty_dynamic_array_destroy(¤t_hash_table->Table[i]); + FledastyError result = fledasty_dynamic_array_destroy(¤t_hash_table->Table[i]); + if (result != FLEDASTY_ERROR_NONE) { + return result; + } } - HallocyError result = hallocy_free(current_hash_table->Table); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(current_hash_table->Table) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -75,6 +77,9 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, FledastyDynamicArray *previous_table = current_hash_table->Table; current_hash_table->Table = (FledastyDynamicArray*)hallocy_realloc(current_hash_table->Table, current_hash_table->capacity * sizeof(FledastyDynamicArray)); + if (current_hash_table->Table == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } if (previous_table != current_hash_table->Table) { hallocy_set_memory(current_hash_table->Table + (current_hash_table->size - 2), 0, current_hash_table->capacity); @@ -83,11 +88,14 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; if (current_hash_table->Table[index].buffer == NULL) { - fledasty_dynamic_array_initialize(¤t_hash_table->Table[index], NULL, 0, sizeof(FledastyHashTablePair)); + FledastyError result = fledasty_dynamic_array_initialize(¤t_hash_table->Table[index], NULL, 0, sizeof(FledastyHashTablePair)); + if (result != FLEDASTY_ERROR_NONE) { + return result; + } } FledastyHashTablePair pair; - + pair.key = hallocy_malloc(current_hash_table->key_byte_size); if (pair.key == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; @@ -101,7 +109,6 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, } hallocy_copy_memory(pair.value, value, current_hash_table->value_byte_size); - fledasty_dynamic_array_append(¤t_hash_table->Table[index], &pair); return FLEDASTY_ERROR_NONE; @@ -144,13 +151,11 @@ FledastyError fledasty_hash_table_remove(FledastyHashTable *current_hash_table, while (list_index < current_hash_table->Table[index].size) { FledastyHashTablePair *value = (FledastyHashTablePair*)fledasty_dynamic_array_get(¤t_hash_table->Table[index], list_index); if (hallocy_compare_memory(value->key, key, current_hash_table->key_byte_size)) { - HallocyError result = hallocy_free(value->key); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(value->key) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - result = hallocy_free(value->value); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(value->value) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -172,12 +177,14 @@ FledastyError fledasty_hash_table_clear(FledastyHashTable *current_hash_table) { for (size_t index = 0; index < current_hash_table->capacity; index += 1) { if (current_hash_table->Table[index].buffer != NULL) { - fledasty_dynamic_array_destroy(¤t_hash_table->Table[index]); + FledastyError result = fledasty_dynamic_array_destroy(¤t_hash_table->Table[index]); + if (result != FLEDASTY_ERROR_NONE) { + return result; + } } } current_hash_table->size = 0; - return FLEDASTY_ERROR_NONE; } -- 2.39.5 From 0c34e6f63da673e78c1a207c50ca59ce245c5f65 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Sun, 25 May 2025 15:14:28 -0500 Subject: [PATCH 18/33] fix(hash table): fixed resizing of hash table by adding rehashing --- Src/Core/HashTable.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/Src/Core/HashTable.c b/Src/Core/HashTable.c index 57894a6..aefc69a 100644 --- a/Src/Core/HashTable.c +++ b/Src/Core/HashTable.c @@ -21,10 +21,12 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Core/HashTable.h" +#include "Fledasty/Core/DynamicArray.h" #include #include #include +#include static const int FLEDASTY_HASH_TABLE_SIZE_THRESHOLD = 75; @@ -73,17 +75,36 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, current_hash_table->size += 1; if (current_hash_table->size >= (current_hash_table->capacity * FLEDASTY_HASH_TABLE_SIZE_THRESHOLD) / 100) { + size_t old_capacity = current_hash_table->capacity; current_hash_table->capacity += current_hash_table->capacity; FledastyDynamicArray *previous_table = current_hash_table->Table; - current_hash_table->Table = (FledastyDynamicArray*)hallocy_realloc(current_hash_table->Table, current_hash_table->capacity * sizeof(FledastyDynamicArray)); + current_hash_table->Table = (FledastyDynamicArray*)hallocy_calloc(sizeof(FledastyDynamicArray), current_hash_table->capacity); if (current_hash_table->Table == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - if (previous_table != current_hash_table->Table) { - hallocy_set_memory(current_hash_table->Table + (current_hash_table->size - 2), 0, current_hash_table->capacity); + for (size_t index = 0; index < old_capacity; index += 1) { + if (previous_table[index].buffer != NULL) { + for (size_t list_index = 0; list_index < previous_table[index].size; list_index += 1) { + FledastyHashTablePair *pair = (FledastyHashTablePair*)fledasty_dynamic_array_get(previous_table + index, list_index); + + size_t key_index = current_hash_table->hash_function(pair->key) % current_hash_table->capacity; + if (current_hash_table->Table[key_index].buffer == NULL) { + FledastyError result = fledasty_dynamic_array_initialize(current_hash_table->Table + key_index, NULL, 0, sizeof(FledastyHashTablePair)); + if (result != FLEDASTY_ERROR_NONE) { + return result; + } + } + + fledasty_dynamic_array_append(current_hash_table->Table + key_index, pair); + } + + fledasty_dynamic_array_destroy(previous_table + index); + } } + + hallocy_free(previous_table); } size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; -- 2.39.5 From f86cd1ae39281b635970c75eced2ab28ce1ef388 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Tue, 27 May 2025 14:10:28 -0500 Subject: [PATCH 19/33] refactor(hash table): made small changes in insert function and added const to some variables --- Src/Core/HashTable.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/Src/Core/HashTable.c b/Src/Core/HashTable.c index aefc69a..19a5b5b 100644 --- a/Src/Core/HashTable.c +++ b/Src/Core/HashTable.c @@ -21,12 +21,10 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Core/HashTable.h" -#include "Fledasty/Core/DynamicArray.h" #include #include #include -#include static const int FLEDASTY_HASH_TABLE_SIZE_THRESHOLD = 75; @@ -75,21 +73,22 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, current_hash_table->size += 1; if (current_hash_table->size >= (current_hash_table->capacity * FLEDASTY_HASH_TABLE_SIZE_THRESHOLD) / 100) { - size_t old_capacity = current_hash_table->capacity; - current_hash_table->capacity += current_hash_table->capacity; - + const size_t old_capacity = current_hash_table->capacity; FledastyDynamicArray *previous_table = current_hash_table->Table; + + current_hash_table->capacity += current_hash_table->capacity; current_hash_table->Table = (FledastyDynamicArray*)hallocy_calloc(sizeof(FledastyDynamicArray), current_hash_table->capacity); if (current_hash_table->Table == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } for (size_t index = 0; index < old_capacity; index += 1) { - if (previous_table[index].buffer != NULL) { - for (size_t list_index = 0; list_index < previous_table[index].size; list_index += 1) { - FledastyHashTablePair *pair = (FledastyHashTablePair*)fledasty_dynamic_array_get(previous_table + index, list_index); + FledastyDynamicArray *current_dynamic_array = previous_table + index; + if (current_dynamic_array->buffer != NULL) { + for (size_t list_index = 0; list_index < current_dynamic_array->size; list_index += 1) { + FledastyHashTablePair *pair = (FledastyHashTablePair*)fledasty_dynamic_array_get(current_dynamic_array, list_index); - size_t key_index = current_hash_table->hash_function(pair->key) % current_hash_table->capacity; + const size_t key_index = current_hash_table->hash_function(pair->key) % current_hash_table->capacity; if (current_hash_table->Table[key_index].buffer == NULL) { FledastyError result = fledasty_dynamic_array_initialize(current_hash_table->Table + key_index, NULL, 0, sizeof(FledastyHashTablePair)); if (result != FLEDASTY_ERROR_NONE) { @@ -100,14 +99,14 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, fledasty_dynamic_array_append(current_hash_table->Table + key_index, pair); } - fledasty_dynamic_array_destroy(previous_table + index); + fledasty_dynamic_array_destroy(current_dynamic_array); } } hallocy_free(previous_table); } - size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; + const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; if (current_hash_table->Table[index].buffer == NULL) { FledastyError result = fledasty_dynamic_array_initialize(¤t_hash_table->Table[index], NULL, 0, sizeof(FledastyHashTablePair)); if (result != FLEDASTY_ERROR_NONE) { @@ -130,8 +129,8 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, } hallocy_copy_memory(pair.value, value, current_hash_table->value_byte_size); - fledasty_dynamic_array_append(¤t_hash_table->Table[index], &pair); + fledasty_dynamic_array_append(¤t_hash_table->Table[index], &pair); return FLEDASTY_ERROR_NONE; } @@ -140,14 +139,14 @@ void *fledasty_hash_table_get(const FledastyHashTable *current_hash_table, void return NULL; } - size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; + const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; if (current_hash_table->Table[index].buffer == NULL) { return NULL; } size_t list_index = 0; while (list_index < current_hash_table->Table[index].size) { - FledastyHashTablePair *value = (FledastyHashTablePair*)fledasty_dynamic_array_get(¤t_hash_table->Table[index], list_index); + const FledastyHashTablePair *value = (FledastyHashTablePair*)fledasty_dynamic_array_get(¤t_hash_table->Table[index], list_index); if (hallocy_compare_memory(value->key, key, current_hash_table->key_byte_size)) { return value->value; } @@ -163,7 +162,7 @@ FledastyError fledasty_hash_table_remove(FledastyHashTable *current_hash_table, return FLEDASTY_ERROR_INVALID_POINTER; } - size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; + const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; if (current_hash_table->Table[index].buffer == NULL) { return FLEDASTY_ERROR_KEY_NOT_FOUND; } @@ -214,14 +213,14 @@ bool fledasty_hash_table_has_key(const FledastyHashTable *current_hash_table, vo return false; } - size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; + const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; if (current_hash_table->Table[index].buffer == NULL) { return false; } size_t list_index = 0; while (list_index < current_hash_table->Table[index].size) { - FledastyHashTablePair *value = (FledastyHashTablePair*)fledasty_dynamic_array_get(¤t_hash_table->Table[index], list_index); + const FledastyHashTablePair *value = (FledastyHashTablePair*)fledasty_dynamic_array_get(¤t_hash_table->Table[index], list_index); if (hallocy_compare_memory(value->key, key, current_hash_table->key_byte_size)) { return true; } -- 2.39.5 From 40ebfe95cf041f9a1387ebd48d9a3770cc09d66f Mon Sep 17 00:00:00 2001 From: Mineplay Date: Wed, 28 May 2025 03:49:18 -0500 Subject: [PATCH 20/33] feat(hash table): implemented shrink to fit --- Include/Fledasty/Core/HashTable.h | 3 +- Src/Core/HashTable.c | 49 +++++++++++++++++++++++++++++-- Tests/Main.c | 4 ++- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/Include/Fledasty/Core/HashTable.h b/Include/Fledasty/Core/HashTable.h index ab26d1e..5c1ceaa 100644 --- a/Include/Fledasty/Core/HashTable.h +++ b/Include/Fledasty/Core/HashTable.h @@ -51,8 +51,9 @@ void *fledasty_hash_table_get(const FledastyHashTable *current_hash_table, void FledastyError fledasty_hash_table_remove(FledastyHashTable *current_hash_table, void *key); FledastyError fledasty_hash_table_clear(FledastyHashTable *current_hash_table); +FledastyError fledasty_hash_table_shrink_to_fit(FledastyHashTable *current_hash_table); bool fledasty_hash_table_has_key(const FledastyHashTable *current_hash_table, void *key); static inline bool fledasty_hash_table_is_empty(const FledastyHashTable *current_hash_table) { return current_hash_table == NULL || current_hash_table->size == 0; } -#endif \ No newline at end of file +#endif diff --git a/Src/Core/HashTable.c b/Src/Core/HashTable.c index 19a5b5b..d0e813b 100644 --- a/Src/Core/HashTable.c +++ b/Src/Core/HashTable.c @@ -71,7 +71,6 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, return FLEDASTY_ERROR_INVALID_POINTER; } - current_hash_table->size += 1; if (current_hash_table->size >= (current_hash_table->capacity * FLEDASTY_HASH_TABLE_SIZE_THRESHOLD) / 100) { const size_t old_capacity = current_hash_table->capacity; FledastyDynamicArray *previous_table = current_hash_table->Table; @@ -129,8 +128,9 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, } hallocy_copy_memory(pair.value, value, current_hash_table->value_byte_size); - fledasty_dynamic_array_append(¤t_hash_table->Table[index], &pair); + + current_hash_table->size += 1; return FLEDASTY_ERROR_NONE; } @@ -138,7 +138,7 @@ void *fledasty_hash_table_get(const FledastyHashTable *current_hash_table, void if (current_hash_table == NULL || key == NULL) { return NULL; } - + const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; if (current_hash_table->Table[index].buffer == NULL) { return NULL; @@ -208,6 +208,49 @@ FledastyError fledasty_hash_table_clear(FledastyHashTable *current_hash_table) { return FLEDASTY_ERROR_NONE; } +FledastyError fledasty_hash_table_shrink_to_fit(FledastyHashTable *current_hash_table) { + if (current_hash_table == NULL) { + return FLEDASTY_ERROR_INVALID_POINTER; + } + + const size_t old_capacity = current_hash_table->capacity; + FledastyDynamicArray *previous_table = current_hash_table->Table; + + current_hash_table->capacity = (current_hash_table->size * 100) / FLEDASTY_HASH_TABLE_SIZE_THRESHOLD; + if (current_hash_table->capacity == 0) { + current_hash_table->capacity = 1024; + } + + current_hash_table->Table = (FledastyDynamicArray*)hallocy_calloc(sizeof(FledastyDynamicArray), current_hash_table->capacity); + if (current_hash_table->Table == NULL) { + return FLEDASTY_ERROR_FAILED_ALLOCATION; + } + + for (size_t index = 0; index < old_capacity; index += 1) { + FledastyDynamicArray *current_dynamic_array = previous_table + index; + if (current_dynamic_array->buffer != NULL) { + for (size_t list_index = 0; list_index < current_dynamic_array->size; list_index += 1) { + FledastyHashTablePair *pair = (FledastyHashTablePair*)fledasty_dynamic_array_get(current_dynamic_array, list_index); + + const size_t key_index = current_hash_table->hash_function(pair->key) % current_hash_table->capacity; + if (current_hash_table->Table[key_index].buffer == NULL) { + FledastyError result = fledasty_dynamic_array_initialize(current_hash_table->Table + key_index, NULL, 0, sizeof(FledastyHashTablePair)); + if (result != FLEDASTY_ERROR_NONE) { + return result; + } + } + + fledasty_dynamic_array_append(current_hash_table->Table + key_index, pair); + } + + fledasty_dynamic_array_destroy(current_dynamic_array); + } + } + + hallocy_free(previous_table); + return FLEDASTY_ERROR_NONE; +} + bool fledasty_hash_table_has_key(const FledastyHashTable *current_hash_table, void *key) { if (current_hash_table == NULL || key == NULL) { return false; diff --git a/Tests/Main.c b/Tests/Main.c index 4ce0f77..fab8be1 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -29,7 +29,7 @@ #include #include -static inline size_t integer_hash_function(const void *key) { return *(size_t*)key; } +static inline size_t integer_hash_function(const void *key) { return *(int*)key; } int main() { FledastyQueue test_queue; @@ -207,6 +207,8 @@ int main() { fledasty_hash_table_insert(&test_hash_table, &pow_value, &i); } + fledasty_hash_table_shrink_to_fit(&test_hash_table); + int hash_table_value = 5; int hash_table_remove = 2; fledasty_hash_table_insert(&test_hash_table, &hash_table_remove, &hash_table_value); -- 2.39.5 From c36696255d350fe4f24c404f18bbe24b0e156103 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Wed, 28 May 2025 03:54:30 -0500 Subject: [PATCH 21/33] perf(hash table): made shrink to fit skip capacity calculation if size is 0 --- Src/Core/HashTable.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Src/Core/HashTable.c b/Src/Core/HashTable.c index d0e813b..b801bc4 100644 --- a/Src/Core/HashTable.c +++ b/Src/Core/HashTable.c @@ -216,9 +216,10 @@ FledastyError fledasty_hash_table_shrink_to_fit(FledastyHashTable *current_hash_ const size_t old_capacity = current_hash_table->capacity; FledastyDynamicArray *previous_table = current_hash_table->Table; - current_hash_table->capacity = (current_hash_table->size * 100) / FLEDASTY_HASH_TABLE_SIZE_THRESHOLD; - if (current_hash_table->capacity == 0) { + if (current_hash_table->size == 0) { current_hash_table->capacity = 1024; + } else { + current_hash_table->capacity = (current_hash_table->size * 100) / FLEDASTY_HASH_TABLE_SIZE_THRESHOLD; } current_hash_table->Table = (FledastyDynamicArray*)hallocy_calloc(sizeof(FledastyDynamicArray), current_hash_table->capacity); -- 2.39.5 From ebafa37fad1ecc35549feced420b7cd8cfa46529 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Fri, 6 Jun 2025 10:50:56 -0500 Subject: [PATCH 22/33] refactor(utf-8 string): improved insert and removed loops and fixed size variable being one character to big --- Include/Fledasty/Strings/UTF8String.h | 2 +- Include/Fledasty/Utils/Error.h | 2 +- Src/Strings/UTF8String.c | 124 ++++++++++++++------------ Tests/Main.c | 6 +- 4 files changed, 71 insertions(+), 63 deletions(-) diff --git a/Include/Fledasty/Strings/UTF8String.h b/Include/Fledasty/Strings/UTF8String.h index a75699d..291953f 100644 --- a/Include/Fledasty/Strings/UTF8String.h +++ b/Include/Fledasty/Strings/UTF8String.h @@ -56,4 +56,4 @@ FledastyUtf8String fledasty_utf8_string_encode(const uint32_t *unicode, const si uint32_t *fledasty_utf8_string_decode(const FledastyUtf8String *current_string, size_t *unicode_string_size); bool fledasty_utf8_string_validate(unsigned char *character_string, const size_t character_string_size); -size_t fledasty_utf8_string_get_size(const unsigned char *character_string); \ No newline at end of file +size_t fledasty_utf8_string_get_size(const unsigned char *character_string); diff --git a/Include/Fledasty/Utils/Error.h b/Include/Fledasty/Utils/Error.h index e9841fd..ce48894 100644 --- a/Include/Fledasty/Utils/Error.h +++ b/Include/Fledasty/Utils/Error.h @@ -33,4 +33,4 @@ typedef enum { FLEDASTY_ERROR_INVALID_VALUE = 6, } FledastyError; -#endif \ No newline at end of file +#endif diff --git a/Src/Strings/UTF8String.c b/Src/Strings/UTF8String.c index 3d18f49..c4a86d2 100644 --- a/Src/Strings/UTF8String.c +++ b/Src/Strings/UTF8String.c @@ -60,8 +60,7 @@ FledastyError fledasty_utf8_string_destroy(FledastyUtf8String *current_string) { return FLEDASTY_ERROR_INVALID_POINTER; } - HallocyError result = hallocy_free(current_string->character_string); - if (result != HALLOCY_ERROR_NONE) { + if (hallocy_free(current_string->character_string) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -79,11 +78,11 @@ FledastyError fledasty_utf8_string_append(FledastyUtf8String *current_string, un } if (current_string->capacity <= current_string->size + character_string_size) { - current_string->capacity += (current_string->capacity > character_string_size) ? current_string->capacity : character_string_size; + current_string->capacity += (current_string->capacity > character_string_size) ? current_string->capacity : character_string_size + 1; current_string->character_string = (unsigned char*)hallocy_realloc(current_string->character_string, current_string->capacity * sizeof(unsigned char)); } - hallocy_copy_memory(current_string->character_string + (current_string->size - 1), character_string, character_string_size); + hallocy_copy_memory(current_string->character_string + current_string->size, character_string, character_string_size); current_string->size += character_string_size; current_string->character_string[current_string->size] = '\0'; @@ -96,7 +95,7 @@ FledastyError fledasty_utf8_string_insert_at_index(FledastyUtf8String *current_s return FLEDASTY_ERROR_INVALID_POINTER; } - if (index >= current_string->size) { + if (index > current_string->size) { return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; } @@ -113,6 +112,7 @@ FledastyError fledasty_utf8_string_insert_at_index(FledastyUtf8String *current_s hallocy_copy_memory(current_string->character_string + index, character_string, character_string_size); current_string->size += character_string_size; + current_string->character_string[current_string->size] = '\0'; return FLEDASTY_ERROR_NONE; } @@ -127,23 +127,23 @@ FledastyError fledasty_utf8_string_insert_before_string(FledastyUtf8String *curr size_t index = 0; while (index < (current_string->size - before_character_string_size) && !hallocy_compare_memory(current_string->character_string + index, before_character_string, before_character_string_size)) { + if (hallocy_compare_memory(current_string->character_string + index, before_character_string, before_character_string_size)) { + if (current_string->capacity <= current_string->size + character_string_size) { + current_string->capacity += (current_string->capacity > character_string_size) ? current_string->capacity : character_string_size + 1; + current_string->character_string = (unsigned char*)hallocy_realloc(current_string->character_string, current_string->capacity * sizeof(unsigned char)); + } + + hallocy_move_memory(current_string->character_string + (index + character_string_size), current_string->character_string + index, current_string->size - index); + hallocy_copy_memory(current_string->character_string + index, character_string, character_string_size); + + current_string->size += character_string_size; + return FLEDASTY_ERROR_NONE; + } + index += 1; } - if (index == current_string->size - before_character_string_size) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - if (current_string->capacity <= current_string->size + character_string_size) { - current_string->capacity += (current_string->capacity > character_string_size) ? current_string->capacity : character_string_size; - current_string->character_string = (unsigned char*)hallocy_realloc(current_string->character_string, current_string->capacity * sizeof(unsigned char)); - } - - hallocy_move_memory(current_string->character_string + (index + character_string_size), current_string->character_string + index, current_string->size - index); - hallocy_copy_memory(current_string->character_string + index, character_string, character_string_size); - - current_string->size += character_string_size; - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } FledastyError fledasty_utf8_string_insert_after_string(FledastyUtf8String *current_string, unsigned char *after_character_string, const size_t after_character_string_size, unsigned char *character_string, const size_t character_string_size) { @@ -156,25 +156,25 @@ FledastyError fledasty_utf8_string_insert_after_string(FledastyUtf8String *curre } size_t index = 0; - while (index < (current_string->size - after_character_string_size) && !hallocy_compare_memory(current_string->character_string + index, after_character_string, after_character_string_size)) { + while (index < (current_string->size - after_character_string_size)) { + if (hallocy_compare_memory(current_string->character_string + index, after_character_string, after_character_string_size)) { + if (current_string->capacity <= current_string->size + character_string_size) { + current_string->capacity += (current_string->capacity > character_string_size) ? current_string->capacity : character_string_size + 1; + current_string->character_string = (unsigned char*)hallocy_realloc(current_string->character_string, current_string->capacity * sizeof(unsigned char)); + } + + index += after_character_string_size; + hallocy_move_memory(current_string->character_string + (index + character_string_size), current_string->character_string + index, current_string->size - index + 1); + hallocy_copy_memory(current_string->character_string + index, character_string, character_string_size); + + current_string->size += character_string_size; + return FLEDASTY_ERROR_NONE; + } + index += 1; } - if (index == current_string->size - after_character_string_size) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - if (current_string->capacity <= current_string->size + character_string_size) { - current_string->capacity += (current_string->capacity > character_string_size) ? current_string->capacity : character_string_size; - current_string->character_string = (unsigned char*)hallocy_realloc(current_string->character_string, current_string->capacity * sizeof(unsigned char)); - } - - index += after_character_string_size; - hallocy_move_memory(current_string->character_string + (index + character_string_size), current_string->character_string + index, current_string->size - index); - hallocy_copy_memory(current_string->character_string + index, character_string, character_string_size); - - current_string->size += character_string_size; - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } FledastyError fledasty_utf8_string_pop(FledastyUtf8String *current_string) { @@ -192,7 +192,7 @@ FledastyError fledasty_utf8_string_pop(FledastyUtf8String *current_string) { current_string->size -= 1; } - current_string->character_string[current_string->size - 1] = '\0'; + current_string->character_string[current_string->size] = '\0'; return FLEDASTY_ERROR_NONE; } @@ -207,18 +207,19 @@ FledastyError fledasty_utf8_string_remove(FledastyUtf8String *current_string, un } size_t index = 0; - while (index < (current_string->size - character_string_size) && !hallocy_compare_memory(current_string->character_string + index, character_string, character_string_size)) { + while (index < (current_string->size - character_string_size)) { + if (hallocy_compare_memory(current_string->character_string + index, character_string, character_string_size)) { + hallocy_move_memory(current_string->character_string + index, current_string->character_string + index + character_string_size, current_string->size - (index + character_string_size)); + + current_string->size -= character_string_size; + current_string->character_string[current_string->size] = '\0'; + return FLEDASTY_ERROR_NONE; + } + index += 1; } - if (index == current_string->size - character_string_size) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - hallocy_move_memory(current_string->character_string + index, current_string->character_string + index + character_string_size, current_string->size - (index + character_string_size)); - current_string->size -= character_string_size; - - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } FledastyError fledasty_utf8_string_remove_range(FledastyUtf8String *current_string, const size_t start_index, const size_t end_index) { @@ -226,13 +227,14 @@ FledastyError fledasty_utf8_string_remove_range(FledastyUtf8String *current_stri return FLEDASTY_ERROR_INVALID_POINTER; } - if (start_index > end_index || end_index > current_string->size) { + if (start_index >= end_index || end_index >= current_string->size) { return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; } hallocy_move_memory(current_string->character_string + start_index, current_string->character_string + end_index, current_string->size - end_index); - current_string->size -= end_index - start_index; + current_string->size -= end_index - start_index; + current_string->character_string[current_string->size] = '\0'; return FLEDASTY_ERROR_NONE; } @@ -257,19 +259,25 @@ FledastyError fledasty_utf8_string_replace_string(FledastyUtf8String *current_st } size_t index = 0; - while (index < current_string->size - replace_character_string_size && !hallocy_compare_memory(current_string->character_string + index, replace_character_string, replace_character_string_size)) { + while (index < current_string->size - replace_character_string_size) { + if (hallocy_compare_memory(current_string->character_string + index, replace_character_string, replace_character_string_size)) { + const size_t new_size = current_string->size + (character_string_size - replace_character_string_size); + if (current_string->capacity <= new_size) { + current_string->capacity += (current_string->capacity > character_string_size) ? current_string->capacity : character_string_size; + current_string->character_string = (unsigned char*)hallocy_realloc(current_string->character_string, current_string->capacity * sizeof(unsigned char)); + } + + hallocy_move_memory(current_string->character_string + index + character_string_size, current_string->character_string + index + replace_character_string_size, current_string->size - (index + replace_character_string_size)); + hallocy_copy_memory(current_string->character_string + index, character_string, character_string_size); + + current_string->size = new_size; + current_string->character_string[current_string->size] = '\0'; + return FLEDASTY_ERROR_NONE; + } index += 1; } - if (index == current_string->size - replace_character_string_size) { - return FLEDASTY_ERROR_VALUE_NOT_FOUND; - } - - hallocy_move_memory(current_string->character_string + index + character_string_size, current_string->character_string + index + replace_character_string_size, current_string->size - (index + replace_character_string_size)); - hallocy_copy_memory(current_string->character_string + index, character_string, character_string_size); - - current_string->size += character_string_size - replace_character_string_size; - return FLEDASTY_ERROR_NONE; + return FLEDASTY_ERROR_VALUE_NOT_FOUND; } bool fledasty_utf8_string_has_string(const FledastyUtf8String *current_string, unsigned char *character_string, const size_t character_string_size) { @@ -345,7 +353,7 @@ FledastyUtf8String fledasty_utf8_string_encode(const uint32_t *unicode, const si } utf8_string.size = string_index; - if (utf8_string.capacity <= utf8_string.size + 1) { + if (utf8_string.capacity <= utf8_string.size) { utf8_string.capacity += utf8_string.capacity; utf8_string.character_string = (unsigned char*)hallocy_realloc(utf8_string.character_string, utf8_string.capacity); } diff --git a/Tests/Main.c b/Tests/Main.c index fab8be1..9ea11ef 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -237,7 +237,7 @@ int main() { fledasty_hash_table_destroy(&test_hash_table); FledastyUtf8String test_utf8_string; unsigned char *test_string = (unsigned char*)"😀€Testing"; - fledasty_utf8_string_initialize(&test_utf8_string, test_string, 15); + fledasty_utf8_string_initialize(&test_utf8_string, test_string, 14); printf("%s\n", test_string); printf("%s\n", test_utf8_string.character_string); @@ -247,7 +247,7 @@ int main() { printf("Insert Before: %s\n", test_utf8_string.character_string); fledasty_utf8_string_insert_after_string(&test_utf8_string, (unsigned char*)"😀", 4, (unsigned char*)"Bye", 3); printf("Insert After: %s\n", test_utf8_string.character_string); - fledasty_utf8_string_insert_at_index(&test_utf8_string, test_utf8_string.size - 1, (unsigned char*)"index", 5); + fledasty_utf8_string_insert_at_index(&test_utf8_string, test_utf8_string.size, (unsigned char*)"index", 5); printf("Insert at Index: %s\n", test_utf8_string.character_string); fledasty_utf8_string_replace_string(&test_utf8_string, (unsigned char*)"😀", 4, (unsigned char*)"𓃶 ", 5); printf("Replace: %s\n", test_utf8_string.character_string); @@ -255,7 +255,7 @@ int main() { printf("Pop: %s\n", test_utf8_string.character_string); fledasty_utf8_string_remove(&test_utf8_string, (unsigned char*)"𓃶 ", 5); printf("Remove: %s\n", test_utf8_string.character_string); - fledasty_utf8_string_remove_range(&test_utf8_string, 0, 5); + fledasty_utf8_string_remove_range(&test_utf8_string, 0, 6); printf("Remove range: %s\n", test_utf8_string.character_string); if (fledasty_utf8_string_has_string(&test_utf8_string, (unsigned char*)"😀", 4)) { -- 2.39.5 From e1d5b72764d1618ae7c8bd8b16f085ebc6c955e5 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Sat, 7 Jun 2025 06:58:41 -0500 Subject: [PATCH 23/33] feat(utf-8 string): implemented shrink to fit for utf-8 string --- Include/Fledasty/Strings/UTF8String.h | 4 ++- Src/Strings/UTF8String.c | 39 +++++++++++++++++++-------- Tests/Main.c | 1 + 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/Include/Fledasty/Strings/UTF8String.h b/Include/Fledasty/Strings/UTF8String.h index 291953f..1d07d55 100644 --- a/Include/Fledasty/Strings/UTF8String.h +++ b/Include/Fledasty/Strings/UTF8String.h @@ -45,10 +45,12 @@ FledastyError fledasty_utf8_string_insert_after_string(FledastyUtf8String *curre FledastyError fledasty_utf8_string_pop(FledastyUtf8String *current_string); FledastyError fledasty_utf8_string_remove(FledastyUtf8String *current_string, unsigned char *character_string, const size_t character_string_size); FledastyError fledasty_utf8_string_remove_range(FledastyUtf8String *current_string, const size_t start_index, const size_t end_index); -FledastyError fledasty_utf8_string_clear(FledastyUtf8String *current_string); FledastyError fledasty_utf8_string_replace_string(FledastyUtf8String *current_string, unsigned char *replace_character_string, const size_t replace_character_string_size, unsigned char *character_string, const size_t character_string_size); +FledastyError fledasty_utf8_string_clear(FledastyUtf8String *current_string); +FledastyError fledasty_utf8_string_shrink_to_fit(FledastyUtf8String *current_string); + bool fledasty_utf8_string_has_string(const FledastyUtf8String *current_string, unsigned char *character_string, const size_t character_string_size); static inline bool fledasty_utf8_string_is_empty(const FledastyUtf8String *current_string) { return current_string == NULL || current_string->size == 0; } diff --git a/Src/Strings/UTF8String.c b/Src/Strings/UTF8String.c index c4a86d2..5baa196 100644 --- a/Src/Strings/UTF8String.c +++ b/Src/Strings/UTF8String.c @@ -24,6 +24,7 @@ * ----------------------------------------------------------------------------- */ #include "../../Include/Fledasty/Strings/UTF8String.h" +#include "Fledasty/Utils/Error.h" #include #include @@ -238,17 +239,6 @@ FledastyError fledasty_utf8_string_remove_range(FledastyUtf8String *current_stri return FLEDASTY_ERROR_NONE; } -FledastyError fledasty_utf8_string_clear(FledastyUtf8String *current_string) { - if (current_string == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - current_string->size = 0; - current_string->character_string[0] = '\0'; - - return FLEDASTY_ERROR_NONE; -} - FledastyError fledasty_utf8_string_replace_string(FledastyUtf8String *current_string, unsigned char *replace_character_string, const size_t replace_character_string_size, unsigned char *character_string, const size_t character_string_size) { if (current_string == NULL || replace_character_string == NULL || replace_character_string_size == 0 || character_string == NULL || character_string_size == 0) { return FLEDASTY_ERROR_INVALID_POINTER; @@ -280,6 +270,33 @@ FledastyError fledasty_utf8_string_replace_string(FledastyUtf8String *current_st return FLEDASTY_ERROR_VALUE_NOT_FOUND; } +FledastyError fledasty_utf8_string_clear(FledastyUtf8String *current_string) { + if (current_string == NULL) { + return FLEDASTY_ERROR_INVALID_POINTER; + } + + current_string->size = 0; + current_string->character_string[0] = '\0'; + + return FLEDASTY_ERROR_NONE; +} + +FledastyError fledasty_utf8_string_shrink_to_fit(FledastyUtf8String *current_string) { + if (current_string == NULL) { + return FLEDASTY_ERROR_INVALID_POINTER; + } + + unsigned char *previous_string = current_string->character_string; + + current_string->capacity = current_string->size + 1; + current_string->character_string = (unsigned char*)hallocy_malloc(current_string->capacity); + hallocy_copy_memory(current_string->character_string, previous_string, current_string->size); + current_string->character_string[current_string->size] = '\0'; + + hallocy_free(previous_string); + return FLEDASTY_ERROR_NONE; +} + bool fledasty_utf8_string_has_string(const FledastyUtf8String *current_string, unsigned char *character_string, const size_t character_string_size) { if (current_string == NULL || character_string == NULL || character_string_size == 0) { return false; diff --git a/Tests/Main.c b/Tests/Main.c index 9ea11ef..b928c5a 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -258,6 +258,7 @@ int main() { fledasty_utf8_string_remove_range(&test_utf8_string, 0, 6); printf("Remove range: %s\n", test_utf8_string.character_string); + fledasty_utf8_string_shrink_to_fit(&test_utf8_string); if (fledasty_utf8_string_has_string(&test_utf8_string, (unsigned char*)"😀", 4)) { printf("String contains 😀!\n"); } -- 2.39.5 From ed8b677f333ae58902e70ef7295f77f065b7ba6b Mon Sep 17 00:00:00 2001 From: Mineplay Date: Sat, 14 Jun 2025 17:17:17 -0500 Subject: [PATCH 24/33] feat(algorithms): implemented murmur3 algorithm for x64 and x32 --- Include/Fledasty/Algorithms/Hashing.h | 36 +++++ Include/Fledasty/Strings/UTF8String.h | 5 + Src/Algorithms copy/Hashing.h | 0 Src/Algorithms/Hashing.c | 188 ++++++++++++++++++++++++++ Tests/Main.c | 7 + 5 files changed, 236 insertions(+) create mode 100644 Include/Fledasty/Algorithms/Hashing.h create mode 100644 Src/Algorithms copy/Hashing.h create mode 100644 Src/Algorithms/Hashing.c diff --git a/Include/Fledasty/Algorithms/Hashing.h b/Include/Fledasty/Algorithms/Hashing.h new file mode 100644 index 0000000..6ed5606 --- /dev/null +++ b/Include/Fledasty/Algorithms/Hashing.h @@ -0,0 +1,36 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * File: Hashing.h + * Description: + * This file contains the functions for hashing common datastructures and types + * for hash tables. + * + * Author: Mineplay + * ----------------------------------------------------------------------------- + */ +#ifndef FLEDASTY_HASHING +#define FLEDASTY_HASHING + +#include +#include + +typedef struct { + uint64_t low, high; +} FledastyHash128; + +uint32_t fledasty_mur_mur_3_hash_x32(const void *bytes, const size_t size, const uint32_t seed); +FledastyHash128 fledasty_mur_mur_3_hash_x64_128(const void *bytes, const size_t size, const uint32_t seed); + +#endif diff --git a/Include/Fledasty/Strings/UTF8String.h b/Include/Fledasty/Strings/UTF8String.h index 1d07d55..cf7915c 100644 --- a/Include/Fledasty/Strings/UTF8String.h +++ b/Include/Fledasty/Strings/UTF8String.h @@ -23,6 +23,9 @@ * Author: Mineplay * ----------------------------------------------------------------------------- */ +#ifndef FLEDASTY_UTF8_STRING +#define FLEDASTY_UTF8_STRING + #include #include #include @@ -59,3 +62,5 @@ uint32_t *fledasty_utf8_string_decode(const FledastyUtf8String *current_string, bool fledasty_utf8_string_validate(unsigned char *character_string, const size_t character_string_size); size_t fledasty_utf8_string_get_size(const unsigned char *character_string); + +#endif diff --git a/Src/Algorithms copy/Hashing.h b/Src/Algorithms copy/Hashing.h new file mode 100644 index 0000000..e69de29 diff --git a/Src/Algorithms/Hashing.c b/Src/Algorithms/Hashing.c new file mode 100644 index 0000000..4c9706a --- /dev/null +++ b/Src/Algorithms/Hashing.c @@ -0,0 +1,188 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ----------------------------------------------------------------------------- + * File: Hashing.c + * Description: + * This file contains the functions for hashing common datastructures and types + * for hash tables. + * + * Author: Mineplay + * ----------------------------------------------------------------------------- + */ +#include "../../Include/Fledasty/Algorithms/Hashing.h" + +#include +#include + +static inline uint32_t fledasty_rolt_32(const uint32_t key, const uint32_t rotation) { return (key << rotation) | (key >> (32 - rotation)); } +static inline uint64_t fledasty_rolt_64(uint64_t key, const uint64_t rotation) { return (key << rotation) | (key >> (64 - rotation)); } + +uint32_t fledasty_mur_mur_3_hash_x32(const void *bytes, const size_t size, const uint32_t seed) { + unsigned char *hashing_bytes = (unsigned char*)bytes; + + uint32_t hash = seed; + uint32_t key = 0; + for (size_t index = size >> 2; index; index -= 1) { + hallocy_copy_memory(&key, hashing_bytes, sizeof(uint32_t)); + hashing_bytes += sizeof(uint32_t); + + key *= 0xcc9e2d51; + key = fledasty_rolt_32(key, 15); + key *= 0x1b873593; + + hash ^= key; + hash = fledasty_rolt_32(hash, 13); + hash = (hash * 5) + 0xe6546b64; + } + + for (size_t index = size & 3; index; index -= 1) { + key = 0; + for (size_t i = (size & 3); i > 0; i -= 1) { + key ^= hashing_bytes[i] << (8 * (i & 3)); + } + + key *= 0xcc9e2d51; + key = fledasty_rolt_32(key, 13); + key *= 0x1b873593; + + hash ^= key; + } + + hash ^= size; + + hash ^= hash >> 16; + hash *= 0x85ebca6b; + hash ^= hash >> 13; + hash *= 0xc2b2ae35; + hash ^= hash >> 16; + + return hash; +} + +FledastyHash128 fledasty_mur_mur_3_hash_x64_128(const void *bytes, const size_t size, const uint32_t seed) { + unsigned char *hashing_bytes = (unsigned char *)bytes; + + FledastyHash128 hash = { .low = seed, .high = seed }; + + size_t low_key = 0; + size_t high_key = 0; + for (size_t index = size >> 4; index; index -= 1) { + hallocy_copy_memory(&low_key, hashing_bytes, sizeof(uint64_t)); + hashing_bytes += sizeof(uint64_t); + + low_key *= 0x87c37b91114253d5ULL; + low_key = fledasty_rolt_64(low_key, 31); + low_key *= 0x4cf5ad432745937fULL; + + hash.low ^= low_key; + hash.low = fledasty_rolt_64(hash.low, 27); + hash.low += hash.high; + hash.low = hash.low * 5 + 0x52dce729; + + hallocy_copy_memory(&high_key, hashing_bytes, sizeof(uint64_t)); + hashing_bytes += sizeof(uint64_t); + + high_key *= 0x4cf5ad432745937fULL; + high_key = fledasty_rolt_64(high_key, 33); + high_key *= 0x87c37b91114253d5ULL; + + hash.high ^= high_key; + hash.high = fledasty_rolt_64(hash.high, 31); + hash.high += hash.low; + hash.high = hash.high * 5 + 0x38495ab5; + } + + low_key = 0; + high_key = 0; + + switch(size & 15) { + case 15: + high_key ^= ((uint64_t)hashing_bytes[14]) << 48; + case 14: + high_key ^= ((uint64_t)hashing_bytes[13]) << 40; + case 13: + high_key ^= ((uint64_t)hashing_bytes[12]) << 32; + case 12: + high_key ^= ((uint64_t)hashing_bytes[11]) << 24; + case 11: + high_key ^= ((uint64_t)hashing_bytes[10]) << 16; + case 10: + high_key ^= ((uint64_t)hashing_bytes[9]) << 8; + case 9: + high_key ^= (uint64_t)hashing_bytes[8]; + case 8: + low_key ^= ((uint64_t)hashing_bytes[7]) << 56; + case 7: + low_key ^= ((uint64_t)hashing_bytes[6]) << 48; + case 6: + low_key ^= ((uint64_t)hashing_bytes[5]) << 40; + case 5: + low_key ^= ((uint64_t)hashing_bytes[4]) << 32; + case 4: + low_key ^= ((uint64_t)hashing_bytes[3]) << 24; + case 3: + low_key ^= ((uint64_t)hashing_bytes[2]) << 16; + case 2: + low_key ^= ((uint64_t)hashing_bytes[1]) << 8; + case 1: + low_key ^= ((uint64_t)hashing_bytes[0]); + } + + if (low_key != 0) { + low_key *= 0x87c37b91114253d5ULL; + low_key = fledasty_rolt_64(low_key, 31); + low_key *= 0x4cf5ad432745937fULL; + + hash.low ^= low_key; + } + + hash.low = fledasty_rolt_64(hash.low, 27); + hash.low += hash.high; + hash.low = hash.low * 5 + 0x52dce729; + + if (high_key != 0) { + high_key *= 0x4cf5ad432745937fULL; + high_key = fledasty_rolt_64(high_key, 33); + high_key *= 0x87c37b91114253d5ULL; + + hash.high ^= high_key; + } + + hash.high = fledasty_rolt_64(hash.high, 31); + hash.high += hash.low; + hash.high = hash.high * 5 + 0x38495ab5; + + hash.low ^= size; + hash.high ^= size; + + hash.low += hash.high; + hash.high += hash.low; + + hash.low ^= hash.low >> 33; + hash.low *= 0xff51afd7ed558ccdULL; + hash.low ^= hash.low >> 33; + hash.low *= 0xc4ceb9fe1a85ec53ULL; + hash.low ^= hash.low >> 33; + + hash.high ^= hash.high >> 33; + hash.high *= 0xff51afd7ed558ccdULL; + hash.high ^= hash.high >> 33; + hash.high *= 0xc4ceb9fe1a85ec53ULL; + hash.high ^= hash.high >> 33; + + hash.low += hash.high; + hash.high += hash.low; + + return hash; +} diff --git a/Tests/Main.c b/Tests/Main.c index b928c5a..43c0a75 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -28,6 +28,7 @@ #include #include #include +#include static inline size_t integer_hash_function(const void *key) { return *(int*)key; } @@ -263,6 +264,12 @@ int main() { printf("String contains 😀!\n"); } + uint32_t hash_x32 = fledasty_mur_mur_3_hash_x32(test_utf8_string.character_string, test_utf8_string.size, 0); + printf("UTF-8 String hash using murmur 32 is: %u\n", hash_x32); + + FledastyHash128 hash_x64 = fledasty_mur_mur_3_hash_x64_128(test_utf8_string.character_string, test_utf8_string.size, 0); + printf("UTF-8 String hash using murmur 64 is: low = %lu, high = %lu\n", hash_x64.low, hash_x64.high); + size_t unicode_length = 0; uint32_t *unicode = fledasty_utf8_string_decode(&test_utf8_string, &unicode_length); FledastyUtf8String encoded_string = fledasty_utf8_string_encode(unicode, unicode_length); -- 2.39.5 From 27fd969f0138c9bf6f191a7086bad06be58a2426 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Sat, 14 Jun 2025 17:19:25 -0500 Subject: [PATCH 25/33] fix(algorithms): removed duplicate files --- Src/Algorithms copy/Hashing.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Src/Algorithms copy/Hashing.h diff --git a/Src/Algorithms copy/Hashing.h b/Src/Algorithms copy/Hashing.h deleted file mode 100644 index e69de29..0000000 -- 2.39.5 From 5f4e0c1f2d5e96812f9697bbcd7a65543e219a9c Mon Sep 17 00:00:00 2001 From: Mineplay Date: Tue, 17 Jun 2025 14:46:06 -0500 Subject: [PATCH 26/33] perf(stack): changed stack to be defined using macros to improve performance --- Include/Fledasty/Core/Stack.h | 102 ++++++++++++++++++++++----- Src/Algorithms/Hashing.c | 1 - Src/Core/Stack.c | 127 ---------------------------------- Tests/Main.c | 24 +++---- 4 files changed, 94 insertions(+), 160 deletions(-) delete mode 100644 Src/Core/Stack.c diff --git a/Include/Fledasty/Core/Stack.h b/Include/Fledasty/Core/Stack.h index 3db1132..ef8a22e 100644 --- a/Include/Fledasty/Core/Stack.h +++ b/Include/Fledasty/Core/Stack.h @@ -25,26 +25,90 @@ #include #include +#include +#include +#include +#include -#include "../Utils/Error.h" +#define FLEDASTY_STACK_DEFINE(type) \ +typedef struct { \ + size_t size, capacity; \ + type *buffer; \ +} FledastyStack_##type; \ + \ +FledastyError fledasty_stack_##type##_free(FledastyStack_##type *current_stack); \ + \ +FledastyError fledasty_stack_##type##_push(FledastyStack_##type *current_stack, type value); \ + \ +FledastyError fledasty_stack_##type##_clear(FledastyStack_##type *current_stack); \ +FledastyError fledasty_stack_##type##_shrink_to_fit(FledastyStack_##type *current_stack); \ + \ +static inline type fledasty_stack_##type##_pop(FledastyStack_##type *current_stack) { return (current_stack != NULL && current_stack->size > 0) ? current_stack->buffer[--current_stack->size] : 0; } \ +static inline type fledasty_stack_##type##_peek(const FledastyStack_##type *current_stack) { return (current_stack != NULL && current_stack->size > 0) ? current_stack->buffer[current_stack->size - 1] : 0; } \ +static inline bool fledasty_stack_##type##_is_empty(const FledastyStack_##type *current_stack) { return current_stack == NULL || current_stack->size == 0; } -typedef struct { - size_t size, capacity; - - size_t element_byte_size; - unsigned char *buffer; -} FledastyStack; - -FledastyError fledasty_stack_initialize(FledastyStack *new_stack, void *values, const size_t values_size, const size_t element_byte_size); -FledastyError fledasty_stack_destroy(FledastyStack *current_stack); - -FledastyError fledasty_stack_push(FledastyStack *current_stack, void *value); -void *fledasty_stack_pop(FledastyStack *current_stack); - -FledastyError fledasty_stack_clear(FledastyStack *current_stack); -FledastyError fledasty_stack_shrink_to_fit(FledastyStack *current_stack); - -static inline void *fledasty_stack_peek(const FledastyStack *current_stack) { return (current_stack == NULL) ? NULL : current_stack->buffer + ((current_stack->size - 1) * current_stack->element_byte_size); } -static inline bool fledasty_stack_is_empty(const FledastyStack *current_stack) { return current_stack == NULL || current_stack->size == 0; } +#define FLEDASTY_STACK_IMPLEMENT(type) \ +FledastyError fledasty_stack_##type##_free(FledastyStack_##type *current_stack) { \ + if (current_stack == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (hallocy_free(current_stack->buffer) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_stack->size = 0; \ + current_stack->capacity = 0; \ + current_stack->buffer = NULL; \ + \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_stack_##type##_push(FledastyStack_##type *current_stack, type value) { \ + if (current_stack == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (current_stack->size == current_stack->capacity) { \ + current_stack->capacity += current_stack->capacity ? current_stack->capacity : 16; \ + current_stack->buffer = (type*)hallocy_realloc(current_stack->buffer, current_stack->capacity * sizeof(type)); \ + \ + if (current_stack->buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + current_stack->buffer[current_stack->size++] = value; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_stack_##type##_clear(FledastyStack_##type *current_stack) { \ + if (current_stack == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + current_stack->size = 0; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_stack_##type##_shrink_to_fit(FledastyStack_##type *current_stack) { \ + if (current_stack == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + current_stack->capacity = (current_stack->size == 0) ? 10 : current_stack->size; \ + type *shrinked_buffer = (type*)hallocy_malloc(current_stack->capacity * sizeof(type)); \ + if (shrinked_buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + hallocy_copy_memory(shrinked_buffer, current_stack->buffer, current_stack->size * sizeof(type)); \ + if (hallocy_free(current_stack->buffer) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_stack->buffer = shrinked_buffer; \ + return FLEDASTY_ERROR_NONE; \ +} #endif diff --git a/Src/Algorithms/Hashing.c b/Src/Algorithms/Hashing.c index 4c9706a..cce7c05 100644 --- a/Src/Algorithms/Hashing.c +++ b/Src/Algorithms/Hashing.c @@ -23,7 +23,6 @@ #include "../../Include/Fledasty/Algorithms/Hashing.h" #include -#include static inline uint32_t fledasty_rolt_32(const uint32_t key, const uint32_t rotation) { return (key << rotation) | (key >> (32 - rotation)); } static inline uint64_t fledasty_rolt_64(uint64_t key, const uint64_t rotation) { return (key << rotation) | (key >> (64 - rotation)); } diff --git a/Src/Core/Stack.c b/Src/Core/Stack.c deleted file mode 100644 index cde42a2..0000000 --- a/Src/Core/Stack.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ----------------------------------------------------------------------------- - * File: Stack.c - * Description: - * This file contains the functions for modifying the stack. It includes functions - * to Push, Pop, Peek and check if empty. - * - * Author: Mineplay - * ----------------------------------------------------------------------------- - */ -#include "../../Include/Fledasty/Core/Stack.h" - -#include -#include -#include - -FledastyError fledasty_stack_initialize(FledastyStack *new_stack, void *values, const size_t values_size, const size_t element_byte_size) { - if (new_stack == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - new_stack->element_byte_size = element_byte_size; - if (values == NULL || values_size == 0) { - new_stack->size = 0; - new_stack->capacity = 10; - - new_stack->buffer = (unsigned char*)hallocy_malloc(new_stack->capacity * element_byte_size); - if (new_stack->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } else { - new_stack->size = values_size; - new_stack->capacity = new_stack->size + new_stack->size; - - new_stack->buffer = (unsigned char*)hallocy_malloc(new_stack->capacity * element_byte_size); - if (new_stack->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_stack->buffer, values, values_size * element_byte_size); - } - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_stack_destroy(FledastyStack *current_stack) { - if (current_stack == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (hallocy_free(current_stack->buffer) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_stack->buffer = NULL; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_stack_push(FledastyStack *current_stack, void *value) { - if (current_stack == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (current_stack->size == current_stack->capacity) { - current_stack->capacity += current_stack->capacity; - current_stack->buffer = (unsigned char*)hallocy_realloc(current_stack->buffer, current_stack->capacity * current_stack->element_byte_size); - - if (current_stack->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - hallocy_copy_memory(current_stack->buffer + (current_stack->size * current_stack->element_byte_size), value, current_stack->element_byte_size); - current_stack->size += 1; - - return FLEDASTY_ERROR_NONE; -} - -void *fledasty_stack_pop(FledastyStack *current_stack) { - if (current_stack == NULL) { - return NULL; - } - - current_stack->size -= 1; - return current_stack->buffer + (current_stack->size * current_stack->element_byte_size); -} - -FledastyError fledasty_stack_clear(FledastyStack *current_stack) { - if (current_stack == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - current_stack->size = 0; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_stack_shrink_to_fit(FledastyStack *current_stack) { - if (current_stack == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - current_stack->capacity = (current_stack->size == 0) ? 10 : current_stack->size; - unsigned char *shrinked_buffer = (unsigned char*)hallocy_malloc(current_stack->capacity * current_stack->element_byte_size); - if (shrinked_buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(shrinked_buffer, current_stack->buffer, current_stack->size * current_stack->element_byte_size); - if (hallocy_free(current_stack->buffer) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_stack->buffer = shrinked_buffer; - return FLEDASTY_ERROR_NONE; -} diff --git a/Tests/Main.c b/Tests/Main.c index 43c0a75..31fd135 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -30,6 +30,9 @@ #include #include +FLEDASTY_STACK_DEFINE(int) +FLEDASTY_STACK_IMPLEMENT(int) + static inline size_t integer_hash_function(const void *key) { return *(int*)key; } int main() { @@ -59,30 +62,25 @@ int main() { fledasty_queue_destroy(&test_queue); - FledastyStack test_stack; - fledasty_stack_initialize(&test_stack, (int[]){ 11, 12, 13, 14, 15 }, 5, sizeof(int)); - + FledastyStack_int test_stack = { 0, 0, NULL }; for (int i = 0; i < 10; i += 1) { - fledasty_stack_push(&test_stack, &i); + fledasty_stack_int_push(&test_stack, i); } - fledasty_stack_shrink_to_fit(&test_stack); + fledasty_stack_int_shrink_to_fit(&test_stack); printf("Stack schrinked to fit %s\n", (test_stack.capacity == test_stack.size) ? "succeeded" : "failed"); - - int *peeked_stack_data = (int*)fledasty_stack_peek(&test_stack); - printf("Stack peeked: %d\n", *peeked_stack_data); + printf("Stack peeked: %d\n", fledasty_stack_int_peek(&test_stack)); for (int i = test_stack.size; i > 0; i -= 1) { - int *popped_data = (int*)fledasty_stack_pop(&test_stack); - printf("Stack popped: %d\n", *popped_data); + printf("Stack popped: %d\n", fledasty_stack_int_pop(&test_stack)); } - fledasty_stack_clear(&test_stack); - if (fledasty_stack_is_empty(&test_stack)) { + fledasty_stack_int_clear(&test_stack); + if (fledasty_stack_int_is_empty(&test_stack)) { printf("Stack is empty\n"); } - fledasty_stack_destroy(&test_stack); + fledasty_stack_int_free(&test_stack); FledastyDynamicArray test_dynamic_array; fledasty_dynamic_array_initialize(&test_dynamic_array, (int[]){11, 12, 13, 14, 15}, 5, sizeof(int)); -- 2.39.5 From 2bfd6ddb4c0a0c9d2e96792c3a1f67f4a6b45ab9 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Tue, 17 Jun 2025 15:20:05 -0500 Subject: [PATCH 27/33] perf(queue): changed queue to be defined using macros to improve performance --- Include/Fledasty/Core/Queue.h | 144 +++++++++++++++++++++++++---- Include/Fledasty/Core/Stack.h | 3 +- Src/Core/Queue.c | 165 ---------------------------------- Tests/Main.c | 26 +++--- 4 files changed, 140 insertions(+), 198 deletions(-) delete mode 100644 Src/Core/Queue.c diff --git a/Include/Fledasty/Core/Queue.h b/Include/Fledasty/Core/Queue.h index 21ba5fa..9f7aad0 100644 --- a/Include/Fledasty/Core/Queue.h +++ b/Include/Fledasty/Core/Queue.h @@ -25,27 +25,135 @@ #include #include +#include +#include +#include #include "../Utils/Error.h" -typedef struct { - size_t size, capacity; - size_t head, tail; +#define FLEDASTY_QUEUE_DEFINE(type) \ +typedef struct { \ + size_t size, capacity; \ + size_t head, tail; \ + type *buffer; \ +} FledastyQueue_##type; \ + \ +FledastyError fledasty_queue_##type##_free(FledastyQueue_##type *current_queue); \ + \ +FledastyError fledasty_queue_##type##_push(FledastyQueue_##type *current_queue, type value); \ +type fledasty_queue_##type##_pop(FledastyQueue_##type *current_queue); \ + \ +FledastyError fledasty_queue_##type##_clear(FledastyQueue_##type *current_queue); \ +FledastyError fledasty_queue_##type##_shrink_to_fit(FledastyQueue_##type *current_queue); \ + \ +static inline type fledasty_queue_##type##_peek(const FledastyQueue_##type *current_queue) { return (current_queue != NULL && current_queue->size > 0) ? current_queue->buffer[current_queue->size - 1] : 0; } \ +static inline bool fledasty_queue_##type##_is_empty(const FledastyQueue_##type *current_queue) { return current_queue == NULL || current_queue->size == 0; } - size_t element_byte_size; - unsigned char *buffer; -} FledastyQueue; - -FledastyError fledasty_queue_initialize(FledastyQueue *new_queue, void *values, const size_t values_size, const size_t element_byte_size); -FledastyError fledasty_queue_destroy(FledastyQueue *current_queue); - -FledastyError fledasty_queue_push(FledastyQueue *current_queue, void *value); -void *fledasty_queue_pop(FledastyQueue *current_queue); - -FledastyError fledasty_queue_clear(FledastyQueue *current_queue); -FledastyError fledasty_queue_shrink_to_fit(FledastyQueue *current_queue); - -static inline void *fledasty_queue_peek(const FledastyQueue *current_queue) { return (current_queue == NULL) ? NULL : current_queue->buffer + (current_queue->head * current_queue->element_byte_size); } -static inline bool fledasty_queue_is_empty(const FledastyQueue *current_queue) { return current_queue == NULL || current_queue->size == 0; } +#define FLEDASTY_QUEUE_IMPLEMENT(type) \ +FledastyError fledasty_queue_##type##_free(FledastyQueue_##type *current_queue) { \ + if (current_queue == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (hallocy_free(current_queue->buffer) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_queue->size = 0; \ + current_queue->capacity = 0; \ + current_queue->buffer = NULL; \ + \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_queue_##type##_push(FledastyQueue_##type *current_queue, type value) { \ + if (current_queue == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (current_queue->size == current_queue->capacity) { \ + current_queue->capacity += current_queue->capacity ? current_queue->capacity : 16; \ + current_queue->buffer = (type*)hallocy_realloc(current_queue->buffer, current_queue->capacity * sizeof(type)); \ + \ + if (current_queue->buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + if (current_queue->tail < current_queue->head) { \ + size_t head_size = current_queue->size - current_queue->tail; \ + \ + hallocy_move_memory(current_queue->buffer, current_queue->buffer + current_queue->head, head_size * sizeof(type)); \ + hallocy_move_memory(current_queue->buffer + head_size, current_queue->buffer, current_queue->tail * sizeof(type)); \ + } else { \ + hallocy_move_memory(current_queue->buffer, current_queue->buffer + current_queue->head, current_queue->size * sizeof(type)); \ + } \ + \ + current_queue->head = 0; \ + current_queue->tail = current_queue->size; \ + } \ + \ + current_queue->buffer[current_queue->tail++] = value; \ + if (current_queue->tail >= current_queue->capacity) { \ + current_queue->tail = 0; \ + } \ + \ + current_queue->size += 1; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +type fledasty_queue_##type##_pop(FledastyQueue_##type *current_queue) { \ + if (current_queue == NULL || current_queue->size == 0) { \ + return 0; \ + } \ + \ + current_queue->size -= 1; \ + current_queue->head += 1; \ + if (current_queue->head == current_queue->capacity) { \ + current_queue->head = 0; \ + } \ + \ + return current_queue->buffer[current_queue->head - 1]; \ +} \ + \ +FledastyError fledasty_queue_##type##_clear(FledastyQueue_##type *current_queue) { \ + if (current_queue == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + current_queue->size = 0; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_queue_##type##_shrink_to_fit(FledastyQueue_##type *current_queue) { \ + if (current_queue == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + size_t new_capacity = (current_queue->size == 0) ? 16 : current_queue->size; \ + type *shrinked_buffer = (type*)hallocy_malloc(new_capacity * sizeof(type)); \ + if (shrinked_buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + if (current_queue->tail < current_queue->head) { \ + size_t head_size = current_queue->size - current_queue->tail; \ + \ + hallocy_copy_memory(shrinked_buffer, current_queue->buffer + current_queue->head, head_size * sizeof(type)); \ + hallocy_copy_memory(shrinked_buffer + head_size, current_queue->buffer, current_queue->tail * sizeof(type)); \ + } else { \ + hallocy_copy_memory(shrinked_buffer, current_queue->buffer + current_queue->head, current_queue->size * sizeof(type)); \ + } \ + \ + if (hallocy_free(current_queue->buffer) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_queue->head = 0; \ + current_queue->tail = current_queue->size; \ + current_queue->capacity = new_capacity; \ + current_queue->buffer = shrinked_buffer; \ + \ + return FLEDASTY_ERROR_NONE; \ +} #endif diff --git a/Include/Fledasty/Core/Stack.h b/Include/Fledasty/Core/Stack.h index ef8a22e..70da942 100644 --- a/Include/Fledasty/Core/Stack.h +++ b/Include/Fledasty/Core/Stack.h @@ -28,7 +28,8 @@ #include #include #include -#include + +#include "../Utils/Error.h" #define FLEDASTY_STACK_DEFINE(type) \ typedef struct { \ diff --git a/Src/Core/Queue.c b/Src/Core/Queue.c deleted file mode 100644 index d3d05d7..0000000 --- a/Src/Core/Queue.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ----------------------------------------------------------------------------- - * File: Queue.c - * Description: - * This file contains the functions for modifying the queue. It includes functions - * to Push, Pop, Peek and check if empty. - * - * Author: Mineplay - * ----------------------------------------------------------------------------- - */ -#include "../../Include/Fledasty/Core/Queue.h" - -#include -#include -#include - -FledastyError fledasty_queue_initialize(FledastyQueue *new_queue, void *values, const size_t values_size, const size_t element_byte_size) { - if (new_queue == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - new_queue->head = 0; - new_queue->element_byte_size = element_byte_size; - if (values == NULL || values_size == 0) { - new_queue->size = 0; - new_queue->capacity = 10; - - new_queue->buffer = (unsigned char*)hallocy_malloc(new_queue->capacity * element_byte_size); - if (new_queue->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } else { - new_queue->size = values_size; - new_queue->capacity = new_queue->size + new_queue->size; - - new_queue->buffer = (unsigned char*)hallocy_malloc(new_queue->capacity * element_byte_size); - if (new_queue->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_queue->buffer, values, values_size * element_byte_size); - } - - new_queue->tail = new_queue->size; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_queue_destroy(FledastyQueue *current_queue) { - if (current_queue == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (hallocy_free(current_queue->buffer) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_queue->buffer = NULL; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_queue_push(FledastyQueue *current_queue, void *value) { - if (current_queue == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (current_queue->size == current_queue->capacity) { - current_queue->capacity += current_queue->capacity; - - current_queue->buffer = (unsigned char*)hallocy_realloc(current_queue->buffer, current_queue->capacity * current_queue->element_byte_size); - if (current_queue->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (current_queue->tail < current_queue->head) { - size_t head_size = (current_queue->size - current_queue->tail) * current_queue->element_byte_size; - - hallocy_move_memory(current_queue->buffer, current_queue->buffer + (current_queue->head * current_queue->element_byte_size), head_size); - hallocy_move_memory(current_queue->buffer + head_size, current_queue->buffer, current_queue->tail * current_queue->element_byte_size); - } else { - hallocy_move_memory(current_queue->buffer, current_queue->buffer + (current_queue->head * current_queue->element_byte_size), current_queue->size * current_queue->element_byte_size); - } - - current_queue->head = 0; - current_queue->tail = current_queue->size; - } - - hallocy_copy_memory(current_queue->buffer + (current_queue->tail * current_queue->element_byte_size), value, current_queue->element_byte_size); - - current_queue->size += 1; - current_queue->tail += 1; - if (current_queue->tail >= current_queue->capacity) { - current_queue->tail = 0; - } - - return FLEDASTY_ERROR_NONE; -} - -void *fledasty_queue_pop(FledastyQueue *current_queue) { - if (current_queue == NULL || current_queue->size == 0) { - return NULL; - } - - void *value_address = current_queue->buffer + (current_queue->head * current_queue->element_byte_size); - - current_queue->size -= 1; - current_queue->head += 1; - if (current_queue->head == current_queue->capacity) { - current_queue->head = 0; - } - - return value_address; -} - -FledastyError fledasty_queue_clear(FledastyQueue *current_queue) { - if (current_queue == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - current_queue->size = 0; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_queue_shrink_to_fit(FledastyQueue *current_queue) { - if (current_queue == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - size_t new_capacity = (current_queue->size == 0) ? 10 : current_queue->size; - unsigned char *shrinked_buffer = (unsigned char*)hallocy_malloc(new_capacity); - if (shrinked_buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (current_queue->tail < current_queue->head) { - size_t head_size = (current_queue->size - current_queue->tail) * current_queue->element_byte_size; - - hallocy_copy_memory(shrinked_buffer, current_queue->buffer + (current_queue->head * current_queue->element_byte_size), head_size); - hallocy_copy_memory(shrinked_buffer + head_size, current_queue->buffer, current_queue->tail * current_queue->element_byte_size); - } else { - hallocy_copy_memory(shrinked_buffer, current_queue->buffer + (current_queue->head * current_queue->element_byte_size), current_queue->size * current_queue->element_byte_size); - } - - if (hallocy_free(current_queue->buffer) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_queue->head = 0; - current_queue->tail = current_queue->size; - current_queue->capacity = new_capacity; - current_queue->buffer = shrinked_buffer; - - return FLEDASTY_ERROR_NONE; -} diff --git a/Tests/Main.c b/Tests/Main.c index 31fd135..0df15e9 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -33,34 +33,32 @@ FLEDASTY_STACK_DEFINE(int) FLEDASTY_STACK_IMPLEMENT(int) +FLEDASTY_QUEUE_DEFINE(int) +FLEDASTY_QUEUE_IMPLEMENT(int) + static inline size_t integer_hash_function(const void *key) { return *(int*)key; } int main() { - FledastyQueue test_queue; - fledasty_queue_initialize(&test_queue, (int[]){11, 12, 13, 14, 15}, 5, sizeof(int)); - + FledastyQueue_int test_queue = { 0, 0, 0, 0, NULL }; for (int i = 0; i < 10; i += 1) { - fledasty_queue_push(&test_queue, &i); + fledasty_queue_int_push(&test_queue, i); } - fledasty_queue_shrink_to_fit(&test_queue); + fledasty_queue_int_shrink_to_fit(&test_queue); printf("Queue schrinked to fit %s\n", (test_queue.capacity == test_queue.size) ? "succeeded" : "failed"); - int test = 0; - fledasty_queue_push(&test_queue, &test); - int *peeked_queue_data = (int*)fledasty_queue_peek(&test_queue); - printf("Queue peeked: %d\n", *peeked_queue_data); + fledasty_queue_int_push(&test_queue, 0); + printf("Queue peeked: %d\n", fledasty_queue_int_peek(&test_queue)); for (int i = test_queue.size; i > 0; i -= 1) { - int *popped_data = (int*)fledasty_queue_pop(&test_queue); - printf("Queue popped: %d\n", *popped_data); + printf("Queue popped: %d\n", fledasty_queue_int_pop(&test_queue)); } - fledasty_queue_clear(&test_queue); - if (fledasty_queue_is_empty(&test_queue)) { + fledasty_queue_int_clear(&test_queue); + if (fledasty_queue_int_is_empty(&test_queue)) { printf("Queue is empty\n"); } - fledasty_queue_destroy(&test_queue); + fledasty_queue_int_free(&test_queue); FledastyStack_int test_stack = { 0, 0, NULL }; for (int i = 0; i < 10; i += 1) { -- 2.39.5 From 25e7e915f4b32dd106bbf1ff90715c643d370630 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Fri, 20 Jun 2025 15:22:56 -0500 Subject: [PATCH 28/33] perf(dynamic array): changed dynamic array to be defined using macros to improve performance --- Include/Fledasty/Core/DynamicArray.h | 241 +++++++++++++++++++++--- Include/Fledasty/Core/HashTable.h | 6 +- Include/Fledasty/Core/Queue.h | 2 +- Src/Core/DynamicArray.c | 267 --------------------------- Src/Core/HashTable.c | 79 +++----- Tests/Main.c | 49 +++-- 6 files changed, 274 insertions(+), 370 deletions(-) delete mode 100644 Src/Core/DynamicArray.c diff --git a/Include/Fledasty/Core/DynamicArray.h b/Include/Fledasty/Core/DynamicArray.h index df7d978..544e4cb 100644 --- a/Include/Fledasty/Core/DynamicArray.h +++ b/Include/Fledasty/Core/DynamicArray.h @@ -26,34 +26,225 @@ #include #include +#include +#include +#include #include "../Utils/Error.h" -typedef struct { - size_t size, capacity; +#define FLEDASTY_DYNAMIC_ARRAY_DEFINE(type, name) \ +typedef struct { \ + size_t size, capacity; \ + type *buffer; \ +} FledastyDynamicArray_##name; \ + \ +FledastyError fledasty_dynamic_array_##name##_free(FledastyDynamicArray_##name *current_dynamic_array); \ + \ +FledastyError fledasty_dynamic_array_##name##_append(FledastyDynamicArray_##name *current_dynamic_array, type value); \ + \ +FledastyError fledasty_dynamic_array_##name##_insert_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index, type value); \ +FledastyError fledasty_dynamic_array_##name##_insert_before_value(FledastyDynamicArray_##name *current_dynamic_array, type before_value, type value); \ +FledastyError fledasty_dynamic_array_##name##_insert_after_value(FledastyDynamicArray_##name *current_dynamic_array, type after_value, type value); \ + \ +FledastyError fledasty_dynamic_array_##name##_remove_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index); \ +FledastyError fledasty_dynamic_array_##name##_remove_value(FledastyDynamicArray_##name *current_dynamic_array, type value); \ + \ +FledastyError fledasty_dynamic_array_##name##_clear(FledastyDynamicArray_##name *current_dynamic_array); \ +FledastyError fledasty_dynamic_array_##name##_shrink_to_fit(FledastyDynamicArray_##name *current_dynamic_array); \ + \ +bool fledasty_dynamic_array_##name##_has_value(const FledastyDynamicArray_##name *current_dynamic_array, type value); \ +inline static bool fledasty_dynamic_array_##name##_is_empty(const FledastyDynamicArray_##name *current_dynamic_array) { return current_dynamic_array == NULL || current_dynamic_array->size == 0; } - size_t element_byte_size; - unsigned char *buffer; -} FledastyDynamicArray; - -FledastyError fledasty_dynamic_array_initialize(FledastyDynamicArray *new_dynamic_array, void *values, const size_t values_size, const size_t element_byte_size); -FledastyError fledasty_dynamic_array_destroy(FledastyDynamicArray *current_dynamic_array); - -FledastyError fledasty_dynamic_array_append(FledastyDynamicArray *current_dynamic_array, void *value); - -FledastyError fledasty_dynamic_array_insert_at_index(FledastyDynamicArray *current_dynamic_array, const size_t index, void *value); -FledastyError fledasty_dynamic_array_insert_before_value(FledastyDynamicArray *current_dynamic_array, void *before_value, void *value); -FledastyError fledasty_dynamic_array_insert_after_value(FledastyDynamicArray *current_dynamic_array, void *after_value, void *value); - -void *fledasty_dynamic_array_get(const FledastyDynamicArray *current_dynamic_array, const size_t index); - -FledastyError fledasty_dynamic_array_remove_at_index(FledastyDynamicArray *current_dynamic_array, const size_t index); -FledastyError fledasty_dynamic_array_remove_value(FledastyDynamicArray *current_dynamic_array, void *value); - -FledastyError fledasty_dynamic_array_clear(FledastyDynamicArray *current_dynamic_array); -FledastyError fledasty_dynamic_array_shrink_to_fit(FledastyDynamicArray *current_dynamic_array); - -bool fledasty_dynamic_array_has_value(const FledastyDynamicArray *current_dynamic_array, void *value); -inline static bool fledasty_dynamic_array_is_empty(const FledastyDynamicArray *current_dynamic_array) { return current_dynamic_array == NULL || current_dynamic_array->size == 0; } +#define FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(type, name, compare_function) \ +FledastyError fledasty_dynamic_array_##name##_free(FledastyDynamicArray_##name *current_dynamic_array) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (hallocy_free(current_dynamic_array->buffer) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_dynamic_array->size = 0; \ + current_dynamic_array->capacity = 0; \ + current_dynamic_array->buffer = NULL; \ + \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_append(FledastyDynamicArray_##name *current_dynamic_array, type value) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (current_dynamic_array->size == current_dynamic_array->capacity) { \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ + \ + if (current_dynamic_array->buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + current_dynamic_array->buffer[current_dynamic_array->size++] = value; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_insert_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index, type value) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + if (index >= current_dynamic_array->size) { \ + return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; \ + } \ + \ + if (current_dynamic_array->size == current_dynamic_array->capacity) { \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ + \ + if (current_dynamic_array->buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + type *insert_pointer = current_dynamic_array->buffer + index; \ + hallocy_move_memory(insert_pointer + 1, insert_pointer, (current_dynamic_array->size - index) * sizeof(type)); \ + *insert_pointer = value; \ + \ + current_dynamic_array->size += 1; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_insert_before_value(FledastyDynamicArray_##name *current_dynamic_array, type before_value, type value) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + for (size_t index = 0; index < current_dynamic_array->size; index += 1) { \ + if (compare_function(current_dynamic_array->buffer[index], before_value)) { \ + if (current_dynamic_array->size == current_dynamic_array->capacity) { \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ + \ + if (current_dynamic_array->buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + type *insert_pointer = current_dynamic_array->buffer + index; \ + hallocy_move_memory(insert_pointer + 1, insert_pointer, (current_dynamic_array->size - index) * sizeof(type)); \ + *insert_pointer = value; \ + \ + current_dynamic_array->size += 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_insert_after_value(FledastyDynamicArray_##name *current_dynamic_array, type after_value, type value) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + for (size_t index = 0; index < current_dynamic_array->size; index += 1) { \ + if (compare_function(current_dynamic_array->buffer[index], after_value)) { \ + if (current_dynamic_array->size == current_dynamic_array->capacity) { \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ + \ + if (current_dynamic_array->buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + type *insert_pointer = current_dynamic_array->buffer + index + 1; \ + hallocy_move_memory(insert_pointer + 1, insert_pointer, (current_dynamic_array->size - index) * sizeof(type)); \ + *insert_pointer = value; \ + \ + current_dynamic_array->size += 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_remove_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (index >= current_dynamic_array->size) { \ + return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; \ + } \ + \ + type *remove_pointer = current_dynamic_array->buffer + index; \ + hallocy_copy_memory(remove_pointer, remove_pointer + 1, (current_dynamic_array->size - index + 1) * sizeof(type)); \ + current_dynamic_array->size -= 1; \ + \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_remove_value(FledastyDynamicArray_##name *current_dynamic_array, type value) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + for (size_t index = 0; index < current_dynamic_array->size; index += 1) { \ + if (compare_function(current_dynamic_array->buffer[index], value)) { \ + hallocy_copy_memory(current_dynamic_array->buffer + index, current_dynamic_array->buffer + index + 1, (current_dynamic_array->size - index) * sizeof(type)); \ + current_dynamic_array->size -= 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_clear(FledastyDynamicArray_##name *current_dynamic_array) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + current_dynamic_array->size = 0; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_dynamic_array_##name##_shrink_to_fit(FledastyDynamicArray_##name *current_dynamic_array) { \ + if (current_dynamic_array == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + current_dynamic_array->capacity = current_dynamic_array->size; \ + type *shrinked_buffer = (type*)hallocy_malloc(current_dynamic_array->capacity * sizeof(type)); \ + if (shrinked_buffer == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + hallocy_copy_memory(shrinked_buffer, current_dynamic_array->buffer, (current_dynamic_array->size - 1) * sizeof(type)); \ + if (hallocy_free(current_dynamic_array->buffer) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_dynamic_array->buffer = shrinked_buffer; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +bool fledasty_dynamic_array_##name##_has_value(const FledastyDynamicArray_##name *current_dynamic_array, type value) { \ + if (current_dynamic_array == NULL) { \ + return false; \ + } \ + \ + for (size_t index = 0; index < current_dynamic_array->size; index += 1) { \ + if (compare_function(current_dynamic_array->buffer[index], value)) { \ + return true; \ + } \ + } \ + \ + return false; \ +} #endif diff --git a/Include/Fledasty/Core/HashTable.h b/Include/Fledasty/Core/HashTable.h index 5c1ceaa..e7e99d1 100644 --- a/Include/Fledasty/Core/HashTable.h +++ b/Include/Fledasty/Core/HashTable.h @@ -29,16 +29,19 @@ #include "../Utils/Error.h" #include "DynamicArray.h" +#include "Hallocy/Core/Memory.h" typedef struct { void *key, *value; } FledastyHashTablePair; +FLEDASTY_DYNAMIC_ARRAY_DEFINE(FledastyHashTablePair, pair) + typedef struct { size_t size, capacity; size_t key_byte_size, value_byte_size; - FledastyDynamicArray *Table; + FledastyDynamicArray_pair *Table; size_t (*hash_function)(const void *key); } FledastyHashTable; @@ -55,5 +58,6 @@ FledastyError fledasty_hash_table_shrink_to_fit(FledastyHashTable *current_hash_ bool fledasty_hash_table_has_key(const FledastyHashTable *current_hash_table, void *key); static inline bool fledasty_hash_table_is_empty(const FledastyHashTable *current_hash_table) { return current_hash_table == NULL || current_hash_table->size == 0; } +static inline bool fledasty_hash_table_compare_pair(const FledastyHashTablePair first_pair, const FledastyHashTablePair second_pair) { return first_pair.key == second_pair.key && first_pair.value == second_pair.value; } #endif diff --git a/Include/Fledasty/Core/Queue.h b/Include/Fledasty/Core/Queue.h index 9f7aad0..b2752d4 100644 --- a/Include/Fledasty/Core/Queue.h +++ b/Include/Fledasty/Core/Queue.h @@ -103,7 +103,7 @@ FledastyError fledasty_queue_##type##_push(FledastyQueue_##type *current_queue, \ type fledasty_queue_##type##_pop(FledastyQueue_##type *current_queue) { \ if (current_queue == NULL || current_queue->size == 0) { \ - return 0; \ + return 0; \ } \ \ current_queue->size -= 1; \ diff --git a/Src/Core/DynamicArray.c b/Src/Core/DynamicArray.c deleted file mode 100644 index bce2953..0000000 --- a/Src/Core/DynamicArray.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ----------------------------------------------------------------------------- - * File: DynamicArray.c - * Description: - * This file contains the functions for modifying the Dynamic Array. It includes - * functions to append, Insert before, Insert after, Insert at index, - * Get, Remove element, Remove at index, Check if has element and Check if is empty. - * - * Author: Mineplay - * ----------------------------------------------------------------------------- - */ -#include "../../Include/Fledasty/Core/DynamicArray.h" - -#include -#include -#include - -FledastyError fledasty_dynamic_array_initialize(FledastyDynamicArray *new_dynamic_array, void *values, const size_t values_size, const size_t element_byte_size) { - if (new_dynamic_array == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - new_dynamic_array->element_byte_size = element_byte_size; - if (values == NULL || values_size == 0) { - new_dynamic_array->size = 0; - new_dynamic_array->capacity = 10; - - new_dynamic_array->buffer = (unsigned char*)hallocy_malloc(new_dynamic_array->capacity * element_byte_size); - if (new_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } else { - new_dynamic_array->size = values_size; - new_dynamic_array->capacity = new_dynamic_array->size + new_dynamic_array->size; - - new_dynamic_array->buffer = (unsigned char*)hallocy_malloc(new_dynamic_array->capacity * element_byte_size); - if (new_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_dynamic_array->buffer, values, values_size * element_byte_size); - } - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_destroy(FledastyDynamicArray *current_dynamic_array) { - if (current_dynamic_array == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (hallocy_free(current_dynamic_array->buffer) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_dynamic_array->buffer = NULL; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_append(FledastyDynamicArray *current_dynamic_array, void *value) { - if (current_dynamic_array == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (current_dynamic_array->size == current_dynamic_array->capacity) { - current_dynamic_array->capacity += current_dynamic_array->capacity; - current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - - if (current_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - hallocy_copy_memory(current_dynamic_array->buffer + (current_dynamic_array->size * current_dynamic_array->element_byte_size), value, current_dynamic_array->element_byte_size); - current_dynamic_array->size += 1; - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_insert_at_index(FledastyDynamicArray *current_dynamic_array, const size_t index, void *value) { - if (current_dynamic_array == NULL || value == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (index >= current_dynamic_array->size) { - return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; - } - - if (current_dynamic_array->size == current_dynamic_array->capacity) { - current_dynamic_array->capacity += current_dynamic_array->capacity; - current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - - if (current_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - unsigned char *insert_pointer = current_dynamic_array->buffer + (index * current_dynamic_array->element_byte_size); - hallocy_move_memory(insert_pointer + current_dynamic_array->element_byte_size, insert_pointer, (current_dynamic_array->size - index) * current_dynamic_array->element_byte_size); - hallocy_copy_memory(insert_pointer, value, current_dynamic_array->element_byte_size); - current_dynamic_array->size += 1; - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_insert_before_value(FledastyDynamicArray *current_dynamic_array, void *before_value, void *value) { - if (current_dynamic_array == NULL || before_value == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - size_t byte_index = 0; - size_t byte_size = current_dynamic_array->size * current_dynamic_array->element_byte_size; - while (byte_index < byte_size) { - if (hallocy_compare_memory(current_dynamic_array->buffer + byte_index, before_value, current_dynamic_array->element_byte_size)) { - if (current_dynamic_array->size == current_dynamic_array->capacity) { - current_dynamic_array->capacity += current_dynamic_array->capacity; - current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - - if (current_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - hallocy_move_memory(current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), current_dynamic_array->buffer + byte_index, byte_size - byte_index); - hallocy_copy_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size); - current_dynamic_array->size += 1; - - return FLEDASTY_ERROR_NONE; - } - - byte_index += current_dynamic_array->element_byte_size; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -FledastyError fledasty_dynamic_array_insert_after_value(FledastyDynamicArray *current_dynamic_array, void *after_value, void *value) { - if (current_dynamic_array == NULL || after_value == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - size_t byte_index = 0; - size_t byte_size = current_dynamic_array->size * current_dynamic_array->element_byte_size; - while (byte_index < byte_size) { - if (hallocy_compare_memory(current_dynamic_array->buffer + byte_index, after_value, current_dynamic_array->element_byte_size)) { - if (current_dynamic_array->size == current_dynamic_array->capacity) { - current_dynamic_array->capacity += current_dynamic_array->capacity; - current_dynamic_array->buffer = (unsigned char*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - - if (current_dynamic_array->buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - byte_index += current_dynamic_array->element_byte_size; - hallocy_move_memory(current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), current_dynamic_array->buffer + byte_index, byte_size - byte_index); - hallocy_copy_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size); - current_dynamic_array->size += 1; - - return FLEDASTY_ERROR_NONE; - } - - byte_index += current_dynamic_array->element_byte_size; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -void *fledasty_dynamic_array_get(const FledastyDynamicArray *current_dynamic_array, const size_t index) { - if (current_dynamic_array == NULL || index >= current_dynamic_array->size) { - return NULL; - } - - return current_dynamic_array->buffer + (index * current_dynamic_array->element_byte_size); -} - -FledastyError fledasty_dynamic_array_remove_at_index(FledastyDynamicArray *current_dynamic_array, const size_t index) { - if (current_dynamic_array == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (index >= current_dynamic_array->size) { - return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; - } - - unsigned char *index_pointer = current_dynamic_array->buffer + (index * current_dynamic_array->element_byte_size); - hallocy_copy_memory(index_pointer, index_pointer + current_dynamic_array->element_byte_size, (current_dynamic_array->size + index) * current_dynamic_array->element_byte_size); - current_dynamic_array->size -= 1; - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_remove_value(FledastyDynamicArray *current_dynamic_array, void *value) { - if (current_dynamic_array == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - size_t byte_index = 0; - size_t byte_size = current_dynamic_array->size * current_dynamic_array->element_byte_size; - while (byte_index < byte_size) { - if (hallocy_compare_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size)) { - hallocy_copy_memory(current_dynamic_array->buffer + byte_index, current_dynamic_array->buffer + (byte_index + current_dynamic_array->element_byte_size), byte_size - (byte_index + current_dynamic_array->element_byte_size)); - current_dynamic_array->size -= 1; - - return FLEDASTY_ERROR_NONE; - } - - byte_index += current_dynamic_array->element_byte_size; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -FledastyError fledasty_dynamic_array_clear(FledastyDynamicArray *current_dynamic_array) { - if (current_dynamic_array == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - current_dynamic_array->size = 0; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_dynamic_array_shrink_to_fit(FledastyDynamicArray *current_dynamic_array) { - if (current_dynamic_array == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - current_dynamic_array->capacity = (current_dynamic_array->size == 0) ? 10 : current_dynamic_array->size; - unsigned char *shrinked_buffer = (unsigned char*)hallocy_malloc(current_dynamic_array->capacity * current_dynamic_array->element_byte_size); - if (shrinked_buffer == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(shrinked_buffer, current_dynamic_array->buffer, current_dynamic_array->size * current_dynamic_array->element_byte_size); - if (hallocy_free(current_dynamic_array->buffer) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_dynamic_array->buffer = shrinked_buffer; - return FLEDASTY_ERROR_NONE; -} - -bool fledasty_dynamic_array_has_value(const FledastyDynamicArray *current_dynamic_array, void *value) { - if (current_dynamic_array == NULL) { - return false; - } - - for (size_t byte_index = 0; byte_index < current_dynamic_array->size * current_dynamic_array->element_byte_size; byte_index += current_dynamic_array->element_byte_size) { - if (hallocy_compare_memory(current_dynamic_array->buffer + byte_index, value, current_dynamic_array->element_byte_size)) { - return true; - } - } - - return false; -} diff --git a/Src/Core/HashTable.c b/Src/Core/HashTable.c index b801bc4..6370bf6 100644 --- a/Src/Core/HashTable.c +++ b/Src/Core/HashTable.c @@ -26,6 +26,8 @@ #include #include +FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(FledastyHashTablePair, pair, fledasty_hash_table_compare_pair) + static const int FLEDASTY_HASH_TABLE_SIZE_THRESHOLD = 75; FledastyError fledasty_hash_table_initialize(FledastyHashTable *new_hash_table, const size_t key_byte_size, const size_t value_byte_size, size_t (*hash_function)(const void *key)) { @@ -39,7 +41,7 @@ FledastyError fledasty_hash_table_initialize(FledastyHashTable *new_hash_table, new_hash_table->size = 0; new_hash_table->capacity = 1024; - new_hash_table->Table = (FledastyDynamicArray*)hallocy_calloc(sizeof(FledastyDynamicArray), new_hash_table->capacity); + new_hash_table->Table = (FledastyDynamicArray_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_pair), new_hash_table->capacity); if (new_hash_table->Table == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } @@ -53,7 +55,7 @@ FledastyError fledasty_hash_table_destroy(FledastyHashTable *current_hash_table) } for (size_t i = 0; i < current_hash_table->capacity; i += 1) { - FledastyError result = fledasty_dynamic_array_destroy(¤t_hash_table->Table[i]); + FledastyError result = fledasty_dynamic_array_pair_free(¤t_hash_table->Table[i]); if (result != FLEDASTY_ERROR_NONE) { return result; } @@ -73,32 +75,25 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, if (current_hash_table->size >= (current_hash_table->capacity * FLEDASTY_HASH_TABLE_SIZE_THRESHOLD) / 100) { const size_t old_capacity = current_hash_table->capacity; - FledastyDynamicArray *previous_table = current_hash_table->Table; + FledastyDynamicArray_pair *previous_table = current_hash_table->Table; current_hash_table->capacity += current_hash_table->capacity; - current_hash_table->Table = (FledastyDynamicArray*)hallocy_calloc(sizeof(FledastyDynamicArray), current_hash_table->capacity); + current_hash_table->Table = (FledastyDynamicArray_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_pair), current_hash_table->capacity); if (current_hash_table->Table == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } for (size_t index = 0; index < old_capacity; index += 1) { - FledastyDynamicArray *current_dynamic_array = previous_table + index; + FledastyDynamicArray_pair *current_dynamic_array = previous_table + index; if (current_dynamic_array->buffer != NULL) { for (size_t list_index = 0; list_index < current_dynamic_array->size; list_index += 1) { - FledastyHashTablePair *pair = (FledastyHashTablePair*)fledasty_dynamic_array_get(current_dynamic_array, list_index); + FledastyHashTablePair pair = current_dynamic_array->buffer[list_index]; - const size_t key_index = current_hash_table->hash_function(pair->key) % current_hash_table->capacity; - if (current_hash_table->Table[key_index].buffer == NULL) { - FledastyError result = fledasty_dynamic_array_initialize(current_hash_table->Table + key_index, NULL, 0, sizeof(FledastyHashTablePair)); - if (result != FLEDASTY_ERROR_NONE) { - return result; - } - } - - fledasty_dynamic_array_append(current_hash_table->Table + key_index, pair); + const size_t key_index = current_hash_table->hash_function(pair.key) % current_hash_table->capacity; + fledasty_dynamic_array_pair_append(current_hash_table->Table + key_index, pair); } - fledasty_dynamic_array_destroy(current_dynamic_array); + fledasty_dynamic_array_pair_free(current_dynamic_array); } } @@ -106,15 +101,8 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, } const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; - if (current_hash_table->Table[index].buffer == NULL) { - FledastyError result = fledasty_dynamic_array_initialize(¤t_hash_table->Table[index], NULL, 0, sizeof(FledastyHashTablePair)); - if (result != FLEDASTY_ERROR_NONE) { - return result; - } - } FledastyHashTablePair pair; - pair.key = hallocy_malloc(current_hash_table->key_byte_size); if (pair.key == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; @@ -128,7 +116,7 @@ FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, } hallocy_copy_memory(pair.value, value, current_hash_table->value_byte_size); - fledasty_dynamic_array_append(¤t_hash_table->Table[index], &pair); + fledasty_dynamic_array_pair_append(¤t_hash_table->Table[index], pair); current_hash_table->size += 1; return FLEDASTY_ERROR_NONE; @@ -146,9 +134,9 @@ void *fledasty_hash_table_get(const FledastyHashTable *current_hash_table, void size_t list_index = 0; while (list_index < current_hash_table->Table[index].size) { - const FledastyHashTablePair *value = (FledastyHashTablePair*)fledasty_dynamic_array_get(¤t_hash_table->Table[index], list_index); - if (hallocy_compare_memory(value->key, key, current_hash_table->key_byte_size)) { - return value->value; + const FledastyHashTablePair value = current_hash_table->Table[index].buffer[list_index]; + if (hallocy_compare_memory(value.key, key, current_hash_table->key_byte_size)) { + return value.value; } list_index += 1; @@ -169,17 +157,17 @@ FledastyError fledasty_hash_table_remove(FledastyHashTable *current_hash_table, size_t list_index = 0; while (list_index < current_hash_table->Table[index].size) { - FledastyHashTablePair *value = (FledastyHashTablePair*)fledasty_dynamic_array_get(¤t_hash_table->Table[index], list_index); - if (hallocy_compare_memory(value->key, key, current_hash_table->key_byte_size)) { - if (hallocy_free(value->key) != HALLOCY_ERROR_NONE) { + FledastyHashTablePair value = current_hash_table->Table[index].buffer[list_index]; + if (hallocy_compare_memory(value.key, key, current_hash_table->key_byte_size)) { + if (hallocy_free(value.key) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - if (hallocy_free(value->value) != HALLOCY_ERROR_NONE) { + if (hallocy_free(value.value) != HALLOCY_ERROR_NONE) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } - fledasty_dynamic_array_remove_at_index(¤t_hash_table->Table[index], list_index); + fledasty_dynamic_array_pair_remove_at_index(¤t_hash_table->Table[index], list_index); current_hash_table->size -= 1; return FLEDASTY_ERROR_NONE; } @@ -197,7 +185,7 @@ FledastyError fledasty_hash_table_clear(FledastyHashTable *current_hash_table) { for (size_t index = 0; index < current_hash_table->capacity; index += 1) { if (current_hash_table->Table[index].buffer != NULL) { - FledastyError result = fledasty_dynamic_array_destroy(¤t_hash_table->Table[index]); + FledastyError result = fledasty_dynamic_array_pair_free(¤t_hash_table->Table[index]); if (result != FLEDASTY_ERROR_NONE) { return result; } @@ -214,7 +202,7 @@ FledastyError fledasty_hash_table_shrink_to_fit(FledastyHashTable *current_hash_ } const size_t old_capacity = current_hash_table->capacity; - FledastyDynamicArray *previous_table = current_hash_table->Table; + FledastyDynamicArray_pair *previous_table = current_hash_table->Table; if (current_hash_table->size == 0) { current_hash_table->capacity = 1024; @@ -222,29 +210,22 @@ FledastyError fledasty_hash_table_shrink_to_fit(FledastyHashTable *current_hash_ current_hash_table->capacity = (current_hash_table->size * 100) / FLEDASTY_HASH_TABLE_SIZE_THRESHOLD; } - current_hash_table->Table = (FledastyDynamicArray*)hallocy_calloc(sizeof(FledastyDynamicArray), current_hash_table->capacity); + current_hash_table->Table = (FledastyDynamicArray_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_pair), current_hash_table->capacity); if (current_hash_table->Table == NULL) { return FLEDASTY_ERROR_FAILED_ALLOCATION; } for (size_t index = 0; index < old_capacity; index += 1) { - FledastyDynamicArray *current_dynamic_array = previous_table + index; + FledastyDynamicArray_pair *current_dynamic_array = previous_table + index; if (current_dynamic_array->buffer != NULL) { for (size_t list_index = 0; list_index < current_dynamic_array->size; list_index += 1) { - FledastyHashTablePair *pair = (FledastyHashTablePair*)fledasty_dynamic_array_get(current_dynamic_array, list_index); + FledastyHashTablePair pair = current_dynamic_array->buffer[list_index]; - const size_t key_index = current_hash_table->hash_function(pair->key) % current_hash_table->capacity; - if (current_hash_table->Table[key_index].buffer == NULL) { - FledastyError result = fledasty_dynamic_array_initialize(current_hash_table->Table + key_index, NULL, 0, sizeof(FledastyHashTablePair)); - if (result != FLEDASTY_ERROR_NONE) { - return result; - } - } - - fledasty_dynamic_array_append(current_hash_table->Table + key_index, pair); + const size_t key_index = current_hash_table->hash_function(pair.key) % current_hash_table->capacity; + fledasty_dynamic_array_pair_append(current_hash_table->Table + key_index, pair); } - fledasty_dynamic_array_destroy(current_dynamic_array); + fledasty_dynamic_array_pair_free(current_dynamic_array); } } @@ -264,8 +245,8 @@ bool fledasty_hash_table_has_key(const FledastyHashTable *current_hash_table, vo size_t list_index = 0; while (list_index < current_hash_table->Table[index].size) { - const FledastyHashTablePair *value = (FledastyHashTablePair*)fledasty_dynamic_array_get(¤t_hash_table->Table[index], list_index); - if (hallocy_compare_memory(value->key, key, current_hash_table->key_byte_size)) { + const FledastyHashTablePair value = current_hash_table->Table[index].buffer[list_index]; + if (hallocy_compare_memory(value.key, key, current_hash_table->key_byte_size)) { return true; } diff --git a/Tests/Main.c b/Tests/Main.c index 0df15e9..8c5cb59 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -30,13 +30,17 @@ #include #include +static inline bool compare_integers(const int first_value, const int second_value) { return first_value == second_value; } +static inline size_t integer_hash_function(const void *key) { return *(int*)key; } + FLEDASTY_STACK_DEFINE(int) FLEDASTY_STACK_IMPLEMENT(int) FLEDASTY_QUEUE_DEFINE(int) FLEDASTY_QUEUE_IMPLEMENT(int) -static inline size_t integer_hash_function(const void *key) { return *(int*)key; } +FLEDASTY_DYNAMIC_ARRAY_DEFINE(int, int) +FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(int, int, compare_integers) int main() { FledastyQueue_int test_queue = { 0, 0, 0, 0, NULL }; @@ -80,44 +84,35 @@ int main() { fledasty_stack_int_free(&test_stack); - FledastyDynamicArray test_dynamic_array; - fledasty_dynamic_array_initialize(&test_dynamic_array, (int[]){11, 12, 13, 14, 15}, 5, sizeof(int)); + FledastyDynamicArray_int test_dynamic_array = { 0, 0, NULL }; for (int i = 0; i < 10; i += 1) { - fledasty_dynamic_array_append(&test_dynamic_array, &i); + fledasty_dynamic_array_int_append(&test_dynamic_array, i); } - fledasty_dynamic_array_shrink_to_fit(&test_dynamic_array); + fledasty_dynamic_array_int_shrink_to_fit(&test_dynamic_array); printf("Dynamic array schrinked to fit %s\n", (test_dynamic_array.capacity == test_dynamic_array.size) ? "succeeded" : "failed"); - int insert_value = 18; - fledasty_dynamic_array_insert_at_index(&test_dynamic_array, 1, &insert_value); + fledasty_dynamic_array_int_insert_at_index(&test_dynamic_array, 1, 18); + fledasty_dynamic_array_int_insert_before_value(&test_dynamic_array, 1, 35); + fledasty_dynamic_array_int_insert_after_value(&test_dynamic_array, 35, 90); - insert_value = 35; - int insert_at_value = 11; - fledasty_dynamic_array_insert_before_value(&test_dynamic_array, &insert_at_value, &insert_value); - insert_value = 90; - insert_at_value = 35; - fledasty_dynamic_array_insert_after_value(&test_dynamic_array, &insert_at_value, &insert_value); - - int remove_value = 15; - fledasty_dynamic_array_remove_value(&test_dynamic_array, &remove_value); - fledasty_dynamic_array_remove_at_index(&test_dynamic_array, test_dynamic_array.size - 2); + fledasty_dynamic_array_int_remove_value(&test_dynamic_array, 35); + fledasty_dynamic_array_int_remove_at_index(&test_dynamic_array, test_dynamic_array.size - 2); for (int i = 0; i < test_dynamic_array.size; i += 1) { - int *dynamic_array_data = (int*)fledasty_dynamic_array_get(&test_dynamic_array, i); - printf("Dynamic array get: %d\n", *dynamic_array_data); + printf("Dynamic array get: %d\n", test_dynamic_array.buffer[i]); } - if (fledasty_dynamic_array_has_value(&test_dynamic_array, &insert_value)) { - printf("Dynamic array contains %d\n", insert_value); + if (fledasty_dynamic_array_int_has_value(&test_dynamic_array, 90)) { + printf("Dynamic array contains 90\n"); } - fledasty_dynamic_array_clear(&test_dynamic_array); - if (fledasty_dynamic_array_is_empty(&test_dynamic_array)) { + fledasty_dynamic_array_int_clear(&test_dynamic_array); + if (fledasty_dynamic_array_int_is_empty(&test_dynamic_array)) { printf("Dynamic array is empty\n"); } - fledasty_dynamic_array_destroy(&test_dynamic_array); + fledasty_dynamic_array_int_free(&test_dynamic_array); FledastyLinkedList test_linked_list; fledasty_linked_list_initialize(&test_linked_list, (int[]){11, 12, 13, 14, 15}, 5, sizeof(int)); @@ -126,16 +121,16 @@ int main() { fledasty_linked_list_append(&test_linked_list, &i); } - insert_value = 35; + int insert_value = 35; fledasty_linked_list_insert_at_index(&test_linked_list, 1, &insert_value); insert_value = 28; - insert_at_value = 35; + int insert_at_value = 35; fledasty_linked_list_insert_before_value(&test_linked_list, &insert_at_value, &insert_value); insert_value = 90; fledasty_linked_list_insert_after_value(&test_linked_list, &insert_at_value, &insert_value); fledasty_linked_list_remove_at_index(&test_linked_list, 2); - remove_value = 0; + int remove_value = 0; fledasty_linked_list_remove_value(&test_linked_list, &remove_value); FledastyLinkedListNode *test_linked_list_node = test_linked_list.start; -- 2.39.5 From 352281790df250bb740562aa41acf5f4272c6ec2 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Sat, 21 Jun 2025 05:17:21 -0500 Subject: [PATCH 29/33] refactor(datastructures): added naming to stack and queue datastructure macro --- Include/Fledasty/Core/Queue.h | 30 +++++++++++++++--------------- Include/Fledasty/Core/Stack.h | 28 ++++++++++++++-------------- Tests/Main.c | 10 +++++----- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Include/Fledasty/Core/Queue.h b/Include/Fledasty/Core/Queue.h index b2752d4..9c5585c 100644 --- a/Include/Fledasty/Core/Queue.h +++ b/Include/Fledasty/Core/Queue.h @@ -31,26 +31,26 @@ #include "../Utils/Error.h" -#define FLEDASTY_QUEUE_DEFINE(type) \ +#define FLEDASTY_QUEUE_DEFINE(type, name) \ typedef struct { \ size_t size, capacity; \ size_t head, tail; \ type *buffer; \ -} FledastyQueue_##type; \ +} FledastyQueue_##name; \ \ -FledastyError fledasty_queue_##type##_free(FledastyQueue_##type *current_queue); \ +FledastyError fledasty_queue_##name##_free(FledastyQueue_##name *current_queue); \ \ -FledastyError fledasty_queue_##type##_push(FledastyQueue_##type *current_queue, type value); \ -type fledasty_queue_##type##_pop(FledastyQueue_##type *current_queue); \ +FledastyError fledasty_queue_##name##_push(FledastyQueue_##name *current_queue, type value); \ +type fledasty_queue_##name##_pop(FledastyQueue_##name *current_queue); \ \ -FledastyError fledasty_queue_##type##_clear(FledastyQueue_##type *current_queue); \ -FledastyError fledasty_queue_##type##_shrink_to_fit(FledastyQueue_##type *current_queue); \ +FledastyError fledasty_queue_##name##_clear(FledastyQueue_##name *current_queue); \ +FledastyError fledasty_queue_##name##_shrink_to_fit(FledastyQueue_##name *current_queue); \ \ -static inline type fledasty_queue_##type##_peek(const FledastyQueue_##type *current_queue) { return (current_queue != NULL && current_queue->size > 0) ? current_queue->buffer[current_queue->size - 1] : 0; } \ -static inline bool fledasty_queue_##type##_is_empty(const FledastyQueue_##type *current_queue) { return current_queue == NULL || current_queue->size == 0; } +static inline type fledasty_queue_##name##_peek(const FledastyQueue_##name *current_queue) { return (current_queue != NULL && current_queue->size > 0) ? current_queue->buffer[current_queue->head] : 0; } \ +static inline bool fledasty_queue_##name##_is_empty(const FledastyQueue_##name *current_queue) { return current_queue == NULL || current_queue->size == 0; } -#define FLEDASTY_QUEUE_IMPLEMENT(type) \ -FledastyError fledasty_queue_##type##_free(FledastyQueue_##type *current_queue) { \ +#define FLEDASTY_QUEUE_IMPLEMENT(type, name) \ +FledastyError fledasty_queue_##name##_free(FledastyQueue_##name *current_queue) { \ if (current_queue == NULL) { \ return FLEDASTY_ERROR_INVALID_POINTER; \ } \ @@ -66,7 +66,7 @@ FledastyError fledasty_queue_##type##_free(FledastyQueue_##type *current_queue) return FLEDASTY_ERROR_NONE; \ } \ \ -FledastyError fledasty_queue_##type##_push(FledastyQueue_##type *current_queue, type value) { \ +FledastyError fledasty_queue_##name##_push(FledastyQueue_##name *current_queue, type value) { \ if (current_queue == NULL) { \ return FLEDASTY_ERROR_INVALID_POINTER; \ } \ @@ -101,7 +101,7 @@ FledastyError fledasty_queue_##type##_push(FledastyQueue_##type *current_queue, return FLEDASTY_ERROR_NONE; \ } \ \ -type fledasty_queue_##type##_pop(FledastyQueue_##type *current_queue) { \ +type fledasty_queue_##name##_pop(FledastyQueue_##name *current_queue) { \ if (current_queue == NULL || current_queue->size == 0) { \ return 0; \ } \ @@ -115,7 +115,7 @@ type fledasty_queue_##type##_pop(FledastyQueue_##type *current_queue) { return current_queue->buffer[current_queue->head - 1]; \ } \ \ -FledastyError fledasty_queue_##type##_clear(FledastyQueue_##type *current_queue) { \ +FledastyError fledasty_queue_##name##_clear(FledastyQueue_##name *current_queue) { \ if (current_queue == NULL) { \ return FLEDASTY_ERROR_INVALID_POINTER; \ } \ @@ -124,7 +124,7 @@ FledastyError fledasty_queue_##type##_clear(FledastyQueue_##type *current_queue) return FLEDASTY_ERROR_NONE; \ } \ \ -FledastyError fledasty_queue_##type##_shrink_to_fit(FledastyQueue_##type *current_queue) { \ +FledastyError fledasty_queue_##name##_shrink_to_fit(FledastyQueue_##name *current_queue) { \ if (current_queue == NULL) { \ return FLEDASTY_ERROR_INVALID_POINTER; \ } \ diff --git a/Include/Fledasty/Core/Stack.h b/Include/Fledasty/Core/Stack.h index 70da942..3eddfc9 100644 --- a/Include/Fledasty/Core/Stack.h +++ b/Include/Fledasty/Core/Stack.h @@ -31,25 +31,25 @@ #include "../Utils/Error.h" -#define FLEDASTY_STACK_DEFINE(type) \ +#define FLEDASTY_STACK_DEFINE(type, name) \ typedef struct { \ size_t size, capacity; \ type *buffer; \ -} FledastyStack_##type; \ +} FledastyStack_##name; \ \ -FledastyError fledasty_stack_##type##_free(FledastyStack_##type *current_stack); \ +FledastyError fledasty_stack_##name##_free(FledastyStack_##name *current_stack); \ \ -FledastyError fledasty_stack_##type##_push(FledastyStack_##type *current_stack, type value); \ +FledastyError fledasty_stack_##name##_push(FledastyStack_##name *current_stack, type value); \ \ -FledastyError fledasty_stack_##type##_clear(FledastyStack_##type *current_stack); \ -FledastyError fledasty_stack_##type##_shrink_to_fit(FledastyStack_##type *current_stack); \ +FledastyError fledasty_stack_##name##_clear(FledastyStack_##name *current_stack); \ +FledastyError fledasty_stack_##name##_shrink_to_fit(FledastyStack_##name *current_stack); \ \ -static inline type fledasty_stack_##type##_pop(FledastyStack_##type *current_stack) { return (current_stack != NULL && current_stack->size > 0) ? current_stack->buffer[--current_stack->size] : 0; } \ -static inline type fledasty_stack_##type##_peek(const FledastyStack_##type *current_stack) { return (current_stack != NULL && current_stack->size > 0) ? current_stack->buffer[current_stack->size - 1] : 0; } \ -static inline bool fledasty_stack_##type##_is_empty(const FledastyStack_##type *current_stack) { return current_stack == NULL || current_stack->size == 0; } +static inline type fledasty_stack_##name##_pop(FledastyStack_##name *current_stack) { return (current_stack != NULL && current_stack->size > 0) ? current_stack->buffer[--current_stack->size] : 0; } \ +static inline type fledasty_stack_##name##_peek(const FledastyStack_##name *current_stack) { return (current_stack != NULL && current_stack->size > 0) ? current_stack->buffer[current_stack->size - 1] : 0; } \ +static inline bool fledasty_stack_##name##_is_empty(const FledastyStack_##name *current_stack) { return current_stack == NULL || current_stack->size == 0; } -#define FLEDASTY_STACK_IMPLEMENT(type) \ -FledastyError fledasty_stack_##type##_free(FledastyStack_##type *current_stack) { \ +#define FLEDASTY_STACK_IMPLEMENT(type, name) \ +FledastyError fledasty_stack_##name##_free(FledastyStack_##name *current_stack) { \ if (current_stack == NULL) { \ return FLEDASTY_ERROR_INVALID_POINTER; \ } \ @@ -65,7 +65,7 @@ FledastyError fledasty_stack_##type##_free(FledastyStack_##type *current_stack) return FLEDASTY_ERROR_NONE; \ } \ \ -FledastyError fledasty_stack_##type##_push(FledastyStack_##type *current_stack, type value) { \ +FledastyError fledasty_stack_##name##_push(FledastyStack_##name *current_stack, type value) { \ if (current_stack == NULL) { \ return FLEDASTY_ERROR_INVALID_POINTER; \ } \ @@ -83,7 +83,7 @@ FledastyError fledasty_stack_##type##_push(FledastyStack_##type *current_stack, return FLEDASTY_ERROR_NONE; \ } \ \ -FledastyError fledasty_stack_##type##_clear(FledastyStack_##type *current_stack) { \ +FledastyError fledasty_stack_##name##_clear(FledastyStack_##name *current_stack) { \ if (current_stack == NULL) { \ return FLEDASTY_ERROR_INVALID_POINTER; \ } \ @@ -92,7 +92,7 @@ FledastyError fledasty_stack_##type##_clear(FledastyStack_##type *current_stack) return FLEDASTY_ERROR_NONE; \ } \ \ -FledastyError fledasty_stack_##type##_shrink_to_fit(FledastyStack_##type *current_stack) { \ +FledastyError fledasty_stack_##name##_shrink_to_fit(FledastyStack_##name *current_stack) { \ if (current_stack == NULL) { \ return FLEDASTY_ERROR_INVALID_POINTER; \ } \ diff --git a/Tests/Main.c b/Tests/Main.c index 8c5cb59..afa2f1f 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -33,11 +33,11 @@ static inline bool compare_integers(const int first_value, const int second_value) { return first_value == second_value; } static inline size_t integer_hash_function(const void *key) { return *(int*)key; } -FLEDASTY_STACK_DEFINE(int) -FLEDASTY_STACK_IMPLEMENT(int) +FLEDASTY_STACK_DEFINE(int, int) +FLEDASTY_STACK_IMPLEMENT(int, int) -FLEDASTY_QUEUE_DEFINE(int) -FLEDASTY_QUEUE_IMPLEMENT(int) +FLEDASTY_QUEUE_DEFINE(int, int) +FLEDASTY_QUEUE_IMPLEMENT(int, int) FLEDASTY_DYNAMIC_ARRAY_DEFINE(int, int) FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(int, int, compare_integers) @@ -50,7 +50,7 @@ int main() { fledasty_queue_int_shrink_to_fit(&test_queue); printf("Queue schrinked to fit %s\n", (test_queue.capacity == test_queue.size) ? "succeeded" : "failed"); - fledasty_queue_int_push(&test_queue, 0); + fledasty_queue_int_push(&test_queue, 10); printf("Queue peeked: %d\n", fledasty_queue_int_peek(&test_queue)); for (int i = test_queue.size; i > 0; i -= 1) { -- 2.39.5 From dfb24b1716ba134e87c58417b014a9685c79e0a2 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Sat, 21 Jun 2025 06:48:10 -0500 Subject: [PATCH 30/33] perf(hash table): changed hash table to be defined using macros to improve performance --- Include/Fledasty/Core/HashTable.h | 238 +++++++++++++++++++++++---- Src/Core/HashTable.c | 257 ------------------------------ Tests/Main.c | 38 ++--- 3 files changed, 227 insertions(+), 306 deletions(-) delete mode 100644 Src/Core/HashTable.c diff --git a/Include/Fledasty/Core/HashTable.h b/Include/Fledasty/Core/HashTable.h index e7e99d1..8ffc78c 100644 --- a/Include/Fledasty/Core/HashTable.h +++ b/Include/Fledasty/Core/HashTable.h @@ -26,38 +26,220 @@ #include #include +#include +#include +#include #include "../Utils/Error.h" #include "DynamicArray.h" -#include "Hallocy/Core/Memory.h" -typedef struct { - void *key, *value; -} FledastyHashTablePair; +#define FLEDASTY_HASH_TABLE_DEFINE(key_type, value_type, name, compare_key_function) \ +typedef struct { \ + key_type key; \ + value_type value; \ +} FledastyHashTablePair_##name; \ + \ +FLEDASTY_DYNAMIC_ARRAY_DEFINE(FledastyHashTablePair_##name, fledasty_internal_pair) \ + \ +typedef struct { \ + size_t size, capacity; \ + FledastyDynamicArray_fledasty_internal_pair *Table; \ + \ + size_t (*hash_function)(const key_type key); \ +} FledastyHashTable_##name; \ + \ +FledastyError fledasty_hash_table_##name##_free(FledastyHashTable_##name *current_hash_table); \ + \ +FledastyError fledasty_hash_table_##name##_insert(FledastyHashTable_##name *current_hash_table, key_type key, value_type value); \ +value_type fledasty_hash_table_##name##_get(const FledastyHashTable_##name *current_hash_table, key_type key); \ +FledastyError fledasty_hash_table_##name##_remove(FledastyHashTable_##name *current_hash_table, key_type key); \ + \ +FledastyError fledasty_hash_table_##name##_clear(FledastyHashTable_##name *current_hash_table); \ +FledastyError fledasty_hash_table_##name##_shrink_to_fit(FledastyHashTable_##name *current_hash_table); \ + \ +bool fledasty_hash_table_##name##_has_key(const FledastyHashTable_##name *current_hash_table, key_type key); \ +static inline bool fledasty_hash_table_##name##_is_empty(const FledastyHashTable_##name *current_hash_table) { return current_hash_table == NULL || current_hash_table->size == 0; } \ +static inline bool fledasty_hash_table_##name##_compare_pair(const FledastyHashTablePair_##name first_pair, const FledastyHashTablePair_##name second_pair) { return compare_key_function(first_pair.key, second_pair.key); } -FLEDASTY_DYNAMIC_ARRAY_DEFINE(FledastyHashTablePair, pair) - -typedef struct { - size_t size, capacity; - - size_t key_byte_size, value_byte_size; - FledastyDynamicArray_pair *Table; - - size_t (*hash_function)(const void *key); -} FledastyHashTable; - -FledastyError fledasty_hash_table_initialize(FledastyHashTable *new_hash_table, const size_t key_byte_size, const size_t value_byte_size, size_t (*hash_function)(const void *key)); -FledastyError fledasty_hash_table_destroy(FledastyHashTable *current_hash_table); - -FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, void *key, void *value); -void *fledasty_hash_table_get(const FledastyHashTable *current_hash_table, void *key); -FledastyError fledasty_hash_table_remove(FledastyHashTable *current_hash_table, void *key); - -FledastyError fledasty_hash_table_clear(FledastyHashTable *current_hash_table); -FledastyError fledasty_hash_table_shrink_to_fit(FledastyHashTable *current_hash_table); - -bool fledasty_hash_table_has_key(const FledastyHashTable *current_hash_table, void *key); -static inline bool fledasty_hash_table_is_empty(const FledastyHashTable *current_hash_table) { return current_hash_table == NULL || current_hash_table->size == 0; } -static inline bool fledasty_hash_table_compare_pair(const FledastyHashTablePair first_pair, const FledastyHashTablePair second_pair) { return first_pair.key == second_pair.key && first_pair.value == second_pair.value; } +#define FLEDASTY_HASH_TABLE_IMPLEMENT(key_type, value_type, name, compare_key_function) \ +FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(FledastyHashTablePair_##name, fledasty_internal_pair, fledasty_hash_table_##name##_compare_pair) \ +static const int FLEDASTY_HASH_TABLE_SIZE_THRESHOLD = 75; \ + \ +FledastyError fledasty_hash_table_##name##_free(FledastyHashTable_##name *current_hash_table) { \ + if (current_hash_table == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + for (size_t i = 0; i < current_hash_table->capacity; i += 1) { \ + FledastyError result = fledasty_dynamic_array_fledasty_internal_pair_free(¤t_hash_table->Table[i]); \ + if (result != FLEDASTY_ERROR_NONE) { \ + return result; \ + } \ + } \ + \ + if (hallocy_free(current_hash_table->Table) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_hash_table_##name##_insert(FledastyHashTable_##name *current_hash_table, key_type key, value_type value) { \ + if (current_hash_table == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (current_hash_table->size >= (current_hash_table->capacity * FLEDASTY_HASH_TABLE_SIZE_THRESHOLD) / 100) { \ + const size_t old_capacity = current_hash_table->capacity; \ + FledastyDynamicArray_fledasty_internal_pair *previous_table = current_hash_table->Table; \ + \ + current_hash_table->capacity += current_hash_table->capacity ? current_hash_table->capacity : 1024; \ + current_hash_table->Table = (FledastyDynamicArray_fledasty_internal_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_fledasty_internal_pair), current_hash_table->capacity); \ + if (current_hash_table->Table == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + for (size_t index = 0; index < old_capacity; index += 1) { \ + FledastyDynamicArray_fledasty_internal_pair *current_dynamic_array = previous_table + index; \ + if (current_dynamic_array->buffer != NULL) { \ + for (size_t list_index = 0; list_index < current_dynamic_array->size; list_index += 1) { \ + FledastyHashTablePair_##name pair = current_dynamic_array->buffer[list_index]; \ + \ + const size_t key_index = current_hash_table->hash_function(pair.key) % current_hash_table->capacity; \ + fledasty_dynamic_array_fledasty_internal_pair_append(current_hash_table->Table + key_index, pair); \ + } \ + \ + fledasty_dynamic_array_fledasty_internal_pair_free(current_dynamic_array); \ + } \ + } \ + \ + hallocy_free(previous_table); \ + } \ + \ + const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; \ + \ + FledastyHashTablePair_##name pair = { .key = key, .value = value }; \ + fledasty_dynamic_array_fledasty_internal_pair_append(¤t_hash_table->Table[index], pair); \ + \ + current_hash_table->size += 1; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +value_type fledasty_hash_table_##name##_get(const FledastyHashTable_##name *current_hash_table, key_type key) { \ + if (current_hash_table == NULL) { \ + return 0; \ + } \ + \ + const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; \ + if (current_hash_table->Table[index].buffer == NULL) { \ + return 0; \ + } \ + \ + for (size_t list_index = 0; list_index < current_hash_table->Table[index].size; list_index += 1) { \ + const FledastyHashTablePair_##name value = current_hash_table->Table[index].buffer[list_index]; \ + if (compare_key_function(value.key, key)) { \ + return value.value; \ + } \ + } \ + \ + return 0; \ +} \ + \ +FledastyError fledasty_hash_table_##name##_remove(FledastyHashTable_##name *current_hash_table, key_type key) { \ + if (current_hash_table == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; \ + if (current_hash_table->Table[index].buffer == NULL) { \ + return FLEDASTY_ERROR_KEY_NOT_FOUND; \ + } \ + \ + for (size_t list_index = 0; list_index < current_hash_table->Table[index].size; list_index += 1) { \ + FledastyHashTablePair_##name value = current_hash_table->Table[index].buffer[list_index]; \ + if (compare_key_function(value.key, key)) { \ + fledasty_dynamic_array_fledasty_internal_pair_remove_at_index(¤t_hash_table->Table[index], list_index); \ + current_hash_table->size -= 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + } \ + \ + return FLEDASTY_ERROR_KEY_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_hash_table_##name##_clear(FledastyHashTable_##name *current_hash_table) { \ + if (current_hash_table == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + for (size_t index = 0; index < current_hash_table->capacity; index += 1) { \ + if (current_hash_table->Table[index].buffer != NULL) { \ + FledastyError result = fledasty_dynamic_array_fledasty_internal_pair_free(¤t_hash_table->Table[index]); \ + if (result != FLEDASTY_ERROR_NONE) { \ + return result; \ + } \ + } \ + } \ + \ + current_hash_table->size = 0; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_hash_table_##name##_shrink_to_fit(FledastyHashTable_##name *current_hash_table) { \ + if (current_hash_table == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + const size_t old_capacity = current_hash_table->capacity; \ + FledastyDynamicArray_fledasty_internal_pair *previous_table = current_hash_table->Table; \ + \ + if (current_hash_table->size == 0) { \ + current_hash_table->capacity = 1024; \ + } else { \ + current_hash_table->capacity = (current_hash_table->size * 100) / FLEDASTY_HASH_TABLE_SIZE_THRESHOLD; \ + } \ + \ + current_hash_table->Table = (FledastyDynamicArray_fledasty_internal_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_fledasty_internal_pair), current_hash_table->capacity); \ + if (current_hash_table->Table == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + for (size_t index = 0; index < old_capacity; index += 1) { \ + FledastyDynamicArray_fledasty_internal_pair *current_dynamic_array = previous_table + index; \ + if (current_dynamic_array->buffer != NULL) { \ + for (size_t list_index = 0; list_index < current_dynamic_array->size; list_index += 1) { \ + FledastyHashTablePair_##name pair = current_dynamic_array->buffer[list_index]; \ + \ + const size_t key_index = current_hash_table->hash_function(pair.key) % current_hash_table->capacity; \ + fledasty_dynamic_array_fledasty_internal_pair_append(current_hash_table->Table + key_index, pair); \ + } \ + \ + fledasty_dynamic_array_fledasty_internal_pair_free(current_dynamic_array); \ + } \ + } \ + \ + hallocy_free(previous_table); \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +bool fledasty_hash_table_##name##_has_key(const FledastyHashTable_##name *current_hash_table, key_type key) { \ + if (current_hash_table == NULL) { \ + return false; \ + } \ + \ + const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; \ + if (current_hash_table->Table[index].buffer == NULL) { \ + return false; \ + } \ + \ + for (size_t list_index = 0; list_index < current_hash_table->Table[index].size; list_index += 1) { \ + const FledastyHashTablePair_##name value = current_hash_table->Table[index].buffer[list_index]; \ + if (compare_key_function(value.key, key)) { \ + return true; \ + } \ + } \ + \ + return false; \ +} #endif diff --git a/Src/Core/HashTable.c b/Src/Core/HashTable.c deleted file mode 100644 index 6370bf6..0000000 --- a/Src/Core/HashTable.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ----------------------------------------------------------------------------- - * File: HashTable.c - * Description: - * This file contains the functions for modifying the Hash Table. It includes functions - * to get, Insert, Remove, check if has key and check if empty. - * - * Author: Mineplay - * ----------------------------------------------------------------------------- - */ -#include "../../Include/Fledasty/Core/HashTable.h" - -#include -#include -#include - -FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(FledastyHashTablePair, pair, fledasty_hash_table_compare_pair) - -static const int FLEDASTY_HASH_TABLE_SIZE_THRESHOLD = 75; - -FledastyError fledasty_hash_table_initialize(FledastyHashTable *new_hash_table, const size_t key_byte_size, const size_t value_byte_size, size_t (*hash_function)(const void *key)) { - if (new_hash_table == NULL || hash_function == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - new_hash_table->key_byte_size = key_byte_size; - new_hash_table->value_byte_size = value_byte_size; - new_hash_table->hash_function = hash_function; - - new_hash_table->size = 0; - new_hash_table->capacity = 1024; - new_hash_table->Table = (FledastyDynamicArray_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_pair), new_hash_table->capacity); - if (new_hash_table->Table == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_hash_table_destroy(FledastyHashTable *current_hash_table) { - if (current_hash_table == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - for (size_t i = 0; i < current_hash_table->capacity; i += 1) { - FledastyError result = fledasty_dynamic_array_pair_free(¤t_hash_table->Table[i]); - if (result != FLEDASTY_ERROR_NONE) { - return result; - } - } - - if (hallocy_free(current_hash_table->Table) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_hash_table_insert(FledastyHashTable *current_hash_table, void *key, void *value) { - if (current_hash_table == NULL || key == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (current_hash_table->size >= (current_hash_table->capacity * FLEDASTY_HASH_TABLE_SIZE_THRESHOLD) / 100) { - const size_t old_capacity = current_hash_table->capacity; - FledastyDynamicArray_pair *previous_table = current_hash_table->Table; - - current_hash_table->capacity += current_hash_table->capacity; - current_hash_table->Table = (FledastyDynamicArray_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_pair), current_hash_table->capacity); - if (current_hash_table->Table == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - for (size_t index = 0; index < old_capacity; index += 1) { - FledastyDynamicArray_pair *current_dynamic_array = previous_table + index; - if (current_dynamic_array->buffer != NULL) { - for (size_t list_index = 0; list_index < current_dynamic_array->size; list_index += 1) { - FledastyHashTablePair pair = current_dynamic_array->buffer[list_index]; - - const size_t key_index = current_hash_table->hash_function(pair.key) % current_hash_table->capacity; - fledasty_dynamic_array_pair_append(current_hash_table->Table + key_index, pair); - } - - fledasty_dynamic_array_pair_free(current_dynamic_array); - } - } - - hallocy_free(previous_table); - } - - const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; - - FledastyHashTablePair pair; - pair.key = hallocy_malloc(current_hash_table->key_byte_size); - if (pair.key == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(pair.key, key, current_hash_table->key_byte_size); - - pair.value = hallocy_malloc(current_hash_table->value_byte_size); - if (pair.value == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(pair.value, value, current_hash_table->value_byte_size); - fledasty_dynamic_array_pair_append(¤t_hash_table->Table[index], pair); - - current_hash_table->size += 1; - return FLEDASTY_ERROR_NONE; -} - -void *fledasty_hash_table_get(const FledastyHashTable *current_hash_table, void *key) { - if (current_hash_table == NULL || key == NULL) { - return NULL; - } - - const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; - if (current_hash_table->Table[index].buffer == NULL) { - return NULL; - } - - size_t list_index = 0; - while (list_index < current_hash_table->Table[index].size) { - const FledastyHashTablePair value = current_hash_table->Table[index].buffer[list_index]; - if (hallocy_compare_memory(value.key, key, current_hash_table->key_byte_size)) { - return value.value; - } - - list_index += 1; - } - - return NULL; -} - -FledastyError fledasty_hash_table_remove(FledastyHashTable *current_hash_table, void *key) { - if (current_hash_table == NULL || key == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; - if (current_hash_table->Table[index].buffer == NULL) { - return FLEDASTY_ERROR_KEY_NOT_FOUND; - } - - size_t list_index = 0; - while (list_index < current_hash_table->Table[index].size) { - FledastyHashTablePair value = current_hash_table->Table[index].buffer[list_index]; - if (hallocy_compare_memory(value.key, key, current_hash_table->key_byte_size)) { - if (hallocy_free(value.key) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (hallocy_free(value.value) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - fledasty_dynamic_array_pair_remove_at_index(¤t_hash_table->Table[index], list_index); - current_hash_table->size -= 1; - return FLEDASTY_ERROR_NONE; - } - - list_index += 1; - } - - return FLEDASTY_ERROR_KEY_NOT_FOUND; -} - -FledastyError fledasty_hash_table_clear(FledastyHashTable *current_hash_table) { - if (current_hash_table == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - for (size_t index = 0; index < current_hash_table->capacity; index += 1) { - if (current_hash_table->Table[index].buffer != NULL) { - FledastyError result = fledasty_dynamic_array_pair_free(¤t_hash_table->Table[index]); - if (result != FLEDASTY_ERROR_NONE) { - return result; - } - } - } - - current_hash_table->size = 0; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_hash_table_shrink_to_fit(FledastyHashTable *current_hash_table) { - if (current_hash_table == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - const size_t old_capacity = current_hash_table->capacity; - FledastyDynamicArray_pair *previous_table = current_hash_table->Table; - - if (current_hash_table->size == 0) { - current_hash_table->capacity = 1024; - } else { - current_hash_table->capacity = (current_hash_table->size * 100) / FLEDASTY_HASH_TABLE_SIZE_THRESHOLD; - } - - current_hash_table->Table = (FledastyDynamicArray_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_pair), current_hash_table->capacity); - if (current_hash_table->Table == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - for (size_t index = 0; index < old_capacity; index += 1) { - FledastyDynamicArray_pair *current_dynamic_array = previous_table + index; - if (current_dynamic_array->buffer != NULL) { - for (size_t list_index = 0; list_index < current_dynamic_array->size; list_index += 1) { - FledastyHashTablePair pair = current_dynamic_array->buffer[list_index]; - - const size_t key_index = current_hash_table->hash_function(pair.key) % current_hash_table->capacity; - fledasty_dynamic_array_pair_append(current_hash_table->Table + key_index, pair); - } - - fledasty_dynamic_array_pair_free(current_dynamic_array); - } - } - - hallocy_free(previous_table); - return FLEDASTY_ERROR_NONE; -} - -bool fledasty_hash_table_has_key(const FledastyHashTable *current_hash_table, void *key) { - if (current_hash_table == NULL || key == NULL) { - return false; - } - - const size_t index = current_hash_table->hash_function(key) % current_hash_table->capacity; - if (current_hash_table->Table[index].buffer == NULL) { - return false; - } - - size_t list_index = 0; - while (list_index < current_hash_table->Table[index].size) { - const FledastyHashTablePair value = current_hash_table->Table[index].buffer[list_index]; - if (hallocy_compare_memory(value.key, key, current_hash_table->key_byte_size)) { - return true; - } - - list_index += 1; - } - - return false; -} diff --git a/Tests/Main.c b/Tests/Main.c index afa2f1f..d0f8498 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -31,7 +31,7 @@ #include static inline bool compare_integers(const int first_value, const int second_value) { return first_value == second_value; } -static inline size_t integer_hash_function(const void *key) { return *(int*)key; } +static inline size_t integer_hash_function(const int key) { return key; } FLEDASTY_STACK_DEFINE(int, int) FLEDASTY_STACK_IMPLEMENT(int, int) @@ -42,6 +42,9 @@ FLEDASTY_QUEUE_IMPLEMENT(int, int) FLEDASTY_DYNAMIC_ARRAY_DEFINE(int, int) FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(int, int, compare_integers) +FLEDASTY_HASH_TABLE_DEFINE(int, int, int_int, compare_integers) +FLEDASTY_HASH_TABLE_IMPLEMENT(int, int, int_int, compare_integers) + int main() { FledastyQueue_int test_queue = { 0, 0, 0, 0, NULL }; for (int i = 0; i < 10; i += 1) { @@ -191,42 +194,35 @@ int main() { fledasty_doubly_list_destroy(&test_doubly_linked_list); - FledastyHashTable test_hash_table; - fledasty_hash_table_initialize(&test_hash_table, sizeof(int), sizeof(int), integer_hash_function); - + FledastyHashTable_int_int test_hash_table = { .size = 0, .capacity = 0, .Table = NULL, .hash_function = (size_t(*)(const int))integer_hash_function }; for (int i = 0; i < 10; i += 1) { - int pow_value = i * i; - fledasty_hash_table_insert(&test_hash_table, &pow_value, &i); + fledasty_hash_table_int_int_insert(&test_hash_table, i * i, i); } - fledasty_hash_table_shrink_to_fit(&test_hash_table); + fledasty_hash_table_int_int_shrink_to_fit(&test_hash_table); - int hash_table_value = 5; - int hash_table_remove = 2; - fledasty_hash_table_insert(&test_hash_table, &hash_table_remove, &hash_table_value); - fledasty_hash_table_remove(&test_hash_table, &hash_table_remove); + fledasty_hash_table_int_int_insert(&test_hash_table, 2, 5); + fledasty_hash_table_int_int_remove(&test_hash_table, 2); - if (fledasty_hash_table_get(&test_hash_table, &hash_table_remove) != NULL) { + if (fledasty_hash_table_int_int_get(&test_hash_table, 2) != 0) { printf("Value not removed from hash table\n"); } for (int i = 0; i < 10; i += 1) { - int pow_value = i * i; - int *hash_table_value = (int*)fledasty_hash_table_get(&test_hash_table, &pow_value); - printf("Hash table get: %d\n", *hash_table_value); + printf("Hash table get: %d\n", fledasty_hash_table_int_int_get(&test_hash_table, i * i)); } - hash_table_value = 4; - if (fledasty_hash_table_has_key(&test_hash_table, &hash_table_value)) { - printf("Hash table contains key %d\n", hash_table_value); + if (fledasty_hash_table_int_int_has_key(&test_hash_table, 4)) { + printf("Hash table contains key 4\n"); } - fledasty_hash_table_clear(&test_hash_table); - if (fledasty_hash_table_is_empty(&test_hash_table)) { + fledasty_hash_table_int_int_clear(&test_hash_table); + if (fledasty_hash_table_int_int_is_empty(&test_hash_table)) { printf("Hash table is empty\n"); } - fledasty_hash_table_destroy(&test_hash_table); + fledasty_hash_table_int_int_free(&test_hash_table); + FledastyUtf8String test_utf8_string; unsigned char *test_string = (unsigned char*)"😀€Testing"; fledasty_utf8_string_initialize(&test_utf8_string, test_string, 14); -- 2.39.5 From 38f0cf8fde2f27562da341217f49772c7bf0d42d Mon Sep 17 00:00:00 2001 From: Mineplay Date: Mon, 7 Jul 2025 17:54:24 -0500 Subject: [PATCH 31/33] refactor(datatypes): removed magical numbers and changed them for constant values --- Include/Fledasty/Core/DynamicArray.h | 10 ++++++---- Include/Fledasty/Core/HashTable.h | 13 ++++++++----- Include/Fledasty/Core/Queue.h | 6 ++++-- Include/Fledasty/Core/Stack.h | 6 ++++-- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Include/Fledasty/Core/DynamicArray.h b/Include/Fledasty/Core/DynamicArray.h index 544e4cb..e2ebf4b 100644 --- a/Include/Fledasty/Core/DynamicArray.h +++ b/Include/Fledasty/Core/DynamicArray.h @@ -32,6 +32,8 @@ #include "../Utils/Error.h" +static const size_t FLEDASTY_DYNAMIC_ARRAY_DEFAULT_ALLOCATION_SIZE = 16; + #define FLEDASTY_DYNAMIC_ARRAY_DEFINE(type, name) \ typedef struct { \ size_t size, capacity; \ @@ -78,7 +80,7 @@ FledastyError fledasty_dynamic_array_##name##_append(FledastyDynamicArray_##name } \ \ if (current_dynamic_array->size == current_dynamic_array->capacity) { \ - current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : FLEDASTY_DYNAMIC_ARRAY_DEFAULT_ALLOCATION_SIZE; \ current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ \ if (current_dynamic_array->buffer == NULL) { \ @@ -100,7 +102,7 @@ FledastyError fledasty_dynamic_array_##name##_insert_at_index(FledastyDynamicArr } \ \ if (current_dynamic_array->size == current_dynamic_array->capacity) { \ - current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : FLEDASTY_DYNAMIC_ARRAY_DEFAULT_ALLOCATION_SIZE; \ current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ \ if (current_dynamic_array->buffer == NULL) { \ @@ -124,7 +126,7 @@ FledastyError fledasty_dynamic_array_##name##_insert_before_value(FledastyDynami for (size_t index = 0; index < current_dynamic_array->size; index += 1) { \ if (compare_function(current_dynamic_array->buffer[index], before_value)) { \ if (current_dynamic_array->size == current_dynamic_array->capacity) { \ - current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : FLEDASTY_DYNAMIC_ARRAY_DEFAULT_ALLOCATION_SIZE; \ current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ \ if (current_dynamic_array->buffer == NULL) { \ @@ -152,7 +154,7 @@ FledastyError fledasty_dynamic_array_##name##_insert_after_value(FledastyDynamic for (size_t index = 0; index < current_dynamic_array->size; index += 1) { \ if (compare_function(current_dynamic_array->buffer[index], after_value)) { \ if (current_dynamic_array->size == current_dynamic_array->capacity) { \ - current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : 16; \ + current_dynamic_array->capacity += current_dynamic_array->capacity ? current_dynamic_array->capacity : FLEDASTY_DYNAMIC_ARRAY_DEFAULT_ALLOCATION_SIZE; \ current_dynamic_array->buffer = (type*)hallocy_realloc(current_dynamic_array->buffer, current_dynamic_array->capacity * sizeof(type)); \ \ if (current_dynamic_array->buffer == NULL) { \ diff --git a/Include/Fledasty/Core/HashTable.h b/Include/Fledasty/Core/HashTable.h index 8ffc78c..fc5f1f4 100644 --- a/Include/Fledasty/Core/HashTable.h +++ b/Include/Fledasty/Core/HashTable.h @@ -33,6 +33,10 @@ #include "../Utils/Error.h" #include "DynamicArray.h" +static const int FLEDASTY_HASH_TABLE_TOTAL_SIZE_PERCENTAGE = 100; +static const int FLEDASTY_HASH_TABLE_THRESHOLD_SIZE_PERCENTAGE = 75; +static const size_t FLEDASTY_HASH_TABLE_DEFAULT_ALLOCATION_SIZE = 1024; + #define FLEDASTY_HASH_TABLE_DEFINE(key_type, value_type, name, compare_key_function) \ typedef struct { \ key_type key; \ @@ -63,7 +67,6 @@ static inline bool fledasty_hash_table_##name##_compare_pair(const FledastyHashT #define FLEDASTY_HASH_TABLE_IMPLEMENT(key_type, value_type, name, compare_key_function) \ FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(FledastyHashTablePair_##name, fledasty_internal_pair, fledasty_hash_table_##name##_compare_pair) \ -static const int FLEDASTY_HASH_TABLE_SIZE_THRESHOLD = 75; \ \ FledastyError fledasty_hash_table_##name##_free(FledastyHashTable_##name *current_hash_table) { \ if (current_hash_table == NULL) { \ @@ -89,11 +92,11 @@ FledastyError fledasty_hash_table_##name##_insert(FledastyHashTable_##name *curr return FLEDASTY_ERROR_INVALID_POINTER; \ } \ \ - if (current_hash_table->size >= (current_hash_table->capacity * FLEDASTY_HASH_TABLE_SIZE_THRESHOLD) / 100) { \ + if (current_hash_table->size >= (current_hash_table->capacity * FLEDASTY_HASH_TABLE_THRESHOLD_SIZE_PERCENTAGE) / FLEDASTY_HASH_TABLE_TOTAL_SIZE_PERCENTAGE) { \ const size_t old_capacity = current_hash_table->capacity; \ FledastyDynamicArray_fledasty_internal_pair *previous_table = current_hash_table->Table; \ \ - current_hash_table->capacity += current_hash_table->capacity ? current_hash_table->capacity : 1024; \ + current_hash_table->capacity += current_hash_table->capacity ? current_hash_table->capacity : FLEDASTY_HASH_TABLE_DEFAULT_ALLOCATION_SIZE; \ current_hash_table->Table = (FledastyDynamicArray_fledasty_internal_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_fledasty_internal_pair), current_hash_table->capacity); \ if (current_hash_table->Table == NULL) { \ return FLEDASTY_ERROR_FAILED_ALLOCATION; \ @@ -194,9 +197,9 @@ FledastyError fledasty_hash_table_##name##_shrink_to_fit(FledastyHashTable_##nam FledastyDynamicArray_fledasty_internal_pair *previous_table = current_hash_table->Table; \ \ if (current_hash_table->size == 0) { \ - current_hash_table->capacity = 1024; \ + current_hash_table->capacity = FLEDASTY_HASH_TABLE_DEFAULT_ALLOCATION_SIZE; \ } else { \ - current_hash_table->capacity = (current_hash_table->size * 100) / FLEDASTY_HASH_TABLE_SIZE_THRESHOLD; \ + current_hash_table->capacity = (current_hash_table->size * FLEDASTY_HASH_TABLE_TOTAL_SIZE_PERCENTAGE) / FLEDASTY_HASH_TABLE_THRESHOLD_SIZE_PERCENTAGE; \ } \ \ current_hash_table->Table = (FledastyDynamicArray_fledasty_internal_pair*)hallocy_calloc(sizeof(FledastyDynamicArray_fledasty_internal_pair), current_hash_table->capacity); \ diff --git a/Include/Fledasty/Core/Queue.h b/Include/Fledasty/Core/Queue.h index 9c5585c..a6a1a03 100644 --- a/Include/Fledasty/Core/Queue.h +++ b/Include/Fledasty/Core/Queue.h @@ -31,6 +31,8 @@ #include "../Utils/Error.h" +static const size_t FLEDASTY_QUEUE_DEFAULT_ALLOCATION_SIZE = 16; + #define FLEDASTY_QUEUE_DEFINE(type, name) \ typedef struct { \ size_t size, capacity; \ @@ -72,7 +74,7 @@ FledastyError fledasty_queue_##name##_push(FledastyQueue_##name *current_queue, } \ \ if (current_queue->size == current_queue->capacity) { \ - current_queue->capacity += current_queue->capacity ? current_queue->capacity : 16; \ + current_queue->capacity += current_queue->capacity ? current_queue->capacity : FLEDASTY_QUEUE_DEFAULT_ALLOCATION_SIZE; \ current_queue->buffer = (type*)hallocy_realloc(current_queue->buffer, current_queue->capacity * sizeof(type)); \ \ if (current_queue->buffer == NULL) { \ @@ -129,7 +131,7 @@ FledastyError fledasty_queue_##name##_shrink_to_fit(FledastyQueue_##name *curren return FLEDASTY_ERROR_INVALID_POINTER; \ } \ \ - size_t new_capacity = (current_queue->size == 0) ? 16 : current_queue->size; \ + size_t new_capacity = (current_queue->size == 0) ? FLEDASTY_QUEUE_DEFAULT_ALLOCATION_SIZE : current_queue->size; \ type *shrinked_buffer = (type*)hallocy_malloc(new_capacity * sizeof(type)); \ if (shrinked_buffer == NULL) { \ return FLEDASTY_ERROR_FAILED_ALLOCATION; \ diff --git a/Include/Fledasty/Core/Stack.h b/Include/Fledasty/Core/Stack.h index 3eddfc9..c756c3e 100644 --- a/Include/Fledasty/Core/Stack.h +++ b/Include/Fledasty/Core/Stack.h @@ -31,6 +31,8 @@ #include "../Utils/Error.h" +static const size_t FLEDASTY_STACK_DEFAULT_ALLOCATION_SIZE = 16; + #define FLEDASTY_STACK_DEFINE(type, name) \ typedef struct { \ size_t size, capacity; \ @@ -71,7 +73,7 @@ FledastyError fledasty_stack_##name##_push(FledastyStack_##name *current_stack, } \ \ if (current_stack->size == current_stack->capacity) { \ - current_stack->capacity += current_stack->capacity ? current_stack->capacity : 16; \ + current_stack->capacity += current_stack->capacity ? current_stack->capacity : FLEDASTY_STACK_DEFAULT_ALLOCATION_SIZE; \ current_stack->buffer = (type*)hallocy_realloc(current_stack->buffer, current_stack->capacity * sizeof(type)); \ \ if (current_stack->buffer == NULL) { \ @@ -97,7 +99,7 @@ FledastyError fledasty_stack_##name##_shrink_to_fit(FledastyStack_##name *curren return FLEDASTY_ERROR_INVALID_POINTER; \ } \ \ - current_stack->capacity = (current_stack->size == 0) ? 10 : current_stack->size; \ + current_stack->capacity = (current_stack->size == 0) ? FLEDASTY_STACK_DEFAULT_ALLOCATION_SIZE : current_stack->size; \ type *shrinked_buffer = (type*)hallocy_malloc(current_stack->capacity * sizeof(type)); \ if (shrinked_buffer == NULL) { \ return FLEDASTY_ERROR_FAILED_ALLOCATION; \ -- 2.39.5 From 9b2c601a82f5448389489342d030be5f9975d9c4 Mon Sep 17 00:00:00 2001 From: Mineplay Date: Wed, 9 Jul 2025 13:33:48 -0500 Subject: [PATCH 32/33] perf(linked list): changed linked list to be defined using macros to improve performance --- Include/Fledasty/Core/DynamicArray.h | 42 +-- Include/Fledasty/Core/HashTable.h | 52 ++-- Include/Fledasty/Core/LinkedList.h | 310 +++++++++++++++++++-- Include/Fledasty/Core/Queue.h | 32 +-- Src/Core/LinkedList.c | 393 --------------------------- Tests/Main.c | 44 ++- 6 files changed, 368 insertions(+), 505 deletions(-) delete mode 100644 Src/Core/LinkedList.c diff --git a/Include/Fledasty/Core/DynamicArray.h b/Include/Fledasty/Core/DynamicArray.h index e2ebf4b..feeaeff 100644 --- a/Include/Fledasty/Core/DynamicArray.h +++ b/Include/Fledasty/Core/DynamicArray.h @@ -34,27 +34,27 @@ static const size_t FLEDASTY_DYNAMIC_ARRAY_DEFAULT_ALLOCATION_SIZE = 16; -#define FLEDASTY_DYNAMIC_ARRAY_DEFINE(type, name) \ -typedef struct { \ - size_t size, capacity; \ - type *buffer; \ -} FledastyDynamicArray_##name; \ - \ -FledastyError fledasty_dynamic_array_##name##_free(FledastyDynamicArray_##name *current_dynamic_array); \ - \ -FledastyError fledasty_dynamic_array_##name##_append(FledastyDynamicArray_##name *current_dynamic_array, type value); \ - \ -FledastyError fledasty_dynamic_array_##name##_insert_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index, type value); \ -FledastyError fledasty_dynamic_array_##name##_insert_before_value(FledastyDynamicArray_##name *current_dynamic_array, type before_value, type value); \ -FledastyError fledasty_dynamic_array_##name##_insert_after_value(FledastyDynamicArray_##name *current_dynamic_array, type after_value, type value); \ - \ -FledastyError fledasty_dynamic_array_##name##_remove_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index); \ -FledastyError fledasty_dynamic_array_##name##_remove_value(FledastyDynamicArray_##name *current_dynamic_array, type value); \ - \ -FledastyError fledasty_dynamic_array_##name##_clear(FledastyDynamicArray_##name *current_dynamic_array); \ -FledastyError fledasty_dynamic_array_##name##_shrink_to_fit(FledastyDynamicArray_##name *current_dynamic_array); \ - \ -bool fledasty_dynamic_array_##name##_has_value(const FledastyDynamicArray_##name *current_dynamic_array, type value); \ +#define FLEDASTY_DYNAMIC_ARRAY_DEFINE(type, name) \ +typedef struct { \ + size_t size, capacity; \ + type *buffer; \ +} FledastyDynamicArray_##name; \ + \ +FledastyError fledasty_dynamic_array_##name##_free(FledastyDynamicArray_##name *current_dynamic_array); \ + \ +FledastyError fledasty_dynamic_array_##name##_append(FledastyDynamicArray_##name *current_dynamic_array, type value); \ + \ +FledastyError fledasty_dynamic_array_##name##_insert_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index, type value); \ +FledastyError fledasty_dynamic_array_##name##_insert_before_value(FledastyDynamicArray_##name *current_dynamic_array, type before_value, type value); \ +FledastyError fledasty_dynamic_array_##name##_insert_after_value(FledastyDynamicArray_##name *current_dynamic_array, type after_value, type value); \ + \ +FledastyError fledasty_dynamic_array_##name##_remove_at_index(FledastyDynamicArray_##name *current_dynamic_array, const size_t index); \ +FledastyError fledasty_dynamic_array_##name##_remove_value(FledastyDynamicArray_##name *current_dynamic_array, type value); \ + \ +FledastyError fledasty_dynamic_array_##name##_clear(FledastyDynamicArray_##name *current_dynamic_array); \ +FledastyError fledasty_dynamic_array_##name##_shrink_to_fit(FledastyDynamicArray_##name *current_dynamic_array); \ + \ +bool fledasty_dynamic_array_##name##_has_value(const FledastyDynamicArray_##name *current_dynamic_array, type value); \ inline static bool fledasty_dynamic_array_##name##_is_empty(const FledastyDynamicArray_##name *current_dynamic_array) { return current_dynamic_array == NULL || current_dynamic_array->size == 0; } #define FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(type, name, compare_function) \ diff --git a/Include/Fledasty/Core/HashTable.h b/Include/Fledasty/Core/HashTable.h index fc5f1f4..7e23655 100644 --- a/Include/Fledasty/Core/HashTable.h +++ b/Include/Fledasty/Core/HashTable.h @@ -37,32 +37,32 @@ static const int FLEDASTY_HASH_TABLE_TOTAL_SIZE_PERCENTAGE = 100; static const int FLEDASTY_HASH_TABLE_THRESHOLD_SIZE_PERCENTAGE = 75; static const size_t FLEDASTY_HASH_TABLE_DEFAULT_ALLOCATION_SIZE = 1024; -#define FLEDASTY_HASH_TABLE_DEFINE(key_type, value_type, name, compare_key_function) \ -typedef struct { \ - key_type key; \ - value_type value; \ -} FledastyHashTablePair_##name; \ - \ -FLEDASTY_DYNAMIC_ARRAY_DEFINE(FledastyHashTablePair_##name, fledasty_internal_pair) \ - \ -typedef struct { \ - size_t size, capacity; \ - FledastyDynamicArray_fledasty_internal_pair *Table; \ - \ - size_t (*hash_function)(const key_type key); \ -} FledastyHashTable_##name; \ - \ -FledastyError fledasty_hash_table_##name##_free(FledastyHashTable_##name *current_hash_table); \ - \ -FledastyError fledasty_hash_table_##name##_insert(FledastyHashTable_##name *current_hash_table, key_type key, value_type value); \ -value_type fledasty_hash_table_##name##_get(const FledastyHashTable_##name *current_hash_table, key_type key); \ -FledastyError fledasty_hash_table_##name##_remove(FledastyHashTable_##name *current_hash_table, key_type key); \ - \ -FledastyError fledasty_hash_table_##name##_clear(FledastyHashTable_##name *current_hash_table); \ -FledastyError fledasty_hash_table_##name##_shrink_to_fit(FledastyHashTable_##name *current_hash_table); \ - \ -bool fledasty_hash_table_##name##_has_key(const FledastyHashTable_##name *current_hash_table, key_type key); \ -static inline bool fledasty_hash_table_##name##_is_empty(const FledastyHashTable_##name *current_hash_table) { return current_hash_table == NULL || current_hash_table->size == 0; } \ +#define FLEDASTY_HASH_TABLE_DEFINE(key_type, value_type, name, compare_key_function) \ +typedef struct { \ + key_type key; \ + value_type value; \ +} FledastyHashTablePair_##name; \ + \ +FLEDASTY_DYNAMIC_ARRAY_DEFINE(FledastyHashTablePair_##name, fledasty_internal_pair) \ + \ +typedef struct { \ + size_t size, capacity; \ + FledastyDynamicArray_fledasty_internal_pair *Table; \ + \ + size_t (*hash_function)(const key_type key); \ +} FledastyHashTable_##name; \ + \ +FledastyError fledasty_hash_table_##name##_free(FledastyHashTable_##name *current_hash_table); \ + \ +FledastyError fledasty_hash_table_##name##_insert(FledastyHashTable_##name *current_hash_table, key_type key, value_type value); \ +value_type fledasty_hash_table_##name##_get(const FledastyHashTable_##name *current_hash_table, key_type key); \ +FledastyError fledasty_hash_table_##name##_remove(FledastyHashTable_##name *current_hash_table, key_type key); \ + \ +FledastyError fledasty_hash_table_##name##_clear(FledastyHashTable_##name *current_hash_table); \ +FledastyError fledasty_hash_table_##name##_shrink_to_fit(FledastyHashTable_##name *current_hash_table); \ + \ +bool fledasty_hash_table_##name##_has_key(const FledastyHashTable_##name *current_hash_table, key_type key); \ +static inline bool fledasty_hash_table_##name##_is_empty(const FledastyHashTable_##name *current_hash_table) { return current_hash_table == NULL || current_hash_table->size == 0; } \ static inline bool fledasty_hash_table_##name##_compare_pair(const FledastyHashTablePair_##name first_pair, const FledastyHashTablePair_##name second_pair) { return compare_key_function(first_pair.key, second_pair.key); } #define FLEDASTY_HASH_TABLE_IMPLEMENT(key_type, value_type, name, compare_key_function) \ diff --git a/Include/Fledasty/Core/LinkedList.h b/Include/Fledasty/Core/LinkedList.h index 49f5bc7..e496808 100644 --- a/Include/Fledasty/Core/LinkedList.h +++ b/Include/Fledasty/Core/LinkedList.h @@ -26,34 +26,294 @@ #include #include +#include +#include +#include #include "../Utils/Error.h" -typedef struct FledastyLinkedListNode{ - void *value; - struct FledastyLinkedListNode *next; -} FledastyLinkedListNode; +#define FLEDASTY_LINKED_LIST_DEFINE(type, name) \ +typedef struct FledastyLinkedListNode_##name { \ + type value; \ + struct FledastyLinkedListNode_##name *next; \ +} FledastyLinkedListNode_##name; \ + \ +typedef struct { \ + size_t size; \ + FledastyLinkedListNode_##name *start, *end; \ +} FledastyLinkedList_##name; \ + \ +FledastyError fledasty_linked_list_##name##_free(FledastyLinkedList_##name *current_linked_list); \ + \ +FledastyError fledasty_linked_list_##name##_append(FledastyLinkedList_##name *current_linked_list, type value); \ + \ +FledastyError fledasty_linked_list_##name##_insert_at_index(FledastyLinkedList_##name *current_linked_list, const size_t index, type value); \ +FledastyError fledasty_linked_list_##name##_insert_before_value(FledastyLinkedList_##name *current_linked_list, type before_value, type value); \ +FledastyError fledasty_linked_list_##name##_insert_after_value(FledastyLinkedList_##name *current_linked_list, type after_value, type value); \ + \ +FledastyError fledasty_linked_list_##name##_remove_at_index(FledastyLinkedList_##name *current_linked_list, const size_t index); \ +FledastyError fledasty_linked_list_##name##_remove_value(FledastyLinkedList_##name *current_linked_list, type value); \ + \ +FledastyError fledasty_linked_list_##name##_clear(FledastyLinkedList_##name *current_linked_list); \ + \ +bool fledasty_linked_list_##name##_has_value(const FledastyLinkedList_##name *current_linked_list, type value); \ +static inline bool fledasty_linked_list_##name##_is_empty(const FledastyLinkedList_##name *current_linked_list) { return current_linked_list == NULL || current_linked_list->size == 0; } -typedef struct { - size_t size, element_byte_size; - FledastyLinkedListNode *start, *end; -} FledastyLinkedList; - -FledastyError fledasty_linked_list_initialize(FledastyLinkedList *new_linked_list, void *values, const size_t values_size, const size_t element_byte_size); -FledastyError fledasty_linked_list_destroy(FledastyLinkedList *current_linked_list); - -FledastyError fledasty_linked_list_append(FledastyLinkedList *current_linked_list, void *value); - -FledastyError fledasty_linked_list_insert_at_index(FledastyLinkedList *current_linked_list, const size_t index, void *value); -FledastyError fledasty_linked_list_insert_before_value(FledastyLinkedList *current_linked_list, void *before_value, void *value); -FledastyError fledasty_linked_list_insert_after_value(FledastyLinkedList *current_linked_list, void *after_value, void *value); - -FledastyError fledasty_linked_list_remove_at_index(FledastyLinkedList *current_linked_list, const size_t index); -FledastyError fledasty_linked_list_remove_value(FledastyLinkedList *current_linked_list, void *value); - -FledastyError fledasty_linked_list_clear(FledastyLinkedList *current_linked_list); - -bool fledasty_linked_list_has_value(const FledastyLinkedList *current_linked_list, void *value); -static inline bool fledasty_linked_list_is_empty(const FledastyLinkedList *current_linked_list) { return current_linked_list == NULL || current_linked_list->size == 0; } +#define FLEDASTY_LINKED_LIST_IMPLEMENT(type, name, compare_function) \ +FledastyError fledasty_linked_list_##name##_free(FledastyLinkedList_##name *current_linked_list) { \ + if (current_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyLinkedListNode_##name *previous_node = NULL; \ + FledastyLinkedListNode_##name *current_node = current_linked_list->start; \ + while (current_node != NULL) { \ + previous_node = current_node; \ + current_node = current_node->next; \ + \ + if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_linked_list_##name##_append(FledastyLinkedList_##name *current_linked_list, type value) { \ + if (current_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyLinkedListNode_##name *new_node = (FledastyLinkedListNode_##name*)hallocy_malloc(sizeof(FledastyLinkedListNode_##name)); \ + if (new_node == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + new_node->value = value; \ + new_node->next = NULL; \ + \ + if (current_linked_list->start == NULL) { \ + current_linked_list->start = new_node; \ + current_linked_list->end = new_node; \ + } else { \ + current_linked_list->end->next = new_node; \ + current_linked_list->end = new_node; \ + } \ + \ + current_linked_list->size += 1; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_linked_list_##name##_insert_at_index(FledastyLinkedList_##name *current_linked_list, const size_t index, type value) { \ + if (current_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (index > current_linked_list->size) { \ + return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; \ + } \ + \ + FledastyLinkedListNode_##name *new_node = (FledastyLinkedListNode_##name*)hallocy_malloc(sizeof(FledastyLinkedListNode_##name)); \ + if (new_node == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + new_node->value = value; \ + if (index == 0) { \ + new_node->next = current_linked_list->start; \ + current_linked_list->start = new_node; \ + } else if (index == current_linked_list->size) { \ + new_node->next = NULL; \ + current_linked_list->end->next = new_node; \ + current_linked_list->end = new_node; \ + } else { \ + FledastyLinkedListNode_##name *current_node = current_linked_list->start; \ + for (size_t node = 0; node < index - 1; node += 1) { \ + current_node = current_node->next; \ + } \ + \ + new_node->next = current_node->next; \ + current_node->next = new_node; \ + } \ + \ + current_linked_list->size += 1; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_linked_list_##name##_insert_before_value(FledastyLinkedList_##name *current_linked_list, type before_value, type value) { \ + if (current_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyLinkedListNode_##name *previous_node = NULL; \ + FledastyLinkedListNode_##name *current_node = current_linked_list->start; \ + while (current_node != NULL) { \ + if (compare_function(current_node->value, before_value)) { \ + FledastyLinkedListNode_##name *new_node = (FledastyLinkedListNode_##name*)hallocy_malloc(sizeof(FledastyLinkedListNode_##name)); \ + if (new_node == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + new_node->value = value; \ + if (previous_node == NULL) { \ + new_node->next = current_linked_list->start; \ + current_linked_list->start = new_node; \ + } else { \ + new_node->next = current_node; \ + previous_node->next = new_node; \ + } \ + \ + current_linked_list->size += 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + \ + previous_node = current_node; \ + current_node = current_node->next; \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_linked_list_##name##_insert_after_value(FledastyLinkedList_##name *current_linked_list, type after_value, type value) { \ + if (current_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyLinkedListNode_##name *current_node = current_linked_list->start; \ + while (current_node != NULL) { \ + if (compare_function(current_node->value, after_value)) { \ + FledastyLinkedListNode_##name *new_node = (FledastyLinkedListNode_##name*)hallocy_malloc(sizeof(FledastyLinkedListNode_##name)); \ + if (new_node == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + new_node->value = value; \ + if (current_node == current_linked_list->end) { \ + new_node->next = NULL; \ + \ + current_linked_list->end->next = new_node; \ + current_linked_list->end = new_node; \ + } else { \ + new_node->next = current_node->next; \ + current_node->next = new_node; \ + } \ + \ + current_linked_list->size += 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + \ + current_node = current_node->next; \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_linked_list_##name##_remove_at_index(FledastyLinkedList_##name *current_linked_list, const size_t index) { \ + if (current_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (index >= current_linked_list->size) { \ + return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; \ + } \ + \ + FledastyLinkedListNode_##name *previous_node = NULL; \ + FledastyLinkedListNode_##name *current_node = current_linked_list->start; \ + for (size_t node = 0; node < index; node += 1) { \ + previous_node = current_node; \ + current_node = current_node->next; \ + } \ + \ + if (current_node == current_linked_list->end) { \ + current_linked_list->end = previous_node; \ + } \ + \ + if (previous_node == NULL) { \ + current_linked_list->start = current_node->next; \ + } else { \ + previous_node->next = current_node->next; \ + } \ + \ + if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_linked_list->size -= 1; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_linked_list_##name##_remove_value(FledastyLinkedList_##name *current_linked_list, type value) { \ + if (current_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyLinkedListNode_##name *previous_node = NULL; \ + FledastyLinkedListNode_##name *current_node = current_linked_list->start; \ + while (current_node != NULL) { \ + if (compare_function(current_node->value, value)) { \ + if (current_node == current_linked_list->end) { \ + current_linked_list->end = previous_node; \ + } \ + \ + if (previous_node == NULL) { \ + current_linked_list->start = current_node->next; \ + } else { \ + previous_node->next = current_node->next; \ + } \ + \ + if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_linked_list->size -= 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + \ + previous_node = current_node; \ + current_node = current_node->next; \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_linked_list_##name##_clear(FledastyLinkedList_##name *current_linked_list) { \ + if (current_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyLinkedListNode_##name *previous_node = NULL; \ + FledastyLinkedListNode_##name *current_node = current_linked_list->start; \ + while (current_node != NULL) { \ + previous_node = current_node; \ + current_node = current_node->next; \ + \ + if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + current_linked_list->start = NULL; \ + current_linked_list->end = NULL; \ + \ + current_linked_list->size = 0; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +bool fledasty_linked_list_##name##_has_value(const FledastyLinkedList_##name *current_linked_list, type value) { \ + if (current_linked_list == NULL) { \ + return false; \ + } \ + \ + FledastyLinkedListNode_##name *current_node = current_linked_list->start; \ + while (current_node != NULL) { \ + if (compare_function(current_node->value, value)) { \ + return true; \ + } \ + \ + current_node = current_node->next; \ + } \ + \ + return false; \ +} #endif diff --git a/Include/Fledasty/Core/Queue.h b/Include/Fledasty/Core/Queue.h index a6a1a03..1d59790 100644 --- a/Include/Fledasty/Core/Queue.h +++ b/Include/Fledasty/Core/Queue.h @@ -33,22 +33,22 @@ static const size_t FLEDASTY_QUEUE_DEFAULT_ALLOCATION_SIZE = 16; -#define FLEDASTY_QUEUE_DEFINE(type, name) \ -typedef struct { \ - size_t size, capacity; \ - size_t head, tail; \ - type *buffer; \ -} FledastyQueue_##name; \ - \ -FledastyError fledasty_queue_##name##_free(FledastyQueue_##name *current_queue); \ - \ -FledastyError fledasty_queue_##name##_push(FledastyQueue_##name *current_queue, type value); \ -type fledasty_queue_##name##_pop(FledastyQueue_##name *current_queue); \ - \ -FledastyError fledasty_queue_##name##_clear(FledastyQueue_##name *current_queue); \ -FledastyError fledasty_queue_##name##_shrink_to_fit(FledastyQueue_##name *current_queue); \ - \ -static inline type fledasty_queue_##name##_peek(const FledastyQueue_##name *current_queue) { return (current_queue != NULL && current_queue->size > 0) ? current_queue->buffer[current_queue->head] : 0; } \ +#define FLEDASTY_QUEUE_DEFINE(type, name) \ +typedef struct { \ + size_t size, capacity; \ + size_t head, tail; \ + type *buffer; \ +} FledastyQueue_##name; \ + \ +FledastyError fledasty_queue_##name##_free(FledastyQueue_##name *current_queue); \ + \ +FledastyError fledasty_queue_##name##_push(FledastyQueue_##name *current_queue, type value); \ +type fledasty_queue_##name##_pop(FledastyQueue_##name *current_queue); \ + \ +FledastyError fledasty_queue_##name##_clear(FledastyQueue_##name *current_queue); \ +FledastyError fledasty_queue_##name##_shrink_to_fit(FledastyQueue_##name *current_queue); \ + \ +static inline type fledasty_queue_##name##_peek(const FledastyQueue_##name *current_queue) { return (current_queue != NULL && current_queue->size > 0) ? current_queue->buffer[current_queue->head] : 0; } \ static inline bool fledasty_queue_##name##_is_empty(const FledastyQueue_##name *current_queue) { return current_queue == NULL || current_queue->size == 0; } #define FLEDASTY_QUEUE_IMPLEMENT(type, name) \ diff --git a/Src/Core/LinkedList.c b/Src/Core/LinkedList.c deleted file mode 100644 index 609658c..0000000 --- a/Src/Core/LinkedList.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ----------------------------------------------------------------------------- - * File: LinkedList.c - * Description: - * This file contains the functions for modifying the Linked List. It includes - * functions to append, Insert before, Insert after, Insert at index, - * Get, Remove element, Remove at index, Check if has element and Check if is empty. - * - * Author: Mineplay - * ----------------------------------------------------------------------------- - */ -#include "../../Include/Fledasty/Core/LinkedList.h" - -#include -#include -#include - -FledastyError fledasty_linked_list_initialize(FledastyLinkedList *new_linked_list, void *values, const size_t values_size, const size_t element_byte_size) { - if (new_linked_list == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_linked_list->element_byte_size = element_byte_size; - if (values == NULL || values_size == 0) { - new_linked_list->size = 0; - new_linked_list->start = NULL; - new_linked_list->end = NULL; - } else { - new_linked_list->size = values_size; - - new_linked_list->start = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - if (new_linked_list->start == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_linked_list->start->value = hallocy_malloc(new_linked_list->element_byte_size); - if (new_linked_list->start->value == NULL) { - hallocy_free(new_linked_list->start); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_linked_list->start->value, values, new_linked_list->element_byte_size); - new_linked_list->start->next = NULL; - - FledastyLinkedListNode *last_node = new_linked_list->start; - for (size_t index = new_linked_list->element_byte_size; index < new_linked_list->size * new_linked_list->element_byte_size; index += new_linked_list->element_byte_size) { - FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - if (new_node == NULL) { - FledastyLinkedListNode *previous_node = NULL; - FledastyLinkedListNode *current_node = new_linked_list->start; - while (current_node != NULL) { - previous_node = current_node; - current_node = current_node->next; - - hallocy_free(previous_node->value); - hallocy_free(previous_node); - } - - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(new_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - - FledastyLinkedListNode *previous_node = NULL; - FledastyLinkedListNode *current_node = new_linked_list->start; - while (current_node != NULL) { - previous_node = current_node; - current_node = current_node->next; - - hallocy_free(previous_node->value); - hallocy_free(previous_node); - } - - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, (unsigned char*)values + index, new_linked_list->element_byte_size); - - new_node->next = NULL; - last_node->next = new_node; - last_node = new_node; - } - - new_linked_list->end = last_node; - } - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_linked_list_destroy(FledastyLinkedList *current_linked_list) { - if (current_linked_list == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyLinkedListNode *previous_node = NULL; - FledastyLinkedListNode *current_node = current_linked_list->start; - while (current_node != NULL) { - previous_node = current_node; - current_node = current_node->next; - - if (hallocy_free(previous_node->value) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_linked_list_append(FledastyLinkedList *current_linked_list, void *value) { - if (current_linked_list == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); - new_node->next = NULL; - - current_linked_list->end->next = new_node; - current_linked_list->end = new_node; - current_linked_list->size += 1; - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_linked_list_insert_at_index(FledastyLinkedList *current_linked_list, const size_t index, void *value) { - if (current_linked_list == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (index > current_linked_list->size) { - return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; - } - - FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); - if (index == 0) { - new_node->next = current_linked_list->start; - current_linked_list->start = new_node; - } else if (index == current_linked_list->size) { - new_node->next = NULL; - current_linked_list->end->next = new_node; - current_linked_list->end = new_node; - } else { - FledastyLinkedListNode *current_node = current_linked_list->start; - for (size_t node = 0; node < index - 1; node += 1) { - current_node = current_node->next; - } - - new_node->next = current_node->next; - current_node->next = new_node; - } - - current_linked_list->size += 1; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_linked_list_insert_before_value(FledastyLinkedList *current_linked_list, void *before_value, void *value) { - if (current_linked_list == NULL || before_value == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyLinkedListNode *previous_node = NULL; - FledastyLinkedListNode *current_node = current_linked_list->start; - while (current_node != NULL) { - if (hallocy_compare_memory(current_node->value, before_value, current_linked_list->element_byte_size)) { - FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); - if (previous_node == NULL) { - new_node->next = current_linked_list->start; - current_linked_list->start = new_node; - } else { - new_node->next = current_node; - previous_node->next = new_node; - } - - current_linked_list->size += 1; - return FLEDASTY_ERROR_NONE; - } - - previous_node = current_node; - current_node = current_node->next; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -FledastyError fledasty_linked_list_insert_after_value(FledastyLinkedList *current_linked_list, void *after_value, void *value) { - if (current_linked_list == NULL || after_value == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyLinkedListNode *current_node = current_linked_list->start; - while (current_node != NULL) { - if (hallocy_compare_memory(current_node->value, after_value, current_linked_list->element_byte_size)) { - FledastyLinkedListNode *new_node = (FledastyLinkedListNode*)hallocy_malloc(sizeof(FledastyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_linked_list->element_byte_size); - if (current_node == current_linked_list->end) { - new_node->next = NULL; - - current_linked_list->end->next = new_node; - current_linked_list->end = new_node; - } else { - new_node->next = current_node->next; - current_node->next = new_node; - } - - current_linked_list->size += 1; - return FLEDASTY_ERROR_NONE; - } - - current_node = current_node->next; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -FledastyError fledasty_linked_list_remove_at_index(FledastyLinkedList *current_linked_list, const size_t index) { - if (current_linked_list == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (index >= current_linked_list->size) { - return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; - } - - FledastyLinkedListNode *previous_node = NULL; - FledastyLinkedListNode *current_node = current_linked_list->start; - for (size_t node = 0; node < index; node += 1) { - previous_node = current_node; - current_node = current_node->next; - } - - if (current_node == current_linked_list->end) { - current_linked_list->end = previous_node; - } - - if (previous_node == NULL) { - current_linked_list->start = current_node->next; - } else { - previous_node->next = current_node->next; - } - - if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_linked_list->size -= 1; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_linked_list_remove_value(FledastyLinkedList *current_linked_list, void *value) { - if (current_linked_list == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyLinkedListNode *previous_node = NULL; - FledastyLinkedListNode *current_node = current_linked_list->start; - while (current_node != NULL) { - if (hallocy_compare_memory(current_node->value, value, current_linked_list->element_byte_size)) { - if (current_node == current_linked_list->end) { - current_linked_list->end = previous_node; - } - - if (previous_node == NULL) { - current_linked_list->start = current_node->next; - } else { - previous_node->next = current_node->next; - } - - if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_linked_list->size -= 1; - return FLEDASTY_ERROR_NONE; - } - - previous_node = current_node; - current_node = current_node->next; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -FledastyError fledasty_linked_list_clear(FledastyLinkedList *current_linked_list) { - if (current_linked_list == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyLinkedListNode *previous_node = NULL; - FledastyLinkedListNode *current_node = current_linked_list->start; - while (current_node != NULL) { - previous_node = current_node; - current_node = current_node->next; - - if (hallocy_free(previous_node->value) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - current_linked_list->start = NULL; - current_linked_list->end = NULL; - - current_linked_list->size = 0; - return FLEDASTY_ERROR_NONE; -} - -bool fledasty_linked_list_has_value(const FledastyLinkedList *current_linked_list, void *value) { - if (current_linked_list == NULL || value == NULL) { - return false; - } - - FledastyLinkedListNode *current_node = current_linked_list->start; - while (current_node != NULL) { - if (hallocy_compare_memory(current_node->value, value, current_linked_list->element_byte_size)) { - return true; - } - - current_node = current_node->next; - } - - return false; -} diff --git a/Tests/Main.c b/Tests/Main.c index d0f8498..e13c48a 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -45,6 +45,9 @@ FLEDASTY_DYNAMIC_ARRAY_IMPLEMENT(int, int, compare_integers) FLEDASTY_HASH_TABLE_DEFINE(int, int, int_int, compare_integers) FLEDASTY_HASH_TABLE_IMPLEMENT(int, int, int_int, compare_integers) +FLEDASTY_LINKED_LIST_DEFINE(int, int) +FLEDASTY_LINKED_LIST_IMPLEMENT(int, int, compare_integers) + int main() { FledastyQueue_int test_queue = { 0, 0, 0, 0, NULL }; for (int i = 0; i < 10; i += 1) { @@ -117,41 +120,34 @@ int main() { fledasty_dynamic_array_int_free(&test_dynamic_array); - FledastyLinkedList test_linked_list; - fledasty_linked_list_initialize(&test_linked_list, (int[]){11, 12, 13, 14, 15}, 5, sizeof(int)); - + FledastyLinkedList_int test_linked_list = { 0, NULL, NULL }; for (int i = 0; i < 10; i += 1) { - fledasty_linked_list_append(&test_linked_list, &i); + fledasty_linked_list_int_append(&test_linked_list, i); } - int insert_value = 35; - fledasty_linked_list_insert_at_index(&test_linked_list, 1, &insert_value); - insert_value = 28; - int insert_at_value = 35; - fledasty_linked_list_insert_before_value(&test_linked_list, &insert_at_value, &insert_value); - insert_value = 90; - fledasty_linked_list_insert_after_value(&test_linked_list, &insert_at_value, &insert_value); + fledasty_linked_list_int_insert_at_index(&test_linked_list, 1, 35); + fledasty_linked_list_int_insert_before_value(&test_linked_list, 35, 28); + fledasty_linked_list_int_insert_after_value(&test_linked_list, 35, 90); - fledasty_linked_list_remove_at_index(&test_linked_list, 2); - int remove_value = 0; - fledasty_linked_list_remove_value(&test_linked_list, &remove_value); + fledasty_linked_list_int_remove_at_index(&test_linked_list, 2); + fledasty_linked_list_int_remove_value(&test_linked_list, 0); - FledastyLinkedListNode *test_linked_list_node = test_linked_list.start; + FledastyLinkedListNode_int *test_linked_list_node = test_linked_list.start; for (int i = 0; i < test_linked_list.size; i += 1) { - printf("Linked list get: %d\n", *(int*)test_linked_list_node->value); + printf("Linked list get: %d\n", test_linked_list_node->value); test_linked_list_node = test_linked_list_node->next; } - if (fledasty_linked_list_has_value(&test_linked_list, &insert_value)) { - printf("Linked list contains %d\n", insert_value); + if (fledasty_linked_list_int_has_value(&test_linked_list, 90)) { + printf("Linked list contains 90\n"); } - fledasty_linked_list_clear(&test_linked_list); - if (fledasty_linked_list_is_empty(&test_linked_list)) { + fledasty_linked_list_int_clear(&test_linked_list); + if (fledasty_linked_list_int_is_empty(&test_linked_list)) { printf("Linked list is empty\n"); } - fledasty_linked_list_destroy(&test_linked_list); + fledasty_linked_list_int_free(&test_linked_list); FledastyDoublyLinkedList test_doubly_linked_list; fledasty_doubly_linked_list_initialize(&test_doubly_linked_list, (int[]){11, 12, 13, 14, 15}, 5, sizeof(int)); @@ -159,16 +155,16 @@ int main() { fledasty_doubly_linked_list_append(&test_doubly_linked_list, &i); } - insert_value = 35; + int insert_value = 35; fledasty_doubly_linked_list_insert_at_index(&test_doubly_linked_list, test_doubly_linked_list.size - 1, &insert_value); insert_value = 28; - insert_at_value = 35; + int insert_at_value = 35; fledasty_doubly_linked_list_insert_before_value(&test_doubly_linked_list, &insert_at_value, &insert_value); insert_value = 90; fledasty_doubly_linked_list_insert_after_value(&test_doubly_linked_list, &insert_at_value, &insert_value); fledasty_doubly_linked_list_remove_at_index(&test_doubly_linked_list, 2); - remove_value = 0; + int remove_value = 0; fledasty_doubly_linked_list_remove_value(&test_doubly_linked_list, &remove_value); FledastyDoublyLinkedListNode *test_doubly_linked_list_node = test_doubly_linked_list.start; -- 2.39.5 From 00dac4ff9cd5fc14200f165a34e416a7b99128ba Mon Sep 17 00:00:00 2001 From: Mineplay Date: Thu, 10 Jul 2025 16:51:59 -0500 Subject: [PATCH 33/33] perf(doubly linked list): changed doubly linked list to be defined using macros to improve performance --- Include/Fledasty/Core/DoublyLinkedList.h | 344 ++++++++++++++++-- Src/Core/DoublyLinkedList.c | 436 ----------------------- Tests/Main.c | 39 +- 3 files changed, 337 insertions(+), 482 deletions(-) delete mode 100644 Src/Core/DoublyLinkedList.c diff --git a/Include/Fledasty/Core/DoublyLinkedList.h b/Include/Fledasty/Core/DoublyLinkedList.h index 5cdb667..a7d1a02 100644 --- a/Include/Fledasty/Core/DoublyLinkedList.h +++ b/Include/Fledasty/Core/DoublyLinkedList.h @@ -27,34 +27,328 @@ #include #include +#include +#include +#include #include "../Utils/Error.h" -typedef struct FledastyDoublyLinkedListNode { - void *value; - struct FledastyDoublyLinkedListNode *previous, *next; -} FledastyDoublyLinkedListNode; +#define FLEDASTY_DOUBLY_LINKED_LIST_DEFINE(type, name) \ +typedef struct FledastyDoublyLinkedListNode_##name { \ + type value; \ + struct FledastyDoublyLinkedListNode_##name *previous, *next; \ +} FledastyDoublyLinkedListNode_##name; \ + \ +typedef struct { \ + size_t size; \ + FledastyDoublyLinkedListNode_##name *start, *end; \ +} FledastyDoublyLinkedList_##name; \ + \ +FledastyError fledasty_doubly_list_##name##_free(FledastyDoublyLinkedList_##name *current_doubly_linked_list); \ + \ +FledastyError fledasty_doubly_linked_list_##name##_append(FledastyDoublyLinkedList_##name *current_doubly_linked_list, type value); \ + \ +FledastyError fledasty_doubly_linked_list_##name##_insert_at_index(FledastyDoublyLinkedList_##name *current_doubly_linked_list, const size_t index, type value); \ +FledastyError fledasty_doubly_linked_list_##name##_insert_before_value(FledastyDoublyLinkedList_##name *current_doubly_linked_list, type before_value, type value); \ +FledastyError fledasty_doubly_linked_list_##name##_insert_after_value(FledastyDoublyLinkedList_##name *current_doubly_linked_list, type after_value, type value); \ + \ +FledastyError fledasty_doubly_linked_list_##name##_remove_at_index(FledastyDoublyLinkedList_##name *current_doubly_linked_list, const size_t index); \ +FledastyError fledasty_doubly_linked_list_##name##_remove_value(FledastyDoublyLinkedList_##name *current_doubly_linked_list, type value); \ + \ +FledastyError fledasty_doubly_linked_list_##name##_clear(FledastyDoublyLinkedList_##name *current_doubly_linked_list); \ + \ +bool fledasty_doubly_linked_list_##name##_has_value(const FledastyDoublyLinkedList_##name *current_doubly_linked_list, type value); \ +static inline bool fledasty_doubly_linked_list_##name##_is_empty(const FledastyDoublyLinkedList_##name *current_doubly_linked_list) { return current_doubly_linked_list == NULL || current_doubly_linked_list->size == 0; } -typedef struct { - size_t size, element_byte_size; - FledastyDoublyLinkedListNode *start, *end; -} FledastyDoublyLinkedList; - -FledastyError fledasty_doubly_linked_list_initialize(FledastyDoublyLinkedList *new_doubly_linked_list, void *values, const size_t values_size, const size_t element_byte_size); -FledastyError fledasty_doubly_list_destroy(FledastyDoublyLinkedList *current_doubly_linked_list); - -FledastyError fledasty_doubly_linked_list_append(FledastyDoublyLinkedList *current_doubly_linked_list, void *value); - -FledastyError fledasty_doubly_linked_list_insert_at_index(FledastyDoublyLinkedList *current_doubly_linked_list, const size_t index, void *value); -FledastyError fledasty_doubly_linked_list_insert_before_value(FledastyDoublyLinkedList *current_doubly_linked_list, void *before_value, void *value); -FledastyError fledasty_doubly_linked_list_insert_after_value(FledastyDoublyLinkedList *current_doubly_linked_list, void *after_value, void *value); - -FledastyError fledasty_doubly_linked_list_remove_at_index(FledastyDoublyLinkedList *current_doubly_linked_list, const size_t index); -FledastyError fledasty_doubly_linked_list_remove_value(FledastyDoublyLinkedList *current_doubly_linked_list, void *value); - -FledastyError fledasty_doubly_linked_list_clear(FledastyDoublyLinkedList *current_doubly_linked_list); - -bool fledasty_doubly_linked_list_has_value(const FledastyDoublyLinkedList *current_doubly_linked_list, void *value); -static inline bool fledasty_doubly_linked_list_is_empty(const FledastyDoublyLinkedList *current_doubly_linked_list) { return current_doubly_linked_list == NULL || current_doubly_linked_list->size == 0; } +#define FLEDASTY_DOUBLY_LINKED_LIST_IMPLEMENT(type, name, compare_function) \ +FledastyError fledasty_doubly_list_##name##_free(FledastyDoublyLinkedList_##name *current_doubly_linked_list) { \ + if (current_doubly_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyDoublyLinkedListNode_##name *previous_node = NULL; \ + FledastyDoublyLinkedListNode_##name *current_node = current_doubly_linked_list->start; \ + while (current_node != NULL) { \ + previous_node = current_node; \ + current_node = current_node->next; \ + \ + if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_doubly_linked_list_##name##_append(FledastyDoublyLinkedList_##name *current_doubly_linked_list, type value) { \ + if (current_doubly_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyDoublyLinkedListNode_##name *new_node = (FledastyDoublyLinkedListNode_##name*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode_##name)); \ + if (new_node == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + new_node->value = value; \ + \ + new_node->previous = current_doubly_linked_list->end; \ + new_node->next = NULL; \ + \ + if (current_doubly_linked_list->start == NULL) { \ + current_doubly_linked_list->start = new_node; \ + } else { \ + current_doubly_linked_list->end->next = new_node; \ + } \ + \ + current_doubly_linked_list->end = new_node; \ + current_doubly_linked_list->size += 1; \ + \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_doubly_linked_list_##name##_insert_at_index(FledastyDoublyLinkedList_##name *current_doubly_linked_list, const size_t index, type value) { \ + if (current_doubly_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (index > current_doubly_linked_list->size) { \ + return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; \ + } \ + \ + FledastyDoublyLinkedListNode_##name *new_node = (FledastyDoublyLinkedListNode_##name*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode_##name)); \ + if (new_node == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + new_node->value = value; \ + if (index == 0) { \ + new_node->previous = NULL; \ + new_node->next = current_doubly_linked_list->start; \ + \ + current_doubly_linked_list->start->previous = new_node; \ + current_doubly_linked_list->start = new_node; \ + } else if (index == current_doubly_linked_list->size) { \ + new_node->previous = current_doubly_linked_list->end; \ + new_node->next = NULL; \ + \ + current_doubly_linked_list->end->next = new_node; \ + current_doubly_linked_list->end = new_node; \ + } else { \ + FledastyDoublyLinkedListNode_##name *current_node = NULL; \ + if (index < current_doubly_linked_list->size / 2) { \ + current_node = current_doubly_linked_list->start; \ + for (size_t node = 0; node < index - 1; node += 1) { \ + current_node = current_node->next; \ + } \ + } else { \ + current_node = current_doubly_linked_list->end; \ + for (size_t node = current_doubly_linked_list->size - 1; node > index - 1; node -= 1) { \ + current_node = current_node->previous; \ + } \ + } \ + \ + new_node->previous = current_node; \ + new_node->next = current_node->next; \ + \ + current_node->next->previous = new_node; \ + current_node->next = new_node; \ + } \ + \ + current_doubly_linked_list->size += 1; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_doubly_linked_list_##name##_insert_before_value(FledastyDoublyLinkedList_##name *current_doubly_linked_list, type before_value, type value) { \ + if (current_doubly_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyDoublyLinkedListNode_##name *current_node = current_doubly_linked_list->start; \ + while (current_node != NULL) { \ + if (compare_function(current_node->value, before_value)) { \ + FledastyDoublyLinkedListNode_##name *new_node = (FledastyDoublyLinkedListNode_##name*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode_##name)); \ + if (new_node == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + new_node->value = value; \ + if (current_node->previous == NULL) { \ + new_node->previous = NULL; \ + new_node->next = current_doubly_linked_list->start; \ + \ + current_doubly_linked_list->start->previous = new_node; \ + current_doubly_linked_list->start = new_node; \ + } else { \ + new_node->previous = current_node->previous; \ + new_node->next = current_node; \ + \ + current_node->previous->next = new_node; \ + current_node->previous = new_node; \ + } \ + \ + current_doubly_linked_list->size += 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + \ + current_node = current_node->next; \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_doubly_linked_list_##name##_insert_after_value(FledastyDoublyLinkedList_##name *current_doubly_linked_list, type after_value, type value) { \ + if (current_doubly_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyDoublyLinkedListNode_##name *current_node = current_doubly_linked_list->start; \ + while (current_node != NULL) { \ + if (compare_function(current_node->value, after_value)) { \ + FledastyDoublyLinkedListNode_##name *new_node = (FledastyDoublyLinkedListNode_##name*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode_##name)); \ + if (new_node == NULL) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + new_node->value = value; \ + if (current_node == current_doubly_linked_list->end) { \ + new_node->next = NULL; \ + new_node->previous = current_doubly_linked_list->end; \ + \ + current_doubly_linked_list->end->next = new_node; \ + current_doubly_linked_list->end = new_node; \ + } else { \ + new_node->previous = current_node; \ + new_node->next = current_node->next; \ + \ + current_node->next->previous = new_node; \ + current_node->next = new_node; \ + } \ + \ + current_doubly_linked_list->size += 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + \ + current_node = current_node->next; \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_doubly_linked_list_##name##_remove_at_index(FledastyDoublyLinkedList_##name *current_doubly_linked_list, const size_t index) { \ + if (current_doubly_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + if (index >= current_doubly_linked_list->size) { \ + return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; \ + } \ + \ + FledastyDoublyLinkedListNode_##name *current_node = NULL; \ + if (index < current_doubly_linked_list->size / 2) { \ + current_node = current_doubly_linked_list->start; \ + for (size_t node = 0; node < index; node += 1) { \ + current_node = current_node->next; \ + } \ + } else { \ + current_node = current_doubly_linked_list->end; \ + for (size_t node = current_doubly_linked_list->size - 1; node > index; node -= 1) { \ + current_node = current_node->previous; \ + } \ + } \ + \ + if (current_node == current_doubly_linked_list->start) { \ + current_doubly_linked_list->start = current_node->next; \ + } else { \ + current_node->previous->next = current_node->next; \ + } \ + \ + if (current_node == current_doubly_linked_list->end) { \ + current_doubly_linked_list->end = current_node->previous; \ + } else { \ + current_node->next->previous = current_node->previous; \ + } \ + \ + if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_doubly_linked_list->size -= 1; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +FledastyError fledasty_doubly_linked_list_##name##_remove_value(FledastyDoublyLinkedList_##name *current_doubly_linked_list, type value) { \ + if (current_doubly_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyDoublyLinkedListNode_##name *current_node = current_doubly_linked_list->start; \ + while (current_node != NULL) { \ + if (compare_function(current_node->value, value)) { \ + if (current_node == current_doubly_linked_list->start) { \ + current_doubly_linked_list->start = current_node->next; \ + } else { \ + current_node->previous->next = current_node->next; \ + } \ + \ + if (current_node == current_doubly_linked_list->end) { \ + current_doubly_linked_list->end = current_node->previous; \ + } else { \ + current_node->next->previous = current_node->previous; \ + } \ + \ + if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + \ + current_doubly_linked_list->size -= 1; \ + return FLEDASTY_ERROR_NONE; \ + } \ + \ + current_node = current_node->next; \ + } \ + \ + return FLEDASTY_ERROR_VALUE_NOT_FOUND; \ +} \ + \ +FledastyError fledasty_doubly_linked_list_##name##_clear(FledastyDoublyLinkedList_##name *current_doubly_linked_list) { \ + if (current_doubly_linked_list == NULL) { \ + return FLEDASTY_ERROR_INVALID_POINTER; \ + } \ + \ + FledastyDoublyLinkedListNode_##name *previous_node = NULL; \ + FledastyDoublyLinkedListNode_##name *current_node = current_doubly_linked_list->start; \ + while (current_node != NULL) { \ + previous_node = current_node; \ + current_node = current_node->next; \ + \ + if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { \ + return FLEDASTY_ERROR_FAILED_ALLOCATION; \ + } \ + } \ + \ + current_doubly_linked_list->start = NULL; \ + current_doubly_linked_list->end = NULL; \ + \ + current_doubly_linked_list->size = 0; \ + return FLEDASTY_ERROR_NONE; \ +} \ + \ +bool fledasty_doubly_linked_list_##name##_has_value(const FledastyDoublyLinkedList_##name *current_doubly_linked_list, type value) { \ + if (current_doubly_linked_list == NULL) { \ + return false; \ + } \ + \ + FledastyDoublyLinkedListNode_##name *current_node = current_doubly_linked_list->start; \ + while (current_node != NULL) { \ + if (compare_function(current_node->value, value)) { \ + return true; \ + } \ + \ + current_node = current_node->next; \ + } \ + \ + return false; \ +} #endif diff --git a/Src/Core/DoublyLinkedList.c b/Src/Core/DoublyLinkedList.c deleted file mode 100644 index 8a55a33..0000000 --- a/Src/Core/DoublyLinkedList.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * ----------------------------------------------------------------------------- - * File: DoublyLinkedList.c - * Description: - * This file contains the functions for modifying the Doubly Linked List. It - * includes functions to append, Insert before, Insert after, Insert at index, - * Get, Remove element, Remove at index, Check if has element and Check if is empty. - * - * Author: Mineplay - * ----------------------------------------------------------------------------- - */ -#include "../../Include/Fledasty/Core/DoublyLinkedList.h" - -#include -#include -#include - -FledastyError fledasty_doubly_linked_list_initialize(FledastyDoublyLinkedList *new_doubly_linked_list, void *values, const size_t values_size, const size_t element_byte_size) { - if (new_doubly_linked_list == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_doubly_linked_list->element_byte_size = element_byte_size; - if (values == NULL || values_size == 0) { - new_doubly_linked_list->size = 0; - new_doubly_linked_list->start = NULL; - new_doubly_linked_list->end = NULL; - } else { - new_doubly_linked_list->size = values_size; - - new_doubly_linked_list->start = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - if (new_doubly_linked_list->start == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_doubly_linked_list->start->value = hallocy_malloc(new_doubly_linked_list->element_byte_size); - if (new_doubly_linked_list->start->value == NULL) { - hallocy_free(new_doubly_linked_list->start); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_doubly_linked_list->start->value, values, new_doubly_linked_list->element_byte_size); - - new_doubly_linked_list->start->previous = NULL; - new_doubly_linked_list->start->next = NULL; - - FledastyDoublyLinkedListNode *last_node = new_doubly_linked_list->start; - for (size_t index = new_doubly_linked_list->element_byte_size; index < new_doubly_linked_list->size * new_doubly_linked_list->element_byte_size; index += new_doubly_linked_list->element_byte_size) { - FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - if (new_node == NULL) { - FledastyDoublyLinkedListNode *current_node = new_doubly_linked_list->start; - while (current_node->next != NULL) { - current_node = current_node->next; - - hallocy_free(current_node->previous->value); - hallocy_free(current_node->previous); - } - - hallocy_free(current_node->value); - hallocy_free(current_node); - - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(new_doubly_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - - FledastyDoublyLinkedListNode *current_node = new_doubly_linked_list->start; - while (current_node->next != NULL) { - current_node = current_node->next; - - hallocy_free(current_node->previous->value); - hallocy_free(current_node); - } - - hallocy_free(current_node->value); - hallocy_free(current_node); - - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, (unsigned char*)values + index, new_doubly_linked_list->element_byte_size); - - new_node->previous = last_node; - new_node->next = NULL; - - last_node->next = new_node; - last_node = new_node; - } - - new_doubly_linked_list->end = last_node; - } - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_doubly_list_destroy(FledastyDoublyLinkedList *current_doubly_linked_list) { - if (current_doubly_linked_list == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyDoublyLinkedListNode *previous_node = NULL; - FledastyDoublyLinkedListNode *current_node = current_doubly_linked_list->start; - while (current_node != NULL) { - previous_node = current_node; - current_node = current_node->next; - - if (hallocy_free(previous_node->value) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_doubly_linked_list_append(FledastyDoublyLinkedList *current_doubly_linked_list, void *value) { - if (current_doubly_linked_list == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); - - new_node->previous = current_doubly_linked_list->end; - new_node->next = NULL; - - current_doubly_linked_list->end->next = new_node; - current_doubly_linked_list->end = new_node; - current_doubly_linked_list->size += 1; - - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_doubly_linked_list_insert_at_index(FledastyDoublyLinkedList *current_doubly_linked_list, const size_t index, void *value) { - if (current_doubly_linked_list == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (index > current_doubly_linked_list->size) { - return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; - } - - FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); - if (new_node->value) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); - - if (index == 0) { - new_node->previous = NULL; - new_node->next = current_doubly_linked_list->start; - - current_doubly_linked_list->start->previous = new_node; - current_doubly_linked_list->start = new_node; - } else if (index == current_doubly_linked_list->size) { - new_node->previous = current_doubly_linked_list->end; - new_node->next = NULL; - - current_doubly_linked_list->end->next = new_node; - current_doubly_linked_list->end = new_node; - } else { - FledastyDoublyLinkedListNode *current_node = NULL; - if (index < current_doubly_linked_list->size / 2) { - current_node = current_doubly_linked_list->start; - for (size_t node = 0; node < index - 1; node += 1) { - current_node = current_node->next; - } - } else { - current_node = current_doubly_linked_list->end; - for (size_t node = current_doubly_linked_list->size - 1; node > index - 1; node -= 1) { - current_node = current_node->previous; - } - } - - new_node->previous = current_node; - new_node->next = current_node->next; - - current_node->next->previous = new_node; - current_node->next = new_node; - } - - current_doubly_linked_list->size += 1; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_doubly_linked_list_insert_before_value(FledastyDoublyLinkedList *current_doubly_linked_list, void *before_value, void *value) { - if (current_doubly_linked_list == NULL || before_value == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyDoublyLinkedListNode *current_node = current_doubly_linked_list->start; - while (current_node != NULL) { - if (hallocy_compare_memory(current_node->value, before_value, current_doubly_linked_list->element_byte_size)) { - FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); - - if (current_node->previous == NULL) { - new_node->previous = NULL; - new_node->next = current_doubly_linked_list->start; - - current_doubly_linked_list->start->previous = new_node; - current_doubly_linked_list->start = new_node; - } else { - new_node->previous = current_node->previous; - new_node->next = current_node; - - current_node->previous->next = new_node; - current_node->previous = new_node; - } - - current_doubly_linked_list->size += 1; - return FLEDASTY_ERROR_NONE; - } - - current_node = current_node->next; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -FledastyError fledasty_doubly_linked_list_insert_after_value(FledastyDoublyLinkedList *current_doubly_linked_list, void *after_value, void *value) { - if (current_doubly_linked_list == NULL || after_value == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyDoublyLinkedListNode *current_node = current_doubly_linked_list->start; - while (current_node != NULL) { - if (hallocy_compare_memory(current_node->value, after_value, current_doubly_linked_list->element_byte_size)) { - FledastyDoublyLinkedListNode *new_node = (FledastyDoublyLinkedListNode*)hallocy_malloc(sizeof(FledastyDoublyLinkedListNode)); - if (new_node == NULL) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - new_node->value = hallocy_malloc(current_doubly_linked_list->element_byte_size); - if (new_node->value == NULL) { - hallocy_free(new_node); - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - hallocy_copy_memory(new_node->value, value, current_doubly_linked_list->element_byte_size); - - if (current_node == current_doubly_linked_list->end) { - new_node->next = NULL; - new_node->previous = current_doubly_linked_list->end; - - current_doubly_linked_list->end->next = new_node; - current_doubly_linked_list->end = new_node; - } else { - new_node->previous = current_node; - new_node->next = current_node->next; - - current_node->next->previous = new_node; - current_node->next = new_node; - } - - current_doubly_linked_list->size += 1; - return FLEDASTY_ERROR_NONE; - } - - current_node = current_node->next; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -FledastyError fledasty_doubly_linked_list_remove_at_index(FledastyDoublyLinkedList *current_doubly_linked_list, const size_t index) { - if (current_doubly_linked_list == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - if (index >= current_doubly_linked_list->size) { - return FLEDASTY_ERROR_INDEX_OUT_OF_RANGE; - } - - FledastyDoublyLinkedListNode *current_node = NULL; - if (index < current_doubly_linked_list->size / 2) { - current_node = current_doubly_linked_list->start; - for (size_t node = 0; node < index; node += 1) { - current_node = current_node->next; - } - } else { - current_node = current_doubly_linked_list->end; - for (size_t node = current_doubly_linked_list->size - 1; node > index; node -= 1) { - current_node = current_node->previous; - } - } - - if (current_node == current_doubly_linked_list->start) { - current_doubly_linked_list->start = current_node->next; - } else { - current_node->previous->next = current_node->next; - } - - if (current_node == current_doubly_linked_list->end) { - current_doubly_linked_list->end = current_node->previous; - } else { - current_node->next->previous = current_node->previous; - } - - if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_doubly_linked_list->size -= 1; - return FLEDASTY_ERROR_NONE; -} - -FledastyError fledasty_doubly_linked_list_remove_value(FledastyDoublyLinkedList *current_doubly_linked_list, void *value) { - if (current_doubly_linked_list == NULL || value == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyDoublyLinkedListNode *current_node = current_doubly_linked_list->start; - while (current_node != NULL) { - if (hallocy_compare_memory(current_node->value, value, current_doubly_linked_list->element_byte_size)) { - if (current_node == current_doubly_linked_list->start) { - current_doubly_linked_list->start = current_node->next; - } else { - current_node->previous->next = current_node->next; - } - - if (current_node == current_doubly_linked_list->end) { - current_doubly_linked_list->end = current_node->previous; - } else { - current_node->next->previous = current_node->previous; - } - - if (hallocy_free(current_node->value) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (hallocy_free(current_node) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - current_doubly_linked_list->size -= 1; - return FLEDASTY_ERROR_NONE; - } - - current_node = current_node->next; - } - - return FLEDASTY_ERROR_VALUE_NOT_FOUND; -} - -FledastyError fledasty_doubly_linked_list_clear(FledastyDoublyLinkedList *current_doubly_linked_list) { - if (current_doubly_linked_list == NULL) { - return FLEDASTY_ERROR_INVALID_POINTER; - } - - FledastyDoublyLinkedListNode *previous_node = NULL; - FledastyDoublyLinkedListNode *current_node = current_doubly_linked_list->start; - while (current_node != NULL) { - previous_node = current_node; - current_node = current_node->next; - - if (hallocy_free(previous_node->value) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - - if (hallocy_free(previous_node) != HALLOCY_ERROR_NONE) { - return FLEDASTY_ERROR_FAILED_ALLOCATION; - } - } - - current_doubly_linked_list->start = NULL; - current_doubly_linked_list->end = NULL; - - current_doubly_linked_list->size = 0; - return FLEDASTY_ERROR_NONE; -} - -bool fledasty_doubly_linked_list_has_value(const FledastyDoublyLinkedList *current_doubly_linked_list, void *value) { - if (current_doubly_linked_list == NULL || value == NULL) { - return false; - } - - FledastyDoublyLinkedListNode *current_node = current_doubly_linked_list->start; - while (current_node != NULL) { - if (hallocy_compare_memory(current_node->value, value, current_doubly_linked_list->element_byte_size)) { - return true; - } - - current_node = current_node->next; - } - - return false; -} diff --git a/Tests/Main.c b/Tests/Main.c index e13c48a..8b66987 100644 --- a/Tests/Main.c +++ b/Tests/Main.c @@ -48,6 +48,9 @@ FLEDASTY_HASH_TABLE_IMPLEMENT(int, int, int_int, compare_integers) FLEDASTY_LINKED_LIST_DEFINE(int, int) FLEDASTY_LINKED_LIST_IMPLEMENT(int, int, compare_integers) +FLEDASTY_DOUBLY_LINKED_LIST_DEFINE(int, int) +FLEDASTY_DOUBLY_LINKED_LIST_IMPLEMENT(int, int, compare_integers) + int main() { FledastyQueue_int test_queue = { 0, 0, 0, 0, NULL }; for (int i = 0; i < 10; i += 1) { @@ -149,46 +152,40 @@ int main() { fledasty_linked_list_int_free(&test_linked_list); - FledastyDoublyLinkedList test_doubly_linked_list; - fledasty_doubly_linked_list_initialize(&test_doubly_linked_list, (int[]){11, 12, 13, 14, 15}, 5, sizeof(int)); + FledastyDoublyLinkedList_int test_doubly_linked_list = { 0, NULL , NULL }; for (int i = 0; i < 10; i += 1) { - fledasty_doubly_linked_list_append(&test_doubly_linked_list, &i); + fledasty_doubly_linked_list_int_append(&test_doubly_linked_list, i); } - int insert_value = 35; - fledasty_doubly_linked_list_insert_at_index(&test_doubly_linked_list, test_doubly_linked_list.size - 1, &insert_value); - insert_value = 28; - int insert_at_value = 35; - fledasty_doubly_linked_list_insert_before_value(&test_doubly_linked_list, &insert_at_value, &insert_value); - insert_value = 90; - fledasty_doubly_linked_list_insert_after_value(&test_doubly_linked_list, &insert_at_value, &insert_value); + fledasty_doubly_linked_list_int_insert_at_index(&test_doubly_linked_list, test_doubly_linked_list.size - 1, 35); + fledasty_doubly_linked_list_int_insert_before_value(&test_doubly_linked_list, 35, 28); + fledasty_doubly_linked_list_int_insert_after_value(&test_doubly_linked_list, 35, 90); - fledasty_doubly_linked_list_remove_at_index(&test_doubly_linked_list, 2); - int remove_value = 0; - fledasty_doubly_linked_list_remove_value(&test_doubly_linked_list, &remove_value); + fledasty_doubly_linked_list_int_remove_at_index(&test_doubly_linked_list, 2); + fledasty_doubly_linked_list_int_remove_value(&test_doubly_linked_list, 0); - FledastyDoublyLinkedListNode *test_doubly_linked_list_node = test_doubly_linked_list.start; + FledastyDoublyLinkedListNode_int *test_doubly_linked_list_node = test_doubly_linked_list.start; for (int i = 0; i < test_doubly_linked_list.size; i += 1) { - printf("Doubly linked list get: %d\n", *(int*)test_doubly_linked_list_node->value); + printf("Doubly linked list get: %d\n", test_doubly_linked_list_node->value); test_doubly_linked_list_node = test_doubly_linked_list_node->next; } test_doubly_linked_list_node = test_doubly_linked_list.end; for (int i = 0; i < test_doubly_linked_list.size; i += 1) { - printf("Doubly linked list get backwards: %d\n", *(int*)test_doubly_linked_list_node->value); + printf("Doubly linked list get backwards: %d\n", test_doubly_linked_list_node->value); test_doubly_linked_list_node = test_doubly_linked_list_node->previous; } - if (fledasty_doubly_linked_list_has_value(&test_doubly_linked_list, &insert_value)) { - printf("Doubly linked list contains %d\n", insert_value); + if (fledasty_doubly_linked_list_int_has_value(&test_doubly_linked_list, 35)) { + printf("Doubly linked list contains 35\n"); } - fledasty_doubly_linked_list_clear(&test_doubly_linked_list); - if (fledasty_doubly_linked_list_is_empty(&test_doubly_linked_list)) { + fledasty_doubly_linked_list_int_clear(&test_doubly_linked_list); + if (fledasty_doubly_linked_list_int_is_empty(&test_doubly_linked_list)) { printf("Doubly linked list is empty\n"); } - fledasty_doubly_list_destroy(&test_doubly_linked_list); + fledasty_doubly_list_int_free(&test_doubly_linked_list); FledastyHashTable_int_int test_hash_table = { .size = 0, .capacity = 0, .Table = NULL, .hash_function = (size_t(*)(const int))integer_hash_function }; for (int i = 0; i < 10; i += 1) { -- 2.39.5