Compare commits

..

2 Commits

13 changed files with 118 additions and 49 deletions

View File

@ -79,7 +79,7 @@ segarray *-- ringbuf : 组合
segarray *-- rawbuf : 组合
arraylist *-- darray : 组合
string *-- darray : 组合
string *-- arraylist : 组合
hashtable *-- darray : 组合
@ -107,22 +107,26 @@ equeue ..> ringbuf : 依赖
## 数据结构
### 底层基础容器
> 原生裸数据结构
|数据结构 |名称 |说明 |
|---|---|---|
| darray | 动态数组 | 扩容
| ringbuf | 环形缓存区 | 扩容/外部缓存
| linklist | 单链表 |
| dlinklist | 双向链表 |
| darray | 动态数组 | 扩容
| ringbuf | 环形缓存区 | 扩容/外部缓存
| rawbuf | 原始缓冲区 | 动态分配固定容量/外部缓存
| segarray | 分段数组 | 扩容
### 中层容器
|数据结构 |名称 |说明 |
|---|---|---|
| segarray | 分段数组 | 扩容
| arraylist | 动态数组 | 扩容(负索引/切片)
**使用建议**
- ringbuf 小数据,少库容
- segarray 大数据,优先扩容
### 通用标准容器
> 基于底层封装
@ -131,6 +135,7 @@ equeue ..> ringbuf : 依赖
| deque | 双端队列 | 扩容
| stack | 栈 | 扩容
| queue | 队列 | 扩容
| ustring | 字符串 | 扩容
### 嵌入式专用容器
> 适配嵌入式场景、外置内存、无动态堆分配
@ -192,6 +197,7 @@ size_t index(void *obj); // 获取元素索引, -1为不存在
bool insert(size_t index, const void* obj); // 插入元素
bool remove(size_t index, const void *obj); // 删除元素 < delete !!!废弃防止项目用于C++关键字冲突>
bool erase(size_t index, size_t count); // 删除区间元素
// 随机访问
bool set(uint32_t index, const void* obj); // 设置元素

View File

@ -62,15 +62,6 @@ struct _ustring
bool (*full)(struct _ustring *self);
bool (*clear)(struct _ustring *self);
// sort and search
size_t (*index)(struct _ustring *self, const void *obj); // O(n) return (size_t)-1 if not found
bool (*contains)(struct _ustring *self, const void *obj); // O(n)
bool (*sort)(struct _ustring *self); // O(nlogn)
size_t (*search)(struct _ustring *self, const void *obj); // O(n) if not sorted; O(logn) if sorted
// return leftmost matched index; return (size_t)-1 if not found
size_t (*count)(struct _ustring *self, const void *obj); // O(nlogn) if sorted; O(n) if not sorted
// -------------------- uview --------------------
// erase
bool (*erase)(struct _ustring *self, ssize_t index, size_t count);
@ -84,6 +75,10 @@ struct _ustring
bool (*replace)(struct _ustring *self, uview_t oldstr, uview_t newstr);
bool (*remove)(struct _ustring *self, uview_t oldstr);
size_t (*index)(struct _ustring *self, uview_t uvstr);
bool (*contains)(struct _ustring *self, uview_t uvstr);
size_t (*count)(struct _ustring *self, uview_t uvstr);
// split
struct _ustring *(*substr)(struct _ustring *self, ssize_t start, ssize_t end);
// bool (*split)(struct _ustring *self, uview_t delim);

View File

@ -238,7 +238,7 @@ bool darray_iter_hasnext(struct _iterator *iter)
}
else
{
if (iter->_index == 0)
if (iter->_index == -1)
{
return false;
}

View File

@ -306,7 +306,7 @@ bool ringbuf_iter_hasnext(struct _iterator *iter)
}
else
{
if (iter->_index == self->_head)
if (iter->_index == ring_index_prev(self->_head, self->_capacity))
{
return false;
}

View File

@ -636,7 +636,7 @@ bool segarray_iter_hasnext(struct _iterator *iter)
}
else
{
if (iter->_index == 0)
if (iter->_index == -1)
{
return false;
}

View File

@ -324,7 +324,7 @@ bool ustring_iter_hasnext(struct _iterator *iter)
}
else
{
if (iter->_index == 0)
if (iter->_index == (size_t)-1)
{
return false;
}
@ -348,7 +348,7 @@ const void *ustring_iter_next(struct _iterator *iter)
{
iter->_index = iter->_index - 1;
}
return self->_alist->at(self->_alist, index);
return self->at(self, index);
}
iterator_t ustring_iter(struct _ustring *self, linear_order_t order)
@ -367,43 +367,44 @@ iterator_t ustring_iter(struct _ustring *self, linear_order_t order)
{
iter->_index = self->len(self) - 1;
}
iter->hasnext = ustring_iter_hasnext;
iter->next = ustring_iter_next;
return iter;
}
static size_t ustring_index(struct _ustring *self, const void *obj)
static size_t ustring_index(struct _ustring *self, uview_t uvstr)
{
unicstl_assert(self != NULL);
return self->search(self, obj);
char *p = strstr(self->cstr(self), uvstr.str);
if(p == NULL)
{
return (size_t)-1;
}
return p - self->at(self, 0);
}
static bool ustring_contains(struct _ustring *self, const void *obj)
static bool ustring_contains(struct _ustring *self, uview_t uvstr)
{
unicstl_assert(self != NULL);
return self->search(self, obj) != (size_t)-1;
return self->index(self, uvstr) != (size_t)-1;
}
static bool darry_sort(struct _ustring *self)
static size_t ustring_count(struct _ustring *self, uview_t uvstr)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_alist != NULL);
return self->_alist->sort(self->_alist);
}
static size_t darry_search(struct _ustring *self, const void *obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_alist != NULL);
return self->_alist->search(self->_alist, obj);
}
static size_t darry_count(struct _ustring *self, const void *obj)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_alist != NULL);
return self->_alist->count(self->_alist, obj);
size_t count = 0;
char *p = (char *)self->cstr(self);
while(*p != '\0')
{
p = strstr(p, uvstr.str);
if(p == NULL)
{
break;
}
count++;
p += uvstr.len;
}
return count;
}
bool ustring_isdigit(struct _ustring *self)
@ -867,8 +868,7 @@ static bool ustring_init(struct _ustring *self, uview_t view, bool is_view)
// sort and search
self->index = ustring_index;
self->contains = ustring_contains;
self->sort = darry_sort;
self->search = darry_search;
self->count = ustring_count;
// string
self->isdigit = ustring_isdigit;

View File

@ -20,7 +20,7 @@
#include "unity.h"
#define UNITTEST_ALL 0
#define UNITTEST_ALL 1
#define UNITTEST_LINKLIST (UNITTEST_ALL || 0)
#define UNITTEST_DLINKLIST (UNITTEST_ALL || 0)

View File

@ -870,7 +870,7 @@ static void test_arraylist_iter(void)
TEST_ASSERT_EQUAL_INT(data[i], temp);
i--;
}
TEST_ASSERT_EQUAL_INT(0, i);
TEST_ASSERT_EQUAL_INT(-1, i);
arraylist_free(&arraylist);
}

View File

@ -662,8 +662,10 @@ static void test_darray_iter(void)
temp = *(int *)iter->next(iter);
TEST_ASSERT_EQUAL_INT(data[i], temp);
i--;
// darray->print_obj(&temp);
}
TEST_ASSERT_EQUAL_INT(0, i);
TEST_ASSERT_EQUAL_INT(-1, i);
darray_free(&darray);
}

View File

@ -375,7 +375,7 @@ static void test_deque_iter(void)
TEST_ASSERT_EQUAL_INT(data[i], temp);
i--;
}
TEST_ASSERT_EQUAL_INT(0, i);
TEST_ASSERT_EQUAL_INT(-1, i);
deque_free(&deque);
}

View File

@ -511,8 +511,10 @@ static void test_ringbuf_iter(void)
temp = *(int *)iter->next(iter);
TEST_ASSERT_EQUAL_INT(data[i], temp);
i--;
ringbuf->print_obj(&temp);
}
TEST_ASSERT_EQUAL_INT(0, i);
TEST_ASSERT_EQUAL_INT(-1, i);
ringbuf_free(&ringbuf);
}

View File

@ -489,7 +489,7 @@ static void test_segarray_iter(void)
TEST_ASSERT_EQUAL_INT(data[i], temp);
i--;
}
TEST_ASSERT_EQUAL_INT(0, i);
TEST_ASSERT_EQUAL_INT(-1, i);
log_info("iter-reverse cuccess!");
segarray_free(&segarray);

View File

@ -411,6 +411,66 @@ void test_ustring_substr(void)
ustring_free(&str);
}
void test_ustring_index(void)
{
ustring_t str = ustring_new_fromcstr("hello world");
TEST_ASSERT_EQUAL_INT(2, str->index(str, uv("l")));
TEST_ASSERT_EQUAL_INT(6, str->index(str, uv("wor")));
TEST_ASSERT_TRUE(str->contains(str, uv("l")));
TEST_ASSERT_TRUE(str->contains(str, uv("wor")));
ustring_free(&str);
}
void test_ustring_count(void)
{
ustring_t str = ustring_new_fromcstr("hello world");
TEST_ASSERT_EQUAL_INT(3, str->count(str, uv("l")));
TEST_ASSERT_EQUAL_INT(1, str->count(str, uv("ll")));
ustring_free(&str);
}
static void test_ustring_iter(void)
{
const char *data = "hello wolrd!";
ustring_t ustring = ustring_new(uv(data));
size_t i = 0;
char temp;
size_t len = ustring->len(ustring);
iterator_t iter = ustring->iter(ustring, LINEAR_FORWARD);
i = 0;
TEST_ASSERT_TRUE(iter->hasnext(iter));
while(iter->hasnext(iter))
{
temp = *(int *)iter->next(iter);
TEST_ASSERT_EQUAL_INT(data[i], temp);
i++;
// ustring->print_obj(&temp);
}
TEST_ASSERT_EQUAL_INT(len, i);
iter = ustring->iter(ustring, LINEAR_REVERSE);
i = 0;
size_t idx = len - 1;
TEST_ASSERT_TRUE(iter->hasnext(iter));
while(iter->hasnext(iter))
{
temp = *(int *)iter->next(iter);
TEST_ASSERT_EQUAL_INT(data[idx], temp);
idx-=1;
i++;
ustring->print_obj(&temp);
}
TEST_ASSERT_EQUAL_INT(len, i);
ustring_free(&ustring);
}
void test_ustring(void)
{
UnitySetTestFile(__FILE__);
@ -459,4 +519,8 @@ void test_ustring(void)
RUN_TEST(test_ustring_cmp);
RUN_TEST(test_ustring_substr);
RUN_TEST(test_ustring_index);
RUN_TEST(test_ustring_count);
RUN_TEST(test_ustring_iter);
}