Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
慢慢CG
TDengine
提交
af315a9c
T
TDengine
项目概览
慢慢CG
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
af315a9c
编写于
3月 14, 2020
作者:
H
hjxilinx
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add hash iterator
上级
d1b298bc
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
198 addition
and
51 deletion
+198
-51
src/util/inc/hash.h
src/util/inc/hash.h
+57
-12
src/util/src/hash.c
src/util/src/hash.c
+141
-39
未找到文件。
src/util/inc/hash.h
浏览文件 @
af315a9c
...
...
@@ -23,17 +23,18 @@ extern "C" {
#include "hashfunc.h"
#define HASH_MAX_CAPACITY (1024 * 1024 * 16)
#define HASH_VALUE_IN_TRASH (-1)
#define HASH_DEFAULT_LOAD_FACTOR (0.75)
#define HASH_INDEX(v, c) ((v) & ((c)-1))
typedef
void
(
*
_hash_free_fn_t
)(
void
*
param
);
typedef
struct
SHashNode
{
char
*
key
;
// null-terminated string
char
*
key
;
union
{
struct
SHashNode
*
prev
;
struct
SHashEntry
*
prev1
;
};
struct
SHashNode
*
next
;
uint32_t
hashVal
;
// the hash value of key, if hashVal == HASH_VALUE_IN_TRASH, this node is moved to trash
uint32_t
keyLen
;
// length of the key
...
...
@@ -46,18 +47,27 @@ typedef struct SHashEntry {
}
SHashEntry
;
typedef
struct
SHashObj
{
SHashEntry
**
hashList
;
size_t
capacity
;
// number of slots
size_t
size
;
// number of elements in hash table
_hash_fn_t
hashFp
;
// hash function
#if defined (LINUX)
pthread_rwlock_t
*
lock
;
SHashEntry
**
hashList
;
size_t
capacity
;
// number of slots
size_t
size
;
// number of elements in hash table
_hash_fn_t
hashFp
;
// hash function
_hash_free_fn_t
freeFp
;
// hash node free callback function
#if defined(LINUX)
pthread_rwlock_t
*
lock
;
#else
pthread_mutex_t
*
lock
;
pthread_mutex_t
*
lock
;
#endif
}
SHashObj
;
typedef
struct
SHashMutableIterator
{
SHashObj
*
pHashObj
;
int32_t
entryIndex
;
SHashNode
*
pCur
;
SHashNode
*
pNext
;
// current node can be deleted for mutable iterator, so keep the next one before return current
int32_t
num
;
// already check number of elements in hash table
}
SHashMutableIterator
;
/**
* init the hash table
*
...
...
@@ -102,7 +112,7 @@ void *taosHashGet(SHashObj *pHashObj, const char *key, size_t keyLen);
* @param key
* @param keyLen
*/
void
taosHashRemove
(
SHashObj
*
pHashObj
,
const
char
*
key
,
size_t
keyLen
);
void
taosHashRemove
(
SHashObj
*
pHashObj
,
const
char
*
key
,
size_t
keyLen
);
/**
* clean up hash table
...
...
@@ -110,6 +120,41 @@ void taosHashRemove(SHashObj *pHashObj, const char *key, size_t keyLen);
*/
void
taosHashCleanup
(
SHashObj
*
pHashObj
);
/**
* Set the free callback function
* This function if set will be invoked right before freeing each hash node
* @param pHashObj
*/
void
taosHashSetFreecb
(
SHashObj
*
pHashObj
,
_hash_free_fn_t
freeFp
);
/**
*
* @param pHashObj
* @return
*/
SHashMutableIterator
*
taosHashCreateIter
(
SHashObj
*
pHashObj
);
/**
*
* @param iter
* @return
*/
bool
taosHashIterNext
(
SHashMutableIterator
*
iter
);
/**
*
* @param iter
* @return
*/
void
*
taosHashIterGet
(
SHashMutableIterator
*
iter
);
/**
*
* @param iter
* @return
*/
void
*
taosHashDestroyIter
(
SHashMutableIterator
*
iter
);
/**
*
* @param pHashObj
...
...
src/util/src/hash.c
浏览文件 @
af315a9c
...
...
@@ -24,8 +24,8 @@ static FORCE_INLINE void __wr_lock(void *lock) {
if
(
lock
==
NULL
)
{
return
;
}
#if defined
(LINUX)
#if defined(LINUX)
pthread_rwlock_wrlock
(
lock
);
#else
pthread_mutex_lock
(
lock
);
...
...
@@ -36,8 +36,8 @@ static FORCE_INLINE void __rd_lock(void *lock) {
if
(
lock
==
NULL
)
{
return
;
}
#if defined
(LINUX)
#if defined(LINUX)
pthread_rwlock_rdlock
(
lock
);
#else
pthread_mutex_lock
(
lock
);
...
...
@@ -48,8 +48,8 @@ static FORCE_INLINE void __unlock(void *lock) {
if
(
lock
==
NULL
)
{
return
;
}
#if defined
(LINUX)
#if defined(LINUX)
pthread_rwlock_unlock
(
lock
);
#else
pthread_mutex_unlock
(
lock
);
...
...
@@ -60,8 +60,8 @@ static FORCE_INLINE int32_t __lock_init(void *lock) {
if
(
lock
==
NULL
)
{
return
0
;
}
#if defined
(LINUX)
#if defined(LINUX)
return
pthread_rwlock_init
(
lock
,
NULL
);
#else
return
pthread_mutex_init
(
lock
,
NULL
);
...
...
@@ -72,8 +72,8 @@ static FORCE_INLINE void __lock_destroy(void *lock) {
if
(
lock
==
NULL
)
{
return
;
}
#if defined
(LINUX)
#if defined(LINUX)
pthread_rwlock_destroy
(
lock
);
#else
pthread_mutex_destroy
(
lock
);
...
...
@@ -107,7 +107,7 @@ static void doUpdateHashTable(SHashObj *pHashObj, SHashNode *pNode) {
/**
* get SHashNode from hashlist, nodes from trash are not included.
* @param pHashObj
Cache objection
* @param pHashObj Cache objection
* @param key key for hash
* @param keyLen key length
* @return
...
...
@@ -155,24 +155,24 @@ static void taosHashTableResize(SHashObj *pHashObj) {
int32_t
newSize
=
pHashObj
->
capacity
<<
1U
;
if
(
newSize
>
HASH_MAX_CAPACITY
)
{
pTrace
(
"current capacity:%d, maximum capacity:%d, no resize applied due to limitation is reached"
,
pHashObj
->
capacity
,
HASH_MAX_CAPACITY
);
pTrace
(
"current capacity:%d, maximum capacity:%d, no resize applied due to limitation is reached"
,
pHashObj
->
capacity
,
HASH_MAX_CAPACITY
);
return
;
}
int64_t
st
=
taosGetTimestampUs
();
SHashEntry
**
pNewEntry
=
realloc
(
pHashObj
->
hashList
,
sizeof
(
SHashEntry
*
)
*
newSize
);
SHashEntry
**
pNewEntry
=
realloc
(
pHashObj
->
hashList
,
sizeof
(
SHashEntry
*
)
*
newSize
);
if
(
pNewEntry
==
NULL
)
{
pTrace
(
"cache resize failed due to out of memory, capacity remain:%d"
,
pHashObj
->
capacity
);
return
;
}
pHashObj
->
hashList
=
pNewEntry
;
for
(
int32_t
i
=
pHashObj
->
capacity
;
i
<
newSize
;
++
i
)
{
for
(
int32_t
i
=
pHashObj
->
capacity
;
i
<
newSize
;
++
i
)
{
pHashObj
->
hashList
[
i
]
=
calloc
(
1
,
sizeof
(
SHashEntry
));
}
pHashObj
->
capacity
=
newSize
;
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
capacity
;
++
i
)
{
...
...
@@ -182,7 +182,7 @@ static void taosHashTableResize(SHashObj *pHashObj) {
if
(
pNode
!=
NULL
)
{
assert
(
pNode
->
prev1
==
pEntry
&&
pEntry
->
num
>
0
);
}
while
(
pNode
)
{
int32_t
j
=
HASH_INDEX
(
pNode
->
hashVal
,
pHashObj
->
capacity
);
if
(
j
==
i
)
{
// this key resides in the same slot, no need to relocate it
...
...
@@ -192,13 +192,13 @@ static void taosHashTableResize(SHashObj *pHashObj) {
// remove from current slot
assert
(
pNode
->
prev1
!=
NULL
);
if
(
pNode
->
prev1
==
pEntry
)
{
// first node of the overflow linked list
if
(
pNode
->
prev1
==
pEntry
)
{
// first node of the overflow linked list
pEntry
->
next
=
pNode
->
next
;
}
else
{
pNode
->
prev
->
next
=
pNode
->
next
;
}
pEntry
->
num
--
;
assert
(
pEntry
->
num
>=
0
);
...
...
@@ -214,13 +214,13 @@ static void taosHashTableResize(SHashObj *pHashObj) {
if
(
pNewIndexEntry
->
next
!=
NULL
)
{
assert
(
pNewIndexEntry
->
next
->
prev1
==
pNewIndexEntry
);
pNewIndexEntry
->
next
->
prev
=
pNode
;
}
pNode
->
next
=
pNewIndexEntry
->
next
;
pNode
->
prev1
=
pNewIndexEntry
;
pNewIndexEntry
->
next
=
pNode
;
pNewIndexEntry
->
num
++
;
...
...
@@ -258,14 +258,14 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool threadsafe) {
pHashObj
->
hashFp
=
fn
;
pHashObj
->
hashList
=
(
SHashEntry
**
)
calloc
(
pHashObj
->
capacity
,
sizeof
(
SHashEntry
*
));
pHashObj
->
hashList
=
(
SHashEntry
**
)
calloc
(
pHashObj
->
capacity
,
sizeof
(
SHashEntry
*
));
if
(
pHashObj
->
hashList
==
NULL
)
{
free
(
pHashObj
);
pError
(
"failed to allocate memory, reason:%s"
,
strerror
(
errno
));
return
NULL
;
}
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
capacity
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
capacity
;
++
i
)
{
pHashObj
->
hashList
[
i
]
=
calloc
(
1
,
sizeof
(
SHashEntry
));
}
...
...
@@ -276,7 +276,7 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool threadsafe) {
pHashObj
->
lock
=
calloc
(
1
,
sizeof
(
pthread_mutex_t
));
#endif
}
if
(
__lock_init
(
pHashObj
->
lock
)
!=
0
)
{
free
(
pHashObj
->
hashList
);
free
(
pHashObj
);
...
...
@@ -347,7 +347,7 @@ static void doAddToHashTable(SHashObj *pHashObj, SHashNode *pNode) {
int32_t
index
=
HASH_INDEX
(
pNode
->
hashVal
,
pHashObj
->
capacity
);
SHashEntry
*
pEntry
=
pHashObj
->
hashList
[
index
];
pNode
->
next
=
pEntry
->
next
;
if
(
pEntry
->
next
)
{
...
...
@@ -356,7 +356,7 @@ static void doAddToHashTable(SHashObj *pHashObj, SHashNode *pNode) {
pEntry
->
next
=
pNode
;
pNode
->
prev1
=
pEntry
;
pEntry
->
num
++
;
pHashObj
->
size
++
;
}
...
...
@@ -365,7 +365,7 @@ size_t taosHashGetSize(const SHashObj *pHashObj) {
if
(
pHashObj
==
NULL
)
{
return
0
;
}
return
pHashObj
->
size
;
}
...
...
@@ -430,7 +430,7 @@ void *taosHashGet(SHashObj *pHashObj, const char *key, size_t keyLen) {
void
taosHashRemove
(
SHashObj
*
pHashObj
,
const
char
*
key
,
size_t
keyLen
)
{
__wr_lock
(
pHashObj
->
lock
);
uint32_t
val
=
0
;
uint32_t
val
=
0
;
SHashNode
*
pNode
=
doGetNodeFromHashTable
(
pHashObj
,
key
,
keyLen
,
&
val
);
if
(
pNode
==
NULL
)
{
__unlock
(
pHashObj
->
lock
);
...
...
@@ -446,13 +446,13 @@ void taosHashRemove(SHashObj *pHashObj, const char *key, size_t keyLen) {
pNode
->
prev
->
next
=
pNext
;
}
}
if
(
pNext
!=
NULL
)
{
pNext
->
prev
=
pNode
->
prev
;
}
uint32_t
index
=
HASH_INDEX
(
pNode
->
hashVal
,
pHashObj
->
capacity
);
SHashEntry
*
pEntry
=
pHashObj
->
hashList
[
index
];
pEntry
->
num
--
;
...
...
@@ -483,10 +483,14 @@ void taosHashCleanup(SHashObj *pHashObj) {
while
(
pNode
)
{
pNext
=
pNode
->
next
;
if
(
pHashObj
->
freeFp
)
{
pHashObj
->
freeFp
(
pNode
->
data
);
}
free
(
pNode
);
pNode
=
pNext
;
}
tfree
(
pEntry
);
}
...
...
@@ -496,24 +500,122 @@ void taosHashCleanup(SHashObj *pHashObj) {
__unlock
(
pHashObj
->
lock
);
__lock_destroy
(
pHashObj
->
lock
);
tfree
(
pHashObj
->
lock
);
memset
(
pHashObj
,
0
,
sizeof
(
SHashObj
));
free
(
pHashObj
);
}
void
taosHashSetFreecb
(
SHashObj
*
pHashObj
,
_hash_free_fn_t
freeFp
)
{
if
(
pHashObj
==
NULL
||
freeFp
==
NULL
)
{
return
;
}
pHashObj
->
freeFp
=
freeFp
;
}
SHashMutableIterator
*
taosHashCreateIter
(
SHashObj
*
pHashObj
)
{
SHashMutableIterator
*
pIter
=
calloc
(
1
,
sizeof
(
SHashMutableIterator
));
if
(
pIter
==
NULL
)
{
return
NULL
;
}
pIter
->
pHashObj
=
pHashObj
;
}
static
SHashNode
*
getNextHashNode
(
SHashMutableIterator
*
pIter
)
{
assert
(
pIter
!=
NULL
);
while
(
pIter
->
entryIndex
<
pIter
->
pHashObj
->
capacity
)
{
SHashEntry
*
pEntry
=
pIter
->
pHashObj
->
hashList
[
pIter
->
entryIndex
];
if
(
pEntry
->
next
==
NULL
)
{
pIter
->
entryIndex
++
;
continue
;
}
return
pEntry
->
next
;
}
return
NULL
;
}
bool
taosHashIterNext
(
SHashMutableIterator
*
pIter
)
{
if
(
pIter
==
NULL
)
{
return
false
;
}
size_t
size
=
taosHashGetSize
(
pIter
->
pHashObj
);
if
(
size
==
0
||
pIter
->
num
>=
size
)
{
return
false
;
}
// check the first one
if
(
pIter
->
num
==
0
)
{
assert
(
pIter
->
pCur
==
NULL
&&
pIter
->
pNext
==
NULL
);
while
(
1
)
{
SHashEntry
*
pEntry
=
pIter
->
pHashObj
->
hashList
[
pIter
->
entryIndex
];
if
(
pEntry
->
next
==
NULL
)
{
pIter
->
entryIndex
++
;
continue
;
}
pIter
->
pCur
=
pEntry
->
next
;
if
(
pIter
->
pCur
->
next
)
{
pIter
->
pNext
=
pIter
->
pCur
->
next
;
}
else
{
pIter
->
pNext
=
getNextHashNode
(
pIter
);
}
break
;
}
pIter
->
num
++
;
return
true
;
}
else
{
assert
(
pIter
->
pCur
!=
NULL
);
if
(
pIter
->
pNext
)
{
pIter
->
pCur
=
pIter
->
pNext
;
}
else
{
// no more data in the hash list
return
false
;
}
pIter
->
num
++
;
if
(
pIter
->
pCur
->
next
)
{
pIter
->
pNext
=
pIter
->
pCur
->
next
;
}
else
{
pIter
->
pNext
=
getNextHashNode
(
pIter
);
}
return
true
;
}
}
void
*
taosHashIterGet
(
SHashMutableIterator
*
iter
)
{
return
(
iter
==
NULL
)
?
NULL
:
iter
->
pCur
->
data
;
}
void
*
taosHashDestroyIter
(
SHashMutableIterator
*
iter
)
{
if
(
iter
==
NULL
)
{
return
NULL
;
}
free
(
iter
);
}
// for profile only
int32_t
taosHashGetMaxOverflowLinkLength
(
const
SHashObj
*
pHashObj
)
{
int32_t
taosHashGetMaxOverflowLinkLength
(
const
SHashObj
*
pHashObj
)
{
if
(
pHashObj
==
NULL
||
pHashObj
->
size
==
0
)
{
return
0
;
}
int32_t
num
=
0
;
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
size
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
size
;
++
i
)
{
SHashEntry
*
pEntry
=
pHashObj
->
hashList
[
i
];
if
(
num
<
pEntry
->
num
)
{
num
=
pEntry
->
num
;
}
}
return
num
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录