diff --git a/include/ringbuf.h b/include/ringbuf.h index 580f738..7ca5729 100644 --- a/include/ringbuf.h +++ b/include/ringbuf.h @@ -12,7 +12,6 @@ #define _RINGBUFFER_H_ #include "unicstl_internal.h" -#include "darray.h" enum _ringbuf_order { diff --git a/include/segarray.h b/include/segarray.h new file mode 100644 index 0000000..468f485 --- /dev/null +++ b/include/segarray.h @@ -0,0 +1,76 @@ +/** + * @file segarray.h + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2026-05-15 + * + * @copyright Copyright (c) 2026 + * + */ +#ifndef _SEGARRAY_H_ +#define _SEGARRAY_H_ + +#include "unicstl_internal.h" +#include "darray.h" + +enum _segarray_order +{ + SEGARRAY_FORWARD, + SEGARRAY_REVERSE, +}; + +struct _obj_pos +{ + size_t map; + size_t seg; +}; + +struct _segarray +{ + // -------------------- private -------------------- + void *obj; + + size_t _obj_size; + size_t _size; + size_t _capacity; + bool _dynamic; + + darray_t _map; + + struct _obj_pos _head; + struct _obj_pos _tail; + + struct _iterator _iter; + void (*_destory)(struct _segarray* self); + + // -------------------- public -------------------- + // kernel + bool (*push_back)(struct _segarray* self, const void* obj); + bool (*push_front)(struct _segarray* self, const void* obj); + bool (*pop_back)(struct _segarray* self, void* obj); + bool (*pop_front)(struct _segarray* self, void* obj); + bool (*back)(struct _segarray* self, void* obj); + bool (*front)(struct _segarray* self, void* obj); + + // base + bool (*resize)(struct _segarray *self, size_t capacity); + size_t (*size)(struct _segarray* self); + size_t (*capacity)(struct _segarray* self); + bool (*empty)(struct _segarray* self); + bool (*full)(struct _segarray* self); + bool (*clear)(struct _segarray* self); + + // iter + iterator_t (*iter)(struct _segarray* self, enum _segarray_order order); + + // -------------------- debug -------------------- + void (*print)(struct _segarray* self); + void (*print_obj)(const void* obj); +}; +typedef struct _segarray* segarray_t; + +segarray_t segarray_new(size_t obj_size, size_t capacity); +void segarray_free(segarray_t* segarray); + +#endif diff --git a/include/unicstl_internal.h b/include/unicstl_internal.h index 82be680..618cebb 100644 --- a/include/unicstl_internal.h +++ b/include/unicstl_internal.h @@ -133,17 +133,6 @@ static inline void obj_copy(void *dst, const void *src, size_t count, size_t obj 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 * diff --git a/src/ringbuf.c b/src/ringbuf.c index 3d0082e..73277a8 100644 --- a/src/ringbuf.c +++ b/src/ringbuf.c @@ -10,6 +10,16 @@ */ #include "ringbuf.h" +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; +} + static bool ringbuf_push_back(struct _ringbuf *self, const void *obj) { unicstl_assert(self != NULL); diff --git a/src/segarray.c b/src/segarray.c new file mode 100644 index 0000000..bf84fa5 --- /dev/null +++ b/src/segarray.c @@ -0,0 +1,392 @@ +/** + * @file segarray.c + * @author wenjf (Orig5826@163.com) + * @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; +} + +static inline struct _obj_pos index_next(struct _segarray *self, const struct _obj_pos* cur_pos) +{ + struct _obj_pos pos; + pos.map = cur_pos->map; + pos.seg = cur_pos->seg; + + if(pos.seg + 1 >= self->_capacity) + { + pos.map++; + pos.seg = 0; + } + else + { + pos.seg++; + } + return pos; +} + +static inline struct _obj_pos index_prev(struct _segarray *self, const struct _obj_pos* cur_pos) +{ + struct _obj_pos pos; + pos.map = cur_pos->map; + pos.seg = cur_pos->seg; + + if (pos.map == 0 && pos.seg == 0) { + return pos; + } + + if(pos.seg == 0) + { + pos.map--; + pos.seg = self->_capacity - 1; + } + else + { + pos.seg--; + } + return pos; +} + +static bool segarray_push_back(struct _segarray *self, const void *obj) +{ + unicstl_assert(self != NULL); + if(self->obj == NULL || obj == NULL) + { + return false; + } + + if (self->full(self)) + { + if(self->_dynamic != true) + { + return false; + } + // size_t new_capacity = unicstl_new_capacity(self->capacity(self)); + // if (self->resize(self, new_capacity) == false) + // { + // return false; + // } + } + + + self->_size++; + return true; +} + +static bool segarray_push_front(struct _segarray *self, const void *obj) +{ + unicstl_assert(self != NULL); + if(self->obj == NULL || obj == NULL) + { + return false; + } + + if (self->full(self)) + { + if(self->_dynamic != true) + { + return false; + } + size_t new_capacity = unicstl_new_capacity(self->capacity(self)); + if (self->resize(self, new_capacity) == false) + { + return false; + } + } + + self->_size++; + return true; +} + +static bool segarray_pop_back(struct _segarray *self, void *obj) +{ + unicstl_assert(self != NULL); + if(self->obj == NULL || self->empty(self)) + { + return false; + } + + self->_size--; + return true; +} + +static bool segarray_pop_front(struct _segarray *self, void *obj) +{ + unicstl_assert(self != NULL); + if(self->obj == NULL || self->empty(self)) + { + return false; + } + + if (self->empty(self)) + { + return false; + } + + self->_size--; + return true; +} + +static bool segarray_back(struct _segarray *self, void *obj) +{ + unicstl_assert(self != NULL); + if(self->obj == NULL || obj == NULL|| self->empty(self)) + { + return false; + } + + + return true; +} + +static bool segarray_front(struct _segarray *self, void *obj) +{ + unicstl_assert(self != NULL); + if(self->obj == NULL || obj == NULL|| self->empty(self)) + { + return false; + } + + + return true; +} + +static bool segarray_resize(struct _segarray *self, size_t capacity) +{ + unicstl_assert(self != NULL); + if (self->_dynamic != true || capacity == 0 || capacity > UNICSTL_CAPACITY_MAX - 1) + { + return false; + } + + return true; +} + +static size_t segarray_size(struct _segarray *self) +{ + unicstl_assert(self != NULL); + return self->_size; +} + +static size_t segarray_capacity(struct _segarray *self) +{ + unicstl_assert(self != NULL); + return self->_capacity; +} + +static bool segarray_empty(struct _segarray *self) +{ + unicstl_assert(self != NULL); + return self->_head.map == self->_tail.map && self->_head.seg == self->_tail.seg; +} + +static bool segarray_full(struct _segarray *self) +{ + unicstl_assert(self != NULL); + size_t map_cap = self->_map->capacity(self->_map); + + return (self->_head.map == 0 && self->_head.seg == 0) || + ( self->_tail.map == map_cap - 1 && self->_head.seg == self->_capacity - 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; + return true; +} + +static void segarray_destory(struct _segarray *self) +{ + unicstl_assert(self != NULL); + if (self->obj != NULL && self->_dynamic == true) + { + free(self->obj); + self->obj = NULL; + } +} + +static void segarray_print(struct _segarray *self) +{ + unicstl_assert(self != NULL); + + for (size_t i = 0; i < self->size(self); i++) + { + self->print_obj(obj_at(self->obj, self->_obj_size, i)); + } +} + +bool segarray_iter_hasnext(struct _iterator *iter) +{ + unicstl_assert(iter != NULL); + unicstl_assert(iter->_container != NULL); + + segarray_t self = (segarray_t)iter->_container; + + if (iter->_order == SEGARRAY_FORWARD) + { + + } + else + { + + } + return true; +} + +const void *segarray_iter_next(struct _iterator *iter) +{ + unicstl_assert(iter != NULL); + unicstl_assert(iter->_container != NULL); + + segarray_t self = (segarray_t)iter->_container; + + size_t index = iter->_index; + if (iter->_order == SEGARRAY_FORWARD) + { + //iter->_index = index_next(index, self->_capacity); + } + else + { + //iter->_index = index_prev(index, self->_capacity); + } + + return obj_at(self->obj, index, self->_obj_size); +} + +iterator_t segarray_iter(struct _segarray *self, enum _segarray_order order) +{ + unicstl_assert(self != NULL); + iterator_t iter = &self->_iter; + + iter->_container = self; + iter->_index = 0; + iter->_order = order; + + //.. + + iter->hasnext = segarray_iter_hasnext; + iter->next = segarray_iter_next; + return iter; +} + +/** + * @brief + * + * @param self + * @param obj_size + * @param capacity + * @param mem_pool !!! mem_pool_size = capacity * obj_size + * @return true + * @return false + */ +bool segarray_init(struct _segarray *self, size_t obj_size, size_t capacity, void *mem_pool) +{ + unicstl_assert(self != NULL); + unicstl_assert(obj_size > 0); + + // -------------------- private -------------------- + self->_obj_size = obj_size; + self->_size = 0; + self->_capacity = capacity + 1; + + if (mem_pool != NULL) + { + self->obj = (char *)mem_pool; + self->_dynamic = false; + } + else + { + self->_dynamic = true; + + self->_map = darray_new(sizeof(darray_t), 8); + if(self->_map == NULL) + { + return false; + } + + darray_t seg = darray_new(obj_size, capacity); + if(seg == NULL) + { + darray_free(&self->_map); + return false; + } + + 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->_tail.seg = self->_head.seg; + } + + self->_destory = segarray_destory; + + // -------------------- public -------------------- + // kernel + self->push_back = segarray_push_back; + self->push_front = segarray_push_front; + self->pop_back = segarray_pop_back; + self->pop_front = segarray_pop_front; + self->back = segarray_back; + self->front = segarray_front; + + // base + self->resize = segarray_resize; + self->size = segarray_size; + self->capacity = segarray_capacity; + self->empty = segarray_empty; + self->full = segarray_full; + self->clear = segarray_clear; + + // iter + self->iter = segarray_iter; + + // -------------------- default -------------------- + self->print_obj = default_print_obj; + + // -------------------- debug -------------------- + self->print = segarray_print; + + return true; +} + +segarray_t segarray_new(size_t obj_size, size_t capacity) +{ + struct _segarray *segarray = NULL; + segarray = (struct _segarray *)unicstl_malloc(sizeof(struct _segarray)); + if (segarray == NULL) + { + return NULL; + } + + if (segarray_init(segarray, obj_size, capacity, NULL) != true) + { + free(segarray); + return NULL; + } + return segarray; +} + +void segarray_free(segarray_t *segarray) +{ + if (*segarray != NULL) + { + (*segarray)->_destory(*segarray); + free(*segarray); + } + *segarray = NULL; +}