mirror of
https://gitee.com/apaki/unicstl.git
synced 2026-05-28 22:54:19 +08:00
segarray的流程还不对,今天太晚了,明天再调整。
This commit is contained in:
parent
fb7ac93623
commit
dcce634326
@ -12,7 +12,6 @@
|
||||
#define _RINGBUFFER_H_
|
||||
|
||||
#include "unicstl_internal.h"
|
||||
#include "darray.h"
|
||||
|
||||
enum _ringbuf_order
|
||||
{
|
||||
|
||||
76
include/segarray.h
Normal file
76
include/segarray.h
Normal 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
|
||||
@ -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
|
||||
*
|
||||
|
||||
@ -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
392
src/segarray.c
Normal 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;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user