mirror of
https://github.com/zlgopen/awtk.git
synced 2025-05-08 19:44:45 +08:00
add hash table
This commit is contained in:
parent
5f570df4fc
commit
ee695cf212
@ -1,5 +1,8 @@
|
||||
# 最新动态
|
||||
|
||||
2021/11/15
|
||||
* 增加hash table。
|
||||
|
||||
2021/11/11
|
||||
* 修复在fb为bgra8888格式时半透明边缘出现明显边缘的问题以及前景和背景色都为半透明时候颜色不正常的问题(感谢智明提供补丁)。
|
||||
|
||||
|
204
src/tkc/hash_table.c
Normal file
204
src/tkc/hash_table.c
Normal file
@ -0,0 +1,204 @@
|
||||
/**
|
||||
* File: hash_table.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: hash table
|
||||
*
|
||||
* Copyright (c) 2018 - 2021 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2021-11-15 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/utils.h"
|
||||
#include "tkc/hash_table.h"
|
||||
|
||||
hash_table_t* hash_table_create(uint32_t capacity, tk_destroy_t destroy, tk_compare_t compare,
|
||||
tk_hash_t hash) {
|
||||
hash_table_t* hash_table = NULL;
|
||||
return_value_if_fail(capacity > 0 && hash != NULL && compare != NULL, NULL);
|
||||
hash_table = TKMEM_ZALLOC(hash_table_t);
|
||||
return_value_if_fail(hash_table != NULL, NULL);
|
||||
|
||||
if (hash_table_init(hash_table, capacity, destroy, compare, hash) == NULL) {
|
||||
TKMEM_FREE(hash_table);
|
||||
}
|
||||
|
||||
return hash_table;
|
||||
}
|
||||
|
||||
hash_table_t* hash_table_init(hash_table_t* hash_table, uint32_t capacity, tk_destroy_t destroy,
|
||||
tk_compare_t compare, tk_hash_t hash) {
|
||||
uint32_t i = 0;
|
||||
return_value_if_fail(hash_table != NULL, NULL);
|
||||
return_value_if_fail(capacity > 0 && hash != NULL && compare != NULL, NULL);
|
||||
|
||||
memset(hash_table, 0, sizeof(hash_table_t));
|
||||
|
||||
hash_table->hash = hash;
|
||||
hash_table->destroy = destroy;
|
||||
hash_table->compare = compare;
|
||||
goto_error_if_fail(
|
||||
darray_init(&(hash_table->buckets), capacity, (tk_destroy_t)darray_destroy, NULL));
|
||||
|
||||
for (i = 0; i < capacity; i++) {
|
||||
darray_t* arr = darray_create(5, destroy, compare);
|
||||
goto_error_if_fail(arr != NULL);
|
||||
ENSURE(darray_push(&(hash_table->buckets), arr) == RET_OK);
|
||||
}
|
||||
|
||||
return hash_table;
|
||||
error:
|
||||
hash_table_deinit(hash_table);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static darray_t* hash_table_get_array(hash_table_t* hash_table, void* ctx) {
|
||||
uint32_t index = 0;
|
||||
return_value_if_fail(hash_table != NULL, NULL);
|
||||
return_value_if_fail(hash_table->hash != NULL && hash_table->buckets.size > 0, NULL);
|
||||
|
||||
index = hash_table->hash(ctx) % hash_table->buckets.size;
|
||||
|
||||
return (darray_t*)darray_get(&(hash_table->buckets), index);
|
||||
}
|
||||
|
||||
void* hash_table_find(hash_table_t* hash_table, tk_compare_t cmp, void* ctx) {
|
||||
darray_t* arr = hash_table_get_array(hash_table, ctx);
|
||||
return_value_if_fail(arr != NULL, NULL);
|
||||
|
||||
return darray_find_ex(arr, cmp, ctx);
|
||||
}
|
||||
|
||||
ret_t hash_table_add(hash_table_t* hash_table, void* data, bool_t replace_if_exist) {
|
||||
darray_t* arr = hash_table_get_array(hash_table, data);
|
||||
return_value_if_fail(arr != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return darray_sorted_insert(arr, data, hash_table->compare, replace_if_exist);
|
||||
}
|
||||
|
||||
ret_t hash_table_remove(hash_table_t* hash_table, tk_compare_t cmp, void* ctx) {
|
||||
darray_t* arr = hash_table_get_array(hash_table, ctx);
|
||||
return_value_if_fail(arr != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return darray_remove_ex(arr, hash_table->compare, ctx);
|
||||
}
|
||||
|
||||
ret_t hash_table_remove_all(hash_table_t* hash_table, tk_compare_t cmp, void* ctx) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 0;
|
||||
darray_t** arrs = NULL;
|
||||
return_value_if_fail(hash_table != NULL, 0);
|
||||
|
||||
n = hash_table->buckets.size;
|
||||
arrs = (darray_t**)(hash_table->buckets.elms);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
darray_t* iter = arrs[i];
|
||||
darray_remove_all(iter, cmp, ctx);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int32_t hash_table_count(hash_table_t* hash_table, tk_compare_t cmp, void* ctx) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 0;
|
||||
int32_t count = 0;
|
||||
darray_t** arrs = NULL;
|
||||
return_value_if_fail(hash_table != NULL, 0);
|
||||
|
||||
n = hash_table->buckets.size;
|
||||
arrs = (darray_t**)(hash_table->buckets.elms);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
darray_t* iter = arrs[i];
|
||||
|
||||
iter->compare = cmp;
|
||||
count += darray_count(iter, ctx);
|
||||
iter->compare = hash_table->compare;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
ret_t hash_table_clear(hash_table_t* hash_table) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 0;
|
||||
darray_t** arrs = NULL;
|
||||
return_value_if_fail(hash_table != NULL, RET_BAD_PARAMS);
|
||||
|
||||
n = hash_table->buckets.size;
|
||||
arrs = (darray_t**)(hash_table->buckets.elms);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
darray_t* iter = arrs[i];
|
||||
darray_clear(iter);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t hash_table_foreach(hash_table_t* hash_table, tk_visit_t visit, void* ctx) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 0;
|
||||
darray_t** arrs = NULL;
|
||||
return_value_if_fail(hash_table != NULL, RET_BAD_PARAMS);
|
||||
|
||||
n = hash_table->buckets.size;
|
||||
arrs = (darray_t**)(hash_table->buckets.elms);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
darray_t* iter = arrs[i];
|
||||
ret_t ret = darray_foreach(iter, visit, ctx);
|
||||
if (ret != RET_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t hash_table_deinit(hash_table_t* hash_table) {
|
||||
return_value_if_fail(hash_table != NULL, RET_BAD_PARAMS);
|
||||
|
||||
darray_deinit(&(hash_table->buckets));
|
||||
memset(hash_table, 0x00, sizeof(hash_table_t));
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t hash_table_destroy(hash_table_t* hash_table) {
|
||||
return_value_if_fail(hash_table != NULL, RET_BAD_PARAMS);
|
||||
|
||||
hash_table_deinit(hash_table);
|
||||
TKMEM_FREE(hash_table);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
uint32_t hash_table_hash_str(const void* data) {
|
||||
const char* p = (const char*)data;
|
||||
uint32_t value = 0;
|
||||
return_value_if_fail(data != NULL, 0);
|
||||
while (*p) {
|
||||
value += *p++;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32_t hash_table_hash_int(const void* data) {
|
||||
return tk_pointer_to_int(data);
|
||||
}
|
222
src/tkc/hash_table.h
Normal file
222
src/tkc/hash_table.h
Normal file
@ -0,0 +1,222 @@
|
||||
/**
|
||||
* File: hash_table.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: hash table
|
||||
*
|
||||
* Copyright (c) 2018 - 2021 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2021-11-15 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_HASH_TABLE_H
|
||||
#define TK_HASH_TABLE_H
|
||||
|
||||
#include "tkc/darray.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class hash_table_t
|
||||
* 哈希表。
|
||||
*
|
||||
* 用hash_table\_init初始化时,用hash_table\_deinit释放。如:
|
||||
*
|
||||
* ```c
|
||||
* hash_table_t hash_table;
|
||||
* hash_table_init(&hash_table, 10, destroy, compare, hash);
|
||||
* ...
|
||||
* hash_table_deinit(&hash_table);
|
||||
* ```
|
||||
*
|
||||
* 用hash_table\_create创建时,用hash_table\_destroy销毁。如:
|
||||
*
|
||||
* ```c
|
||||
* hash_table_t* hash_table = hash_table_create(10, destroy, compare, hash);
|
||||
* ...
|
||||
* hash_table_destroy(hash_table);
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
typedef struct _hash_table_t {
|
||||
/**
|
||||
* @property {darray_t} buckets
|
||||
* @annotation ["readable"]
|
||||
* buckets。
|
||||
*/
|
||||
darray_t buckets;
|
||||
|
||||
/**
|
||||
* @property {tk_destroy_t} destroy
|
||||
* @annotation ["readable"]
|
||||
* 元素销毁函数。
|
||||
*/
|
||||
tk_destroy_t destroy;
|
||||
/**
|
||||
* @property {tk_compare_t} compare
|
||||
* @annotation ["readable"]
|
||||
* 元素比较函数。
|
||||
*/
|
||||
tk_compare_t compare;
|
||||
/**
|
||||
* @property {tk_hash_t} hash
|
||||
* @annotation ["readable"]
|
||||
* 元素哈希函数。
|
||||
*/
|
||||
tk_hash_t hash;
|
||||
} hash_table_t;
|
||||
|
||||
/**
|
||||
* @method hash_table_create
|
||||
* @annotation ["constructor"]
|
||||
* 创建hash_table对象。
|
||||
*
|
||||
* @param {uint32_t} capacity 哈希表桶数。
|
||||
* @param {tk_destroy_t} destroy 元素销毁函数。
|
||||
* @param {tk_compare_t} compare 元素比较函数。
|
||||
* @param {tk_hash_t} hash 元素哈希函数。
|
||||
*
|
||||
* @return {hash_table_t*} 哈希表对象。
|
||||
*/
|
||||
hash_table_t* hash_table_create(uint32_t capacity, tk_destroy_t destroy, tk_compare_t compare,
|
||||
tk_hash_t hash);
|
||||
|
||||
/**
|
||||
* @method hash_table_init
|
||||
* 初始化hash_table对象。
|
||||
*
|
||||
* @param {hash_table_t*} hash_table 哈希表对象。
|
||||
* @param {uint32_t} capacity 哈希表桶数。
|
||||
* @param {tk_destroy_t} destroy 元素销毁函数。
|
||||
* @param {tk_compare_t} compare 元素比较函数。
|
||||
* @param {tk_hash_t} hash 元素哈希函数。
|
||||
*
|
||||
* @return {hash_table_t*} 哈希表对象。
|
||||
*/
|
||||
hash_table_t* hash_table_init(hash_table_t* hash_table, uint32_t capacity, tk_destroy_t destroy,
|
||||
tk_compare_t compare, tk_hash_t hash);
|
||||
|
||||
/**
|
||||
* @method hash_table_find
|
||||
* 查找第一个满足条件的元素。
|
||||
* @param {hash_table_t*} hash_table 哈希表对象。
|
||||
* @param {tk_compare_t} cmp 比较函数,为NULL则使用内置的比较函数。
|
||||
* @param {void*} ctx 比较函数的上下文。
|
||||
*
|
||||
* @return {void*} 如果找到,返回满足条件的对象,否则返回NULL。
|
||||
*/
|
||||
void* hash_table_find(hash_table_t* hash_table, tk_compare_t cmp, void* ctx);
|
||||
|
||||
/**
|
||||
* @method hash_table_add
|
||||
* 加入一个元素。
|
||||
* @param {hash_table_t*} hash_table 哈希表对象。
|
||||
* @param {void*} data 数据。
|
||||
* @param {bool_t} replace_if_exist 如果存在是否替换。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t hash_table_add(hash_table_t* hash_table, void* data, bool_t replace_if_exist);
|
||||
|
||||
/**
|
||||
* @method hash_table_remove
|
||||
* 删除第一个满足条件的元素。
|
||||
* @param {hash_table_t*} hash_table 哈希表对象。
|
||||
* @param {tk_compare_t} cmp 比较函数,为NULL则使用内置的比较函数。
|
||||
* @param {void*} ctx 比较函数的上下文。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t hash_table_remove(hash_table_t* hash_table, tk_compare_t cmp, void* ctx);
|
||||
|
||||
/**
|
||||
* @method hash_table_remove_all
|
||||
* 删除全部满足条件的元素。
|
||||
* @param {hash_table_t*} hash_table 哈希表对象。
|
||||
* @param {tk_compare_t} cmp 比较函数,为NULL则使用内置的比较函数。
|
||||
* @param {void*} ctx 比较函数的上下文。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t hash_table_remove_all(hash_table_t* hash_table, tk_compare_t cmp, void* ctx);
|
||||
|
||||
/**
|
||||
* @method hash_table_count
|
||||
* 返回满足条件元素的个数。
|
||||
* @param {hash_table_t*} hash_table 单向链表对象。
|
||||
* @param {tk_compare_t} cmp 比较函数,为NULL则使用内置的比较函数。
|
||||
* @param {void*} ctx 比较函数的上下文。
|
||||
*
|
||||
* @return {int32_t} 返回元素个数。
|
||||
*/
|
||||
int32_t hash_table_count(hash_table_t* hash_table, tk_compare_t cmp, void* ctx);
|
||||
|
||||
/**
|
||||
* @method hash_table_clear
|
||||
* 清除全部元素。
|
||||
* @param {hash_table_t*} hash_table 哈希表对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t hash_table_clear(hash_table_t* hash_table);
|
||||
|
||||
/**
|
||||
* @method hash_table_foreach
|
||||
* 遍历元素。
|
||||
* @param {hash_table_t*} hash_table 哈希表对象。
|
||||
* @param {tk_visit_t} visit 遍历函数。
|
||||
* @param {void*} ctx 遍历函数的上下文。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t hash_table_foreach(hash_table_t* hash_table, tk_visit_t visit, void* ctx);
|
||||
|
||||
/**
|
||||
* @method hash_table_deinit
|
||||
* 清除全部元素,并释放elms。
|
||||
* @param {hash_table_t*} hash_table 哈希表对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t hash_table_deinit(hash_table_t* hash_table);
|
||||
|
||||
/**
|
||||
* @method hash_table_destroy
|
||||
* 销毁hash_table对象。
|
||||
* @param {hash_table_t*} hash_table 哈希表对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t hash_table_destroy(hash_table_t* hash_table);
|
||||
|
||||
/**
|
||||
* @method hash_table_hash_str
|
||||
* 计算字符串hash值。
|
||||
* @param {const void*} data 数据。
|
||||
*
|
||||
* @return {uint32_t} 返回hash值。
|
||||
*/
|
||||
uint32_t hash_table_hash_str(const void* data);
|
||||
|
||||
/**
|
||||
* @method hash_table_hash_int
|
||||
* 计算int的hash值。
|
||||
* @param {const void*} data 数据。
|
||||
*
|
||||
* @return {uint32_t} 返回hash值。
|
||||
*/
|
||||
uint32_t hash_table_hash_int(const void* data);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_HASH_TABLE_H*/
|
@ -333,6 +333,7 @@ typedef bool_t (*tk_is_valid_t)(void* data);
|
||||
typedef bool_t (*tk_filter_t)(void* ctx, const void* data);
|
||||
typedef int (*tk_compare_t)(const void* a, const void* b);
|
||||
typedef ret_t (*tk_visit_t)(void* ctx, const void* data);
|
||||
typedef uint32_t (*tk_hash_t)(const void* data);
|
||||
typedef ret_t (*tk_callback_t)(void* ctx);
|
||||
|
||||
/*TK_NAME_LEN+1 must aligned to 4*/
|
||||
|
107
tests/hash_table_test.cc
Normal file
107
tests/hash_table_test.cc
Normal file
@ -0,0 +1,107 @@
|
||||
#include "tkc/utils.h"
|
||||
#include "tkc/hash_table.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
static int int_compare(const void* a, const void* b) {
|
||||
return tk_pointer_to_int(a) - tk_pointer_to_int(b);
|
||||
}
|
||||
|
||||
TEST(DHashTable, int_add_remove) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 10000;
|
||||
hash_table_t* ht = hash_table_create(10, NULL, int_compare, hash_table_hash_int);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
ASSERT_EQ(hash_table_add(ht, tk_pointer_from_int(i), TRUE), RET_OK);
|
||||
ASSERT_EQ(hash_table_count(ht, compare_always_equal, NULL), (i + 1));
|
||||
ASSERT_EQ(tk_pointer_to_int(hash_table_find(ht, int_compare, tk_pointer_from_int(i))), i);
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
ASSERT_EQ(hash_table_remove(ht, int_compare, tk_pointer_from_int(i)), RET_OK);
|
||||
ASSERT_EQ(hash_table_count(ht, compare_always_equal, NULL), n - i - 1);
|
||||
ASSERT_EQ(tk_pointer_to_int(hash_table_find(ht, int_compare, tk_pointer_from_int(i))), 0);
|
||||
}
|
||||
|
||||
hash_table_destroy(ht);
|
||||
}
|
||||
|
||||
TEST(DHashTable, int_add_clear) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 10000;
|
||||
hash_table_t* ht = hash_table_create(10, NULL, int_compare, hash_table_hash_int);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
ASSERT_EQ(hash_table_add(ht, tk_pointer_from_int(i), TRUE), RET_OK);
|
||||
ASSERT_EQ(hash_table_count(ht, compare_always_equal, NULL), (i + 1));
|
||||
ASSERT_EQ(tk_pointer_to_int(hash_table_find(ht, int_compare, tk_pointer_from_int(i))), i);
|
||||
}
|
||||
|
||||
ASSERT_EQ(hash_table_clear(ht), RET_OK);
|
||||
ASSERT_EQ(hash_table_count(ht, compare_always_equal, NULL), 0);
|
||||
|
||||
hash_table_destroy(ht);
|
||||
}
|
||||
|
||||
TEST(DHashTable, int_remove_all) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 10000;
|
||||
hash_table_t* ht = hash_table_create(10, NULL, int_compare, hash_table_hash_int);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
ASSERT_EQ(hash_table_add(ht, tk_pointer_from_int(i), TRUE), RET_OK);
|
||||
ASSERT_EQ(hash_table_count(ht, compare_always_equal, NULL), (i + 1));
|
||||
ASSERT_EQ(tk_pointer_to_int(hash_table_find(ht, int_compare, tk_pointer_from_int(i))), i);
|
||||
}
|
||||
|
||||
ASSERT_EQ(hash_table_remove_all(ht, compare_always_equal, NULL), RET_OK);
|
||||
ASSERT_EQ(hash_table_count(ht, compare_always_equal, NULL), 0);
|
||||
|
||||
hash_table_destroy(ht);
|
||||
}
|
||||
|
||||
static ret_t visit_int(void* ctx, const void* data) {
|
||||
int32_t v = tk_pointer_to_int(data);
|
||||
str_t* str = (str_t*)ctx;
|
||||
str_append_char(str, ';');
|
||||
str_append_int(str, v);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
TEST(DHashTable, int_foreach) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 20;
|
||||
str_t str;
|
||||
hash_table_t* ht = hash_table_create(10, NULL, int_compare, hash_table_hash_int);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
ASSERT_EQ(hash_table_add(ht, tk_pointer_from_int(i), TRUE), RET_OK);
|
||||
ASSERT_EQ(hash_table_count(ht, compare_always_equal, NULL), (i + 1));
|
||||
ASSERT_EQ(tk_pointer_to_int(hash_table_find(ht, int_compare, tk_pointer_from_int(i))), i);
|
||||
}
|
||||
|
||||
str_init(&str, 0);
|
||||
ASSERT_EQ(hash_table_foreach(ht, visit_int, &str), RET_OK);
|
||||
ASSERT_STREQ(str.str, ";0;10;1;11;2;12;3;13;4;14;5;15;6;16;7;17;8;18;9;19");
|
||||
str_reset(&str);
|
||||
|
||||
hash_table_destroy(ht);
|
||||
}
|
||||
|
||||
TEST(DHashTable, str_add_remove) {
|
||||
char str[32];
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 10000;
|
||||
hash_table_t* ht =
|
||||
hash_table_create(10, default_destroy, (tk_compare_t)strcmp, hash_table_hash_str);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
tk_snprintf(str, sizeof(str), "%u", i);
|
||||
ASSERT_EQ(hash_table_add(ht, tk_strdup(str), TRUE), RET_OK);
|
||||
ASSERT_EQ(hash_table_count(ht, compare_always_equal, NULL), (i + 1));
|
||||
ASSERT_STREQ((char*)hash_table_find(ht, (tk_compare_t)strcmp, str), str);
|
||||
}
|
||||
|
||||
hash_table_destroy(ht);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user