diff --git a/doc/README.md b/doc/README.md index 7be8a8e..2063651 100644 --- a/doc/README.md +++ b/doc/README.md @@ -13,6 +13,8 @@ flowchart TB subgraph hal segarray[segarray
大数据扩容优先] --> darray + string --> darray + hashtable --> darray end subgraph adapter @@ -27,7 +29,10 @@ flowchart TB end subgraph top - tree -.-> stack - tree -.-> queue + rbtree -.-> stack + rbtree -.-> queue + + map -.-> rbtree + unordered_map -.-> hashtable end ``` diff --git a/include/deque.h b/include/deque.h index d050202..7f432f2 100644 --- a/include/deque.h +++ b/include/deque.h @@ -42,9 +42,11 @@ struct _deque bool (*front)(struct _deque* self, void* obj); // base - size_t(*size)(struct _deque* self); + size_t (*size)(struct _deque* self); + size_t (*capacity)(struct _deque* self); bool (*clear)(struct _deque* self); bool (*empty)(struct _deque* self); + bool (*full)(struct _deque* self); // iter iterator_t (*iter)(struct _deque* self, enum _deque_order order); diff --git a/include/logger.h b/include/logger.h index a444c8d..965f8e8 100644 --- a/include/logger.h +++ b/include/logger.h @@ -18,7 +18,7 @@ #include "unicstl_config.h" // -------------------- DEBUG CONFIG -------------------- -#ifndef LOGGER_ON +#ifdef LOGGER_ON #ifndef LOG_LEVEL #define LOG_LEVEL LOG_NONE diff --git a/include/stack.h b/include/stack.h index ef668ae..aed5e09 100644 --- a/include/stack.h +++ b/include/stack.h @@ -12,30 +12,14 @@ #define _STACK_H_ #include "unicstl_internal.h" - -struct _stack_node -{ - void * obj; - struct _stack_node * next; -}; +#include "deque.h" struct _stack { - // -------------------- private -------------------- - /** - * @brief head pointer of stack - * 1. linklist: head->next is valid, head->obj is NULL - * 2. array: head->obj is valid, head->next is NULL, - */ - struct _stack_node * _head; - - size_t _size; - size_t _obj_size; - size_t _capacity; - size_t _ratio; + deque_t _deque; + iterator_t _iter_deque; struct _iterator _iter; - void (*_destory)(struct _stack* self); // -------------------- public -------------------- @@ -60,9 +44,9 @@ struct _stack typedef struct _stack* stack_t; // create and free stack -stack_t stack_new(size_t obj_size); stack_t stack_new2(size_t obj_size, size_t capacity); - void stack_free(stack_t* stack); +#define stack_new(obj_type) stack_new2(sizeof(obj_type), 16) + #endif // _STACK_H_ diff --git a/include/unicstl_config.h b/include/unicstl_config.h index 5e3c773..cb1551e 100644 --- a/include/unicstl_config.h +++ b/include/unicstl_config.h @@ -10,6 +10,8 @@ */ #ifndef _UNICSTL_CONFIG_H_ +// #define NDEBUG // release + /** * @brief unicstl contains which module * @@ -28,17 +30,17 @@ * */ #define UNICSTL_MALLOC -#define UNICSTL_ASSERT /** * @brief * */ +#ifndef NDEBUG #define UNICSTL_DEBUG - - +#endif #ifdef UNICSTL_DEBUG + #define UNICSTL_DEBUG_STACK #define UNICSTL_DEBUG_QUEUE #define UNICSTL_DEBUG_DEQUE @@ -47,10 +49,8 @@ #define UNICSTL_DEBUG_GRAPH -/** - * @brief log enable - */ -// #define LOGGER_ON +#define UNICSTL_ASSERT // assert +#define LOGGER_ON // logger on /** * @brief debug level @@ -59,7 +59,8 @@ * 2. WARN * 3. ERROR */ -#define LOG_LEVEL 4 +#define LOG_LEVEL 0 + /** * @brief * 0. simple diff --git a/include/unicstl_internal.h b/include/unicstl_internal.h index 2a21e80..c0e3220 100644 --- a/include/unicstl_internal.h +++ b/include/unicstl_internal.h @@ -51,7 +51,7 @@ static inline void _unicstl_assert(const char *expr, const char *file, int line) exit(1); } #else -#define unicstl_assert assert +#define unicstl_assert(expr) // assert(expr) #endif diff --git a/src/deque.c b/src/deque.c index 1f9afb7..0d12a39 100644 --- a/src/deque.c +++ b/src/deque.c @@ -66,6 +66,13 @@ static size_t deque_size(struct _deque* self) return self->ringbuf->size(self->ringbuf); } +static size_t deque_capacity(struct _deque* self) +{ + unicstl_assert(self != NULL); + unicstl_assert(self->ringbuf != NULL); + return self->ringbuf->capacity(self->ringbuf); +} + static bool deque_empty(struct _deque* self) { unicstl_assert(self != NULL); diff --git a/src/stack.c b/src/stack.c index 6f63433..42205b2 100644 --- a/src/stack.c +++ b/src/stack.c @@ -10,247 +10,84 @@ */ #include "stack.h" -static struct _stack_node* stack_node_new(void *obj, size_t obj_size) -{ - void* new_obj = (void*)calloc(1, obj_size); - if (new_obj == NULL) - { - goto done; - } - memmove(new_obj, obj, obj_size); - - struct _stack_node* new_node = (struct _stack_node*)malloc(sizeof(struct _stack_node)); - if (new_node == NULL) - { - goto done1; - } - new_node->obj = new_obj; - new_node->next = NULL; - - return new_node; -done1: - free(new_obj); -done: - return NULL; -} - -static void stack_node_free(struct _stack_node** node) -{ - if(node != NULL && *node != NULL) - { - if((*node)->obj != NULL) - { - free((*node)->obj); - } - free(*node); - *node = NULL; - } -} - static bool stack_push(struct _stack* self, void* obj) { unicstl_assert(self != NULL); - unicstl_assert(self->_head != NULL); - unicstl_assert(obj != NULL); + unicstl_assert(self->_deque != NULL); + deque_t deque = self->_deque; - struct _stack_node* new_node = stack_node_new(obj, self->_obj_size); - if (new_node == NULL) - { - return false; - } - new_node->next = self->_head->next; - self->_head->next = new_node; - - self->_size += 1; - return true; + return deque->push_back(deque, obj); } static bool stack_pop(struct _stack* self, void* obj) { unicstl_assert(self != NULL); - unicstl_assert(self->_head != NULL); - if (self->empty(self)) - { - return false; - } - struct _stack_node* node = self->_head->next; + unicstl_assert(self->_deque != NULL); + deque_t deque = self->_deque; - if (obj != NULL) - { - memmove(obj, node->obj, self->_obj_size); - } - self->_head->next = node->next; - - stack_node_free(&node); - self->_size -= 1; - return true; + return deque->pop_back(deque, obj); } static bool stack_peek(struct _stack* self, void* obj) { unicstl_assert(self != NULL); - unicstl_assert(self->_head != NULL); - unicstl_assert(obj != NULL); + unicstl_assert(self->_deque != NULL); + deque_t deque = self->_deque; - if (self->empty(self)) - { - return false; - } - - struct _stack_node * node = self->_head->next; - memmove(obj, node->obj, self->_obj_size); - return true; + return deque->back(deque, obj); } static size_t stack_size(struct _stack* self) { unicstl_assert(self != NULL); - return self->_size; + unicstl_assert(self->_deque != NULL); + deque_t deque = self->_deque; + + return deque->size(deque); } static bool stack_empty(struct _stack* self) { unicstl_assert(self != NULL); - unicstl_assert(self->size != NULL); - return self->size(self) == 0; + unicstl_assert(self->_deque != NULL); + deque_t deque = self->_deque; + + return deque->empty(deque); } static size_t stack_capacity(struct _stack* self) { unicstl_assert(self != NULL); - return self->_capacity; + unicstl_assert(self->_deque != NULL); + deque_t deque = self->_deque; + + return deque->capacity(deque); } static bool stack_clear(struct _stack* self) { unicstl_assert(self != NULL); - if (self->empty(self)) - { - return true; - } + unicstl_assert(self->_deque != NULL); + deque_t deque = self->_deque; - struct _stack_node* node = self->_head->next; - while (node != NULL) - { - self->_head->next = node->next; - stack_node_free(&node); - node = self->_head->next; - } - self->_size = 0; - return true; + return deque->clear(deque); } static void stack_destory(struct _stack* self) { unicstl_assert(self != NULL); - self->clear(self); - if(self->_head != NULL) - { - free(self->_head); - self->_head = NULL; - } + unicstl_assert(self->_deque != NULL); + deque_free(&self->_deque); } static void stack_print(struct _stack* self) -{ - size_t i = 0; - struct _stack_node* node = self->_head->next; - while (node != NULL) - { - self->print_obj(node->obj); - node = node->next; - } -} - -static bool stack2_push(struct _stack* self, void* obj) { unicstl_assert(self != NULL); - unicstl_assert(self->_head != NULL); - unicstl_assert(obj != NULL); + unicstl_assert(self->_deque != NULL); + deque_t deque = self->_deque; + deque->print_obj = self->print_obj; - if (self->size(self) == self->capacity(self)) - { - void* obj_new = (void*)realloc(self->_head->obj, self->capacity(self) * self->_obj_size * self->_ratio); - if (obj_new == NULL) - { - return false; - } - self->_head->obj = obj_new; - } - - size_t top = self->size(self); - size_t offset = top * self->_obj_size; - memmove((char*)self->_head->obj + offset, obj, self->_obj_size); - - self->_size += 1; - return true; -} - -static bool stack2_pop(struct _stack* self, void* obj) -{ - unicstl_assert(self != NULL); - unicstl_assert(self->_head != NULL); - if (self->empty(self)) - { - return false; - } - - if (obj != NULL) - { - size_t top = self->size(self) - 1; - size_t offset = top * self->_obj_size; - memmove(obj, (char*)self->_head->obj + offset, self->_obj_size); - } - self->_size -= 1; - return true; -} - -static bool stack2_peek(struct _stack* self, void* obj) -{ - unicstl_assert(self != NULL); - unicstl_assert(self->_head != NULL); - unicstl_assert(obj != NULL); - if (self->empty(self)) - { - return false; - } - - size_t top = self->size(self) - 1; - size_t offset = top * self->_obj_size; - memmove(obj, (char *)self->_head->obj + offset, self->_obj_size); - return true; -} - -static void stack2_destory(struct _stack* self) -{ - unicstl_assert(self != NULL); - self->clear(self); - if(self->_head != NULL) - { - if(self->_head->obj != NULL) - { - free(self->_head->obj); - self->_head->obj = NULL; - } - free(self->_head); - self->_head = NULL; - } -} - -static void stack2_print(struct _stack* self) -{ - unicstl_assert(self != NULL); - unicstl_assert(self->_head != NULL); - - void* obj = NULL; - size_t offset = 0; - - for (int i = self->size(self) - 1; i >= 0; i--) - { - offset = self->_obj_size * i; - obj = (char*)self->_head->obj + offset; - self->print_obj(obj); - } + deque->print(deque); } bool stack_iter_hasnext(struct _iterator* iter) @@ -259,11 +96,7 @@ bool stack_iter_hasnext(struct _iterator* iter) unicstl_assert(iter->_container != NULL); stack_t self = (stack_t)iter->_container; - if(iter->_index < self->size(self)) - { - return true; - } - return false; + return self->_iter_deque->hasnext(self->_iter_deque); } /** @@ -276,65 +109,42 @@ const void* stack_iter_next(struct _iterator* iter) unicstl_assert(iter->_container != NULL); stack_t self = (stack_t)iter->_container; - void *obj = NULL; - - if(self->_head->obj == NULL) - { - // base on linklist - struct _stack_node* node = (struct _stack_node *)iter->_node; - if(node != NULL) - { - obj = node->obj; - iter->_node = node->next; - } - } - else - { - // base on array - size_t index = self->size(self) - 1 - iter->_index; - obj = self->_head->obj + self->_obj_size * index; - } - - iter->_index += 1; - return obj; + return self->_iter_deque->next(self->_iter_deque); } iterator_t stack_iter(struct _stack* self) { unicstl_assert(self != NULL); - iterator_t iter = &self->_iter; + unicstl_assert(self->_deque != NULL); + deque_t deque = self->_deque; + iterator_t iter = &self->_iter; iter->_container = self; - iter->_index = 0; - iter->_node = self->_head->next; + + self->_iter_deque = deque->iter(deque, DEQUE_FORWARD); iter->hasnext = stack_iter_hasnext; iter->next = stack_iter_next; return iter; } -static bool stack_init(struct _stack* self, size_t obj_size) +static bool stack_init(struct _stack* self, size_t obj_size, size_t capacity) { // unicstl_assert(self != NULL); - // unicstl_assert(obj_size != 0); - if(self == NULL || obj_size == 0) + if(self == NULL || obj_size == 0 || capacity == 0) { return false; } // -------------------- private -------------------- - self->_obj_size = obj_size; - self->_size = 0; - self->_capacity = UINT32_MAX; - self->_ratio = 1; - - self->_head = (struct _stack_node *)malloc(sizeof(struct _stack_node)); - if (self->_head == NULL) + self->_deque = deque_new(obj_size, capacity); + if(self->_deque == NULL) { return false; } - self->_head->obj = NULL; - self->_head->next = NULL; + + self->_iter.next = stack_iter_next; + self->_iter.hasnext = stack_iter_hasnext; self->_destory = stack_destory; @@ -352,91 +162,16 @@ static bool stack_init(struct _stack* self, size_t obj_size) // iter self->iter = stack_iter; - + // -------------------- default -------------------- self->print_obj = default_print_obj; - + // -------------------- debug -------------------- self->print = stack_print; return true; } -static bool stack_init2(struct _stack* self, size_t obj_size, size_t capacity) -{ - // unicstl_assert(self != NULL); - if(self == NULL || obj_size == 0 || capacity == 0) - { - return false; - } - - // -------------------- private -------------------- - self->_obj_size = obj_size; - self->_size = 0; - self->_capacity = capacity; - self->_ratio = 2; - - self->_head = (struct _stack_node*)malloc(sizeof(struct _stack_node)); - if (self->_head == NULL) - { - return false; - } - self->_head->next = NULL; - - self->_head->obj = (void *)calloc(self->_capacity, self->_obj_size); - if (self->_head->obj == NULL) - { - free(self->_head); - self->_head = NULL; - return false; - } - - self->_iter.next = stack_iter_next; - self->_iter.hasnext = stack_iter_hasnext; - - self->_destory = stack2_destory; - - // -------------------- public -------------------- - // kernel - self->push = stack2_push; - self->pop = stack2_pop; - self->peek = stack2_peek; - self->empty = stack_empty; - - // base - self->size = stack_size; - self->capacity = stack_capacity; - self->clear = stack_clear; - - // iter - self->iter = stack_iter; - - // -------------------- default -------------------- - self->print_obj = default_print_obj; - - // -------------------- debug -------------------- - self->print = stack2_print; - - return true; -} - -stack_t stack_new(size_t obj_size) -{ - stack_t stack = NULL; - stack = (struct _stack*)calloc(1, sizeof(struct _stack)); - if(stack == NULL) - { - return NULL; - } - - if(stack_init(stack, obj_size) != true) - { - free(stack); - return NULL; - } - return stack; -} - stack_t stack_new2(size_t obj_size, size_t capacity) { stack_t stack = NULL; @@ -446,7 +181,7 @@ stack_t stack_new2(size_t obj_size, size_t capacity) return NULL; } - if(stack_init2(stack, obj_size, capacity) != true) + if(stack_init(stack, obj_size, capacity) != true) { free(stack); return NULL; @@ -456,7 +191,6 @@ stack_t stack_new2(size_t obj_size, size_t capacity) void stack_free(stack_t *stack) { - unicstl_assert(stack != NULL); if(stack != NULL && *stack != NULL) { if((*stack)->_destory != NULL) diff --git a/src/unicstl_internal.c b/src/unicstl_internal.c index f97ac33..196a863 100644 --- a/src/unicstl_internal.c +++ b/src/unicstl_internal.c @@ -25,19 +25,19 @@ void default_print_obj(const void* obj) size_t unicstl_new_capacity(size_t capacity) { size_t new_capacity = 0; - if(capacity < 4) + if(capacity <= 8) { - new_capacity = 8; + new_capacity = 16; } else if (capacity < 1024) { - new_capacity = capacity * 2; + // capacity * 2; + new_capacity = capacity << 1; } else { + // capacity + capacity / 8 = capacity * 1.125; new_capacity = capacity + (capacity >> 3); } - return new_capacity; } - diff --git a/test/test_stack.c b/test/test_stack.c index 8c89884..cedb98a 100644 --- a/test/test_stack.c +++ b/test/test_stack.c @@ -221,7 +221,7 @@ static void test_stack_clear(void) static void test_stack_num(void) { size_t i = 0; - int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + int data[10] = { 1,2,3,4,5,6,7,8,9,10 }; int temp = 0; size_t len = sizeof(data) / sizeof(data[0]); @@ -237,7 +237,15 @@ static void test_stack_num(void) TEST_ASSERT_TRUE(stack->push(stack, &data[i])); TEST_ASSERT_EQUAL_INT(i + 1, stack->size(stack)); + LOG_DEBUG("[%d] stack size: %d", i, stack->size(stack)); + stack->print(stack); TEST_ASSERT_TRUE(stack->peek(stack, &temp)); + for(int j = 0; j < 10; j++) + { + printf("%d ", data[j]); + } + + LOG_DEBUG("data[%d]=%d, temp=%d\n", i, data[i], temp); TEST_ASSERT_EQUAL_INT(data[i], temp); }