segarray的流程还不对,今天太晚了,明天再调整。

This commit is contained in:
建峰 2026-05-15 02:45:21 +08:00
parent fb7ac93623
commit dcce634326
5 changed files with 478 additions and 12 deletions

View File

@ -12,7 +12,6 @@
#define _RINGBUFFER_H_
#include "unicstl_internal.h"
#include "darray.h"
enum _ringbuf_order
{

76
include/segarray.h Normal file
View File

@ -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

View File

@ -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
*

View File

@ -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);

392
src/segarray.c Normal file
View File

@ -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;
}