mirror of
https://gitee.com/apaki/unicstl.git
synced 2026-05-28 22:54:19 +08:00
ringbuffer重构底层代码,并将obj和index的操作独立成内联函数,另外将deque的底层架构直接修改为ringbuffer
This commit is contained in:
parent
a58d480ae4
commit
cd6eff28a7
@ -17,7 +17,7 @@ static void demo_deque_num(void)
|
||||
int temp = 0;
|
||||
size_t len = sizeof(data) / sizeof(data[0]);
|
||||
|
||||
deque_t deque = deque_new(sizeof(int));
|
||||
deque_t deque = deque_new(sizeof(int), len);
|
||||
deque->print_obj = print_num;
|
||||
|
||||
printf("\n\n----- demo_deque_num -----\n");
|
||||
@ -190,7 +190,7 @@ static void demo_deque_struct(void)
|
||||
struct _student temp = {0};
|
||||
size_t len = sizeof(data) / sizeof(data[0]);
|
||||
|
||||
deque_t deque = deque_new(sizeof(struct _student));
|
||||
deque_t deque = deque_new(sizeof(struct _student), len);
|
||||
deque->print_obj = print_struct;
|
||||
|
||||
printf("\n\n----- demo_deque_struct -----\n");
|
||||
|
||||
@ -8,10 +8,10 @@ flowchart TB
|
||||
darray
|
||||
linklist
|
||||
dlinklist
|
||||
ringbuffer[ringbuffer<br>小数据或尽量不扩容]
|
||||
end
|
||||
|
||||
subgraph hal
|
||||
ringbuffer[ringbuffer<br>小数据或尽量不扩容] --> darray
|
||||
segarray[segarray<br>大数据扩容优先] --> darray
|
||||
end
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#define _DEQUE_H_
|
||||
|
||||
#include "unicstl_internal.h"
|
||||
#include "ringbuffer.h"
|
||||
|
||||
enum _deque_order
|
||||
{
|
||||
@ -19,26 +20,16 @@ enum _deque_order
|
||||
DEQUE_REVERSE,
|
||||
};
|
||||
|
||||
struct _deque_node
|
||||
{
|
||||
void* obj;
|
||||
struct _deque_node* prev;
|
||||
struct _deque_node* next;
|
||||
};
|
||||
|
||||
struct _deque
|
||||
{
|
||||
// -------------------- private --------------------
|
||||
struct _deque_node* _head;
|
||||
struct _deque_node* _tail;
|
||||
|
||||
size_t _obj_size;
|
||||
size_t _size;
|
||||
// size_t _capacity;
|
||||
// size_t _ratio;
|
||||
|
||||
union
|
||||
{
|
||||
ringbuffer_t ringbuf;
|
||||
};
|
||||
iterator_t _iter_ringbuf;
|
||||
|
||||
struct _iterator _iter;
|
||||
|
||||
void (*_destory)(struct _deque* self);
|
||||
|
||||
// -------------------- public --------------------
|
||||
@ -64,9 +55,7 @@ struct _deque
|
||||
};
|
||||
typedef struct _deque* deque_t;
|
||||
|
||||
// create and free deque
|
||||
deque_t deque_new(size_t obj_size);
|
||||
|
||||
deque_t deque_new(size_t obj_size, size_t capacity);
|
||||
void deque_free(deque_t* deque);
|
||||
|
||||
#endif
|
||||
|
||||
@ -23,11 +23,12 @@ enum _ringbuffer_order
|
||||
struct _ringbuffer
|
||||
{
|
||||
// -------------------- private --------------------
|
||||
// size_t _obj_size;
|
||||
void *obj;
|
||||
|
||||
size_t _obj_size;
|
||||
size_t _size;
|
||||
size_t _capacity;
|
||||
|
||||
darray_t darray;
|
||||
size_t _head;
|
||||
size_t _tail;
|
||||
|
||||
@ -36,8 +37,8 @@ struct _ringbuffer
|
||||
|
||||
// -------------------- public --------------------
|
||||
// kernel
|
||||
bool (*push_back)(struct _ringbuffer* self, void* obj);
|
||||
bool (*push_front)(struct _ringbuffer* self, void* obj);
|
||||
bool (*push_back)(struct _ringbuffer* self, const void* obj);
|
||||
bool (*push_front)(struct _ringbuffer* self, const void* obj);
|
||||
bool (*pop_back)(struct _ringbuffer* self, void* obj);
|
||||
bool (*pop_front)(struct _ringbuffer* self, void* obj);
|
||||
bool (*back)(struct _ringbuffer* self, void* obj);
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
* 3. ERROR
|
||||
* 9.None
|
||||
*/
|
||||
#define LOG_LEVEL 9
|
||||
#define LOG_LEVEL 0
|
||||
/**
|
||||
* @brief
|
||||
* 0. simple
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "iterator.h"
|
||||
#include "logger.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief default capacity and ratio
|
||||
*
|
||||
@ -36,6 +37,24 @@
|
||||
#define DEFAULT_CAPACITY 8
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief assert function
|
||||
*
|
||||
*/
|
||||
#ifdef UNICSTL_ASSERT
|
||||
#define unicstl_assert(expr) (void) ((!!(expr)) || (_unicstl_assert(#expr,__FILE__,__LINE__),0))
|
||||
|
||||
static inline void _unicstl_assert(const char *expr, const char *file, int line)
|
||||
{
|
||||
printf("Assertion failed: %s, file:%s line:%d\n", expr, file, line);
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
#define unicstl_assert assert
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief malloc and free function
|
||||
*
|
||||
@ -56,12 +75,53 @@ static inline void unicstl_free(void * ptr) {
|
||||
#error "UNICSTL_MALLOC not defined"
|
||||
#endif
|
||||
|
||||
#ifdef UNICSTL_ASSERT
|
||||
#define unicstl_assert(expr) (void) ((!!(expr)) || (_unicstl_assert(#expr,__FILE__,__LINE__),0))
|
||||
void _unicstl_assert(const char *expr, const char *file, int line);
|
||||
#else
|
||||
#define unicstl_assert assert
|
||||
|
||||
|
||||
static inline const void *obj_at(const void *objs, size_t index, size_t obj_size)
|
||||
{
|
||||
#ifdef UNICSTL_DEBUG
|
||||
unicstl_assert(objs != NULL);
|
||||
#endif
|
||||
return (const char *)objs + obj_size * index;
|
||||
}
|
||||
|
||||
static inline void obj_set(void *objs, size_t index, const void *obj, size_t obj_size)
|
||||
{
|
||||
#ifdef UNICSTL_DEBUG
|
||||
unicstl_assert(objs != NULL);
|
||||
unicstl_assert(obj != NULL);
|
||||
#endif
|
||||
memmove((char *)objs + obj_size * index, obj, obj_size);
|
||||
}
|
||||
|
||||
static inline void obj_get(const void *objs, size_t index, void *obj, size_t obj_size)
|
||||
{
|
||||
#ifdef UNICSTL_DEBUG
|
||||
unicstl_assert(objs != NULL);
|
||||
unicstl_assert(obj != NULL);
|
||||
#endif
|
||||
memmove(obj, (const char *)objs + obj_size * index, obj_size);
|
||||
}
|
||||
|
||||
static inline void obj_copy(void *dst, const void *src, size_t count, size_t obj_size)
|
||||
{
|
||||
#ifdef UNICSTL_DEBUG
|
||||
unicstl_assert(dst != NULL);
|
||||
unicstl_assert(src != NULL);
|
||||
#endif
|
||||
memmove(dst, src, obj_size * count);
|
||||
}
|
||||
|
||||
static inline size_t index_next(size_t index, size_t capacity)
|
||||
{
|
||||
return (index + 1) % capacity;
|
||||
}
|
||||
|
||||
static inline size_t index_prev(size_t index, size_t capacity)
|
||||
{
|
||||
return index == 0 ? (capacity - 1) : index - 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief obj compare with obj2
|
||||
|
||||
257
src/deque.c
257
src/deque.c
@ -13,234 +13,80 @@
|
||||
static bool deque_push_back(struct _deque* self, void* obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
struct _deque_node* front = NULL;
|
||||
struct _deque_node* back = NULL;
|
||||
|
||||
// create a new object
|
||||
void* new_obj = (void*)malloc(self->_obj_size);
|
||||
if (new_obj == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memmove(new_obj, obj, self->_obj_size);
|
||||
|
||||
// create a new node
|
||||
struct _deque_node* new_node = (struct _deque_node*)malloc(sizeof(struct _deque_node));
|
||||
if (new_node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
new_node->obj = new_obj;
|
||||
|
||||
// link node
|
||||
if(self->empty(self))
|
||||
{
|
||||
// if this is first node
|
||||
self->_tail = new_node;
|
||||
self->_head = new_node;
|
||||
}
|
||||
new_node->prev = self->_tail; // step 1
|
||||
new_node->next = self->_head; // step 2
|
||||
|
||||
back = self->_tail;
|
||||
back->next = new_node; // step 3
|
||||
|
||||
front = self->_head;
|
||||
front->prev = new_node; // step 4
|
||||
|
||||
self->_tail = new_node; // step 5
|
||||
|
||||
self->_size += 1;
|
||||
return true;
|
||||
unicstl_assert(self->ringbuf != NULL);
|
||||
return self->ringbuf->push_back(self->ringbuf, obj);
|
||||
}
|
||||
|
||||
static bool deque_push_front(struct _deque* self, void* obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
struct _deque_node* front = NULL;
|
||||
struct _deque_node* back = NULL;
|
||||
|
||||
// create a new object
|
||||
void* new_obj = (void*)malloc(self->_obj_size);
|
||||
if (new_obj == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memmove(new_obj, obj, self->_obj_size);
|
||||
|
||||
// create a new node
|
||||
struct _deque_node* new_node = (struct _deque_node*)malloc(sizeof(struct _deque_node));
|
||||
if (new_node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
new_node->obj = new_obj;
|
||||
|
||||
// link node
|
||||
if (self->empty(self))
|
||||
{
|
||||
// if this is first node
|
||||
self->_tail = new_node;
|
||||
self->_head = new_node;
|
||||
}
|
||||
new_node->prev = self->_tail; // step 1
|
||||
new_node->next = self->_head; // step 2
|
||||
|
||||
back = self->_tail;
|
||||
back->next = new_node; // step 3
|
||||
|
||||
front = self->_head;
|
||||
front->prev = new_node; // step 4
|
||||
|
||||
self->_head = new_node; // step 5
|
||||
|
||||
self->_size += 1;
|
||||
return true;
|
||||
unicstl_assert(self->ringbuf != NULL);
|
||||
return self->ringbuf->push_front(self->ringbuf, obj);
|
||||
}
|
||||
|
||||
static bool deque_pop_back(struct _deque* self, void* obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
struct _deque_node* node = NULL;
|
||||
struct _deque_node* front = NULL;
|
||||
|
||||
if (self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
node = self->_tail;
|
||||
if (obj != NULL)
|
||||
{
|
||||
memmove(obj, node->obj, self->_obj_size);
|
||||
}
|
||||
|
||||
if (self->size(self) == 1)
|
||||
{
|
||||
self->_tail = NULL;
|
||||
self->_head = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->_tail = node->prev; // step 1
|
||||
|
||||
front = self->_head;
|
||||
front->prev = node->prev; // step 2
|
||||
}
|
||||
|
||||
free(node->obj);
|
||||
free(node);
|
||||
|
||||
self->_size -= 1;
|
||||
return true;
|
||||
unicstl_assert(self->ringbuf != NULL);
|
||||
return self->ringbuf->pop_back(self->ringbuf, obj);
|
||||
}
|
||||
|
||||
static bool deque_pop_front(struct _deque* self, void* obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
struct _deque_node* node = NULL;
|
||||
struct _deque_node* back = NULL;
|
||||
|
||||
if (self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
node = self->_head;
|
||||
if (obj != NULL)
|
||||
{
|
||||
memmove(obj, node->obj, self->_obj_size);
|
||||
}
|
||||
|
||||
if (self->size(self) == 1)
|
||||
{
|
||||
self->_tail = NULL;
|
||||
self->_head = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->_head = node->next; // step 1
|
||||
|
||||
back = self->_tail;
|
||||
back->next = node->next; // step 2
|
||||
}
|
||||
|
||||
free(node->obj);
|
||||
free(node);
|
||||
|
||||
self->_size -= 1;
|
||||
return true;
|
||||
unicstl_assert(self->ringbuf != NULL);
|
||||
return self->ringbuf->pop_front(self->ringbuf, obj);
|
||||
}
|
||||
|
||||
static bool deque_back(struct _deque* self, void* obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(obj != NULL);
|
||||
|
||||
if (self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memmove(obj, self->_tail->obj, self->_obj_size);
|
||||
return true;
|
||||
unicstl_assert(self->ringbuf != NULL);
|
||||
return self->ringbuf->back(self->ringbuf, obj);
|
||||
}
|
||||
|
||||
static bool deque_front(struct _deque* self, void* obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(obj != NULL);
|
||||
|
||||
if (self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memmove(obj, self->_head->obj, self->_obj_size);
|
||||
return true;
|
||||
unicstl_assert(self->ringbuf != NULL);
|
||||
return self->ringbuf->front(self->ringbuf, obj);
|
||||
}
|
||||
|
||||
static bool deque_clear(struct _deque* self)
|
||||
{
|
||||
while (!self->empty(self))
|
||||
{
|
||||
deque_pop_back(self, NULL);
|
||||
}
|
||||
return true;
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(self->ringbuf != NULL);
|
||||
return self->ringbuf->clear(self->ringbuf);
|
||||
}
|
||||
|
||||
static size_t deque_size(struct _deque* self)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
return self->_size;
|
||||
unicstl_assert(self->ringbuf != NULL);
|
||||
return self->ringbuf->size(self->ringbuf);
|
||||
}
|
||||
|
||||
static bool deque_empty(struct _deque* self)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
return !self->size(self);
|
||||
unicstl_assert(self->ringbuf != NULL);
|
||||
return self->ringbuf->empty(self->ringbuf);
|
||||
}
|
||||
|
||||
static void deque_destory(struct _deque* self)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
self->clear(self);
|
||||
if (self->_head != NULL)
|
||||
{
|
||||
free(self->_head);
|
||||
self->_head = NULL;
|
||||
}
|
||||
ringbuffer_free(&self->ringbuf);
|
||||
}
|
||||
|
||||
static void deque_print(struct _deque* self)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(self->ringbuf != NULL);
|
||||
|
||||
size_t i = 0;
|
||||
struct _deque_node * node = self->_head;
|
||||
for (size_t i = 0; i < self->size(self); i++)
|
||||
{
|
||||
self->print_obj(node->obj);
|
||||
node = node->next;
|
||||
}
|
||||
self->ringbuf->print_obj = self->print_obj;
|
||||
self->ringbuf->print(self->ringbuf);
|
||||
}
|
||||
|
||||
bool deque_iter_hasnext(struct _iterator* iter)
|
||||
@ -249,11 +95,7 @@ bool deque_iter_hasnext(struct _iterator* iter)
|
||||
unicstl_assert(iter->_container != NULL);
|
||||
|
||||
deque_t self = (deque_t)iter->_container;
|
||||
if(iter->_index < self->size(self))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return self->_iter_ringbuf->hasnext(self->_iter_ringbuf);
|
||||
}
|
||||
|
||||
const void* deque_iter_next(struct _iterator* iter)
|
||||
@ -262,26 +104,7 @@ const void* deque_iter_next(struct _iterator* iter)
|
||||
unicstl_assert(iter->_container != NULL);
|
||||
|
||||
deque_t self = (deque_t)iter->_container;
|
||||
void *obj = NULL;
|
||||
|
||||
struct _deque_node * cur_node = (struct _deque_node *)iter->_node;
|
||||
if(cur_node == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
obj = cur_node->obj;
|
||||
if(iter->_order == DEQUE_FORWARD)
|
||||
{
|
||||
iter->_node = cur_node->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter->_node = cur_node->prev;
|
||||
}
|
||||
|
||||
iter->_index += 1;
|
||||
return obj;
|
||||
return self->_iter_ringbuf->next(self->_iter_ringbuf);
|
||||
}
|
||||
|
||||
iterator_t deque_iter(struct _deque* self, enum _deque_order order)
|
||||
@ -292,36 +115,26 @@ iterator_t deque_iter(struct _deque* self, enum _deque_order order)
|
||||
iter->_container = self;
|
||||
iter->_index = 0;
|
||||
iter->_order = order;
|
||||
if(iter->_order == DEQUE_FORWARD)
|
||||
{
|
||||
iter->_node = self->_head;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter->_node = self->_tail;
|
||||
}
|
||||
self->_iter_ringbuf = self->ringbuf->iter(self->ringbuf, order);
|
||||
|
||||
iter->hasnext = deque_iter_hasnext;
|
||||
iter->next = deque_iter_next;
|
||||
return iter;
|
||||
}
|
||||
|
||||
static bool deque_init(struct _deque* self, size_t obj_size)
|
||||
static bool deque_init(struct _deque* self, size_t obj_size, size_t capacity)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
if(obj_size == 0)
|
||||
if(obj_size == 0 || capacity == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// -------------------- private --------------------
|
||||
self->_obj_size = obj_size;
|
||||
self->_size = 0;
|
||||
// self->_capacity = 64;
|
||||
// self->_ratio = 2;
|
||||
|
||||
self->_head = NULL;
|
||||
self->_tail = NULL;
|
||||
|
||||
self->ringbuf = ringbuffer_new(obj_size, capacity);
|
||||
if(self->ringbuf == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
self->_destory = deque_destory;
|
||||
|
||||
// -------------------- public --------------------
|
||||
@ -350,7 +163,7 @@ static bool deque_init(struct _deque* self, size_t obj_size)
|
||||
return true;
|
||||
}
|
||||
|
||||
deque_t deque_new(size_t obj_size)
|
||||
deque_t deque_new(size_t obj_size, size_t capacity)
|
||||
{
|
||||
struct _deque* deque = NULL;
|
||||
deque = (struct _deque*)malloc(sizeof(struct _deque));
|
||||
@ -359,7 +172,7 @@ deque_t deque_new(size_t obj_size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(deque_init(deque, obj_size) != true)
|
||||
if(deque_init(deque, obj_size, capacity) != true)
|
||||
{
|
||||
free(deque);
|
||||
return NULL;
|
||||
|
||||
132
src/ringbuffer.c
132
src/ringbuffer.c
@ -10,49 +10,38 @@
|
||||
*/
|
||||
#include "ringbuffer.h"
|
||||
|
||||
static size_t calc_index_next(size_t capacity, size_t index)
|
||||
{
|
||||
return (index + 1) % capacity;
|
||||
}
|
||||
|
||||
static size_t calc_index_prev(size_t capacity, size_t index)
|
||||
{
|
||||
return index == 0 ? (capacity - 1) : index - 1;
|
||||
}
|
||||
|
||||
static bool ringbuffer_push_back(struct _ringbuffer *self, void *obj)
|
||||
static bool ringbuffer_push_back(struct _ringbuffer *self, const void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(self->darray != NULL);
|
||||
darray_t darray = self->darray;
|
||||
size_t capacity_total = darray->capacity(darray);
|
||||
|
||||
unicstl_assert(self->obj != NULL);
|
||||
unicstl_assert(obj != NULL);
|
||||
|
||||
if(self->full(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
darray->set(darray, self->_tail, obj);
|
||||
self->_tail = calc_index_next(capacity_total, self->_tail);
|
||||
|
||||
LOG_DEBUG("head: %lu, tail: %lu", self->_head, self->_tail);
|
||||
size_t index = self->_tail;
|
||||
obj_set(self->obj, index, obj, self->_obj_size);
|
||||
self->_tail = index_next(index, self->_capacity);
|
||||
|
||||
self->_size++;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ringbuffer_push_front(struct _ringbuffer *self, void *obj)
|
||||
static bool ringbuffer_push_front(struct _ringbuffer *self, const void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(self->darray != NULL);
|
||||
darray_t darray = self->darray;
|
||||
size_t capacity_total = darray->capacity(darray);
|
||||
unicstl_assert(self->obj != NULL);
|
||||
unicstl_assert(obj != NULL);
|
||||
|
||||
if(self->full(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
size_t index = calc_index_prev(capacity_total, self->_head);
|
||||
darray->set(darray, index, obj);
|
||||
|
||||
size_t index = index_prev(self->_head, self->_capacity);
|
||||
obj_set(self->obj, index, obj, self->_obj_size);
|
||||
self->_head = index;
|
||||
|
||||
self->_size++;
|
||||
@ -62,17 +51,18 @@ static bool ringbuffer_push_front(struct _ringbuffer *self, void *obj)
|
||||
static bool ringbuffer_pop_back(struct _ringbuffer *self, void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(self->darray != NULL);
|
||||
darray_t darray = self->darray;
|
||||
size_t capacity_total = darray->capacity(darray);
|
||||
unicstl_assert(self->obj != NULL);
|
||||
unicstl_assert(obj != NULL);
|
||||
|
||||
if(self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
size_t index = calc_index_prev(capacity_total, self->_tail);
|
||||
darray->get(darray, index, obj);
|
||||
|
||||
size_t index = index_prev(self->_tail, self->_capacity);
|
||||
obj_get(self->obj, index, obj, self->_obj_size);
|
||||
self->_tail = index;
|
||||
|
||||
self->_size--;
|
||||
return true;
|
||||
}
|
||||
@ -80,16 +70,17 @@ static bool ringbuffer_pop_back(struct _ringbuffer *self, void *obj)
|
||||
static bool ringbuffer_pop_front(struct _ringbuffer *self, void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(self->darray != NULL);
|
||||
darray_t darray = self->darray;
|
||||
size_t capacity_total = darray->capacity(darray);
|
||||
unicstl_assert(self->obj != NULL);
|
||||
unicstl_assert(obj != NULL);
|
||||
|
||||
if(self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
darray->get(darray, self->_head, obj);
|
||||
self->_head = calc_index_next(capacity_total, self->_head);
|
||||
|
||||
obj_get(self->obj, self->_head, obj, self->_obj_size);
|
||||
self->_head = index_next(self->_head, self->_capacity);
|
||||
|
||||
self->_size--;
|
||||
return true;
|
||||
}
|
||||
@ -97,30 +88,33 @@ static bool ringbuffer_pop_front(struct _ringbuffer *self, void *obj)
|
||||
static bool ringbuffer_back(struct _ringbuffer *self, void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(self->darray != NULL);
|
||||
darray_t darray = self->darray;
|
||||
unicstl_assert(self->obj != NULL);
|
||||
unicstl_assert(obj != NULL);
|
||||
|
||||
if(self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
size_t capacity_total = darray->capacity(darray);
|
||||
size_t index = calc_index_prev(capacity_total, self->_tail);
|
||||
darray->get(darray, index, obj);
|
||||
|
||||
size_t index = index_prev(self->_tail, self->_capacity);
|
||||
obj_get(self->obj, index, obj, self->_obj_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ringbuffer_front(struct _ringbuffer *self, void *obj)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(self->darray != NULL);
|
||||
darray_t darray = self->darray;
|
||||
unicstl_assert(self->obj != NULL);
|
||||
unicstl_assert(obj != NULL);
|
||||
|
||||
if(self->empty(self))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
darray->get(darray, self->_head, obj);
|
||||
|
||||
obj_get(self->obj, self->_head, obj, self->_obj_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -142,42 +136,39 @@ static size_t ringbuffer_size(struct _ringbuffer *self)
|
||||
static size_t ringbuffer_capacity(struct _ringbuffer* self)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
return self->_capacity;
|
||||
return self->_capacity - 1;
|
||||
}
|
||||
|
||||
static bool ringbuffer_empty(struct _ringbuffer *self)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
// return self->size(self) == 0;
|
||||
return self->_head == self->_tail;
|
||||
}
|
||||
|
||||
static bool ringbuffer_full(struct _ringbuffer *self)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
// return self->size(self) == self->capacity(self) - 1;
|
||||
return self->_head == calc_index_next(self->_capacity, self->_tail);
|
||||
return self->_head == index_next(self->_tail, self->_capacity);
|
||||
}
|
||||
|
||||
static void ringbuffer_destory(struct _ringbuffer *self)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(self->darray != NULL);
|
||||
darray_free(&self->darray);
|
||||
}
|
||||
|
||||
|
||||
static void print_num(const void* obj)
|
||||
{
|
||||
printf("(%2d ) ", *(int*)obj);
|
||||
if(self->obj != NULL)
|
||||
{
|
||||
free(self->obj);
|
||||
self->obj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ringbuffer_print(struct _ringbuffer *self)
|
||||
{
|
||||
unicstl_assert(self != NULL);
|
||||
unicstl_assert(self->darray != NULL);
|
||||
self->darray->print_obj = self->print_obj;
|
||||
self->darray->print(self->darray);
|
||||
|
||||
for(size_t i = 0; i < self->size(self); i++)
|
||||
{
|
||||
self->print_obj(obj_at(self->obj, self->_obj_size, i));
|
||||
}
|
||||
}
|
||||
|
||||
bool ringbuffer_iter_hasnext(struct _iterator *iter)
|
||||
@ -186,8 +177,6 @@ bool ringbuffer_iter_hasnext(struct _iterator *iter)
|
||||
unicstl_assert(iter->_container != NULL);
|
||||
|
||||
ringbuffer_t self = (ringbuffer_t)iter->_container;
|
||||
darray_t darray = self->darray;
|
||||
size_t capacity_total = darray->capacity(darray);
|
||||
|
||||
if(iter->_order == RINGBUF_FORWARD)
|
||||
{
|
||||
@ -212,19 +201,18 @@ const void *ringbuffer_iter_next(struct _iterator *iter)
|
||||
unicstl_assert(iter->_container != NULL);
|
||||
|
||||
ringbuffer_t self = (ringbuffer_t)iter->_container;
|
||||
darray_t darray = self->darray;
|
||||
size_t capacity_total = darray->capacity(darray);
|
||||
|
||||
size_t index = iter->_index;
|
||||
if(iter->_order == RINGBUF_FORWARD)
|
||||
{
|
||||
iter->_index = calc_index_next(capacity_total, index);
|
||||
iter->_index = index_next(index, self->_capacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter->_index = calc_index_prev(capacity_total, index);
|
||||
iter->_index = index_prev(index, self->_capacity);
|
||||
}
|
||||
return darray->at(darray, index);
|
||||
|
||||
return obj_at(self->obj, index, self->_obj_size);
|
||||
}
|
||||
|
||||
iterator_t ringbuffer_iter(struct _ringbuffer *self, enum _ringbuffer_order order)
|
||||
@ -241,9 +229,7 @@ iterator_t ringbuffer_iter(struct _ringbuffer *self, enum _ringbuffer_order orde
|
||||
}
|
||||
else
|
||||
{
|
||||
darray_t darray = self->darray;
|
||||
size_t capacity_total = darray->capacity(darray);
|
||||
iter->_index = calc_index_prev(capacity_total, self->_tail);
|
||||
iter->_index = index_prev(self->_tail, self->_capacity);
|
||||
}
|
||||
|
||||
iter->hasnext = ringbuffer_iter_hasnext;
|
||||
@ -259,12 +245,16 @@ static bool ringbuffer_init(struct _ringbuffer *self, size_t obj_size, size_t ca
|
||||
return false;
|
||||
}
|
||||
// -------------------- private --------------------
|
||||
self->darray = darray_new(obj_size, capacity + 1);
|
||||
self->darray->set_dynamic(self->darray, false);
|
||||
self->darray->_size = capacity + 1;
|
||||
|
||||
self->_obj_size = obj_size;
|
||||
self->_size = 0;
|
||||
self->_capacity = capacity + 1;
|
||||
|
||||
self->obj = (char *)malloc(self->_obj_size * self->_capacity);
|
||||
if(self->obj == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
self->_head = 0;
|
||||
self->_tail = 0;
|
||||
|
||||
|
||||
@ -10,12 +10,6 @@
|
||||
*/
|
||||
#include "unicstl_internal.h"
|
||||
|
||||
void _unicstl_assert(const char *expr, const char *file, int line)
|
||||
{
|
||||
printf("Assertion failed: %s, file:%s line:%d\n", expr, file, line);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int default_compare(const void* obj1, const void* obj2)
|
||||
{
|
||||
printf("compare is not implemented!\n");
|
||||
|
||||
@ -10,6 +10,23 @@
|
||||
*/
|
||||
#include "test.h"
|
||||
|
||||
|
||||
static void test_deque_new(void)
|
||||
{
|
||||
// ------------------------------
|
||||
deque_t deque = deque_new(sizeof(int), 10);
|
||||
TEST_ASSERT_NOT_NULL(deque);
|
||||
deque_free(&deque);
|
||||
|
||||
TEST_ASSERT_NULL(deque_new(0, 0));
|
||||
TEST_ASSERT_NULL(deque_new(0, 1));
|
||||
TEST_ASSERT_NULL(deque_new(sizeof(int), 0));
|
||||
|
||||
// ------------------------------
|
||||
TEST_ASSERT_NULL(deque);
|
||||
deque_free(&deque);
|
||||
}
|
||||
|
||||
static void test_deque_num(void)
|
||||
{
|
||||
size_t i = 0;
|
||||
@ -17,7 +34,7 @@ static void test_deque_num(void)
|
||||
int temp = 0;
|
||||
size_t len = sizeof(data) / sizeof(data[0]);
|
||||
|
||||
deque_t deque = deque_new(sizeof(int));
|
||||
deque_t deque = deque_new(sizeof(int), len);
|
||||
TEST_ASSERT_NOT_NULL(deque);
|
||||
deque->print_obj = print_num;
|
||||
|
||||
@ -148,7 +165,7 @@ static void test_deque_struct(void)
|
||||
struct _student temp = {0};
|
||||
size_t len = sizeof(data) / sizeof(data[0]);
|
||||
|
||||
deque_t deque = deque_new(sizeof(struct _student));
|
||||
deque_t deque = deque_new(sizeof(struct _student), len);
|
||||
TEST_ASSERT_NOT_NULL(deque);
|
||||
deque->print_obj = print_struct;
|
||||
|
||||
@ -275,7 +292,7 @@ static void test_deque_iter(void)
|
||||
int temp = 0;
|
||||
size_t len = sizeof(data) / sizeof(data[0]);
|
||||
|
||||
deque_t deque = deque_new(sizeof(int));
|
||||
deque_t deque = deque_new(sizeof(int), len);
|
||||
TEST_ASSERT_NOT_NULL(deque);
|
||||
deque->print_obj = print_num;
|
||||
|
||||
@ -327,6 +344,8 @@ void test_deque(void)
|
||||
{
|
||||
UnitySetTestFile(__FILE__);
|
||||
|
||||
RUN_TEST(test_deque_new);
|
||||
|
||||
RUN_TEST(test_deque_num);
|
||||
RUN_TEST(test_deque_struct);
|
||||
|
||||
|
||||
@ -10,6 +10,47 @@
|
||||
*/
|
||||
#include "test.h"
|
||||
|
||||
static void test_ringbuffer_new(void)
|
||||
{
|
||||
darray_t ringbuffer = darray_new(sizeof(int), 10);
|
||||
TEST_ASSERT_NOT_NULL(ringbuffer);
|
||||
darray_free(&ringbuffer);
|
||||
|
||||
TEST_ASSERT_NULL(darray_new(0, 0));
|
||||
TEST_ASSERT_NULL(darray_new(0, 1));
|
||||
TEST_ASSERT_NULL(darray_new(sizeof(int), 0));
|
||||
|
||||
// ------------------------------
|
||||
TEST_ASSERT_NULL(ringbuffer);
|
||||
darray_free(&ringbuffer);
|
||||
}
|
||||
|
||||
static void test_ringbuffer_push(void)
|
||||
{
|
||||
size_t i = 0;
|
||||
int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
int temp = 0;
|
||||
size_t len = sizeof(data) / sizeof(data[0]);
|
||||
|
||||
ringbuffer_t ringbuffer = ringbuffer_new(sizeof(int), len);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(ringbuffer->push_back(ringbuffer, &data[i]));
|
||||
}
|
||||
TEST_ASSERT_FALSE(ringbuffer->push_back(ringbuffer, &data[0]));
|
||||
|
||||
TEST_ASSERT_TRUE(ringbuffer->clear(ringbuffer));
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
TEST_ASSERT_TRUE(ringbuffer->push_front(ringbuffer, &data[i]));
|
||||
}
|
||||
TEST_ASSERT_FALSE(ringbuffer->push_front(ringbuffer, &data[0]));
|
||||
|
||||
ringbuffer_free(&ringbuffer);
|
||||
}
|
||||
|
||||
static void test_ringbuffer_num(void)
|
||||
{
|
||||
size_t i = 0;
|
||||
@ -18,7 +59,6 @@ static void test_ringbuffer_num(void)
|
||||
size_t len = sizeof(data) / sizeof(data[0]);
|
||||
|
||||
ringbuffer_t ringbuffer = ringbuffer_new(sizeof(int), len);
|
||||
TEST_ASSERT_NOT_NULL(ringbuffer);
|
||||
ringbuffer->print_obj = print_num;
|
||||
|
||||
TEST_ASSERT_TRUE(ringbuffer->empty(ringbuffer));
|
||||
@ -44,6 +84,7 @@ static void test_ringbuffer_num(void)
|
||||
{
|
||||
TEST_ASSERT_TRUE(ringbuffer->push_back(ringbuffer, &data[i]));
|
||||
}
|
||||
// ringbuffer->print(ringbuffer);
|
||||
|
||||
for (i = 0; i < len + 1; i++)
|
||||
{
|
||||
@ -285,7 +326,7 @@ static void test_ringbuffer_iter(void)
|
||||
{
|
||||
ringbuffer->push_back(ringbuffer, &data[i]);
|
||||
}
|
||||
|
||||
|
||||
iterator_t iter = ringbuffer->iter(ringbuffer, RINGBUF_FORWARD);
|
||||
i = 0;
|
||||
while(iter->hasnext(iter))
|
||||
@ -311,6 +352,9 @@ void test_ringbuffer(void)
|
||||
{
|
||||
UnitySetTestFile(__FILE__);
|
||||
|
||||
RUN_TEST(test_ringbuffer_new);
|
||||
RUN_TEST(test_ringbuffer_push);
|
||||
|
||||
RUN_TEST(test_ringbuffer_num);
|
||||
RUN_TEST(test_ringbuffer_struct);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user