Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
9df1fed6
T
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1192
Star
22018
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
9df1fed6
编写于
2月 28, 2022
作者:
S
Shengliang Guan
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cache
上级
1360f6b2
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
168 addition
and
162 deletion
+168
-162
include/util/tcache.h
include/util/tcache.h
+39
-38
source/util/src/tcache.c
source/util/src/tcache.c
+129
-124
未找到文件。
include/util/tcache.h
浏览文件 @
9df1fed6
...
...
@@ -13,27 +13,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_UTIL_CACHE_H
#define _TD_UTIL_CACHE_H
#ifndef _TD_UTIL_CACHE_H_
#define _TD_UTIL_CACHE_H_
#include "thash.h"
#include "tlockfree.h"
#ifdef __cplusplus
extern
"C"
{
#endif
#include "os.h"
#include "tlockfree.h"
#include "thash.h"
#if defined(_TD_ARM_32)
#define TSDB_CACHE_PTR_KEY TSDB_DATA_TYPE_INT
#define TSDB_CACHE_PTR_TYPE int32_t
#define TSDB_CACHE_PTR_KEY TSDB_DATA_TYPE_INT
#define TSDB_CACHE_PTR_TYPE int32_t
#else
#define TSDB_CACHE_PTR_KEY TSDB_DATA_TYPE_BIGINT
#define TSDB_CACHE_PTR_TYPE int64_t
#define TSDB_CACHE_PTR_KEY TSDB_DATA_TYPE_BIGINT
#define TSDB_CACHE_PTR_TYPE int64_t
#endif
typedef
void
(
*
__cache_free_fn_t
)(
void
*
);
typedef
void
(
*
__cache_trav_fn_t
)(
void
*
,
void
*
);
typedef
void
(
*
__cache_free_fn_t
)(
void
*
);
typedef
void
(
*
__cache_trav_fn_t
)(
void
*
,
void
*
);
typedef
struct
SCacheStatis
{
int64_t
missCount
;
...
...
@@ -50,8 +49,8 @@ typedef struct SCacheDataNode {
uint64_t
expireTime
;
// expire time
uint64_t
signature
;
struct
STrashElem
*
pTNodeHeader
;
// point to trash node head
uint16_t
keySize
:
15
;
// max key size: 32kb
bool
inTrashcan
:
1
;
// denote if it is in trash or not
uint16_t
keySize
:
15
;
// max key size: 32kb
bool
inTrashcan
:
1
;
// denote if it is in trash or not
uint32_t
size
;
// allocated size for current SCacheDataNode
T_REF_DECLARE
()
char
*
key
;
...
...
@@ -75,10 +74,10 @@ typedef struct STrashElem {
typedef
struct
{
int64_t
totalSize
;
// total allocated buffer in this hash table, SCacheObj is not included.
int64_t
refreshTime
;
STrashElem
*
pTrash
;
char
*
name
;
STrashElem
*
pTrash
;
char
*
name
;
SCacheStatis
statistics
;
SHashObj
*
pHashTable
;
SHashObj
*
pHashTable
;
__cache_free_fn_t
freeFp
;
uint32_t
numOfElemsInTrash
;
// number of element in trash
uint8_t
deleting
;
// set the deleting flag to stop refreshing ASAP.
...
...
@@ -101,7 +100,8 @@ typedef struct {
* @param fn free resource callback function
* @return
*/
SCacheObj
*
taosCacheInit
(
int32_t
keyType
,
int64_t
refreshTimeInSeconds
,
bool
extendLifespan
,
__cache_free_fn_t
fn
,
const
char
*
cacheName
);
SCacheObj
*
taosCacheInit
(
int32_t
keyType
,
int64_t
refreshTimeInSeconds
,
bool
extendLifespan
,
__cache_free_fn_t
fn
,
const
char
*
cacheName
);
/**
* add data into cache
...
...
@@ -113,7 +113,8 @@ SCacheObj *taosCacheInit(int32_t keyType, int64_t refreshTimeInSeconds, bool ext
* @param keepTime survival time in second
* @return cached element
*/
void
*
taosCachePut
(
SCacheObj
*
pCacheObj
,
const
void
*
key
,
size_t
keyLen
,
const
void
*
pData
,
size_t
dataSize
,
int
durationMS
);
void
*
taosCachePut
(
SCacheObj
*
pCacheObj
,
const
void
*
key
,
size_t
keyLen
,
const
void
*
pData
,
size_t
dataSize
,
int32_t
durationMS
);
/**
* get data from cache
...
...
@@ -177,7 +178,7 @@ void taosCacheCleanup(SCacheObj *pCacheObj);
* @param fp
* @return
*/
void
taosCacheRefresh
(
SCacheObj
*
pCacheObj
,
__cache_trav_fn_t
fp
,
void
*
param1
);
void
taosCacheRefresh
(
SCacheObj
*
pCacheObj
,
__cache_trav_fn_t
fp
,
void
*
param1
);
/**
* stop background refresh worker thread
...
...
@@ -188,4 +189,4 @@ void taosStopCacheRefreshWorker();
}
#endif
#endif
/*_TD_UTIL_CACHE_H
*/
#endif
/*_TD_UTIL_CACHE_H_
*/
source/util/src/tcache.c
浏览文件 @
9df1fed6
...
...
@@ -14,11 +14,10 @@
*/
#define _DEFAULT_SOURCE
#include "
os
.h"
#include "
tcache
.h"
#include "tlog.h"
#include "ttimer.h"
#include "tutil.h"
#include "tcache.h"
static
FORCE_INLINE
void
__cache_wr_lock
(
SCacheObj
*
pCacheObj
)
{
#if defined(LINUX)
...
...
@@ -62,12 +61,12 @@ static void doCleanupDataCache(SCacheObj *pCacheObj);
* refresh cache to remove data in both hash list and trash, if any nodes' refcount == 0, every pCacheObj->refreshTime
* @param handle Cache object handle
*/
static
void
*
taosCacheTimedRefresh
(
void
*
handle
);
static
void
*
taosCacheTimedRefresh
(
void
*
handle
);
static
pthread_t
cacheRefreshWorker
=
{
0
};
static
pthread_once_t
cacheThreadInit
=
PTHREAD_ONCE_INIT
;
static
pthread_mutex_t
guard
=
PTHREAD_MUTEX_INITIALIZER
;
static
SArray
*
pCacheArrayList
=
NULL
;
static
SArray
*
pCacheArrayList
=
NULL
;
static
bool
stopRefreshWorker
=
false
;
static
bool
refreshWorkerNormalStopped
=
false
;
static
bool
refreshWorkerUnexpectedStopped
=
false
;
...
...
@@ -83,7 +82,7 @@ static void doInitRefreshThread(void) {
pthread_attr_destroy
(
&
thattr
);
}
pthread_t
doRegisterCacheObj
(
SCacheObj
*
pCacheObj
)
{
pthread_t
doRegisterCacheObj
(
SCacheObj
*
pCacheObj
)
{
pthread_once
(
&
cacheThreadInit
,
doInitRefreshThread
);
pthread_mutex_lock
(
&
guard
);
...
...
@@ -102,7 +101,8 @@ pthread_t doRegisterCacheObj(SCacheObj* pCacheObj) {
* @param lifespan total survial expiredTime from now
* @return SCacheDataNode
*/
static
SCacheDataNode
*
taosCreateCacheNode
(
const
char
*
key
,
size_t
keyLen
,
const
char
*
pData
,
size_t
size
,
uint64_t
duration
);
static
SCacheDataNode
*
taosCreateCacheNode
(
const
char
*
key
,
size_t
keyLen
,
const
char
*
pData
,
size_t
size
,
uint64_t
duration
);
/**
* addedTime object node into trash, and this object is closed for referencing if it is addedTime to trash
...
...
@@ -146,13 +146,13 @@ static FORCE_INLINE void taosCacheReleaseNode(SCacheObj *pCacheObj, SCacheDataNo
free
(
pNode
);
}
static
FORCE_INLINE
STrashElem
*
doRemoveElemInTrashcan
(
SCacheObj
*
pCacheObj
,
STrashElem
*
pElem
)
{
if
(
pElem
->
pData
->
signature
!=
(
uint64_t
)
pElem
->
pData
)
{
static
FORCE_INLINE
STrashElem
*
doRemoveElemInTrashcan
(
SCacheObj
*
pCacheObj
,
STrashElem
*
pElem
)
{
if
(
pElem
->
pData
->
signature
!=
(
uint64_t
)
pElem
->
pData
)
{
uWarn
(
"key:sig:0x%"
PRIx64
" %p data has been released, ignore"
,
pElem
->
pData
->
signature
,
pElem
->
pData
);
return
NULL
;
}
STrashElem
*
next
=
pElem
->
next
;
STrashElem
*
next
=
pElem
->
next
;
pCacheObj
->
numOfElemsInTrash
--
;
if
(
pElem
->
prev
)
{
...
...
@@ -172,7 +172,7 @@ static FORCE_INLINE STrashElem* doRemoveElemInTrashcan(SCacheObj* pCacheObj, STr
return
next
;
}
static
FORCE_INLINE
void
doDestroyTrashcanElem
(
SCacheObj
*
pCacheObj
,
STrashElem
*
pElem
)
{
static
FORCE_INLINE
void
doDestroyTrashcanElem
(
SCacheObj
*
pCacheObj
,
STrashElem
*
pElem
)
{
if
(
pCacheObj
->
freeFp
)
{
pCacheObj
->
freeFp
(
pElem
->
pData
->
data
);
}
...
...
@@ -181,8 +181,9 @@ static FORCE_INLINE void doDestroyTrashcanElem(SCacheObj* pCacheObj, STrashElem
free
(
pElem
);
}
SCacheObj
*
taosCacheInit
(
int32_t
keyType
,
int64_t
refreshTimeInSeconds
,
bool
extendLifespan
,
__cache_free_fn_t
fn
,
const
char
*
cacheName
)
{
const
int32_t
SLEEP_DURATION
=
500
;
//500 ms
SCacheObj
*
taosCacheInit
(
int32_t
keyType
,
int64_t
refreshTimeInSeconds
,
bool
extendLifespan
,
__cache_free_fn_t
fn
,
const
char
*
cacheName
)
{
const
int32_t
SLEEP_DURATION
=
500
;
// 500 ms
if
(
refreshTimeInSeconds
<=
0
)
{
return
NULL
;
...
...
@@ -220,7 +221,8 @@ SCacheObj *taosCacheInit(int32_t keyType, int64_t refreshTimeInSeconds, bool ext
return
pCacheObj
;
}
void
*
taosCachePut
(
SCacheObj
*
pCacheObj
,
const
void
*
key
,
size_t
keyLen
,
const
void
*
pData
,
size_t
dataSize
,
int
durationMS
)
{
void
*
taosCachePut
(
SCacheObj
*
pCacheObj
,
const
void
*
key
,
size_t
keyLen
,
const
void
*
pData
,
size_t
dataSize
,
int32_t
durationMS
)
{
if
(
pCacheObj
==
NULL
||
pCacheObj
->
pHashTable
==
NULL
||
pCacheObj
->
deleting
==
1
)
{
return
NULL
;
}
...
...
@@ -242,8 +244,8 @@ void *taosCachePut(SCacheObj *pCacheObj, const void *key, size_t keyLen, const v
(
int32_t
)
taosHashGetSize
(
pCacheObj
->
pHashTable
),
pCacheObj
->
totalSize
,
(
int64_t
)
dataSize
);
}
else
{
// duplicated key exists
while
(
1
)
{
SCacheDataNode
*
p
=
NULL
;
// int32_t ret = taosHashRemoveWithData(pCacheObj->pHashTable, key, keyLen, (void*) &p, sizeof(void*));
SCacheDataNode
*
p
=
NULL
;
// int32_t ret = taosHashRemoveWithData(pCacheObj->pHashTable, key, keyLen, (void*) &p, sizeof(void*));
int32_t
ret
=
taosHashRemove
(
pCacheObj
->
pHashTable
,
key
,
keyLen
);
// add to trashcan
...
...
@@ -283,10 +285,10 @@ void *taosCachePut(SCacheObj *pCacheObj, const void *key, size_t keyLen, const v
return
pNode1
->
data
;
}
static
void
incRefFn
(
void
*
ptNode
)
{
static
void
incRefFn
(
void
*
ptNode
)
{
assert
(
ptNode
!=
NULL
);
SCacheDataNode
**
p
=
(
SCacheDataNode
**
)
ptNode
;
SCacheDataNode
**
p
=
(
SCacheDataNode
**
)
ptNode
;
assert
(
T_REF_VAL_GET
(
*
p
)
>=
0
);
int32_t
ret
=
T_REF_INC
(
*
p
);
...
...
@@ -303,15 +305,16 @@ void *taosCacheAcquireByKey(SCacheObj *pCacheObj, const void *key, size_t keyLen
return
NULL
;
}
SCacheDataNode
*
ptNode
=
NULL
;
SCacheDataNode
*
ptNode
=
NULL
;
taosHashGetClone
(
pCacheObj
->
pHashTable
,
key
,
keyLen
,
&
ptNode
);
// taosHashGetClone(pCacheObj->pHashTable, key, keyLen, incRefFn, &ptNode);
// taosHashGetClone(pCacheObj->pHashTable, key, keyLen, incRefFn, &ptNode);
void
*
pData
=
(
ptNode
!=
NULL
)
?
ptNode
->
data
:
NULL
;
void
*
pData
=
(
ptNode
!=
NULL
)
?
ptNode
->
data
:
NULL
;
if
(
pData
!=
NULL
)
{
atomic_add_fetch_32
(
&
pCacheObj
->
statistics
.
hitCount
,
1
);
uDebug
(
"cache:%s, key:%p, %p is retrieved from cache, refcnt:%d"
,
pCacheObj
->
name
,
key
,
pData
,
T_REF_VAL_GET
(
ptNode
));
uDebug
(
"cache:%s, key:%p, %p is retrieved from cache, refcnt:%d"
,
pCacheObj
->
name
,
key
,
pData
,
T_REF_VAL_GET
(
ptNode
));
}
else
{
atomic_add_fetch_32
(
&
pCacheObj
->
statistics
.
missCount
,
1
);
uDebug
(
"cache:%s, key:%p, not in cache, retrieved failed"
,
pCacheObj
->
name
,
key
);
...
...
@@ -371,7 +374,6 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
return
;
}
// The operation of removal from hash table and addition to trashcan is not an atomic operation,
// therefore the check for the empty of both the hash table and the trashcan has a race condition.
// It happens when there is only one object in the cache, and two threads which has referenced this object
...
...
@@ -391,20 +393,20 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
if
(
pCacheObj
->
extendLifespan
&&
(
!
inTrashcan
)
&&
(
!
_remove
))
{
atomic_store_64
(
&
pNode
->
expireTime
,
pNode
->
lifespan
+
taosGetTimestampMs
());
uDebug
(
"cache:%s, data:%p extend expire time: %"
PRId64
,
pCacheObj
->
name
,
pNode
->
data
,
pNode
->
expireTime
);
uDebug
(
"cache:%s, data:%p extend expire time: %"
PRId64
,
pCacheObj
->
name
,
pNode
->
data
,
pNode
->
expireTime
);
}
if
(
_remove
)
{
// NOTE: once refcount is decrease, pNode may be freed by other thread immediately.
char
*
key
=
pNode
->
key
;
char
*
d
=
pNode
->
data
;
char
*
key
=
pNode
->
key
;
char
*
d
=
pNode
->
data
;
int32_t
ref
=
T_REF_VAL_GET
(
pNode
);
uDebug
(
"cache:%s, key:%p, %p is released, refcnt:%d, in trashcan:%d"
,
pCacheObj
->
name
,
key
,
d
,
ref
-
1
,
inTrashcan
);
/*
* If it is not referenced by other users, remove it immediately. Otherwise move this node to trashcan wait for all
users
* releasing this resources.
* If it is not referenced by other users, remove it immediately. Otherwise move this node to trashcan wait for all
*
users
releasing this resources.
*
* NOTE: previous ref is 0, and current ref is still 0, remove it. If previous is not 0, there is another thread
* that tries to do the same thing.
...
...
@@ -434,15 +436,18 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
// when reaches here.
SCacheDataNode
*
p
=
NULL
;
int32_t
ret
=
taosHashRemove
(
pCacheObj
->
pHashTable
,
pNode
->
key
,
pNode
->
keySize
);
// int32_t ret = taosHashRemoveWithData(pCacheObj->pHashTable, pNode->key, pNode->keySize, &p, sizeof(void *));
// int32_t ret = taosHashRemoveWithData(pCacheObj->pHashTable, pNode->key, pNode->keySize, &p, sizeof(void
// *));
ref
=
T_REF_DEC
(
pNode
);
// successfully remove from hash table, if failed, this node must have been move to trash already, do nothing.
// note that the remove operation can be executed only once.
if
(
ret
==
0
)
{
if
(
p
!=
pNode
)
{
uDebug
(
"cache:%s, key:%p, successfully removed a new entry:%p, refcnt:%d, prev entry:%p has been removed by "
"others already"
,
pCacheObj
->
name
,
pNode
->
key
,
p
->
data
,
T_REF_VAL_GET
(
p
),
pNode
->
data
);
uDebug
(
"cache:%s, key:%p, successfully removed a new entry:%p, refcnt:%d, prev entry:%p has been removed by "
"others already"
,
pCacheObj
->
name
,
pNode
->
key
,
p
->
data
,
T_REF_VAL_GET
(
p
),
pNode
->
data
);
assert
(
p
->
pTNodeHeader
==
NULL
);
taosAddToTrashcan
(
pCacheObj
,
p
);
...
...
@@ -468,35 +473,36 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
}
}
}
else
{
uDebug
(
"cache:%s, key:%p, %p has been removed from hash table by others already, refcnt:%d"
,
p
CacheObj
->
name
,
p
Node
->
key
,
pNode
->
data
,
ref
);
uDebug
(
"cache:%s, key:%p, %p has been removed from hash table by others already, refcnt:%d"
,
pCacheObj
->
name
,
pNode
->
key
,
pNode
->
data
,
ref
);
}
}
}
else
{
// NOTE: once refcount is decrease, pNode may be freed by other thread immediately.
char
*
key
=
pNode
->
key
;
char
*
p
=
pNode
->
data
;
// int32_t ref = T_REF_VAL_GET(pNode);
//
// if (ref == 1 && inTrashcan) {
// // If it is the last ref, remove it from trashcan linked-list first, and then destroy it.Otherwise, it may be
// // destroyed by refresh worker if decrease ref count before removing it from linked-list.
// assert(pNode->pTNodeHeader->pData == pNode);
//
// __cache_wr_lock(pCacheObj);
// doRemoveElemInTrashcan(pCacheObj, pNode->pTNodeHeader);
// __cache_unlock(pCacheObj);
//
// ref = T_REF_DEC(pNode);
// assert(ref == 0);
//
// doDestroyTrashcanElem(pCacheObj, pNode->pTNodeHeader);
// } else {
// ref = T_REF_DEC(pNode);
// assert(ref >= 0);
// }
char
*
key
=
pNode
->
key
;
char
*
p
=
pNode
->
data
;
// int32_t ref = T_REF_VAL_GET(pNode);
//
// if (ref == 1 && inTrashcan) {
// // If it is the last ref, remove it from trashcan linked-list first, and then destroy it.Otherwise, it may
// be
// // destroyed by refresh worker if decrease ref count before removing it from linked-list.
// assert(pNode->pTNodeHeader->pData == pNode);
//
// __cache_wr_lock(pCacheObj);
// doRemoveElemInTrashcan(pCacheObj, pNode->pTNodeHeader);
// __cache_unlock(pCacheObj);
//
// ref = T_REF_DEC(pNode);
// assert(ref == 0);
//
// doDestroyTrashcanElem(pCacheObj, pNode->pTNodeHeader);
// } else {
// ref = T_REF_DEC(pNode);
// assert(ref >= 0);
// }
int32_t
ref
=
T_REF_DEC
(
pNode
);
uDebug
(
"cache:%s, key:%p, %p released, refcnt:%d, data in trashcan:%d"
,
pCacheObj
->
name
,
key
,
p
,
ref
,
inTrashcan
);
...
...
@@ -504,17 +510,17 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
}
typedef
struct
SHashTravSupp
{
SCacheObj
*
pCacheObj
;
SCacheObj
*
pCacheObj
;
int64_t
time
;
__cache_trav_fn_t
fp
;
void
*
param1
;
void
*
param1
;
}
SHashTravSupp
;
static
bool
travHashTableEmptyFn
(
void
*
param
,
void
*
data
)
{
SHashTravSupp
*
ps
=
(
SHashTravSupp
*
)
param
;
SCacheObj
*
pCacheObj
=
ps
->
pCacheObj
;
static
bool
travHashTableEmptyFn
(
void
*
param
,
void
*
data
)
{
SHashTravSupp
*
ps
=
(
SHashTravSupp
*
)
param
;
SCacheObj
*
pCacheObj
=
ps
->
pCacheObj
;
SCacheDataNode
*
pNode
=
*
(
SCacheDataNode
**
)
data
;
SCacheDataNode
*
pNode
=
*
(
SCacheDataNode
**
)
data
;
if
(
T_REF_VAL_GET
(
pNode
)
==
0
)
{
taosCacheReleaseNode
(
pCacheObj
,
pNode
);
...
...
@@ -529,7 +535,7 @@ static bool travHashTableEmptyFn(void* param, void* data) {
void
taosCacheEmpty
(
SCacheObj
*
pCacheObj
)
{
SHashTravSupp
sup
=
{.
pCacheObj
=
pCacheObj
,
.
fp
=
NULL
,
.
time
=
taosGetTimestampMs
()};
// taosHashCondTraverse(pCacheObj->pHashTable, travHashTableEmptyFn, &sup);
// taosHashCondTraverse(pCacheObj->pHashTable, travHashTableEmptyFn, &sup);
taosTrashcanEmpty
(
pCacheObj
,
false
);
}
...
...
@@ -542,7 +548,7 @@ void taosCacheCleanup(SCacheObj *pCacheObj) {
// wait for the refresh thread quit before destroying the cache object.
// But in the dll, the child thread will be killed before atexit takes effect.
while
(
atomic_load_8
(
&
pCacheObj
->
deleting
)
!=
0
)
{
while
(
atomic_load_8
(
&
pCacheObj
->
deleting
)
!=
0
)
{
if
(
refreshWorkerNormalStopped
)
break
;
if
(
refreshWorkerUnexpectedStopped
)
return
;
taosMsleep
(
50
);
...
...
@@ -610,16 +616,17 @@ void taosTrashcanEmpty(SCacheObj *pCacheObj, bool force) {
if
(
pCacheObj
->
numOfElemsInTrash
==
0
)
{
if
(
pCacheObj
->
pTrash
!=
NULL
)
{
pCacheObj
->
pTrash
=
NULL
;
uError
(
"cache:%s, key:inconsistency data in cache, numOfElem in trashcan:%d"
,
pCacheObj
->
name
,
pCacheObj
->
numOfElemsInTrash
);
uError
(
"cache:%s, key:inconsistency data in cache, numOfElem in trashcan:%d"
,
pCacheObj
->
name
,
pCacheObj
->
numOfElemsInTrash
);
}
__cache_unlock
(
pCacheObj
);
return
;
}
const
char
*
stat
[]
=
{
"false"
,
"true"
};
const
char
*
stat
[]
=
{
"false"
,
"true"
};
uDebug
(
"cache:%s start to cleanup trashcan, numOfElem in trashcan:%d, free:%s"
,
pCacheObj
->
name
,
pCacheObj
->
numOfElemsInTrash
,
(
force
?
stat
[
1
]
:
stat
[
0
]));
pCacheObj
->
numOfElemsInTrash
,
(
force
?
stat
[
1
]
:
stat
[
0
]));
STrashElem
*
pElem
=
pCacheObj
->
pTrash
;
while
(
pElem
)
{
...
...
@@ -627,8 +634,8 @@ void taosTrashcanEmpty(SCacheObj *pCacheObj, bool force) {
assert
(
pElem
->
next
!=
pElem
&&
pElem
->
prev
!=
pElem
);
if
(
force
||
(
T_REF_VAL_GET
(
pElem
->
pData
)
==
0
))
{
uDebug
(
"cache:%s, key:%p, %p removed from trashcan. numOfElem in trashcan:%d"
,
pCacheObj
->
name
,
pElem
->
pData
->
key
,
pElem
->
pData
->
data
,
pCacheObj
->
numOfElemsInTrash
-
1
);
uDebug
(
"cache:%s, key:%p, %p removed from trashcan. numOfElem in trashcan:%d"
,
pCacheObj
->
name
,
pElem
->
pData
->
key
,
p
Elem
->
pData
->
data
,
p
CacheObj
->
numOfElemsInTrash
-
1
);
doRemoveElemInTrashcan
(
pCacheObj
,
pElem
);
doDestroyTrashcanElem
(
pCacheObj
,
pElem
);
...
...
@@ -642,8 +649,8 @@ void taosTrashcanEmpty(SCacheObj *pCacheObj, bool force) {
}
void
doCleanupDataCache
(
SCacheObj
*
pCacheObj
)
{
// SHashTravSupp sup = {.pCacheObj = pCacheObj, .fp = NULL, .time = taosGetTimestampMs()};
// taosHashCondTraverse(pCacheObj->pHashTable, travHashTableEmptyFn, &sup);
// SHashTravSupp sup = {.pCacheObj = pCacheObj, .fp = NULL, .time = taosGetTimestampMs()};
// taosHashCondTraverse(pCacheObj->pHashTable, travHashTableEmptyFn, &sup);
// todo memory leak if there are object with refcount greater than 0 in hash table?
taosHashCleanup
(
pCacheObj
->
pHashTable
);
...
...
@@ -656,11 +663,11 @@ void doCleanupDataCache(SCacheObj *pCacheObj) {
free
(
pCacheObj
);
}
bool
travHashTableFn
(
void
*
param
,
void
*
data
)
{
SHashTravSupp
*
ps
=
(
SHashTravSupp
*
)
param
;
SCacheObj
*
pCacheObj
=
ps
->
pCacheObj
;
bool
travHashTableFn
(
void
*
param
,
void
*
data
)
{
SHashTravSupp
*
ps
=
(
SHashTravSupp
*
)
param
;
SCacheObj
*
pCacheObj
=
ps
->
pCacheObj
;
SCacheDataNode
*
pNode
=
*
(
SCacheDataNode
**
)
data
;
SCacheDataNode
*
pNode
=
*
(
SCacheDataNode
**
)
data
;
if
((
int64_t
)
pNode
->
expireTime
<
ps
->
time
&&
T_REF_VAL_GET
(
pNode
)
<=
0
)
{
taosCacheReleaseNode
(
pCacheObj
,
pNode
);
...
...
@@ -676,30 +683,30 @@ bool travHashTableFn(void* param, void* data) {
return
true
;
}
static
void
doCacheRefresh
(
SCacheObj
*
pCacheObj
,
int64_t
time
,
__cache_trav_fn_t
fp
,
void
*
param1
)
{
static
void
doCacheRefresh
(
SCacheObj
*
pCacheObj
,
int64_t
time
,
__cache_trav_fn_t
fp
,
void
*
param1
)
{
assert
(
pCacheObj
!=
NULL
);
SHashTravSupp
sup
=
{.
pCacheObj
=
pCacheObj
,
.
fp
=
fp
,
.
time
=
time
,
.
param1
=
param1
};
// taosHashCondTraverse(pCacheObj->pHashTable, travHashTableFn, &sup);
// taosHashCondTraverse(pCacheObj->pHashTable, travHashTableFn, &sup);
}
void
taosCacheRefreshWorkerUnexpectedStopped
(
void
)
{
if
(
!
refreshWorkerNormalStopped
)
{
refreshWorkerUnexpectedStopped
=
true
;
if
(
!
refreshWorkerNormalStopped
)
{
refreshWorkerUnexpectedStopped
=
true
;
}
}
void
*
taosCacheTimedRefresh
(
void
*
handle
)
{
void
*
taosCacheTimedRefresh
(
void
*
handle
)
{
assert
(
pCacheArrayList
!=
NULL
);
uDebug
(
"cache refresh thread starts"
);
setThreadName
(
"cacheRefresh"
);
const
int32_t
SLEEP_DURATION
=
500
;
//
500 ms
const
int32_t
SLEEP_DURATION
=
500
;
//
500 ms
int64_t
count
=
0
;
atexit
(
taosCacheRefreshWorkerUnexpectedStopped
);
while
(
1
)
{
while
(
1
)
{
taosMsleep
(
SLEEP_DURATION
);
if
(
stopRefreshWorker
)
{
goto
_end
;
...
...
@@ -711,9 +718,9 @@ void* taosCacheTimedRefresh(void *handle) {
count
+=
1
;
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
pthread_mutex_lock
(
&
guard
);
SCacheObj
*
pCacheObj
=
taosArrayGetP
(
pCacheArrayList
,
i
);
SCacheObj
*
pCacheObj
=
taosArrayGetP
(
pCacheArrayList
,
i
);
if
(
pCacheObj
==
NULL
)
{
uError
(
"object is destroyed. ignore and try next"
);
...
...
@@ -726,8 +733,8 @@ void* taosCacheTimedRefresh(void *handle) {
taosArrayRemove
(
pCacheArrayList
,
i
);
size
=
taosArrayGetSize
(
pCacheArrayList
);
uDebug
(
"%s is destroying, remove it from refresh list, remain cache obj:%"
PRIzu
,
pCacheObj
->
name
,
size
);
pCacheObj
->
deleting
=
0
;
//reset the deleting flag to enable pCacheObj to continue releasing resources.
uDebug
(
"%s is destroying, remove it from refresh list, remain cache obj:%"
PRIzu
,
pCacheObj
->
name
,
size
);
pCacheObj
->
deleting
=
0
;
//
reset the deleting flag to enable pCacheObj to continue releasing resources.
pthread_mutex_unlock
(
&
guard
);
continue
;
...
...
@@ -757,18 +764,18 @@ void* taosCacheTimedRefresh(void *handle) {
}
}
_end:
_end:
taosArrayDestroy
(
pCacheArrayList
);
pCacheArrayList
=
NULL
;
pthread_mutex_destroy
(
&
guard
);
refreshWorkerNormalStopped
=
true
;
refreshWorkerNormalStopped
=
true
;
uDebug
(
"cache refresh thread quits"
);
return
NULL
;
}
void
taosCacheRefresh
(
SCacheObj
*
pCacheObj
,
__cache_trav_fn_t
fp
,
void
*
param1
)
{
void
taosCacheRefresh
(
SCacheObj
*
pCacheObj
,
__cache_trav_fn_t
fp
,
void
*
param1
)
{
if
(
pCacheObj
==
NULL
)
{
return
;
}
...
...
@@ -777,6 +784,4 @@ void taosCacheRefresh(SCacheObj *pCacheObj, __cache_trav_fn_t fp, void* param1)
doCacheRefresh
(
pCacheObj
,
now
,
fp
,
param1
);
}
void
taosStopCacheRefreshWorker
(
void
)
{
stopRefreshWorker
=
true
;
}
\ No newline at end of file
void
taosStopCacheRefreshWorker
(
void
)
{
stopRefreshWorker
=
true
;
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录