Compare commits

..

2 commits
main ... dev

Author SHA1 Message Date
ed85ded967 Add single-ptr variants data structures' free fns
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 6s
2024-09-13 12:51:09 +09:00
6b862ab022 Refactor priority-heap insert fn
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 6s
priority-heap insert now takes a pointer to a priority-heap instead of a
double pointer.
2024-09-13 11:33:15 +09:00
7 changed files with 89 additions and 57 deletions

View file

@ -159,16 +159,21 @@ SDArchiverHashMap *simple_archiver_hash_map_init(void) {
return hash_map; return hash_map;
} }
void simple_archiver_hash_map_free(SDArchiverHashMap **hash_map) { void simple_archiver_hash_map_free_single_ptr(SDArchiverHashMap *hash_map) {
if (hash_map && *hash_map) { if (hash_map) {
for (size_t idx = 0; idx < (*hash_map)->buckets_size; ++idx) { for (size_t idx = 0; idx < hash_map->buckets_size; ++idx) {
SDArchiverLinkedList **linked_list = (*hash_map)->buckets + idx; SDArchiverLinkedList **linked_list = hash_map->buckets + idx;
simple_archiver_list_free(linked_list); simple_archiver_list_free(linked_list);
} }
free((*hash_map)->buckets); free(hash_map->buckets);
free(*hash_map); free(hash_map);
}
}
void simple_archiver_hash_map_free(SDArchiverHashMap **hash_map) {
if (hash_map && *hash_map) {
simple_archiver_hash_map_free_single_ptr(*hash_map);
*hash_map = NULL; *hash_map = NULL;
} }
} }

View file

@ -32,6 +32,11 @@ typedef struct SDArchiverHashMap {
} SDArchiverHashMap; } SDArchiverHashMap;
SDArchiverHashMap *simple_archiver_hash_map_init(void); SDArchiverHashMap *simple_archiver_hash_map_init(void);
/// It is recommended to use the double-pointer version of hash-map free as
/// that will ensure the variable holding the pointer will end up pointing to
/// NULL after free.
void simple_archiver_hash_map_free_single_ptr(SDArchiverHashMap *hash_map);
void simple_archiver_hash_map_free(SDArchiverHashMap **hash_map); void simple_archiver_hash_map_free(SDArchiverHashMap **hash_map);
/// Returns zero on success. /// Returns zero on success.

View file

@ -41,9 +41,9 @@ SDArchiverLinkedList *simple_archiver_list_init(void) {
return list; return list;
} }
void simple_archiver_list_free(SDArchiverLinkedList **list) { void simple_archiver_list_free_single_ptr(SDArchiverLinkedList *list) {
if (list && *list) { if (list) {
SDArchiverLLNode *node = (*list)->head; SDArchiverLLNode *node = list->head;
SDArchiverLLNode *prev; SDArchiverLLNode *prev;
while (node) { while (node) {
prev = node; prev = node;
@ -58,7 +58,13 @@ void simple_archiver_list_free(SDArchiverLinkedList **list) {
} }
} }
free(*list); free(list);
}
}
void simple_archiver_list_free(SDArchiverLinkedList **list) {
if (list && *list) {
simple_archiver_list_free_single_ptr(*list);
*list = NULL; *list = NULL;
} }
} }

View file

@ -35,6 +35,11 @@ typedef struct SDArchiverLinkedList {
} SDArchiverLinkedList; } SDArchiverLinkedList;
SDArchiverLinkedList *simple_archiver_list_init(void); SDArchiverLinkedList *simple_archiver_list_init(void);
/// It is recommended to use the double-pointer version of list free as that
/// will ensure the variable holding the pointer will end up pointing to NULL
/// after free.
void simple_archiver_list_free_single_ptr(SDArchiverLinkedList *list);
void simple_archiver_list_free(SDArchiverLinkedList **list); void simple_archiver_list_free(SDArchiverLinkedList **list);
/// Returns 0 on success. Puts data at the end of the list /// Returns 0 on success. Puts data at the end of the list

View file

@ -21,27 +21,27 @@
#include <stdlib.h> #include <stdlib.h>
void simple_archiver_priority_heap_internal_realloc( void simple_archiver_priority_heap_internal_realloc(
SDArchiverPHeap **priority_heap) { SDArchiverPHeap *priority_heap) {
SDArchiverPHeap *new_priority_heap = malloc(sizeof(SDArchiverPHeap)); SDArchiverPHeap new_priority_heap;
new_priority_heap->capacity = (*priority_heap)->capacity * 2; new_priority_heap.capacity = priority_heap->capacity * 2;
new_priority_heap->size = 0; new_priority_heap.size = 0;
new_priority_heap->less_fn = (*priority_heap)->less_fn; new_priority_heap.less_fn = priority_heap->less_fn;
new_priority_heap->nodes = new_priority_heap.nodes =
calloc(new_priority_heap->capacity, sizeof(SDArchiverPHNode)); calloc(new_priority_heap.capacity, sizeof(SDArchiverPHNode));
for (size_t idx = 1; idx < (*priority_heap)->size + 1; ++idx) { for (size_t idx = 1; idx < priority_heap->size + 1; ++idx) {
if ((*priority_heap)->nodes[idx].is_valid != 0) { if (priority_heap->nodes[idx].is_valid != 0) {
simple_archiver_priority_heap_insert( simple_archiver_priority_heap_insert(
&new_priority_heap, (*priority_heap)->nodes[idx].priority, &new_priority_heap, priority_heap->nodes[idx].priority,
(*priority_heap)->nodes[idx].data, priority_heap->nodes[idx].data,
(*priority_heap)->nodes[idx].data_cleanup_fn); priority_heap->nodes[idx].data_cleanup_fn);
(*priority_heap)->nodes[idx].is_valid = 0; priority_heap->nodes[idx].is_valid = 0;
} }
} }
simple_archiver_priority_heap_free(priority_heap); free(priority_heap->nodes);
*priority_heap = new_priority_heap; *priority_heap = new_priority_heap;
} }
@ -77,54 +77,59 @@ SDArchiverPHeap *simple_archiver_priority_heap_init_less_fn(
return priority_heap; return priority_heap;
} }
void simple_archiver_priority_heap_free(SDArchiverPHeap **priority_heap) { void simple_archiver_priority_heap_free_single_ptr(
if (priority_heap && *priority_heap) { SDArchiverPHeap *priority_heap) {
for (size_t idx = 1; idx < (*priority_heap)->size + 1; ++idx) { if (priority_heap) {
if ((*priority_heap)->nodes[idx].is_valid != 0) { for (size_t idx = 1; idx < priority_heap->size + 1; ++idx) {
if ((*priority_heap)->nodes[idx].data_cleanup_fn) { if (priority_heap->nodes[idx].is_valid != 0) {
(*priority_heap) if (priority_heap->nodes[idx].data_cleanup_fn) {
->nodes[idx] priority_heap->nodes[idx].data_cleanup_fn(
.data_cleanup_fn((*priority_heap)->nodes[idx].data); priority_heap->nodes[idx].data);
} else { } else {
free((*priority_heap)->nodes[idx].data); free(priority_heap->nodes[idx].data);
} }
(*priority_heap)->nodes[idx].is_valid = 0; priority_heap->nodes[idx].is_valid = 0;
} }
} }
free((*priority_heap)->nodes); free(priority_heap->nodes);
free(*priority_heap); free(priority_heap);
}
}
void simple_archiver_priority_heap_free(SDArchiverPHeap **priority_heap) {
if (priority_heap && *priority_heap) {
simple_archiver_priority_heap_free_single_ptr(*priority_heap);
*priority_heap = NULL; *priority_heap = NULL;
} }
} }
void simple_archiver_priority_heap_insert(SDArchiverPHeap **priority_heap, void simple_archiver_priority_heap_insert(SDArchiverPHeap *priority_heap,
long long priority, void *data, long long priority, void *data,
void (*data_cleanup_fn)(void *)) { void (*data_cleanup_fn)(void *)) {
if (!priority_heap || !*priority_heap) { if (!priority_heap) {
return; return;
} }
if ((*priority_heap)->size + 1 >= (*priority_heap)->capacity) { if (priority_heap->size + 1 >= priority_heap->capacity) {
simple_archiver_priority_heap_internal_realloc(priority_heap); simple_archiver_priority_heap_internal_realloc(priority_heap);
} }
size_t hole = (*priority_heap)->size + 1; size_t hole = priority_heap->size + 1;
while (hole > 1 && while (hole > 1 &&
(*priority_heap) priority_heap->less_fn(priority,
->less_fn(priority, priority_heap->nodes[hole / 2].priority) != 0) {
(*priority_heap)->nodes[hole / 2].priority) != 0) { priority_heap->nodes[hole] = priority_heap->nodes[hole / 2];
(*priority_heap)->nodes[hole] = (*priority_heap)->nodes[hole / 2];
hole /= 2; hole /= 2;
} }
(*priority_heap)->nodes[hole].priority = priority; priority_heap->nodes[hole].priority = priority;
(*priority_heap)->nodes[hole].data = data; priority_heap->nodes[hole].data = data;
(*priority_heap)->nodes[hole].data_cleanup_fn = data_cleanup_fn; priority_heap->nodes[hole].data_cleanup_fn = data_cleanup_fn;
(*priority_heap)->nodes[hole].is_valid = 1; priority_heap->nodes[hole].is_valid = 1;
++(*priority_heap)->size; ++priority_heap->size;
} }
void *simple_archiver_priority_heap_top(SDArchiverPHeap *priority_heap) { void *simple_archiver_priority_heap_top(SDArchiverPHeap *priority_heap) {

View file

@ -43,10 +43,16 @@ int simple_archiver_priority_heap_default_less(long long a, long long b);
SDArchiverPHeap *simple_archiver_priority_heap_init(void); SDArchiverPHeap *simple_archiver_priority_heap_init(void);
SDArchiverPHeap *simple_archiver_priority_heap_init_less_fn( SDArchiverPHeap *simple_archiver_priority_heap_init_less_fn(
int (*less_fn)(long long, long long)); int (*less_fn)(long long, long long));
/// It is recommended to use the double-pointer version of priority-heap free
/// as that will ensure the variable holding the pointer will end up pointing
/// to NULL after free.
void simple_archiver_priority_heap_free_single_ptr(
SDArchiverPHeap *priority_heap);
void simple_archiver_priority_heap_free(SDArchiverPHeap **priority_heap); void simple_archiver_priority_heap_free(SDArchiverPHeap **priority_heap);
/// If data_cleanup_fn is NULL, then "free()" is used on data when freed. /// If data_cleanup_fn is NULL, then "free()" is used on data when freed.
void simple_archiver_priority_heap_insert(SDArchiverPHeap **priority_heap, void simple_archiver_priority_heap_insert(SDArchiverPHeap *priority_heap,
long long priority, void *data, long long priority, void *data,
void (*data_cleanup_fn)(void *)); void (*data_cleanup_fn)(void *));

View file

@ -229,7 +229,7 @@ int main(void) {
for (unsigned int idx = 0; idx < 3; ++idx) { for (unsigned int idx = 0; idx < 3; ++idx) {
unsigned int *data = malloc(sizeof(unsigned int)); unsigned int *data = malloc(sizeof(unsigned int));
*data = idx; *data = idx;
simple_archiver_priority_heap_insert(&priority_heap, idx, data, NULL); simple_archiver_priority_heap_insert(priority_heap, idx, data, NULL);
} }
for (unsigned int idx = 0; idx < 3; ++idx) { for (unsigned int idx = 0; idx < 3; ++idx) {
unsigned int *data = simple_archiver_priority_heap_top(priority_heap); unsigned int *data = simple_archiver_priority_heap_top(priority_heap);
@ -251,7 +251,7 @@ int main(void) {
for (unsigned int idx = 0; idx < max; ++idx) { for (unsigned int idx = 0; idx < max; ++idx) {
unsigned int *data = malloc(sizeof(unsigned int)); unsigned int *data = malloc(sizeof(unsigned int));
*data = idx; *data = idx;
simple_archiver_priority_heap_insert(&priority_heap, idx, data, NULL); simple_archiver_priority_heap_insert(priority_heap, idx, data, NULL);
} }
for (unsigned int idx = 0; idx < max; ++idx) { for (unsigned int idx = 0; idx < max; ++idx) {
@ -266,7 +266,7 @@ int main(void) {
for (unsigned int idx = max; idx-- > 0;) { for (unsigned int idx = max; idx-- > 0;) {
unsigned int *data = malloc(sizeof(unsigned int)); unsigned int *data = malloc(sizeof(unsigned int));
*data = idx; *data = idx;
simple_archiver_priority_heap_insert(&priority_heap, idx, data, NULL); simple_archiver_priority_heap_insert(priority_heap, idx, data, NULL);
} }
for (unsigned int idx = 0; idx < max; ++idx) { for (unsigned int idx = 0; idx < max; ++idx) {
@ -296,7 +296,7 @@ int main(void) {
// Insert the deterministically randomized array. // Insert the deterministically randomized array.
for (unsigned int idx = 0; idx < max; ++idx) { for (unsigned int idx = 0; idx < max; ++idx) {
simple_archiver_priority_heap_insert(&priority_heap, array[idx], simple_archiver_priority_heap_insert(priority_heap, array[idx],
array + idx, no_free_fn); array + idx, no_free_fn);
} }
@ -321,7 +321,7 @@ int main(void) {
for (unsigned int idx = 0; idx < max; ++idx) { for (unsigned int idx = 0; idx < max; ++idx) {
unsigned int *data = malloc(sizeof(unsigned int)); unsigned int *data = malloc(sizeof(unsigned int));
*data = idx; *data = idx;
simple_archiver_priority_heap_insert(&priority_heap, idx, data, NULL); simple_archiver_priority_heap_insert(priority_heap, idx, data, NULL);
} }
simple_archiver_priority_heap_free(&priority_heap); simple_archiver_priority_heap_free(&priority_heap);
@ -331,7 +331,7 @@ int main(void) {
for (unsigned int idx = 0; idx < max; ++idx) { for (unsigned int idx = 0; idx < max; ++idx) {
unsigned int *data = malloc(sizeof(unsigned int)); unsigned int *data = malloc(sizeof(unsigned int));
*data = idx; *data = idx;
simple_archiver_priority_heap_insert(&priority_heap, idx, data, NULL); simple_archiver_priority_heap_insert(priority_heap, idx, data, NULL);
} }
for (unsigned int idx = max; idx-- > 0;) { for (unsigned int idx = max; idx-- > 0;) {
@ -364,7 +364,7 @@ int main(void) {
// Insert the deterministically randomized array. // Insert the deterministically randomized array.
for (unsigned int idx = 0; idx < max; ++idx) { for (unsigned int idx = 0; idx < max; ++idx) {
simple_archiver_priority_heap_insert(&priority_heap, array[idx], simple_archiver_priority_heap_insert(priority_heap, array[idx],
array + idx, no_free_fn); array + idx, no_free_fn);
} }