1
0
Fork 0

More fixes to queue, still needs fixing serialization/enqueuing.

This commit is contained in:
wael 2022-01-05 16:15:46 +02:00
parent 4db662556a
commit 8ae807fb89
No known key found for this signature in database
GPG Key ID: C0A5FBF4558963D4
4 changed files with 55 additions and 42 deletions

View File

@ -29,7 +29,7 @@
/* This function initializes a new empty queue. */
/* Will return a pointer to the queue on success, otherwise will return NULL. */
static inline queue_t *initialize_queue() {
queue_t *initialize_queue() {
/* Variables. */
queue_t *result;
@ -61,31 +61,42 @@ static inline queue_t *initialize_queue() {
/* This function enqueues a node. */
/* This function attempts to enqueue a given node into the given queue, on success will return SUCCESS_CODE_QUEUE_C, otherwise will return FAILURE_CODE_QUEUE_C. */
/* Note that if either the queue or node pointer are NULL, the function will automatically fail. */
static inline int enqueue(queue_t *queue, node_t *node) {
int enqueue(queue_t *queue, node_t *node) {
/* Local variables. */
int result;
/* Input sanity check. */
if (!queue || !(queue->list) || !node || ((!(queue->list->head) && queue->tail) || (queue->list->head && !(queue->tail))))
return FAILURE_CODE_QUEUE_C;
/* Delegate. */
result = prepend_node_single_linked_list(queue->list, node);
/* Check if to update the tail. */
if ((!(queue->tail) || queue->list->length == 1) && result);
queue->tail = node;
/* Return the result. */
return result;
/* Attempt to enqueue the node. */
/* Check if the queue is empty. */
if (!(queue->list->head)) {
/*if (!(queue->list->head)) {
node->next = NULL;
queue->tail = node;
} else
node->next = queue->list->head;
/* Relink the head. */
queue->list->head = node;
/*queue->list->head = node;
/* Increase the length. */
(queue->list->length)++;
/*(queue->list->length)++;
/* Success. */
return SUCCESS_CODE_QUEUE_C;
/*return SUCCESS_CODE_QUEUE_C;*/
}
/* This function allocates and enqueues a node. */
/* This function attempts to create a node then enqueue it into the given queue, on success will return SUCCESS_CODE_QUEUE_C, otherwise will return FAILURE_CODE_QUEUE_C. */
/* Note that if either the queue pointer is NULL or node allocation fails, the function will automatically fail. */
static inline int enqueue_data(queue_t *queue, void *data) {
int enqueue_data(queue_t *queue, void *data) {
/* Variables. */
node_t *node;
@ -98,38 +109,39 @@ static inline int enqueue_data(queue_t *queue, void *data) {
if (!node)
return FAILURE_CODE_QUEUE_C;
/* Add the data to the node. */
node->data = data;
/* Attempt to enqueue the node. */
return enqueue(queue, node);
/* Check if the queue is empty. */
if (!(queue->list->head)) {
/*if (!(queue->list->head)) {
node->next = NULL;
queue->tail = node;
} else
node->next = queue->list->head;
/* Relink the head. */
queue->list->head = node;
/*queue->list->head = node;
/* Increase the length. */
(queue->list->length)++;
/*(queue->list->length)++;
/* Success. */
return SUCCESS_CODE_QUEUE_C;
/*return SUCCESS_CODE_QUEUE_C;*/
}
/* This function dequeues a node. */
/* This function attempts to dequeue a node from the given queue, on success will return a pointer to the dequeued node - otherwise returns NULL. */
/* Note that if either the queue or node pointer are NULL, the function will automatically fail. */
static inline node_t *dequeue(queue_t *queue) {
node_t *dequeue(queue_t *queue) {
/* Variables. */
node_t *result, *replacement, *tmp;
int i;
/* Input sanity check. */
if (!queue || !(queue->list) || ((!(queue->list->head) && queue->tail) || (queue->list->head && !(queue->tail))))
return FAILURE_CODE_QUEUE_C;
return NULL;
/* Attempt to dequeue the node. */
/* Check if the queue is empty. */
if (!(queue->list->head))
return NULL;
else if (queue->list->length == 1) {
/* A queue that is of length 1. */
result = queue->list->head;
@ -156,7 +168,7 @@ static inline node_t *dequeue(queue_t *queue) {
/* This function frees all the nodes of the given queue and the queue itself (setting it to NULL). */
/* Note that it doesn't touch the data stored within the queue's nodes, returns 1 on success and 0 on failure - in the latter case might exhibit undefined behavior. */
static inline int clear_queue(queue_t **queue) {
int clear_queue(queue_t **queue) {
/* Sanity check. */
if (!queue || !(*queue))
return FAILURE_CODE_QUEUE_C;
@ -174,7 +186,7 @@ static inline int clear_queue(queue_t **queue) {
/* This function frees all the nodes of the given queue and the queue itself (setting it to NULL).*/
/* Note that it does free the stored data, returns 1 on success and 0 on failure - in the latter case might exhibit undefined behavior. */
/* If free_function is NULL, then it the standard library's free() call is used. */
static inline int clear_queue_data(queue_t **queue, void (*free_func)()) {
int clear_queue_data(queue_t **queue, void (*free_func)()) {
/* Sanity check. */
if (!queue || !(*queue))
return FAILURE_CODE_QUEUE_C;
@ -193,7 +205,7 @@ static inline int clear_queue_data(queue_t **queue, void (*free_func)()) {
/* Note that it'll return NULL on allocation failure or invalid input. */
/* Note that the array has to be allocated by the caller. */
/* The array setting function is used to set the values at an index, takes the pointer to the array, index and value to put. */
static inline void *serialize_queue(queue_t *queue, void (*array_setting_function)(void*, size_t, void*), void *array) {
void *serialize_queue(queue_t *queue, void (*array_setting_function)(void*, size_t, void*), void *array) {
/* Delegate. */
return (!queue) ? NULL : serialize_linked_list(queue->list, array_setting_function, array);
}

View File

@ -43,18 +43,18 @@ typedef struct queue {
} queue_t;
/* This function initializes a new queue. */
static inline queue_t *initialize_queue();
queue_t *initialize_queue();
/* This function enqueues a node. */
static inline int enqueue(queue_t *queue, node_t *node);
int enqueue(queue_t *queue, node_t *node);
/* This function creates and enqueues a node. */
static inline int enqueue_data(queue_t *queue, void *data);
int enqueue_data(queue_t *queue, void *data);
/* This function dequeues the last node. */
static inline node_t *dequeue(queue_t *queue);
node_t *dequeue(queue_t *queue);
/* This function deletes all the nodes of the given queue. */
static inline int clear_queue(queue_t **queue);
int clear_queue(queue_t **queue);
/* This function deletes all the nodes of the given queue. */
static inline int clear_queue_data(queue_t **queue, void (*free_function)());
int clear_queue_data(queue_t **queue, void (*free_function)());
/* This function serializes the queue into an array, it relies on an array setting function and an allocated buffer. */
static inline void *serialize_queue(queue_t *queue, void (*array_setting_function)(void*, size_t, void*), void *array);
void *serialize_queue(queue_t *queue, void (*array_setting_function)(void*, size_t, void*), void *array);
#endif /* QUEUE_H */

View File

@ -20,10 +20,10 @@ single_linked_list.o: ../linked_lists/single_linked_list.h ../linked_lists/singl
gcc -g -c ../linked_lists/single_linked_list.c -o single_linked_list.o
queue_tests.o: queue_tests.c
gcc -g -c -fanalyzer -fsanitize=address -fsanitize=leak -fsanitize=undefined queue_tests.c -o queue_tests.o
gcc -g -c queue_tests.c -o queue_tests.o
queue_tests.out: queue_tests.o single_linked_list.o
gcc -g -fsanitize=address -fsanitize=leak -fsanitize=undefined queue_tests.o single_linked_list.o -o queue_tests.out
gcc -g -fsanitize=leak queue_tests.o single_linked_list.o -o queue_tests.out
quick_sort_tests.out: array_print.o quick_sort_tests.o
gcc -g -fanalyzer -Wanalyzer-too-complex -fanalyzer-call-summaries -fsanitize=address -fsanitize=leak -fsanitize=undefined array_print.o quick_sort_tests.o -o quick_sort_tests.out

View File

@ -10,14 +10,14 @@
#define ERROR_SERIALIZATION_TEST_FAILURE "Failed the serialization test.\n"
#define SOME_TEST_FAILED "Recheck the tests, one of them failed!\n"
#define INITIAL_QUEUE_LENGTH 0
#define QUEUE_LENGTH_ONE 1
#define QUEUE_LENGTH_ONE 1
#define QUEUE_LENGTH_LONG_TEST 4096
#define SERIALIZATION_TEST_QUEUE_LENGTH 5
/* Define functions. */
node_t* generate_random_node();
queue_t* generate_long_random_queue(int length);
static inline void set_array_value_index(void *array, size_t index, void *value);
void set_array_value_index(void *array, size_t index, void *value);
int queue_count_length(queue_t *queue);
int test_serialization();
int test_queues();
@ -25,9 +25,8 @@ int test_queues();
/* Starting point. */
int main() {
printf(PRINT_INFO_TESTING_START);
if (test_queues()) {
if (test_queues())
printf(SOME_TEST_FAILED);
}
printf(PRINT_INFO_TESTING_END);
}
@ -104,7 +103,7 @@ queue_t* generate_long_random_queue(int length) {
}
/* This function is used to set a value at an index in the array. */
static inline void set_array_value_index(void *array, size_t index, void *value) {
void set_array_value_index(void *array, size_t index, void *value) {
/* Cast. */
int *arr = (int*)array;
int *val = (int*)value;
@ -207,11 +206,11 @@ int test_queues() {
/* Initialize an empty queue. */
queue = initialize_queue();
/* Check that it was correctly created. */
assert(queue != NULL);
assert(queue->list != NULL);
assert(queue);
assert(queue->list);
assert(queue->list->length == INITIAL_QUEUE_LENGTH);
assert(queue->list->head == NULL);
assert(queue->tail == NULL);
assert(!(queue->list->head));
assert(!(queue->tail));
/* Generate and store the node. */
node = generate_random_node();
@ -220,16 +219,18 @@ int test_queues() {
enqueue(queue, node);
/* Check that the queue grew by one and the head got set. */
assert(queue->list->length == QUEUE_LENGTH_ONE);
assert(queue->list->head != NULL && queue->list->head == node);
assert(queue->tail != NULL && queue->tail == node);
assert(queue->list->head && queue->list->head == node);
assert(queue->tail && queue->tail == node);
assert(get_node_i_single_linked_list(queue->list, 0, &error) == node);
assert(get_node_index_pointer_single_linked_list(queue->list, node) == 0);
/* Attempt to free the nodes and then the queue. */
node = dequeue(queue);
assert(queue->list->length == INITIAL_QUEUE_LENGTH);
assert(queue->list->head == NULL);
assert(queue->tail == NULL);
assert(!(queue->list->head));
assert(!(queue->tail));
free(node->data);
free(node);
node = NULL;
free(queue->list);
free(queue);
@ -245,7 +246,7 @@ int test_queues() {
assert(queue->list->length == queue_count_length(queue));
/* Test the freeing functions. */
clear_queue_data(&queue, NULL);
assert(queue == NULL);
assert(!queue);
/* Serialization test. */
if (!test_serialization()) {