From 0dd45ed7dddea49e622c17dd756c265d0d06a029 Mon Sep 17 00:00:00 2001 From: wjf-hs Date: Fri, 15 May 2026 19:01:37 +0800 Subject: [PATCH] =?UTF-8?q?refactor(segarray):=20=E6=AE=B5=E4=BD=BF?= =?UTF-8?q?=E7=94=A8rawbuf=E8=80=8C=E4=B8=8D=E6=98=AFdarray=EF=BC=8C?= =?UTF-8?q?=E5=85=88=E6=8C=89=E7=85=A7=E6=9C=80=E7=AE=80=E5=8D=95=E7=9A=84?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E8=B0=83=E8=AF=95=E9=80=9Apush=E5=92=8Cpop?= =?UTF-8?q?=E7=AD=89=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + include/rawbuf.h | 2 +- include/segarray.h | 16 +- include/unicstl_config.h | 4 +- src/segarray.c | 371 +++++++++++++++++++++++++++------------ test/test.c | 2 +- test/test_segarray.c | 54 +++--- 7 files changed, 298 insertions(+), 154 deletions(-) diff --git a/.gitignore b/.gitignore index 9bab31c..e8f75a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ +# log/txt +*.log + # cmake build/ release/ diff --git a/include/rawbuf.h b/include/rawbuf.h index 68c74f9..270a19c 100644 --- a/include/rawbuf.h +++ b/include/rawbuf.h @@ -40,4 +40,4 @@ void rawbuf_free(rawbuf_t *rawbuf); bool rawbuf_init(struct _rawbuf *self, size_t obj_size, size_t capacity, void *mem_base); #endif -#endif +#endif // _RAWBUF_H_ diff --git a/include/segarray.h b/include/segarray.h index 7dcd1bd..1e6ccd7 100644 --- a/include/segarray.h +++ b/include/segarray.h @@ -12,8 +12,8 @@ #define _SEGARRAY_H_ #include "unicstl_internal.h" -#include "darray.h" #include "ringbuf.h" +#include "rawbuf.h" enum _segarray_order { @@ -21,12 +21,6 @@ enum _segarray_order SEGARRAY_REVERSE, }; -struct _obj_pos -{ - size_t map; - size_t seg; -}; - struct _segarray { // -------------------- private -------------------- @@ -36,11 +30,13 @@ struct _segarray size_t _size; size_t _capacity; bool _dynamic; + size_t _segsize; ringbuf_t _map; - - struct _obj_pos _head; - struct _obj_pos _tail; + size_t _maphead; + size_t _maptail; + size_t _seghead; + size_t _segtail; struct _iterator _iter; void (*_destory)(struct _segarray* self); diff --git a/include/unicstl_config.h b/include/unicstl_config.h index 443b960..f379a37 100644 --- a/include/unicstl_config.h +++ b/include/unicstl_config.h @@ -10,7 +10,7 @@ */ #ifndef _UNICSTL_CONFIG_H_ -#define NDEBUG // release mode if define NDEBUG +// #define NDEBUG // release mode if define NDEBUG /** * @brief unicstl contains which module @@ -66,7 +66,7 @@ * 0. simple * 1. detail */ -#define LOG_DEBUG_DETAIL 1 +#define LOG_DEBUG_DETAIL 0 #endif // UNICSTL_DEBUG #endif diff --git a/src/segarray.c b/src/segarray.c index f0ca9c8..03b076f 100644 --- a/src/segarray.c +++ b/src/segarray.c @@ -1,87 +1,86 @@ /** * @file segarray.c * @author wenjf (Orig5826@163.com) - * @brief + * @brief * @version 0.1 * @date 2026-05-15 - * + * * @copyright Copyright (c) 2026 - * + * */ #include "segarray.h" static inline size_t clac_start_index(size_t capacity) { - return capacity <= 2 ? 0 : (capacity - 1)/ 2; + return capacity <= 2 ? 0 : (capacity - 1) / 2; } -static inline const darray_t get_seg(struct _segarray *self, struct _obj_pos pos) +static inline size_t segarray_map_full(struct _segarray *self, size_t capacity) { - return (const darray_t)self->_map->at(self->_map, pos.map); -} - -static inline void * get_obj(struct _segarray *self, struct _obj_pos pos, void *obj) -{ - darray_t darray = get_seg(self, pos); - return (void *)darray->at(darray, pos.seg); + return 0; } static inline void print_pos(struct _segarray *self) { - printf("head[%d][%d], tail[%d][%d]\n", self->_head.map, self->_head.seg, - self->_tail.map, self->_tail.seg); + LOG_DEBUG("head[%d][%d], tail[%d][%d]\n", + self->_maphead, + self->_seghead, + self->_maptail - 1, + self->_segtail); } - static bool segarray_push_back(struct _segarray *self, const void *obj) { unicstl_assert(self != NULL); - if(self->obj == NULL || obj == NULL) + if (self->obj == NULL || obj == NULL) { return false; } + ringbuf_t map = self->_map; + if (self->_segtail == self->_segsize) + { + if (map->full(map)) + { + LOG_WARN("map->full"); + return false; + // size_t new_capacity = unicstl_new_capacity(self->capacity(self)); + // if (!map->resize(map, new_capacity)) + // { + // LOG_ERROR("map->resize(map, new_capacity) failed!"); + // return false; + // } + } + + rawbuf_t seg = rawbuf_new(self->_obj_size, self->_capacity); + if (seg == NULL) + { + LOG_ERROR("rawbuf_new failed!"); + return false; + } + map->push_back(map, &seg); + + self->_maptail = self->_maptail + 1; + self->_segtail = 0; + } print_pos(self); - if (self->_tail.seg == self->_capacity - 1) + rawbuf_t seg; + if (!map->back(map, &seg)) { - if(map->full(map)) - { - size_t new_capacity = unicstl_new_capacity(self->capacity(self)); - if (!map->resize(map, new_capacity)) - { - printf("map->resize(map, new_capacity) failed!"); - return false; - } - } - else - { - darray_t seg = darray_new(self->_obj_size, self->_capacity); - if(seg == NULL) - { - printf("darray_new failed!"); - return false; - } - map->push_back(map, &seg); - } - } - - darray_t seg; - if(!map->back(map, &seg)) - { - printf("map->back failed!"); + LOG_ERROR("map->back failed!"); return false; } - size_t index = self->_tail.seg; - printf("index = %d\n", index); - if(!seg->set(seg, index, obj)) + size_t index = self->_segtail; + if (!seg->set(seg, index, obj)) { - printf("seg->set failed!"); + LOG_ERROR("seg->set failed!"); return false; } - self->_tail.seg = ring_index_next(self->_tail.seg, self->_capacity); - + self->_segtail = index + 1; + + LOG_INFO("push_back success!"); self->_size++; return true; } @@ -89,39 +88,56 @@ static bool segarray_push_back(struct _segarray *self, const void *obj) static bool segarray_push_front(struct _segarray *self, const void *obj) { unicstl_assert(self != NULL); - if(self->obj == NULL || obj == NULL) + if (self->obj == NULL || obj == NULL) { return false; } - if (self->full(self)) + ringbuf_t map = self->_map; + if (self->_seghead == 0) { - if(self->_dynamic != true) - { - return false; - } - size_t new_capacity = unicstl_new_capacity(self->capacity(self)); - if (self->resize(self, new_capacity) == false) + LOG_DEBUG("map->size = %d\n", map->size(map)); + if (map->full(map)) { + LOG_WARN("map->full"); + return false; + // size_t new_capacity = unicstl_new_capacity(self->capacity(self)); + // if (!map->resize(map, new_capacity)) + // { + // LOG_ERROR("map->resize(map, new_capacity) failed!"); + // return false; + // } + } + + rawbuf_t seg = rawbuf_new(self->_obj_size, self->_capacity); + if (seg == NULL) + { + LOG_ERROR("rawbuf_new failed!"); return false; } + map->push_front(map, &seg); + + self->_maphead = self->_maphead - 1; + self->_seghead = self->_segsize; } - // const darray_t seg = (const darray_t)self->_map->at(self->_map, self->_head.map); - // if(seg == NULL) - // { - // return false; - // } - // self->obj = seg->at(seg, self->_head.seg); - // if(self->obj == NULL) - // { - // return false; - // } - - // size_t index = ring_index_prev(self->_head.seg, self->_capacity); - // obj_set(self->obj, index, obj, self->_obj_size); - // self->_head.seg = index; + print_pos(self); + rawbuf_t seg; + if (!map->front(map, &seg)) + { + LOG_ERROR("map->back failed!"); + return false; + } + size_t index = self->_seghead - 1; + if (!seg->set(seg, index, obj)) + { + LOG_ERROR("seg->set failed!"); + return false; + } + self->_seghead = index; + + LOG_INFO("push_front success!"); self->_size++; return true; } @@ -129,18 +145,41 @@ static bool segarray_push_front(struct _segarray *self, const void *obj) static bool segarray_pop_back(struct _segarray *self, void *obj) { unicstl_assert(self != NULL); - if(self->obj == NULL || self->empty(self)) + if (self->obj == NULL || self->empty(self)) { return false; } - // size_t index = ring_index_prev(self->_tail.seg, self->_capacity); - // if(obj != NULL) - // { - // obj_get(self->obj, index, obj, self->_obj_size); - // } - // self->_tail = index; + print_pos(self); + ringbuf_t map = self->_map; + rawbuf_t seg; + + size_t index = self->_segtail - 1; + if(obj != NULL) + { + if (!map->back(map, &seg)) + { + LOG_ERROR("map->back failed!"); + return false; + } + if (!seg->get(seg, index, obj)) + { + LOG_ERROR("seg->set failed!"); + return false; + } + } + self->_segtail = index; + if(self->_segtail == 0) + { + self->_segtail = self->_segsize; + self->_maptail = self->_maptail - 1; + + map->pop_back(map, &seg); + rawbuf_free(&seg); + } + + LOG_INFO("pop_back success!"); self->_size--; return true; } @@ -148,7 +187,7 @@ static bool segarray_pop_back(struct _segarray *self, void *obj) static bool segarray_pop_front(struct _segarray *self, void *obj) { unicstl_assert(self != NULL); - if(self->obj == NULL || self->empty(self)) + if (self->obj == NULL || self->empty(self)) { return false; } @@ -158,6 +197,36 @@ static bool segarray_pop_front(struct _segarray *self, void *obj) return false; } + print_pos(self); + + ringbuf_t map = self->_map; + size_t index = self->_seghead; + if(obj != NULL) + { + rawbuf_t seg; + if (!map->front(map, &seg)) + { + LOG_ERROR("map->back failed!"); + return false; + } + if (!seg->get(seg, index, obj)) + { + LOG_ERROR("seg->set failed!"); + return false; + } + } + self->_seghead = index + 1; + if(self->_seghead == self->_segsize) + { + self->_seghead = 0; + self->_maphead = self->_maphead + 1; + + rawbuf_t seg; + map->pop_front(map, &seg); + rawbuf_free(&seg); + } + + LOG_INFO("pop_front success!"); self->_size--; return true; } @@ -165,25 +234,37 @@ static bool segarray_pop_front(struct _segarray *self, void *obj) static bool segarray_back(struct _segarray *self, void *obj) { unicstl_assert(self != NULL); - if(self->obj == NULL || obj == NULL|| self->empty(self)) + if (self->obj == NULL || obj == NULL || self->empty(self)) { return false; } - - return true; + ringbuf_t map = self->_map; + rawbuf_t seg; + if (!map->back(map, &seg)) + { + return false; + } + size_t index = self->_segtail - 1; + return seg->get(seg, index, obj); } static bool segarray_front(struct _segarray *self, void *obj) { unicstl_assert(self != NULL); - if(self->obj == NULL || obj == NULL|| self->empty(self)) + if (self->obj == NULL || obj == NULL || self->empty(self)) { return false; } - - return true; + ringbuf_t map = self->_map; + rawbuf_t seg; + if (!map->front(map, &seg)) + { + return false; + } + size_t index = self->_seghead; + return seg->get(seg, index, obj); } static bool segarray_resize(struct _segarray *self, size_t capacity) @@ -194,6 +275,11 @@ static bool segarray_resize(struct _segarray *self, size_t capacity) return false; } + if(capacity < self->_capacity) + { + return false; + } + return true; } @@ -206,8 +292,7 @@ static size_t segarray_size(struct _segarray *self) static size_t segarray_capacity(struct _segarray *self) { unicstl_assert(self != NULL); - // return self->_capacity; - return self->_capacity * self->_map->size(self->_map); + return self->_capacity; } static bool segarray_empty(struct _segarray *self) @@ -219,32 +304,38 @@ static bool segarray_empty(struct _segarray *self) static bool segarray_full(struct _segarray *self) { unicstl_assert(self != NULL); - size_t map_cap = self->_map->size(self->_map); + size_t map_size = self->_map->size(self->_map); - return (self->_head.map == 0 && self->_head.seg == 0) || - ( self->_tail.map == map_cap - 1 && self->_head.seg == self->_capacity - 1); + return (self->_maphead == 0 && self->_seghead == 0) || + (self->_maptail == map_size - 1 && self->_segtail == self->_segsize - 1); } static bool segarray_clear(struct _segarray *self) { unicstl_assert(self != NULL); self->_size = 0; - - self->_head.map = clac_start_index(self->_map->capacity(self->_map)); - self->_tail.map = self->_head.map; - self->_head.seg = clac_start_index(self->capacity(self)); - self->_tail.seg = self->_head.seg; + self->_seghead = clac_start_index(self->_segsize); + self->_segtail = self->_seghead; + self->_maptail = self->_maphead; return true; } static void segarray_destory(struct _segarray *self) { unicstl_assert(self != NULL); - if (self->obj != NULL && self->_dynamic == true) + ringbuf_t map = self->_map; + if (self->_dynamic) { - free(self->obj); - self->obj = NULL; + rawbuf_t seg = NULL; + while(map->empty(map)) + { + if (map->pop_back(map, &seg)) + { + rawbuf_free(&seg); + } + } + ringbuf_free(&map); } } @@ -267,11 +358,17 @@ bool segarray_iter_hasnext(struct _iterator *iter) if (iter->_order == SEGARRAY_FORWARD) { - + if (iter->_index >= self->size(self)) + { + return false; + } } else { - + if (iter->_index == 0) + { + return false; + } } return true; } @@ -283,17 +380,58 @@ const void *segarray_iter_next(struct _iterator *iter) segarray_t self = (segarray_t)iter->_container; + const void *obj = NULL; size_t index = iter->_index; - if (iter->_order == SEGARRAY_FORWARD) + ringbuf_t map = self->_map; + rawbuf_t seg = NULL; + size_t map_index; + size_t seg_index; + + if (iter->_order == SEGARRAY_REVERSE) { - //iter->_index = index_next(index, self->_capacity); + LOG_DEBUG("index:%ld", index); + index = self->size(self) + 1 - index; + LOG_DEBUG("reverse-index:%ld", index); + } + + size_t seg1_left = self->_segsize - self->_seghead; + if(index < seg1_left) + { + map_index = 0; + seg_index = self->_seghead + index; } else { - //iter->_index = index_prev(index, self->_capacity); + size_t index_left = index - seg1_left; + map_index = index_left / self->_segsize + 1; + seg_index = index_left % self->_segsize; + } + + LOG_DEBUG("index:%ld, sethead:%ld", index, seg_index); + LOG_DEBUG("map_index:%ld, seg_index:%ld", map_index, seg_index); + + if (map->get(map, map_index, &seg)) + { + obj = seg->at(seg, seg_index); + if(obj == NULL) + { + return NULL; + } + } + else + { + return NULL; } - return obj_at(self->obj, index, self->_obj_size); + if (iter->_order == SEGARRAY_FORWARD) + { + iter->_index++; + } + else + { + iter->_index--; + } + return obj; } iterator_t segarray_iter(struct _segarray *self, enum _segarray_order order) @@ -306,6 +444,14 @@ iterator_t segarray_iter(struct _segarray *self, enum _segarray_order order) iter->_order = order; //.. + if (iter->_order == SEGARRAY_FORWARD) + { + iter->_index = 0; + } + else + { + iter->_index = self->_map->size(self->_map); + } iter->hasnext = segarray_iter_hasnext; iter->next = segarray_iter_next; @@ -330,7 +476,8 @@ bool segarray_init(struct _segarray *self, size_t obj_size, size_t capacity, voi // -------------------- private -------------------- self->_obj_size = obj_size; self->_size = 0; - self->_capacity = capacity + 1; + self->_capacity = capacity; + self->_segsize = capacity; if (mem_pool != NULL) { @@ -341,25 +488,25 @@ bool segarray_init(struct _segarray *self, size_t obj_size, size_t capacity, voi { self->_dynamic = true; - self->_map = ringbuf_new(sizeof(darray_t), 8); - if(self->_map == NULL) + self->_map = ringbuf_new(sizeof(rawbuf_t), 8); + if (self->_map == NULL) { return false; } - darray_t seg = darray_new(obj_size, capacity); - if(seg == NULL) + rawbuf_t seg = rawbuf_new(obj_size, self->_segsize); + if (seg == NULL) { ringbuf_free(&self->_map); return false; } // config first obj index in seg array - self->_head.seg = clac_start_index(self->_capacity); - self->_tail.seg = self->_head.seg; + self->_seghead = clac_start_index(self->_segsize); + self->_segtail = self->_seghead; // add first seg array to map - self->_head.map = 0; - self->_tail.map = 0; + self->_maphead = 0; + self->_maptail = 1; self->_map->push_back(self->_map, &seg); } diff --git a/test/test.c b/test/test.c index fbf62c1..13732d6 100644 --- a/test/test.c +++ b/test/test.c @@ -96,7 +96,7 @@ int main(int argc, char const *argv[]) TEST_ADD(test_graph); TEST_ADD(test_rawbuf); - // TEST_ADD(test_segarray); + TEST_ADD(test_segarray); return UNITY_END(); } diff --git a/test/test_segarray.c b/test/test_segarray.c index 0925321..78c417b 100644 --- a/test/test_segarray.c +++ b/test/test_segarray.c @@ -103,7 +103,6 @@ static void test_segarray_push_back_invalid(void) segarray_free(&segarray); } -#if 0 static void test_segarray_push_front(void) { size_t i = 0; @@ -196,7 +195,6 @@ static void test_segarray_pop_back(void) segarray_free(&segarray); } - static void test_segarray_pop_front(void) { size_t i = 0; @@ -374,7 +372,7 @@ static void test_segarray_front_invalid(void) segarray_free(&segarray); } - +#if 0 static void test_segarray_set(void) { int temp = 0; @@ -477,6 +475,7 @@ static void test_segarray_at(void) segarray_free(&segarray); } +#endif static void test_segarray_iter(void) { @@ -492,32 +491,38 @@ static void test_segarray_iter(void) { segarray->push_back(segarray, &data[i]); } + TEST_ASSERT_EQUAL_INT(len, segarray->size(segarray)); iterator_t iter = segarray->iter(segarray, RINGBUF_FORWARD); i = 0; TEST_ASSERT_TRUE(iter->hasnext(iter)); while(iter->hasnext(iter)) { + LOG_DEBUG("iter-test: i=%d\n", i); temp = *(int *)iter->next(iter); TEST_ASSERT_EQUAL_INT(data[i], temp); i++; } TEST_ASSERT_EQUAL_INT(len, i); + LOG_INFO("iter-forward cuccess!"); iter = segarray->iter(segarray, RINGBUF_REVERSE); i = len - 1; TEST_ASSERT_TRUE(iter->hasnext(iter)); while(iter->hasnext(iter)) { + LOG_DEBUG("iter-test: i=%d\n", i); temp = *(int *)iter->next(iter); TEST_ASSERT_EQUAL_INT(data[i], temp); i--; } TEST_ASSERT_EQUAL_INT(0, i); + LOG_INFO("iter-reverse cuccess!"); segarray_free(&segarray); } +#if 0 static void test_segarray_resize(void) { int temp = 0; @@ -662,6 +667,7 @@ static void test_segarray_dynamic(void) segarray_free(&segarray); } +#endif static void test_segarray_status(void) { @@ -687,7 +693,7 @@ static void test_segarray_status(void) TEST_ASSERT_FALSE(segarray->full(segarray)); } TEST_ASSERT_TRUE(segarray->push_back(segarray, &data[i])); - TEST_ASSERT_TRUE(segarray->full(segarray)); + // TEST_ASSERT_TRUE(segarray->full(segarray)); TEST_ASSERT_TRUE(segarray->push_back(segarray, &data[i])); TEST_ASSERT_TRUE(segarray->clear(segarray)); @@ -816,18 +822,10 @@ static void test_segarray_struct(void) TEST_ASSERT_TRUE(segarray->push_front(segarray, &data[i])); } -#if 0 - for (i = 0; i < len; i++) - { - TEST_ASSERT_TRUE(segarray->get(segarray, i, &temp)); - } -#endif - segarray_free(&segarray); TEST_ASSERT_NULL(segarray); } -#endif // 0 void test_segarray(void) { @@ -841,29 +839,29 @@ void test_segarray(void) // RUN_TEST(test_segarray_init); // #endif - // RUN_TEST(test_segarray_push_back); - // RUN_TEST(test_segarray_push_back_invalid); + RUN_TEST(test_segarray_push_back); + RUN_TEST(test_segarray_push_back_invalid); -// RUN_TEST(test_segarray_push_front); -// RUN_TEST(test_segarray_push_front_invalid); + RUN_TEST(test_segarray_push_front); + RUN_TEST(test_segarray_push_front_invalid); -// RUN_TEST(test_segarray_pop_back); -// RUN_TEST(test_segarray_pop_front); + RUN_TEST(test_segarray_pop_back); + RUN_TEST(test_segarray_pop_front); -// RUN_TEST(test_segarray_back); -// RUN_TEST(test_segarray_back_invalid); + RUN_TEST(test_segarray_back); + RUN_TEST(test_segarray_back_invalid); -// RUN_TEST(test_segarray_front); -// RUN_TEST(test_segarray_front_invalid); + RUN_TEST(test_segarray_front); + RUN_TEST(test_segarray_front_invalid); -// // ---------- random access ---------- + // ---------- random access ---------- // RUN_TEST(test_segarray_set); // RUN_TEST(test_segarray_set_invalid); // RUN_TEST(test_segarray_at); -// // ---------- base ---------- -// RUN_TEST(test_segarray_iter); + // ---------- base ---------- + // RUN_TEST(test_segarray_iter); // RUN_TEST(test_segarray_resize); // RUN_TEST(test_segarray_resize_invalid); @@ -871,8 +869,8 @@ void test_segarray(void) // RUN_TEST(test_segarray_dynamic); -// RUN_TEST(test_segarray_status); + // RUN_TEST(test_segarray_status); -// // ---------- ext ---------- -// RUN_TEST(test_segarray_struct); + // ---------- ext ---------- + // RUN_TEST(test_segarray_struct); }