unicstl/src/queue.c

352 lines
7.0 KiB
C

/**
* @file queue.c
* @author wenjf (Orig5826@163.com)
* @brief
* @version 0.1
* @date 2024-06-23
*
* @copyright Copyright (c) 2024
*
*/
#include "queue.h"
bool queue_push(struct _queue* self, void* obj)
{
assert(self != NULL);
assert(obj != NULL);
void * obj_new = malloc(self->_obj_size);
if (obj_new == NULL)
{
return false;
}
memmove(obj_new, obj, self->_obj_size);
struct _queue_node* node_new = (struct _queue_node*)malloc(sizeof(struct _queue_node));
if(node_new == NULL)
{
return false;
}
node_new->obj = obj_new;
node_new->next = NULL;
if(self->empty(self))
{
self->_front = node_new;
self->_back = node_new;
}
else
{
self->_back->next = node_new;
self->_back = node_new;
}
self->_size++;
return true;
}
bool queue_pop(struct _queue* self, void* obj)
{
assert(self != NULL);
if (self->empty(self))
{
return false;
}
struct _queue_node* node = self->_front;
if(obj != NULL)
{
memmove(obj, node->obj, self->_obj_size);
}
self->_front = node->next;
self->_size--;
free(node->obj);
free(node);
return true;
}
bool queue_back(struct _queue* self, void* obj)
{
assert(self != NULL);
if (self->empty(self))
{
return false;
}
memmove(obj, self->_back->obj, self->_obj_size);
return true;
}
bool queue_front(struct _queue* self, void* obj)
{
assert(self != NULL);
if (self->empty(self))
{
return false;
}
memmove(obj, self->_front->obj, self->_obj_size);
return true;
}
bool queue_clear(struct _queue* self)
{
assert(self != NULL);
struct _queue_node* node = self->_front;
struct _queue_node* next = NULL;
while (node)
{
next = node->next;
free(node->obj);
free(node);
node = next;
}
self->_front = NULL;
self->_back = NULL;
self->_size = 0;
return true;
}
bool queue_empty(struct _queue* self)
{
assert(self != NULL);
return !self->size(self);
}
uint32_t queue_size(struct _queue* self)
{
assert(self != NULL);
return self->_size;
}
void queue_destory(struct _queue* self)
{
assert(self != NULL);
self->clear(self);
}
void queue_print(struct _queue* self)
{
assert(self != NULL);
struct _queue_node * node = self->_front;
while (node)
{
self->print_obj(node->obj);
node = node->next;
}
}
bool queue_init(struct _queue * queue, uint32_t obj_size)
{
assert(queue != NULL);
assert(obj_size > 0);
// attribute init
queue->_size = 0;
queue->_obj_size = obj_size;
// queue->_capacity = 0;
// queue->_ratio = 0;
// function init
queue->push = queue_push;
queue->pop = queue_pop;
queue->back = queue_back;
queue->front = queue_front;
queue->clear = queue_clear;
queue->empty = queue_empty;
queue->size = queue_size;
queue->destory = queue_destory;
queue->print = queue_print;
// init front & back
queue->_front = NULL;
queue->_back = NULL;
}
bool queue2_push(struct _queue* self, void* obj)
{
assert(self != NULL);
assert(obj != NULL);
if(self->full(self))
{
return false;
}
void * obj_array = self->_front->obj;
uint32_t index = self->_index_back;
memmove((char*)obj_array + index * self->_obj_size, obj, self->_obj_size);
if(index >= self->capacity(self))
{
index = 0;
}
else
{
index++;
}
self->_index_back = index;
self->_size++;
return true;
}
bool queue2_pop(struct _queue* self, void* obj)
{
assert(self != NULL);
if (self->empty(self))
{
return false;
}
void * obj_array = self->_front->obj;
uint32_t index = self->_index_front;
if(obj != NULL)
{
memmove(obj, (char*)obj_array + index * self->_obj_size,self->_obj_size);
}
if(index >= self->capacity(self))
{
index = 0;
}
else
{
index++;
}
self->_index_front = index;
self->_size--;
return true;
}
bool queue2_back(struct _queue* self, void* obj)
{
assert(self != NULL);
if (self->empty(self))
{
return false;
}
void * obj_array = self->_front->obj;
uint32_t index = self->_index_back;
if(index == 0)
{
index = self->capacity(self) - 1;
}
else
{
index--;
}
memmove(obj, (char *)obj_array + index * self->_obj_size, self->_obj_size);
return true;
}
bool queue2_front(struct _queue* self, void* obj)
{
assert(self != NULL);
if (self->empty(self))
{
return false;
}
void * obj_array = self->_front->obj;
uint32_t index = self->_index_front;
memmove(obj, (char *)obj_array + index * self->_obj_size, self->_obj_size);
return true;
}
bool queue2_clear(struct _queue* self)
{
assert(self != NULL);
self->_index_front = 0;
self->_index_back = 0;
self->_size = 0;
return true;
}
bool queue2_full(struct _queue* self)
{
assert(self != NULL);
return self->size(self) == self->capacity(self);
}
uint32_t queue2_capacity(struct _queue* self)
{
assert(self != NULL);
return self->_capacity;
}
void queue2_destory(struct _queue* self)
{
assert(self != NULL);
self->clear(self);
}
void queue2_print(struct _queue* self)
{
assert(self != NULL);
uint32_t index = 0;
void * obj_array = self->_front->obj;
for(uint32_t i = 0; i < self->size(self); i++)
{
index = self->_index_front + i;
if(index >= self->capacity(self))
{
index -= self->_capacity;
}
self->print_obj((char *)obj_array + index * self->_obj_size);
}
}
bool queue_init2(struct _queue * queue, uint32_t obj_size, uint32_t capacity)
{
assert(queue != NULL);
assert(obj_size > 0);
// attribute init
queue->_size = 0;
queue->_obj_size = obj_size;
queue->_capacity = capacity;
queue->_ratio = 2;
// function init
queue->push = queue2_push;
queue->pop = queue2_pop;
queue->back = queue2_back;
queue->front = queue2_front;
queue->clear = queue2_clear;
queue->empty = queue_empty;
queue->full = queue2_full;
queue->size = queue_size;
queue->capacity = queue2_capacity;
queue->destory = queue2_destory;
queue->print = queue2_print;
// init front & back
queue->_front = (struct _queue_node *)malloc(sizeof(struct _queue_node));
if(queue->_front == NULL)
{
return false;
}
queue->_back = queue->_front;
// queue->_front->obj = calloc(queue->_capacity + 1, queue->_obj_size);
queue->_front->obj = calloc(queue->_capacity, queue->_obj_size);
if(queue->_front->obj == NULL)
{
return false;
}
queue->_index_front = 0;
queue->_index_back = 0;
}
queue_t queue_new(void)
{
return (struct _queue *)malloc(sizeof(struct _queue));
}
void queue_free(queue_t* queue)
{
if(*queue != NULL)
{
(*queue)->destory(*queue);
free(*queue);
}
*queue = NULL;
}