refactor(heap): 基于darray重构堆

This commit is contained in:
建峰 2026-05-20 17:35:59 +08:00
parent 81d9cf3c13
commit 18c67dacb3
9 changed files with 198 additions and 201 deletions

View File

@ -23,18 +23,18 @@ classDiagram
direction TB direction TB
namespace basic { namespace basic {
class ringbuf{
不扩容或
小数据扩容
}
class rawbuf
class darray
class linklist{ class linklist{
<<单链表>> <<单链表>>
} }
class dlinklist{ class dlinklist{
<<双向链表>> <<双向链表>>
} }
class ringbuf{
不扩容或
小数据扩容
}
class rawbuf
class darray
} }
namespace embed { namespace embed {
@ -58,7 +58,6 @@ namespace hal {
切片 切片
负索引 负索引
} }
class string
class hashtable class hashtable
} }
@ -69,9 +68,13 @@ namespace adapter {
namespace top { namespace top {
class stack class stack
class queue class queue
class rbtree class rbtree
class map class map
class string
class unordered_map class unordered_map
class heap
} }
%% hal层 %% hal层
@ -90,6 +93,7 @@ deque *-- segarray : 组合
%% 通用标准容器 %% 通用标准容器
stack *-- deque : 组合 stack *-- deque : 组合
queue *-- deque : 组合 queue *-- deque : 组合
heap *-- darray : 组合
%% 红黑树 %% 红黑树
rbtree ..> stack : 依赖 rbtree ..> stack : 依赖
@ -108,14 +112,18 @@ equeue ..> ringbuf : 依赖
### 底层基础容器 ### 底层基础容器
#### 链表结构
|数据结构 |名称 |说明 | |数据结构 |名称 |说明 |
|---|---|---| |---|---|---|
| linklist | 单链表 | | linklist | 单链表 |
| dlinklist | 双向链表 | | dlinklist | 双向链表 |
#### 数组结构
|数据结构 |名称 |说明 |
|---|---|---|
| darray | 动态数组 | 扩容 | darray | 动态数组 | 扩容
| ringbuf | 环形缓存区 | 扩容/外部缓存 | ringbuf | 环形缓存区 | 扩容/外部缓存
| rawbuf | 原始缓冲区 | 动态分配固定容量/外部缓存 | rawbuf | 原始缓冲区 | 动态分配固定容量/外部缓存
| segarray | 分段数组 | 扩容
### 中层容器 ### 中层容器
|数据结构 |名称 |说明 | |数据结构 |名称 |说明 |
@ -136,6 +144,7 @@ equeue ..> ringbuf : 依赖
| stack | 栈 | 扩容 | stack | 栈 | 扩容
| queue | 队列 | 扩容 | queue | 队列 | 扩容
| ustring | 字符串 | 扩容 | ustring | 字符串 | 扩容
| heap | 堆 | 扩容
### 嵌入式专用容器 ### 嵌入式专用容器
> 适配嵌入式场景、外置内存、无动态堆分配 > 适配嵌入式场景、外置内存、无动态堆分配

View File

@ -20,7 +20,7 @@ void demo_heap_num(void)
int temp = 0; int temp = 0;
size_t len = sizeof(data) / sizeof(data[0]); size_t len = sizeof(data) / sizeof(data[0]);
heap_t heap = heap_min_new2(sizeof(int), 64); heap_t heap = heap_min_new(sizeof(int), 64);
heap->print_obj = print_num; heap->print_obj = print_num;
heap->compare = compare_num; heap->compare = compare_num;
@ -86,7 +86,7 @@ static void demo_heap_struct(void)
struct _student temp = {0}; struct _student temp = {0};
size_t len = sizeof(data) / sizeof(data[0]); size_t len = sizeof(data) / sizeof(data[0]);
heap_t heap = heap_min_new2(sizeof(struct _student), 64); heap_t heap = heap_min_new(sizeof(struct _student), 64);
heap->print_obj = print_struct; heap->print_obj = print_struct;
heap->compare = compare_struct; heap->compare = compare_struct;

View File

@ -12,6 +12,7 @@
#define _HEAP_H_ #define _HEAP_H_
#include "unicstl_internal.h" #include "unicstl_internal.h"
#include "darray.h"
typedef enum typedef enum
{ {
@ -22,12 +23,7 @@ typedef enum
struct _heap struct _heap
{ {
// -------------------- private -------------------- // -------------------- private --------------------
void* obj; darray_t _darray;
size_t _size;
size_t _obj_size;
size_t _capacity;
size_t _ratio;
heap_type _type; heap_type _type;
struct _iterator _iter; struct _iterator _iter;
@ -41,8 +37,10 @@ struct _heap
bool (*peek)(struct _heap* self, void* obj); bool (*peek)(struct _heap* self, void* obj);
// base // base
bool (*reserve)(struct _heap* self, size_t capacity);
size_t (*capacity)(struct _heap* self);
size_t (*size)(struct _heap* self);
bool (*empty)(struct _heap* self); bool (*empty)(struct _heap* self);
size_t(*size)(struct _heap* self);
bool (*clear)(struct _heap* self); bool (*clear)(struct _heap* self);
// iter // iter
@ -58,8 +56,8 @@ struct _heap
typedef struct _heap* heap_t; typedef struct _heap* heap_t;
// create and free heap // create and free heap
heap_t heap_max_new2(size_t obj_size, size_t capacity); heap_t heap_max_new(size_t obj_size, size_t capacity);
heap_t heap_min_new2(size_t obj_size, size_t capacity); heap_t heap_min_new(size_t obj_size, size_t capacity);
void heap_free(heap_t* heap); void heap_free(heap_t* heap);

View File

@ -147,6 +147,34 @@ static inline void *unicstl_realloc(void *ptr, size_t size) { return NULL; }
static inline void unicstl_free(void *ptr) {} static inline void unicstl_free(void *ptr) {}
#endif // UNICSTL_MALLOC_ENABLE #endif // UNICSTL_MALLOC_ENABLE
/**
* @brief obj compare with obj2
*
* @return
* obj < obj2 return -1
* obj == obj2 return 0
* obj > obj2 return 1
*/
typedef int (*compare_fun_t)(const void *obj, const void *obj2);
static inline size_t ring_index(size_t head, size_t index, size_t capacity)
{
return (head + index) % capacity;
}
static inline size_t ring_index_next(size_t index, size_t capacity)
{
return (index + 1) % capacity;
}
static inline size_t ring_index_prev(size_t index, size_t capacity)
{
return index == 0 ? (capacity - 1) : index - 1;
}
static inline const void *obj_at(const void *objs, size_t index, size_t obj_size) static inline const void *obj_at(const void *objs, size_t index, size_t obj_size)
{ {
unicstl_assert(objs != NULL); unicstl_assert(objs != NULL);
@ -191,32 +219,27 @@ static inline void obj_zero(const void *objs, size_t index, size_t count, size_t
memset((char *)objs + index * obj_size, 0, count * obj_size); memset((char *)objs + index * obj_size, 0, count * obj_size);
} }
static inline void mem_swap(const void *obj1, void *obj2, size_t obj_size)
static inline size_t ring_index(size_t head, size_t index, size_t capacity)
{ {
return (head + index) % capacity; size_t cnt = obj_size;
for(size_t i = 0; i < cnt; ++i)
{
char tmp = ((char*)obj1)[i];
((char*)obj1)[i] = ((char*)obj2)[i];
((char*)obj2)[i] = tmp;
}
} }
static inline size_t ring_index_next(size_t index, size_t capacity) static inline void obj_swap(const void *base, size_t index1, size_t index2, size_t obj_size)
{ {
return (index + 1) % capacity; mem_swap((char*)base + index1 * obj_size, (char*)base + index2 * obj_size, obj_size);
} }
static inline size_t ring_index_prev(size_t index, size_t capacity) static inline int compare_obj(const void *base, size_t index1, size_t index2, size_t obj_size, compare_fun_t cmp)
{ {
return index == 0 ? (capacity - 1) : index - 1; return cmp((char*)base + index1 * obj_size, (char*)base + index2 * obj_size);
} }
/**
* @brief obj compare with obj2
*
* @return
* obj < obj2 return -1
* obj == obj2 return 0
* obj > obj2 return 1
*/
typedef int (*compare_fun_t)(const void *obj, const void *obj2);
// default function // default function
int default_compare(const void *obj1, const void *obj2); int default_compare(const void *obj1, const void *obj2);
void default_print_obj(const void *obj); void default_print_obj(const void *obj);

View File

@ -10,27 +10,6 @@
*/ */
#include "algo.h" #include "algo.h"
static inline void mem_swap(const void *obj1, void *obj2, size_t obj_size)
{
size_t cnt = obj_size;
for(size_t i = 0; i < cnt; ++i)
{
char tmp = ((char*)obj1)[i];
((char*)obj1)[i] = ((char*)obj2)[i];
((char*)obj2)[i] = tmp;
}
}
static inline void obj_swap(const void *base, size_t index1, size_t index2, size_t obj_size)
{
mem_swap((char*)base + index1 * obj_size, (char*)base + index2 * obj_size, obj_size);
}
static inline int compare_obj(const void *base, size_t index1, size_t index2, size_t obj_size, compare_fun_t cmp)
{
return cmp((char*)base + index1 * obj_size, (char*)base + index2 * obj_size);
}
// 1. 冒泡排序 // 1. 冒泡排序
bool bubble_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp) bool bubble_sort(void* base, size_t count, size_t obj_size, compare_fun_t cmp)
{ {

View File

@ -8,78 +8,45 @@
*/ */
#include "heap.h" #include "heap.h"
static int left(int i) static size_t left(size_t i)
{ {
return 2 * i + 1; return 2 * i + 1;
} }
static int right(int i) static size_t right(size_t i)
{ {
return (i << 1) + 2; return (i << 1) + 2;
} }
static int parent(int i) static size_t parent(size_t i)
{ {
if(i == 0) if(i == 0)
{ {
return -1; return -1;
} }
return (i-1) >> 1; return (i - 1) >> 1;
} }
static bool heap_peek(struct _heap* self, void* obj) static bool heap_peek(struct _heap* self, void* obj)
{ {
unicstl_assert(self != NULL); unicstl_assert(self != NULL);
unicstl_assert(obj != NULL); size_t index = self->size(self) - 1;
if(obj == NULL) if(!self->_darray->get(self->_darray, 0, obj))
{ {
return false; return false;
} }
if(self->empty(self))
{
return false;
}
memmove(obj, self->obj, self->_obj_size);
return true; return true;
} }
static void heap_swap(struct _heap* self, int i, int j) static void heap_fixed_up(struct _heap* self, size_t i)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_obj_size != 0);
#if __STDC_VERSION__ >= 199901L
// #define C99_VLA // VLA should be avoided for portability reasons and due to the risk of stack overflow.
#endif
#ifdef C99_VLA
char tmp[self->_obj_size];
#else
char* tmp = unicstl_malloc(self->_obj_size);
if (tmp == NULL)
{
return;
}
#endif
memmove(tmp, (char *)self->obj + i * self->_obj_size, self->_obj_size);
memmove((char*)self->obj + i * self->_obj_size, (char*)self->obj + j * self->_obj_size, self->_obj_size);
memmove((char*)self->obj + j * self->_obj_size, tmp, self->_obj_size);
#ifndef C99_VLA
unicstl_free(tmp);
#endif
}
static void heap_fixed_up(struct _heap* self, int i)
{ {
unicstl_assert(self != NULL); unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
unicstl_assert(self->compare != NULL); unicstl_assert(self->compare != NULL);
int p = 0;
if(self->compare == NULL) const void *base = self->_darray->at(self->_darray, 0);
{ size_t obj_size = self->_darray->_obj_size;
return ; size_t p = 0;
}
if(self->_type == HEAP_MAX) if(self->_type == HEAP_MAX)
{ {
@ -87,12 +54,14 @@ static void heap_fixed_up(struct _heap* self, int i)
{ {
p = parent(i); p = parent(i);
// if current node is greater than its parent, swap the position. otherwise break out of loop // if current node is greater than its parent, swap the position. otherwise break out of loop
if(p < 0 || self->compare((char *)self->obj + i * self->_obj_size, (char *)self->obj + p * self->_obj_size) <= 0) if(p == (size_t)-1 || compare_obj(base, i, p, obj_size, self->compare) <= 0)
{ {
break; break;
} }
heap_swap(self, i, p); obj_swap(base, i, p, obj_size);
i = p; i = p;
self->print(self);
} }
} }
else /* if(self->_type == HEAP_MIN) */ else /* if(self->_type == HEAP_MIN) */
@ -100,13 +69,17 @@ static void heap_fixed_up(struct _heap* self, int i)
while(1) while(1)
{ {
p = parent(i); p = parent(i);
log_debug("heap_fixed_up: p = %d, i = %zu\n", (ssize_t)p, i);
// if current node is less than its parent, swap the position. otherwise break out of loop // if current node is less than its parent, swap the position. otherwise break out of loop
if(p < 0 || self->compare((char *)self->obj + i * self->_obj_size, (char *)self->obj + p * self->_obj_size) >= 0) if(p == (size_t)-1 || compare_obj(base, i, p, obj_size, self->compare) >= 0)
{ {
break; break;
} }
heap_swap(self, i, p); obj_swap(base, i, p, obj_size);
i = p; i = p;
self->print(self);
} }
} }
} }
@ -114,28 +87,24 @@ static void heap_fixed_up(struct _heap* self, int i)
static bool heap_push(struct _heap* self, void* obj) static bool heap_push(struct _heap* self, void* obj)
{ {
unicstl_assert(self != NULL); unicstl_assert(self != NULL);
if(self->size(self) > self->_capacity) unicstl_assert(self->_darray != NULL);
if(!self->_darray->append(self->_darray, obj))
{ {
return false; return false;
} }
size_t index = self->size(self); heap_fixed_up(self, self->size(self) - 1);
memmove((char *)self->obj + index * self->_obj_size, obj, self->_obj_size);
self->_size++;
heap_fixed_up(self, index);
return true; return true;
} }
static void heap_fixed_down(struct _heap* self, int i) static void heap_fixed_down(struct _heap* self, size_t i)
{ {
unicstl_assert(self != NULL); unicstl_assert(self != NULL);
int l = 0,r = 0; unicstl_assert(self->_darray != NULL);
int max = 0, min = 0; size_t l = 0,r = 0;
size_t max = 0, min = 0;
if(self->compare == NULL) const void *base = self->_darray->at(self->_darray, 0);
{ size_t obj_size = self->_darray->_obj_size;
return;
}
if(self->_type == HEAP_MAX) if(self->_type == HEAP_MAX)
{ {
@ -145,20 +114,20 @@ static void heap_fixed_down(struct _heap* self, int i)
r = right(i); r = right(i);
max = i; max = i;
if(l < self->size(self) && self->compare((char *)self->obj + l * self->_obj_size, (char *)self->obj + max * self->_obj_size) > 0) if(l < self->size(self) && compare_obj(base, l, max, obj_size, self->compare) > 0)
{ {
max = l; max = l;
} }
if(r < self->size(self) && compare_obj(base, r, max, obj_size, self->compare) > 0)
if(r < self->size(self) && self->compare((char *)self->obj + r * self->_obj_size, (char *)self->obj + max * self->_obj_size) > 0)
{ {
max = r; max = r;
} }
if(max == i) if(max == i)
{ {
break; break;
} }
heap_swap(self, i, max); obj_swap(base, i, max, obj_size);
i = max; i = max;
} }
} }
@ -170,12 +139,12 @@ static void heap_fixed_down(struct _heap* self, int i)
r = right(i); r = right(i);
min = i; min = i;
if(l < self->size(self) && self->compare((char *)self->obj + l * self->_obj_size, (char *)self->obj + min * self->_obj_size) < 0) if(l < self->size(self) && compare_obj(base, l, min, obj_size, self->compare) < 0)
{ {
min = l; min = l;
} }
if(r < self->size(self) && self->compare((char *)self->obj + r * self->_obj_size, (char *)self->obj + min * self->_obj_size) < 0) if(r < self->size(self) && compare_obj(base, r, min, obj_size, self->compare) < 0)
{ {
min = r; min = r;
} }
@ -183,7 +152,7 @@ static void heap_fixed_down(struct _heap* self, int i)
{ {
break; break;
} }
heap_swap(self, i, min); obj_swap(self, i, min, obj_size);
i = min; i = min;
} }
} }
@ -192,25 +161,34 @@ static void heap_fixed_down(struct _heap* self, int i)
static bool heap_pop(struct _heap* self, void* obj) static bool heap_pop(struct _heap* self, void* obj)
{ {
unicstl_assert(self != NULL); unicstl_assert(self != NULL);
if(self->empty(self)) unicstl_assert(self->_darray != NULL);
if(!self->_darray->pop(self->_darray, obj))
{ {
return false; return false;
} }
int index = self->size(self) - 1;
heap_swap(self, 0, index);
if(obj != NULL)
{
memmove(obj, (char *)self->obj + index * self->_obj_size, self->_obj_size);
}
self->_size--;
heap_fixed_down(self, 0); heap_fixed_down(self, 0);
return true; return true;
} }
static size_t heap_reserve(struct _heap* self, size_t capacity)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
return self->_darray->reserve(self->_darray, capacity);
}
static size_t heap_size(struct _heap* self) static size_t heap_size(struct _heap* self)
{ {
unicstl_assert(self != NULL); unicstl_assert(self != NULL);
return self->_size; unicstl_assert(self->_darray != NULL);
return self->_darray->size(self->_darray);
}
static size_t heap_capacity(struct _heap* self)
{
unicstl_assert(self != NULL);
unicstl_assert(self->_darray != NULL);
return self->_darray->capacity(self->_darray);
} }
static bool heap_empty(struct _heap* self) static bool heap_empty(struct _heap* self)
@ -222,34 +200,26 @@ static bool heap_empty(struct _heap* self)
static bool heap_clear(struct _heap* self) static bool heap_clear(struct _heap* self)
{ {
unicstl_assert(self != NULL); unicstl_assert(self != NULL);
self->_size = 0; unicstl_assert(self->_darray != NULL);
return true; return self->_darray->clear(self->_darray);
} }
static void heap_destory(struct _heap* self) static void heap_destory(struct _heap* self)
{ {
unicstl_assert(self != NULL); unicstl_assert(self != NULL);
self->clear(self); self->clear(self);
if(self->obj) if(self->_darray != NULL)
{ {
unicstl_free(self->obj); darray_free(&self->_darray);
} }
} }
static void heap_print(struct _heap* self) static void heap_print(struct _heap* self)
{ {
unicstl_assert(self != NULL); unicstl_assert(self != NULL);
unicstl_assert(self->obj != NULL); unicstl_assert(self->_darray != NULL);
self->_darray->print_obj = self->print_obj;
void* obj = NULL; self->_darray->print(self->_darray);
size_t offset = 0;
for (int i = 0; i < self->size(self); i++)
{
offset = self->_obj_size * i;
obj = (char *)self->obj + offset;
self->print_obj(obj);
}
} }
bool heap_iter_hasnext(struct _iterator* iter) bool heap_iter_hasnext(struct _iterator* iter)
@ -269,15 +239,12 @@ const void* heap_iter_next(struct _iterator* iter)
{ {
unicstl_assert(iter != NULL); unicstl_assert(iter != NULL);
unicstl_assert(iter->_container != NULL); unicstl_assert(iter->_container != NULL);
heap_t self = (heap_t)iter->_container; heap_t self = (heap_t)iter->_container;
void *obj = NULL; unicstl_assert(self->_darray != NULL);
size_t index = iter->_index; size_t index = iter->_index;
obj = self->obj + self->_obj_size * index;
iter->_index += 1; iter->_index += 1;
return obj; return self->_darray->at(self->_darray, index);
} }
iterator_t heap_iter(struct _heap* self) iterator_t heap_iter(struct _heap* self)
@ -287,28 +254,20 @@ iterator_t heap_iter(struct _heap* self)
iter->_container = self; iter->_container = self;
iter->_index = 0; iter->_index = 0;
iter->_node = self->obj;
iter->hasnext = heap_iter_hasnext; iter->hasnext = heap_iter_hasnext;
iter->next = heap_iter_next; iter->next = heap_iter_next;
return iter; return iter;
} }
static bool heap_init2(struct _heap* self, size_t obj_size, size_t capacity) static bool heap_init(struct _heap* self, size_t obj_size, size_t capacity, heap_type type)
{ {
unicstl_assert(self != NULL); unicstl_assert(self != NULL);
unicstl_assert(obj_size > 0);
// -------------------- private -------------------- // -------------------- private --------------------
self->_obj_size = obj_size; self->_darray = NULL;
self->_size = 0; self->_type = type;
self->_capacity = capacity;
self->_ratio = 2;
self->obj = (void*)unicstl_malloc(self->_capacity * self->_obj_size);
if(self->obj == NULL)
{
return false;
}
self->_destory = heap_destory; self->_destory = heap_destory;
@ -320,25 +279,31 @@ static bool heap_init2(struct _heap* self, size_t obj_size, size_t capacity)
self->empty = heap_empty; self->empty = heap_empty;
// base // base
self->reserve = heap_reserve;
self->capacity = heap_capacity;
self->size = heap_size; self->size = heap_size;
self->clear = heap_clear; self->clear = heap_clear;
// iter // iter
self->iter = heap_iter; self->iter = heap_iter;
// config
self->compare = NULL;
// -------------------- default -------------------- // -------------------- default --------------------
self->compare = default_compare; self->compare = default_compare;
self->print_obj = default_print_obj; self->print_obj = default_print_obj;
// -------------------- debug -------------------- // -------------------- debug --------------------
self->print = heap_print; self->print = heap_print;
// -------------------- init --------------------
self->_darray = darray_new(obj_size, capacity);
if(self->_darray == NULL)
{
return false;
}
return true; return true;
} }
heap_t heap_max_new2(size_t obj_size, size_t capacity) heap_t heap_max_new(size_t obj_size, size_t capacity)
{ {
heap_t heap = NULL; heap_t heap = NULL;
heap = (struct _heap*)unicstl_malloc(sizeof(struct _heap)); heap = (struct _heap*)unicstl_malloc(sizeof(struct _heap));
@ -347,17 +312,15 @@ heap_t heap_max_new2(size_t obj_size, size_t capacity)
return NULL; return NULL;
} }
if(heap_init2(heap, obj_size, capacity) != true) if(heap_init(heap, obj_size, capacity, HEAP_MAX) != true)
{ {
unicstl_free(heap); unicstl_free(heap);
return NULL; return NULL;
} }
heap->_type = HEAP_MAX;
return heap; return heap;
} }
heap_t heap_min_new2(size_t obj_size, size_t capacity) heap_t heap_min_new(size_t obj_size, size_t capacity)
{ {
heap_t heap = NULL; heap_t heap = NULL;
heap = (struct _heap*)unicstl_malloc(sizeof(struct _heap)); heap = (struct _heap*)unicstl_malloc(sizeof(struct _heap));
@ -367,14 +330,12 @@ heap_t heap_min_new2(size_t obj_size, size_t capacity)
return NULL; return NULL;
} }
if(heap_init2(heap, obj_size, capacity) != true) if(heap_init(heap, obj_size, capacity, HEAP_MIN) != true)
{ {
log_warn("heap init failed\n"); log_warn("heap init failed\n");
unicstl_free(heap); unicstl_free(heap);
return NULL; return NULL;
} }
heap->_type = HEAP_MIN;
return heap; return heap;
} }

View File

@ -10,27 +10,39 @@
*/ */
#include "test.h" #include "test.h"
static void* get_max(struct _heap* heap, void *array, int start, int end) static const void* get_max(const void *base, size_t index, size_t count, size_t obj_size, compare_fun_t compare)
{ {
void* max = array; const void* max = base;
for (int i = start; i < end; i++) if(count <= 1)
{ {
if (heap->compare((char*)array + heap->_obj_size * i, max) > 0) return base;
}
size_t idx = 0;
for (size_t i = 0; i < count; i++)
{ {
max = (char*)array + heap->_obj_size * i; idx = index + i * obj_size;
if (compare((char*)base + idx, max) > 0)
{
max = (char*)base + idx;
} }
} }
return max; return max;
} }
static void* get_min(struct _heap* heap, void *array, int start, int end) static const void* get_min(const void *base, size_t index, size_t count, size_t obj_size, compare_fun_t compare)
{ {
void* min = array; const void* min = base;
for (int i = start; i < end; i++) if(count <= 1)
{ {
if (heap->compare((char*)array + heap->_obj_size * i, min) < 0) return base;
}
size_t idx = 0;
for (size_t i = 0; i < count ; i++)
{ {
min = (char*)array + heap->_obj_size * i; idx = index + i * obj_size;
if (compare((char*)base + idx, min) < 0)
{
min = (char*)base + idx;
} }
} }
return min; return min;
@ -45,8 +57,9 @@ static void test_heap_min_num(void)
int data[] = { 5,2,3,1,7,8,6,4,9,10,12,11,15,14,13 }; int data[] = { 5,2,3,1,7,8,6,4,9,10,12,11,15,14,13 };
int temp = 0; int temp = 0;
size_t len = sizeof(data) / sizeof(data[0]); size_t len = sizeof(data) / sizeof(data[0]);
int min = 0;
heap_t heap = heap_min_new2(sizeof(int), 64); heap_t heap = heap_min_new(sizeof(int), 64);
TEST_ASSERT_NOT_NULL(heap); TEST_ASSERT_NOT_NULL(heap);
heap->print_obj = print_num; heap->print_obj = print_num;
heap->compare = compare_num; heap->compare = compare_num;
@ -58,7 +71,9 @@ static void test_heap_min_num(void)
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap)); TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
TEST_ASSERT_TRUE(heap->peek(heap, &temp)); TEST_ASSERT_TRUE(heap->peek(heap, &temp));
TEST_ASSERT_EQUAL_INT(*(int *)get_min(heap, data, 0, heap->size(heap)), temp); min = *(int *)get_min(data, 0, i + 1, sizeof(int), compare_num);
log_debug("i = %d, min = %d, heap_peek: %d, ", i, min, temp);
TEST_ASSERT_EQUAL_INT(min, temp);
} }
TEST_ASSERT_TRUE(heap->clear(heap)); TEST_ASSERT_TRUE(heap->clear(heap));
@ -96,7 +111,7 @@ static void test_heap_min_struct(void)
struct _student temp = {0}; struct _student temp = {0};
size_t len = sizeof(data) / sizeof(data[0]); size_t len = sizeof(data) / sizeof(data[0]);
heap_t heap = heap_min_new2(sizeof(struct _student), 64); heap_t heap = heap_min_new(sizeof(struct _student), 64);
TEST_ASSERT_NOT_NULL(heap); TEST_ASSERT_NOT_NULL(heap);
heap->print_obj = print_struct; heap->print_obj = print_struct;
heap->compare = compare_struct; heap->compare = compare_struct;
@ -108,8 +123,8 @@ static void test_heap_min_struct(void)
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap)); TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
TEST_ASSERT_TRUE(heap->peek(heap, &temp)); TEST_ASSERT_TRUE(heap->peek(heap, &temp));
TEST_ASSERT_EQUAL_INT(((struct _student*)get_min(heap, data, 0, heap->size(heap)))->id, temp.id); TEST_ASSERT_EQUAL_INT(((struct _student*)get_min(data, 0, i + 1, sizeof(struct _student), compare_struct))->id, temp.id);
TEST_ASSERT_EQUAL_STRING(((struct _student*)get_min(heap, data, 0, heap->size(heap)))->name, temp.name); TEST_ASSERT_EQUAL_STRING(((struct _student*)get_min(data, 0, i + 1, sizeof(struct _student), compare_struct))->name, temp.name);
} }
TEST_ASSERT_TRUE(heap->peek(heap, &temp)); TEST_ASSERT_TRUE(heap->peek(heap, &temp));
TEST_ASSERT_TRUE(heap->peek(heap, &temp)); TEST_ASSERT_TRUE(heap->peek(heap, &temp));
@ -143,7 +158,7 @@ static void test_heap_max_num(void)
int temp = 0; int temp = 0;
size_t len = sizeof(data) / sizeof(data[0]); size_t len = sizeof(data) / sizeof(data[0]);
heap_t heap = heap_max_new2(sizeof(int), 64); heap_t heap = heap_max_new(sizeof(int), 64);
TEST_ASSERT_NOT_NULL(heap); TEST_ASSERT_NOT_NULL(heap);
heap->print_obj = print_num; heap->print_obj = print_num;
heap->compare = compare_num; heap->compare = compare_num;
@ -155,7 +170,7 @@ static void test_heap_max_num(void)
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap)); TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
TEST_ASSERT_TRUE(heap->peek(heap, &temp)); TEST_ASSERT_TRUE(heap->peek(heap, &temp));
TEST_ASSERT_EQUAL_INT(*(int *)get_max(heap, data, 0, heap->size(heap)), temp); TEST_ASSERT_EQUAL_INT(*(int *)get_max(data, 0, i + 1, sizeof(int), compare_num), temp);
} }
TEST_ASSERT_TRUE(heap->clear(heap)); TEST_ASSERT_TRUE(heap->clear(heap));
@ -193,7 +208,7 @@ static void test_heap_max_struct(void)
struct _student temp = {0}; struct _student temp = {0};
size_t len = sizeof(data) / sizeof(data[0]); size_t len = sizeof(data) / sizeof(data[0]);
heap_t heap = heap_max_new2(sizeof(struct _student), 64); heap_t heap = heap_max_new(sizeof(struct _student), 64);
TEST_ASSERT_NOT_NULL(heap); TEST_ASSERT_NOT_NULL(heap);
heap->print_obj = print_struct; heap->print_obj = print_struct;
heap->compare = compare_struct; heap->compare = compare_struct;
@ -205,8 +220,8 @@ static void test_heap_max_struct(void)
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap)); TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
TEST_ASSERT_TRUE(heap->peek(heap, &temp)); TEST_ASSERT_TRUE(heap->peek(heap, &temp));
TEST_ASSERT_EQUAL_INT(((struct _student*)get_max(heap, data, 0, heap->size(heap)))->id, temp.id); TEST_ASSERT_EQUAL_INT(((struct _student*)get_max(data, 0, i + 1, sizeof(struct _student), compare_struct))->id, temp.id);
TEST_ASSERT_EQUAL_STRING(((struct _student*)get_max(heap, data, 0, heap->size(heap)))->name, temp.name); TEST_ASSERT_EQUAL_STRING(((struct _student*)get_max(data, 0, i + 1, sizeof(struct _student), compare_struct))->name, temp.name);
// heap->print_obj(&temp); // heap->print_obj(&temp);
// printf("\n"); // printf("\n");
@ -260,7 +275,7 @@ static void test_heap_max_iter(void)
int out[15] = { 0 }; int out[15] = { 0 };
int outlen = 0; int outlen = 0;
heap_t heap = heap_max_new2(sizeof(int), 64); heap_t heap = heap_max_new(sizeof(int), 64);
TEST_ASSERT_NOT_NULL(heap); TEST_ASSERT_NOT_NULL(heap);
heap->print_obj = print_num; heap->print_obj = print_num;
heap->compare = compare_num; heap->compare = compare_num;
@ -272,7 +287,7 @@ static void test_heap_max_iter(void)
TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap)); TEST_ASSERT_EQUAL_INT(i + 1, heap->size(heap));
TEST_ASSERT_TRUE(heap->peek(heap, &temp)); TEST_ASSERT_TRUE(heap->peek(heap, &temp));
TEST_ASSERT_EQUAL_INT(*(int *)get_max(heap, data, 0, heap->size(heap)), temp); TEST_ASSERT_EQUAL_INT(*(int *)get_max(data, 0, i + 1, sizeof(int), compare_num), temp);
iterator_t iter = heap->iter(heap); iterator_t iter = heap->iter(heap);

View File

@ -512,7 +512,7 @@ static void test_ringbuf_iter(void)
TEST_ASSERT_EQUAL_INT(data[i], temp); TEST_ASSERT_EQUAL_INT(data[i], temp);
i--; i--;
ringbuf->print_obj(&temp); // ringbuf->print_obj(&temp);
} }
TEST_ASSERT_EQUAL_INT(-1, i); TEST_ASSERT_EQUAL_INT(-1, i);

View File

@ -33,10 +33,22 @@ void test_unicstl_capacity(void)
TEST_ASSERT_EQUAL_UINT32(1125000, unicstl_new_capacity(1000000)); TEST_ASSERT_EQUAL_UINT32(1125000, unicstl_new_capacity(1000000));
} }
void test_unicstl_compare_obj(void)
{
int data[] = {1,2,3};
int obj_size = sizeof(int);
TEST_ASSERT_EQUAL_INT(0, compare_obj(data, 0, 0, obj_size, compare_int));
TEST_ASSERT_EQUAL_INT(1, compare_obj(data, 2, 1, obj_size, compare_int));
TEST_ASSERT_EQUAL_INT(-1, compare_obj(data, 0, 1, obj_size, compare_int));
}
void test_unicstl(void) void test_unicstl(void)
{ {
UnitySetTestFile(__FILE__); UnitySetTestFile(__FILE__);
RUN_TEST(test_unicstl_version); RUN_TEST(test_unicstl_version);
RUN_TEST(test_unicstl_capacity); RUN_TEST(test_unicstl_capacity);
RUN_TEST(test_unicstl_compare_obj);
} }