Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
c4aa0be0
T
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1193
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看板
未验证
提交
c4aa0be0
编写于
2月 22, 2022
作者:
H
Haojun Liao
提交者:
GitHub
2月 22, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #8760 from haoyifan/hashtable_cleanup
Hashtable cleanup
上级
f882b496
79502cfe
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
461 addition
and
449 deletion
+461
-449
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+79
-75
src/util/inc/hash.h
src/util/inc/hash.h
+89
-70
src/util/inc/hashfunc.h
src/util/inc/hashfunc.h
+2
-0
src/util/src/hash.c
src/util/src/hash.c
+291
-304
未找到文件。
src/query/src/qExecutor.c
浏览文件 @
c4aa0be0
...
@@ -117,7 +117,7 @@ do { \
...
@@ -117,7 +117,7 @@ do { \
a = a + b; \
a = a + b; \
} \
} \
} \
} \
} while(0)
} while(0)
#define TSKEY_MIN_SUB(a,b) \
#define TSKEY_MIN_SUB(a,b) \
do { \
do { \
...
@@ -1332,7 +1332,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo,
...
@@ -1332,7 +1332,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo,
}
else
{
}
else
{
COPY_DATA
(
&
pCtx
[
k
].
start
.
val
,
(
char
*
)
pColInfo
->
pData
+
prevRowIndex
*
pColInfo
->
info
.
bytes
);
COPY_DATA
(
&
pCtx
[
k
].
start
.
val
,
(
char
*
)
pColInfo
->
pData
+
prevRowIndex
*
pColInfo
->
info
.
bytes
);
}
}
pCtx
[
k
].
start
.
key
=
prevTs
;
pCtx
[
k
].
start
.
key
=
prevTs
;
if
(
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_BINARY
||
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_NCHAR
)
{
if
(
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_BINARY
||
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_NCHAR
)
{
...
@@ -1349,7 +1349,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo,
...
@@ -1349,7 +1349,7 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo,
}
else
{
}
else
{
COPY_DATA
(
&
pCtx
[
k
].
end
.
val
,
(
char
*
)
pColInfo
->
pData
+
curRowIndex
*
pColInfo
->
info
.
bytes
);
COPY_DATA
(
&
pCtx
[
k
].
end
.
val
,
(
char
*
)
pColInfo
->
pData
+
curRowIndex
*
pColInfo
->
info
.
bytes
);
}
}
pCtx
[
k
].
end
.
key
=
curTs
;
pCtx
[
k
].
end
.
key
=
curTs
;
if
(
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_BINARY
||
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_NCHAR
)
{
if
(
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_BINARY
||
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_NCHAR
)
{
...
@@ -1364,9 +1364,9 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo,
...
@@ -1364,9 +1364,9 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo,
}
else
{
}
else
{
GET_TYPED_DATA
(
v1
,
double
,
pColInfo
->
info
.
type
,
(
char
*
)
pColInfo
->
pData
+
prevRowIndex
*
pColInfo
->
info
.
bytes
);
GET_TYPED_DATA
(
v1
,
double
,
pColInfo
->
info
.
type
,
(
char
*
)
pColInfo
->
pData
+
prevRowIndex
*
pColInfo
->
info
.
bytes
);
}
}
GET_TYPED_DATA
(
v2
,
double
,
pColInfo
->
info
.
type
,
(
char
*
)
pColInfo
->
pData
+
curRowIndex
*
pColInfo
->
info
.
bytes
);
GET_TYPED_DATA
(
v2
,
double
,
pColInfo
->
info
.
type
,
(
char
*
)
pColInfo
->
pData
+
curRowIndex
*
pColInfo
->
info
.
bytes
);
SPoint
point1
=
(
SPoint
){.
key
=
prevTs
,
.
val
=
&
v1
};
SPoint
point1
=
(
SPoint
){.
key
=
prevTs
,
.
val
=
&
v1
};
SPoint
point2
=
(
SPoint
){.
key
=
curTs
,
.
val
=
&
v2
};
SPoint
point2
=
(
SPoint
){.
key
=
curTs
,
.
val
=
&
v2
};
SPoint
point
=
(
SPoint
){.
key
=
windowKey
,
.
val
=
&
v
};
SPoint
point
=
(
SPoint
){.
key
=
windowKey
,
.
val
=
&
v
};
...
@@ -2235,6 +2235,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
...
@@ -2235,6 +2235,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
if
(
pRuntimeEnv
->
proot
==
NULL
)
{
if
(
pRuntimeEnv
->
proot
==
NULL
)
{
goto
_clean
;
goto
_clean
;
}
}
int32_t
opType
=
pRuntimeEnv
->
proot
->
upstream
[
0
]
->
operatorType
;
int32_t
opType
=
pRuntimeEnv
->
proot
->
upstream
[
0
]
->
operatorType
;
if
(
opType
!=
OP_DummyInput
)
{
if
(
opType
!=
OP_DummyInput
)
{
setTableScanFilterOperatorInfo
(
pRuntimeEnv
->
proot
->
upstream
[
0
]
->
info
,
pRuntimeEnv
->
proot
);
setTableScanFilterOperatorInfo
(
pRuntimeEnv
->
proot
->
upstream
[
0
]
->
info
,
pRuntimeEnv
->
proot
);
...
@@ -2397,7 +2398,7 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -2397,7 +2398,7 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
if
(
!
pRuntimeEnv
->
udfIsCopy
)
{
if
(
!
pRuntimeEnv
->
udfIsCopy
)
{
destroyUdfInfo
(
pRuntimeEnv
->
pUdfInfo
);
destroyUdfInfo
(
pRuntimeEnv
->
pUdfInfo
);
}
}
destroyResultBuf
(
pRuntimeEnv
->
pResultBuf
);
destroyResultBuf
(
pRuntimeEnv
->
pResultBuf
);
doFreeQueryHandle
(
pRuntimeEnv
);
doFreeQueryHandle
(
pRuntimeEnv
);
...
@@ -3007,7 +3008,7 @@ void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInf
...
@@ -3007,7 +3008,7 @@ void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInf
if
(
i
<
(
numOfRows
-
1
))
{
if
(
i
<
(
numOfRows
-
1
))
{
all
=
false
;
all
=
false
;
}
}
break
;
break
;
}
}
}
}
...
@@ -3032,9 +3033,9 @@ void filterColRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock
...
@@ -3032,9 +3033,9 @@ void filterColRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock
bool
all
=
true
;
bool
all
=
true
;
if
(
pRuntimeEnv
->
pTsBuf
!=
NULL
)
{
if
(
pRuntimeEnv
->
pTsBuf
!=
NULL
)
{
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
0
);
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
0
);
p
=
calloc
(
numOfRows
,
sizeof
(
int8_t
));
p
=
calloc
(
numOfRows
,
sizeof
(
int8_t
));
TSKEY
*
k
=
(
TSKEY
*
)
pColInfoData
->
pData
;
TSKEY
*
k
=
(
TSKEY
*
)
pColInfoData
->
pData
;
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
int32_t
offset
=
ascQuery
?
i
:
(
numOfRows
-
i
-
1
);
int32_t
offset
=
ascQuery
?
i
:
(
numOfRows
-
i
-
1
);
...
@@ -3049,7 +3050,7 @@ void filterColRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock
...
@@ -3049,7 +3050,7 @@ void filterColRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock
p
[
offset
]
=
true
;
p
[
offset
]
=
true
;
}
}
if
(
!
tsBufNextPos
(
pRuntimeEnv
->
pTsBuf
))
{
if
(
!
tsBufNextPos
(
pRuntimeEnv
->
pTsBuf
))
{
if
(
i
<
(
numOfRows
-
1
))
{
if
(
i
<
(
numOfRows
-
1
))
{
all
=
false
;
all
=
false
;
}
}
...
@@ -3057,7 +3058,7 @@ void filterColRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock
...
@@ -3057,7 +3058,7 @@ void filterColRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock
break
;
break
;
}
}
}
}
// save the cursor status
// save the cursor status
pRuntimeEnv
->
current
->
cur
=
tsBufGetCursor
(
pRuntimeEnv
->
pTsBuf
);
pRuntimeEnv
->
current
->
cur
=
tsBufGetCursor
(
pRuntimeEnv
->
pTsBuf
);
}
else
{
}
else
{
...
@@ -3076,7 +3077,7 @@ void filterColRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock
...
@@ -3076,7 +3077,7 @@ void filterColRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSDataBlock* pBlock
tfree
(
p
);
tfree
(
p
);
}
}
static
SColumnInfo
*
doGetTagColumnInfoById
(
SColumnInfo
*
pTagColList
,
int32_t
numOfTags
,
int16_t
colId
);
static
SColumnInfo
*
doGetTagColumnInfoById
(
SColumnInfo
*
pTagColList
,
int32_t
numOfTags
,
int16_t
colId
);
static
void
doSetTagValueInParam
(
void
*
pTable
,
char
*
param
,
int32_t
paraLen
,
int32_t
tagColId
,
tVariant
*
tag
,
int16_t
type
,
int16_t
bytes
);
static
void
doSetTagValueInParam
(
void
*
pTable
,
char
*
param
,
int32_t
paraLen
,
int32_t
tagColId
,
tVariant
*
tag
,
int16_t
type
,
int16_t
bytes
);
...
@@ -3122,7 +3123,7 @@ void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFi
...
@@ -3122,7 +3123,7 @@ void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFi
FORCE_INLINE
int32_t
getColumnDataFromId
(
void
*
param
,
int32_t
id
,
void
**
data
)
{
FORCE_INLINE
int32_t
getColumnDataFromId
(
void
*
param
,
int32_t
id
,
void
**
data
)
{
int32_t
numOfCols
=
((
SColumnDataParam
*
)
param
)
->
numOfCols
;
int32_t
numOfCols
=
((
SColumnDataParam
*
)
param
)
->
numOfCols
;
SArray
*
pDataBlock
=
((
SColumnDataParam
*
)
param
)
->
pDataBlock
;
SArray
*
pDataBlock
=
((
SColumnDataParam
*
)
param
)
->
pDataBlock
;
for
(
int32_t
j
=
0
;
j
<
numOfCols
;
++
j
)
{
for
(
int32_t
j
=
0
;
j
<
numOfCols
;
++
j
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pDataBlock
,
j
);
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pDataBlock
,
j
);
if
(
id
==
pColInfo
->
info
.
colId
)
{
if
(
id
==
pColInfo
->
info
.
colId
)
{
...
@@ -3283,7 +3284,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa
...
@@ -3283,7 +3284,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa
SColumnDataParam
param
=
{.
numOfCols
=
pBlock
->
info
.
numOfCols
,
.
pDataBlock
=
pBlock
->
pDataBlock
};
SColumnDataParam
param
=
{.
numOfCols
=
pBlock
->
info
.
numOfCols
,
.
pDataBlock
=
pBlock
->
pDataBlock
};
filterSetColFieldData
(
pQueryAttr
->
pFilters
,
&
param
,
getColumnDataFromId
);
filterSetColFieldData
(
pQueryAttr
->
pFilters
,
&
param
,
getColumnDataFromId
);
}
}
if
(
pQueryAttr
->
pFilters
!=
NULL
||
pRuntimeEnv
->
pTsBuf
!=
NULL
)
{
if
(
pQueryAttr
->
pFilters
!=
NULL
||
pRuntimeEnv
->
pTsBuf
!=
NULL
)
{
filterColRowsInDataBlock
(
pRuntimeEnv
,
pBlock
,
ascQuery
);
filterColRowsInDataBlock
(
pRuntimeEnv
,
pBlock
,
ascQuery
);
}
}
...
@@ -3445,7 +3446,7 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt
...
@@ -3445,7 +3446,7 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt
}
else
{
}
else
{
if
(
pCtx
[
idx
].
tag
.
pz
!=
NULL
)
{
if
(
pCtx
[
idx
].
tag
.
pz
!=
NULL
)
{
memcpy
(
pRuntimeEnv
->
tagVal
+
offset
,
pCtx
[
idx
].
tag
.
pz
,
pCtx
[
idx
].
tag
.
nLen
);
memcpy
(
pRuntimeEnv
->
tagVal
+
offset
,
pCtx
[
idx
].
tag
.
pz
,
pCtx
[
idx
].
tag
.
nLen
);
}
}
}
}
offset
+=
pLocalExprInfo
->
base
.
resBytes
;
offset
+=
pLocalExprInfo
->
base
.
resBytes
;
...
@@ -4283,13 +4284,13 @@ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow* winx, int
...
@@ -4283,13 +4284,13 @@ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow* winx, int
}
}
TSKEY
key
=
QUERY_IS_ASC_QUERY
(
pQueryAttr
)
?
winx
->
skey
:
winx
->
ekey
;
TSKEY
key
=
QUERY_IS_ASC_QUERY
(
pQueryAttr
)
?
winx
->
skey
:
winx
->
ekey
;
qDebug
(
"0x%"
PRIx64
" update query window, tid:%d, %"
PRId64
" - %"
PRId64
", old:%"
PRId64
" - %"
PRId64
,
GET_QID
(
pRuntimeEnv
),
tid
,
key
,
pTableQueryInfo
->
win
.
ekey
,
qDebug
(
"0x%"
PRIx64
" update query window, tid:%d, %"
PRId64
" - %"
PRId64
", old:%"
PRId64
" - %"
PRId64
,
GET_QID
(
pRuntimeEnv
),
tid
,
key
,
pTableQueryInfo
->
win
.
ekey
,
pTableQueryInfo
->
win
.
skey
,
pTableQueryInfo
->
win
.
ekey
);
pTableQueryInfo
->
win
.
skey
,
pTableQueryInfo
->
win
.
ekey
);
pTableQueryInfo
->
win
.
skey
=
key
;
pTableQueryInfo
->
win
.
skey
=
key
;
STimeWindow
win
=
{.
skey
=
key
,
.
ekey
=
pQueryAttr
->
window
.
ekey
};
STimeWindow
win
=
{.
skey
=
key
,
.
ekey
=
pQueryAttr
->
window
.
ekey
};
/**
/**
* In handling the both ascending and descending order super table query, we need to find the first qualified
* In handling the both ascending and descending order super table query, we need to find the first qualified
* timestamp of this table, and then set the first qualified start timestamp.
* timestamp of this table, and then set the first qualified start timestamp.
...
@@ -4905,7 +4906,7 @@ static int32_t setupQueryHandle(void* tsdb, SQueryRuntimeEnv* pRuntimeEnv, int64
...
@@ -4905,7 +4906,7 @@ static int32_t setupQueryHandle(void* tsdb, SQueryRuntimeEnv* pRuntimeEnv, int64
STsdbQueryCond
cond
=
createTsdbQueryCond
(
pQueryAttr
,
&
pQueryAttr
->
window
);
STsdbQueryCond
cond
=
createTsdbQueryCond
(
pQueryAttr
,
&
pQueryAttr
->
window
);
if
(
pQueryAttr
->
tsCompQuery
||
pQueryAttr
->
pointInterpQuery
)
{
if
(
pQueryAttr
->
tsCompQuery
||
pQueryAttr
->
pointInterpQuery
)
{
cond
.
type
=
BLOCK_LOAD_TABLE_SEQ_ORDER
;
cond
.
type
=
BLOCK_LOAD_TABLE_SEQ_ORDER
;
}
}
if
(
!
isSTableQuery
if
(
!
isSTableQuery
...
@@ -5046,7 +5047,7 @@ int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, void* tsdb, void* sourceOptr
...
@@ -5046,7 +5047,7 @@ int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, void* tsdb, void* sourceOptr
int16_t
order
=
(
pQueryAttr
->
order
.
order
==
pRuntimeEnv
->
pTsBuf
->
tsOrder
)
?
TSDB_ORDER_ASC
:
TSDB_ORDER_DESC
;
int16_t
order
=
(
pQueryAttr
->
order
.
order
==
pRuntimeEnv
->
pTsBuf
->
tsOrder
)
?
TSDB_ORDER_ASC
:
TSDB_ORDER_DESC
;
tsBufResetPos
(
pRuntimeEnv
->
pTsBuf
);
tsBufResetPos
(
pRuntimeEnv
->
pTsBuf
);
tsBufSetTraverseOrder
(
pRuntimeEnv
->
pTsBuf
,
order
);
tsBufSetTraverseOrder
(
pRuntimeEnv
->
pTsBuf
,
order
);
tsBufNextPos
(
pTsBuf
);
tsBufNextPos
(
pTsBuf
);
}
}
int32_t
ps
=
DEFAULT_PAGE_SIZE
;
int32_t
ps
=
DEFAULT_PAGE_SIZE
;
...
@@ -5467,7 +5468,7 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf
...
@@ -5467,7 +5468,7 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf
pTableScanInfo
->
rowCellInfoOffset
=
pIntervalInfo
->
rowCellInfoOffset
;
pTableScanInfo
->
rowCellInfoOffset
=
pIntervalInfo
->
rowCellInfoOffset
;
}
else
if
(
pDownstream
->
operatorType
==
OP_TimeEvery
)
{
}
else
if
(
pDownstream
->
operatorType
==
OP_TimeEvery
)
{
STimeEveryOperatorInfo
*
pEveryInfo
=
pDownstream
->
info
;
STimeEveryOperatorInfo
*
pEveryInfo
=
pDownstream
->
info
;
pTableScanInfo
->
pCtx
=
pEveryInfo
->
binfo
.
pCtx
;
pTableScanInfo
->
pCtx
=
pEveryInfo
->
binfo
.
pCtx
;
pTableScanInfo
->
pResultRowInfo
=
&
pEveryInfo
->
binfo
.
resultRowInfo
;
pTableScanInfo
->
pResultRowInfo
=
&
pEveryInfo
->
binfo
.
resultRowInfo
;
pTableScanInfo
->
rowCellInfoOffset
=
pEveryInfo
->
binfo
.
rowCellInfoOffset
;
pTableScanInfo
->
rowCellInfoOffset
=
pEveryInfo
->
binfo
.
rowCellInfoOffset
;
...
@@ -5525,7 +5526,7 @@ SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntime
...
@@ -5525,7 +5526,7 @@ SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntime
if
(
pRuntimeEnv
->
pQueryAttr
->
pointInterpQuery
)
{
if
(
pRuntimeEnv
->
pQueryAttr
->
pointInterpQuery
)
{
pRuntimeEnv
->
enableGroupData
=
true
;
pRuntimeEnv
->
enableGroupData
=
true
;
}
}
SOperatorInfo
*
pOptr
=
calloc
(
1
,
sizeof
(
SOperatorInfo
));
SOperatorInfo
*
pOptr
=
calloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
pOptr
==
NULL
)
{
if
(
pOptr
==
NULL
)
{
tfree
(
pInfo
);
tfree
(
pInfo
);
...
@@ -5873,7 +5874,7 @@ static SSDataBlock* doSort(void* param, bool* newgroup) {
...
@@ -5873,7 +5874,7 @@ static SSDataBlock* doSort(void* param, bool* newgroup) {
if
(
pInfo
->
pDataBlock
->
info
.
rows
)
{
if
(
pInfo
->
pDataBlock
->
info
.
rows
)
{
taoscQSort
(
pCols
,
pSchema
,
numOfCols
,
pInfo
->
pDataBlock
->
info
.
rows
,
pInfo
->
colIndex
,
comp
);
taoscQSort
(
pCols
,
pSchema
,
numOfCols
,
pInfo
->
pDataBlock
->
info
.
rows
,
pInfo
->
colIndex
,
comp
);
}
}
tfree
(
pCols
);
tfree
(
pCols
);
tfree
(
pSchema
);
tfree
(
pSchema
);
return
(
pInfo
->
pDataBlock
->
info
.
rows
>
0
)
?
pInfo
->
pDataBlock
:
NULL
;
return
(
pInfo
->
pDataBlock
->
info
.
rows
>
0
)
?
pInfo
->
pDataBlock
:
NULL
;
...
@@ -6057,7 +6058,7 @@ static SSDataBlock* doSTableAggregate(void* param, bool* newgroup) {
...
@@ -6057,7 +6058,7 @@ static SSDataBlock* doSTableAggregate(void* param, bool* newgroup) {
key
=
pBlock
->
info
.
window
.
skey
;
key
=
pBlock
->
info
.
window
.
skey
;
TSKEY_MIN_SUB
(
key
,
-
1
);
TSKEY_MIN_SUB
(
key
,
-
1
);
}
}
setExecutionContext
(
pRuntimeEnv
,
pInfo
,
pOperator
->
numOfOutput
,
pRuntimeEnv
->
current
->
groupIndex
,
key
);
setExecutionContext
(
pRuntimeEnv
,
pInfo
,
pOperator
->
numOfOutput
,
pRuntimeEnv
->
current
->
groupIndex
,
key
);
doAggregateImpl
(
pOperator
,
pQueryAttr
->
window
.
skey
,
pInfo
->
pCtx
,
pBlock
);
doAggregateImpl
(
pOperator
,
pQueryAttr
->
window
.
skey
,
pInfo
->
pCtx
,
pBlock
);
}
}
...
@@ -6354,7 +6355,7 @@ static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) {
...
@@ -6354,7 +6355,7 @@ static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) {
if
(
pIntervalInfo
->
resultRowInfo
.
size
>
0
&&
pQueryAttr
->
needSort
)
{
if
(
pIntervalInfo
->
resultRowInfo
.
size
>
0
&&
pQueryAttr
->
needSort
)
{
qsort
(
pIntervalInfo
->
resultRowInfo
.
pResult
,
pIntervalInfo
->
resultRowInfo
.
size
,
POINTER_BYTES
,
resRowCompare
);
qsort
(
pIntervalInfo
->
resultRowInfo
.
pResult
,
pIntervalInfo
->
resultRowInfo
.
size
,
POINTER_BYTES
,
resRowCompare
);
}
}
closeAllResultRows
(
&
pIntervalInfo
->
resultRowInfo
);
closeAllResultRows
(
&
pIntervalInfo
->
resultRowInfo
);
setQueryStatus
(
pRuntimeEnv
,
QUERY_COMPLETED
);
setQueryStatus
(
pRuntimeEnv
,
QUERY_COMPLETED
);
finalizeQueryResult
(
pOperator
,
pIntervalInfo
->
pCtx
,
&
pIntervalInfo
->
resultRowInfo
,
pIntervalInfo
->
rowCellInfoOffset
);
finalizeQueryResult
(
pOperator
,
pIntervalInfo
->
pCtx
,
&
pIntervalInfo
->
resultRowInfo
,
pIntervalInfo
->
rowCellInfoOffset
);
...
@@ -6383,7 +6384,7 @@ static void everyApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *p
...
@@ -6383,7 +6384,7 @@ static void everyApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *p
static
int64_t
getEveryStartTs
(
bool
ascQuery
,
STimeWindow
*
range
,
STimeWindow
*
blockWin
,
SQueryAttr
*
pQueryAttr
)
{
static
int64_t
getEveryStartTs
(
bool
ascQuery
,
STimeWindow
*
range
,
STimeWindow
*
blockWin
,
SQueryAttr
*
pQueryAttr
)
{
int64_t
startTs
=
range
->
skey
,
ekey
=
0
;
int64_t
startTs
=
range
->
skey
,
ekey
=
0
;
assert
(
range
->
skey
!=
INT64_MIN
);
assert
(
range
->
skey
!=
INT64_MIN
);
if
(
ascQuery
)
{
if
(
ascQuery
)
{
...
@@ -6421,15 +6422,15 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
...
@@ -6421,15 +6422,15 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
SQLFunctionCtx
*
pCtx
=
NULL
;
SQLFunctionCtx
*
pCtx
=
NULL
;
*
needApply
=
false
;
*
needApply
=
false
;
if
(
!
pQueryAttr
->
pointInterpQuery
)
{
if
(
!
pQueryAttr
->
pointInterpQuery
)
{
goto
group_finished_exit
;
goto
group_finished_exit
;
}
}
assert
(
pOperatorInfo
->
numOfOutput
>
1
);
assert
(
pOperatorInfo
->
numOfOutput
>
1
);
for
(
int32_t
i
=
1
;
i
<
pOperatorInfo
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
1
;
i
<
pOperatorInfo
->
numOfOutput
;
++
i
)
{
assert
(
pEveryInfo
->
binfo
.
pCtx
[
i
].
functionId
==
TSDB_FUNC_INTERP
assert
(
pEveryInfo
->
binfo
.
pCtx
[
i
].
functionId
==
TSDB_FUNC_INTERP
||
pEveryInfo
->
binfo
.
pCtx
[
i
].
functionId
==
TSDB_FUNC_TS_DUMMY
||
pEveryInfo
->
binfo
.
pCtx
[
i
].
functionId
==
TSDB_FUNC_TS_DUMMY
||
pEveryInfo
->
binfo
.
pCtx
[
i
].
functionId
==
TSDB_FUNC_TAG
||
pEveryInfo
->
binfo
.
pCtx
[
i
].
functionId
==
TSDB_FUNC_TAG
||
pEveryInfo
->
binfo
.
pCtx
[
i
].
functionId
==
TSDB_FUNC_TAG_DUMMY
);
||
pEveryInfo
->
binfo
.
pCtx
[
i
].
functionId
==
TSDB_FUNC_TAG_DUMMY
);
...
@@ -6439,7 +6440,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
...
@@ -6439,7 +6440,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
break
;
break
;
}
}
}
}
TSKEY
*
tsCols
=
NULL
;
TSKEY
*
tsCols
=
NULL
;
if
(
pBlock
&&
pBlock
->
pDataBlock
!=
NULL
)
{
if
(
pBlock
&&
pBlock
->
pDataBlock
!=
NULL
)
{
SColumnInfoData
*
pColDataInfo
=
taosArrayGet
(
pBlock
->
pDataBlock
,
0
);
SColumnInfoData
*
pColDataInfo
=
taosArrayGet
(
pBlock
->
pDataBlock
,
0
);
...
@@ -6449,7 +6450,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
...
@@ -6449,7 +6450,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
if
(
pCtx
->
startTs
==
INT64_MIN
)
{
if
(
pCtx
->
startTs
==
INT64_MIN
)
{
if
(
pQueryAttr
->
range
.
skey
==
INT64_MIN
)
{
if
(
pQueryAttr
->
range
.
skey
==
INT64_MIN
)
{
if
(
NULL
==
tsCols
)
{
if
(
NULL
==
tsCols
)
{
goto
group_finished_exit
;
goto
group_finished_exit
;
}
}
...
@@ -6488,12 +6489,12 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
...
@@ -6488,12 +6489,12 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
}
else
{
}
else
{
pCtx
->
startTs
=
ascQuery
?
pCtx
->
startTs
+
pQueryAttr
->
interval
.
interval
:
pCtx
->
startTs
-
pQueryAttr
->
interval
.
interval
;
pCtx
->
startTs
=
ascQuery
?
pCtx
->
startTs
+
pQueryAttr
->
interval
.
interval
:
pCtx
->
startTs
-
pQueryAttr
->
interval
.
interval
;
}
}
if
(
ascQuery
&&
pQueryAttr
->
range
.
ekey
!=
INT64_MIN
&&
pCtx
->
startTs
>
pQueryAttr
->
range
.
ekey
)
{
if
(
ascQuery
&&
pQueryAttr
->
range
.
ekey
!=
INT64_MIN
&&
pCtx
->
startTs
>
pQueryAttr
->
range
.
ekey
)
{
goto
group_finished_exit
;
goto
group_finished_exit
;
}
}
if
((
!
ascQuery
)
&&
pQueryAttr
->
range
.
skey
!=
INT64_MIN
&&
pCtx
->
startTs
<
pQueryAttr
->
range
.
skey
)
{
if
((
!
ascQuery
)
&&
pQueryAttr
->
range
.
skey
!=
INT64_MIN
&&
pCtx
->
startTs
<
pQueryAttr
->
range
.
skey
)
{
goto
group_finished_exit
;
goto
group_finished_exit
;
}
}
}
else
{
}
else
{
...
@@ -6507,8 +6508,8 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
...
@@ -6507,8 +6508,8 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
if
((
ascQuery
&&
pQueryAttr
->
range
.
ekey
==
INT64_MIN
)
||
((
!
ascQuery
)
&&
pQueryAttr
->
range
.
skey
==
INT64_MIN
))
{
if
((
ascQuery
&&
pQueryAttr
->
range
.
ekey
==
INT64_MIN
)
||
((
!
ascQuery
)
&&
pQueryAttr
->
range
.
skey
==
INT64_MIN
))
{
goto
group_finished_exit
;
goto
group_finished_exit
;
}
}
if
(
pQueryAttr
->
fillType
==
TSDB_FILL_NONE
||
pQueryAttr
->
fillType
==
TSDB_FILL_LINEAR
if
(
pQueryAttr
->
fillType
==
TSDB_FILL_NONE
||
pQueryAttr
->
fillType
==
TSDB_FILL_LINEAR
||
((
ascQuery
&&
pQueryAttr
->
fillType
==
TSDB_FILL_NEXT
)
||
((
!
ascQuery
)
&&
pQueryAttr
->
fillType
==
TSDB_FILL_PREV
)))
{
||
((
ascQuery
&&
pQueryAttr
->
fillType
==
TSDB_FILL_NEXT
)
||
((
!
ascQuery
)
&&
pQueryAttr
->
fillType
==
TSDB_FILL_PREV
)))
{
goto
group_finished_exit
;
goto
group_finished_exit
;
}
}
...
@@ -6530,11 +6531,11 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
...
@@ -6530,11 +6531,11 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
}
}
*
needApply
=
true
;
*
needApply
=
true
;
for
(
int32_t
i
=
0
;
i
<
pOperatorInfo
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pOperatorInfo
->
numOfOutput
;
++
i
)
{
pEveryInfo
->
binfo
.
pCtx
[
i
].
startTs
=
pCtx
->
startTs
;
pEveryInfo
->
binfo
.
pCtx
[
i
].
startTs
=
pCtx
->
startTs
;
}
}
return
false
;
return
false
;
}
}
...
@@ -6557,14 +6558,14 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
...
@@ -6557,14 +6558,14 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
}
else
{
}
else
{
if
(
tsCols
[
startPos
]
==
pCtx
->
startTs
)
{
if
(
tsCols
[
startPos
]
==
pCtx
->
startTs
)
{
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
pCtx
->
startTs
,
startPos
,
INT64_MIN
,
0
,
0
,
RESULT_ROW_START_INTERP
);
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
pCtx
->
startTs
,
startPos
,
INT64_MIN
,
0
,
0
,
RESULT_ROW_START_INTERP
);
}
else
{
}
else
{
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
tsCols
[
startPos
-
1
],
startPos
-
1
,
INT64_MIN
,
0
,
0
,
RESULT_ROW_START_INTERP
);
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
tsCols
[
startPos
-
1
],
startPos
-
1
,
INT64_MIN
,
0
,
0
,
RESULT_ROW_START_INTERP
);
}
}
}
}
if
(
pQueryAttr
->
fillType
!=
TSDB_FILL_LINEAR
)
{
if
(
pQueryAttr
->
fillType
!=
TSDB_FILL_LINEAR
)
{
*
needApply
=
true
;
*
needApply
=
true
;
}
}
}
}
if
((
!
ascQuery
)
&&
(
pQueryAttr
->
fillType
==
TSDB_FILL_LINEAR
||
pQueryAttr
->
fillType
==
TSDB_FILL_NEXT
)
&&
pCtx
->
end
.
key
==
INT64_MIN
)
{
if
((
!
ascQuery
)
&&
(
pQueryAttr
->
fillType
==
TSDB_FILL_LINEAR
||
pQueryAttr
->
fillType
==
TSDB_FILL_NEXT
)
&&
pCtx
->
end
.
key
==
INT64_MIN
)
{
...
@@ -6574,7 +6575,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
...
@@ -6574,7 +6575,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
}
else
if
(
startPos
==
(
pBlock
->
info
.
rows
-
1
))
{
}
else
if
(
startPos
==
(
pBlock
->
info
.
rows
-
1
))
{
if
(
tsCols
[
startPos
]
==
pCtx
->
startTs
)
{
if
(
tsCols
[
startPos
]
==
pCtx
->
startTs
)
{
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
INT64_MIN
,
0
,
pCtx
->
startTs
,
startPos
,
0
,
RESULT_ROW_END_INTERP
);
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
INT64_MIN
,
0
,
pCtx
->
startTs
,
startPos
,
0
,
RESULT_ROW_END_INTERP
);
}
else
{
}
else
{
TSKEY
lastTs
=
*
(
TSKEY
*
)
pRuntimeEnv
->
prevRow
[
0
];
TSKEY
lastTs
=
*
(
TSKEY
*
)
pRuntimeEnv
->
prevRow
[
0
];
if
(
lastTs
!=
INT64_MIN
)
{
if
(
lastTs
!=
INT64_MIN
)
{
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
INT64_MIN
,
0
,
lastTs
,
-
1
,
0
,
RESULT_ROW_END_INTERP
);
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
INT64_MIN
,
0
,
lastTs
,
-
1
,
0
,
RESULT_ROW_END_INTERP
);
...
@@ -6587,17 +6588,17 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
...
@@ -6587,17 +6588,17 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
INT64_MIN
,
0
,
tsCols
[
startPos
+
1
],
startPos
+
1
,
0
,
RESULT_ROW_END_INTERP
);
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
INT64_MIN
,
0
,
tsCols
[
startPos
+
1
],
startPos
+
1
,
0
,
RESULT_ROW_END_INTERP
);
}
}
}
}
if
(
pQueryAttr
->
fillType
!=
TSDB_FILL_LINEAR
)
{
if
(
pQueryAttr
->
fillType
!=
TSDB_FILL_LINEAR
)
{
*
needApply
=
true
;
*
needApply
=
true
;
}
}
}
}
if
(
ascQuery
&&
(
pQueryAttr
->
fillType
==
TSDB_FILL_LINEAR
||
pQueryAttr
->
fillType
==
TSDB_FILL_NEXT
)
&&
pCtx
->
end
.
key
==
INT64_MIN
)
{
if
(
ascQuery
&&
(
pQueryAttr
->
fillType
==
TSDB_FILL_LINEAR
||
pQueryAttr
->
fillType
==
TSDB_FILL_NEXT
)
&&
pCtx
->
end
.
key
==
INT64_MIN
)
{
if
(
startPos
<
0
)
{
if
(
startPos
<
0
)
{
return
true
;
return
true
;
}
}
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
INT64_MIN
,
0
,
tsCols
[
startPos
],
startPos
,
0
,
RESULT_ROW_END_INTERP
);
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
INT64_MIN
,
0
,
tsCols
[
startPos
],
startPos
,
0
,
RESULT_ROW_END_INTERP
);
*
needApply
=
true
;
*
needApply
=
true
;
...
@@ -6607,7 +6608,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
...
@@ -6607,7 +6608,7 @@ static bool doEveryInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlo
if
(
startPos
<
0
)
{
if
(
startPos
<
0
)
{
return
true
;
return
true
;
}
}
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
tsCols
[
startPos
],
startPos
,
INT64_MIN
,
0
,
0
,
RESULT_ROW_START_INTERP
);
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pBlock
->
pDataBlock
,
tsCols
[
startPos
],
startPos
,
INT64_MIN
,
0
,
0
,
RESULT_ROW_START_INTERP
);
*
needApply
=
true
;
*
needApply
=
true
;
...
@@ -6628,7 +6629,7 @@ group_finished_exit:
...
@@ -6628,7 +6629,7 @@ group_finished_exit:
if
(
pQueryAttr
->
needReverseScan
)
{
if
(
pQueryAttr
->
needReverseScan
)
{
pQueryAttr
->
range
.
skey
=
INT64_MIN
;
pQueryAttr
->
range
.
skey
=
INT64_MIN
;
}
}
pEveryInfo
->
groupDone
=
true
;
pEveryInfo
->
groupDone
=
true
;
if
(
pCtx
)
{
if
(
pCtx
)
{
...
@@ -6636,7 +6637,7 @@ group_finished_exit:
...
@@ -6636,7 +6637,7 @@ group_finished_exit:
pCtx
->
start
.
key
=
INT64_MIN
;
pCtx
->
start
.
key
=
INT64_MIN
;
pCtx
->
end
.
key
=
INT64_MIN
;
pCtx
->
end
.
key
=
INT64_MIN
;
}
}
return
true
;
return
true
;
}
}
...
@@ -6671,7 +6672,7 @@ static void doTimeEveryImpl(SOperatorInfo* pOperator, SQLFunctionCtx *pCtx, SSDa
...
@@ -6671,7 +6672,7 @@ static void doTimeEveryImpl(SOperatorInfo* pOperator, SQLFunctionCtx *pCtx, SSDa
setQueryStatus
(
pRuntimeEnv
,
QUERY_COMPLETED
);
setQueryStatus
(
pRuntimeEnv
,
QUERY_COMPLETED
);
return
;
return
;
}
}
tsCols
=
(
int64_t
*
)
pColDataInfo
->
pData
;
tsCols
=
(
int64_t
*
)
pColDataInfo
->
pData
;
assert
(
tsCols
[
0
]
==
pBlock
->
info
.
window
.
skey
&&
assert
(
tsCols
[
0
]
==
pBlock
->
info
.
window
.
skey
&&
tsCols
[
pBlock
->
info
.
rows
-
1
]
==
pBlock
->
info
.
window
.
ekey
);
tsCols
[
pBlock
->
info
.
rows
-
1
]
==
pBlock
->
info
.
window
.
ekey
);
...
@@ -6685,7 +6686,7 @@ static void doTimeEveryImpl(SOperatorInfo* pOperator, SQLFunctionCtx *pCtx, SSDa
...
@@ -6685,7 +6686,7 @@ static void doTimeEveryImpl(SOperatorInfo* pOperator, SQLFunctionCtx *pCtx, SSDa
if
(
needApply
)
{
if
(
needApply
)
{
everyApplyFunctions
(
pRuntimeEnv
,
pEveryInfo
->
binfo
.
pCtx
,
numOfOutput
);
everyApplyFunctions
(
pRuntimeEnv
,
pEveryInfo
->
binfo
.
pCtx
,
numOfOutput
);
pRes
->
info
.
rows
=
getNumOfResult
(
pRuntimeEnv
,
pEveryInfo
->
binfo
.
pCtx
,
pOperator
->
numOfOutput
);
pRes
->
info
.
rows
=
getNumOfResult
(
pRuntimeEnv
,
pEveryInfo
->
binfo
.
pCtx
,
pOperator
->
numOfOutput
);
if
(
pRes
->
info
.
rows
>=
pRuntimeEnv
->
resultInfo
.
threshold
)
{
if
(
pRes
->
info
.
rows
>=
pRuntimeEnv
->
resultInfo
.
threshold
)
{
pEveryInfo
->
lastBlock
=
pBlock
;
pEveryInfo
->
lastBlock
=
pBlock
;
...
@@ -6719,8 +6720,8 @@ static SSDataBlock* doTimeEvery(void* param, bool* newgroup) {
...
@@ -6719,8 +6720,8 @@ static SSDataBlock* doTimeEvery(void* param, bool* newgroup) {
clearNumOfRes
(
pInfo
->
pCtx
,
pOperator
->
numOfOutput
);
clearNumOfRes
(
pInfo
->
pCtx
,
pOperator
->
numOfOutput
);
return
pInfo
->
pRes
;
return
pInfo
->
pRes
;
}
}
if
(
pRes
->
info
.
rows
>
0
)
{
if
(
pRes
->
info
.
rows
>
0
)
{
copyTsColoum
(
pRes
,
pInfo
->
pCtx
,
pOperator
->
numOfOutput
);
copyTsColoum
(
pRes
,
pInfo
->
pCtx
,
pOperator
->
numOfOutput
);
clearNumOfRes
(
pInfo
->
pCtx
,
pOperator
->
numOfOutput
);
clearNumOfRes
(
pInfo
->
pCtx
,
pOperator
->
numOfOutput
);
return
pInfo
->
pRes
;
return
pInfo
->
pRes
;
...
@@ -6779,9 +6780,9 @@ static SSDataBlock* doTimeEvery(void* param, bool* newgroup) {
...
@@ -6779,9 +6780,9 @@ static SSDataBlock* doTimeEvery(void* param, bool* newgroup) {
if
(
pRes
->
info
.
rows
>=
pRuntimeEnv
->
resultInfo
.
threshold
)
{
if
(
pRes
->
info
.
rows
>=
pRuntimeEnv
->
resultInfo
.
threshold
)
{
break
;
break
;
}
}
assert
(
pEveryInfo
->
groupDone
);
assert
(
pEveryInfo
->
groupDone
);
if
(
pRes
->
info
.
rows
>
0
)
{
if
(
pRes
->
info
.
rows
>
0
)
{
break
;
break
;
}
}
...
@@ -7587,12 +7588,12 @@ SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int3
...
@@ -7587,12 +7588,12 @@ SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutput, int3
pCols
[
i
].
colId
=
pExpr
[
i
].
base
.
resColId
;
pCols
[
i
].
colId
=
pExpr
[
i
].
base
.
resColId
;
pCols
[
i
].
flist
.
numOfFilters
=
pExpr
[
i
].
base
.
flist
.
numOfFilters
;
pCols
[
i
].
flist
.
numOfFilters
=
pExpr
[
i
].
base
.
flist
.
numOfFilters
;
if
(
pCols
[
i
].
flist
.
numOfFilters
!=
0
)
{
if
(
pCols
[
i
].
flist
.
numOfFilters
!=
0
)
{
pCols
[
i
].
flist
.
filterInfo
=
calloc
(
pCols
[
i
].
flist
.
numOfFilters
,
sizeof
(
SColumnFilterInfo
));
pCols
[
i
].
flist
.
filterInfo
=
calloc
(
pCols
[
i
].
flist
.
numOfFilters
,
sizeof
(
SColumnFilterInfo
));
memcpy
(
pCols
[
i
].
flist
.
filterInfo
,
pExpr
[
i
].
base
.
flist
.
filterInfo
,
pCols
[
i
].
flist
.
numOfFilters
*
sizeof
(
SColumnFilterInfo
));
memcpy
(
pCols
[
i
].
flist
.
filterInfo
,
pExpr
[
i
].
base
.
flist
.
filterInfo
,
pCols
[
i
].
flist
.
numOfFilters
*
sizeof
(
SColumnFilterInfo
));
}
else
{
}
else
{
// avoid runtime error
// avoid runtime error
pCols
[
i
].
flist
.
filterInfo
=
NULL
;
pCols
[
i
].
flist
.
filterInfo
=
NULL
;
}
}
}
}
...
@@ -7726,7 +7727,7 @@ SOperatorInfo* createTimeEveryOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOpera
...
@@ -7726,7 +7727,7 @@ SOperatorInfo* createTimeEveryOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOpera
if
(
pQueryAttr
->
needReverseScan
)
{
if
(
pQueryAttr
->
needReverseScan
)
{
pInfo
->
rangeStart
=
taosHashInit
(
256
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_TIMESTAMP
),
false
,
false
);
pInfo
->
rangeStart
=
taosHashInit
(
256
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_TIMESTAMP
),
false
,
false
);
}
}
initResultRowInfo
(
&
pBInfo
->
resultRowInfo
,
8
,
TSDB_DATA_TYPE_INT
);
initResultRowInfo
(
&
pBInfo
->
resultRowInfo
,
8
,
TSDB_DATA_TYPE_INT
);
if
(
pBInfo
->
pRes
==
NULL
||
pBInfo
->
pCtx
==
NULL
||
pBInfo
->
resultRowInfo
.
pResult
==
NULL
||
if
(
pBInfo
->
pRes
==
NULL
||
pBInfo
->
pCtx
==
NULL
||
pBInfo
->
resultRowInfo
.
pResult
==
NULL
||
...
@@ -8262,11 +8263,11 @@ _clean:
...
@@ -8262,11 +8263,11 @@ _clean:
static
bool
initMultiDistinctInfo
(
SDistinctOperatorInfo
*
pInfo
,
SOperatorInfo
*
pOperator
,
SSDataBlock
*
pBlock
)
{
static
bool
initMultiDistinctInfo
(
SDistinctOperatorInfo
*
pInfo
,
SOperatorInfo
*
pOperator
,
SSDataBlock
*
pBlock
)
{
if
(
taosArrayGetSize
(
pInfo
->
pDistinctDataInfo
)
==
pOperator
->
numOfOutput
)
{
if
(
taosArrayGetSize
(
pInfo
->
pDistinctDataInfo
)
==
pOperator
->
numOfOutput
)
{
// distinct info already inited
// distinct info already inited
return
true
;
return
true
;
}
}
for
(
int
i
=
0
;
i
<
pOperator
->
numOfOutput
;
i
++
)
{
for
(
int
i
=
0
;
i
<
pOperator
->
numOfOutput
;
i
++
)
{
pInfo
->
totalBytes
+=
pOperator
->
pExpr
[
i
].
base
.
colBytes
;
pInfo
->
totalBytes
+=
pOperator
->
pExpr
[
i
].
base
.
colBytes
;
}
}
for
(
int
i
=
0
;
i
<
pOperator
->
numOfOutput
;
i
++
)
{
for
(
int
i
=
0
;
i
<
pOperator
->
numOfOutput
;
i
++
)
{
int
numOfBlock
=
(
int
)(
taosArrayGetSize
(
pBlock
->
pDataBlock
));
int
numOfBlock
=
(
int
)(
taosArrayGetSize
(
pBlock
->
pDataBlock
));
...
@@ -8286,14 +8287,14 @@ static bool initMultiDistinctInfo(SDistinctOperatorInfo *pInfo, SOperatorInfo* p
...
@@ -8286,14 +8287,14 @@ static bool initMultiDistinctInfo(SDistinctOperatorInfo *pInfo, SOperatorInfo* p
static
void
buildMultiDistinctKey
(
SDistinctOperatorInfo
*
pInfo
,
SSDataBlock
*
pBlock
,
int32_t
rowId
)
{
static
void
buildMultiDistinctKey
(
SDistinctOperatorInfo
*
pInfo
,
SSDataBlock
*
pBlock
,
int32_t
rowId
)
{
char
*
p
=
pInfo
->
buf
;
char
*
p
=
pInfo
->
buf
;
memset
(
p
,
0
,
pInfo
->
totalBytes
);
memset
(
p
,
0
,
pInfo
->
totalBytes
);
for
(
int
i
=
0
;
i
<
taosArrayGetSize
(
pInfo
->
pDistinctDataInfo
);
i
++
)
{
for
(
int
i
=
0
;
i
<
taosArrayGetSize
(
pInfo
->
pDistinctDataInfo
);
i
++
)
{
SDistinctDataInfo
*
pDistDataInfo
=
(
SDistinctDataInfo
*
)
taosArrayGet
(
pInfo
->
pDistinctDataInfo
,
i
);
SDistinctDataInfo
*
pDistDataInfo
=
(
SDistinctDataInfo
*
)
taosArrayGet
(
pInfo
->
pDistinctDataInfo
,
i
);
SColumnInfoData
*
pColDataInfo
=
taosArrayGet
(
pBlock
->
pDataBlock
,
pDistDataInfo
->
index
);
SColumnInfoData
*
pColDataInfo
=
taosArrayGet
(
pBlock
->
pDataBlock
,
pDistDataInfo
->
index
);
char
*
val
=
((
char
*
)
pColDataInfo
->
pData
)
+
pColDataInfo
->
info
.
bytes
*
rowId
;
char
*
val
=
((
char
*
)
pColDataInfo
->
pData
)
+
pColDataInfo
->
info
.
bytes
*
rowId
;
if
(
isNull
(
val
,
pDistDataInfo
->
type
))
{
if
(
isNull
(
val
,
pDistDataInfo
->
type
))
{
p
+=
pDistDataInfo
->
bytes
;
p
+=
pDistDataInfo
->
bytes
;
continue
;
continue
;
}
}
if
(
IS_VAR_DATA_TYPE
(
pDistDataInfo
->
type
))
{
if
(
IS_VAR_DATA_TYPE
(
pDistDataInfo
->
type
))
{
...
@@ -8319,7 +8320,7 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) {
...
@@ -8319,7 +8320,7 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) {
pRes
->
info
.
rows
=
0
;
pRes
->
info
.
rows
=
0
;
SSDataBlock
*
pBlock
=
NULL
;
SSDataBlock
*
pBlock
=
NULL
;
while
(
1
)
{
while
(
1
)
{
publishOperatorProfEvent
(
pOperator
->
upstream
[
0
],
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
publishOperatorProfEvent
(
pOperator
->
upstream
[
0
],
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
pBlock
=
pOperator
->
upstream
[
0
]
->
exec
(
pOperator
->
upstream
[
0
],
newgroup
);
pBlock
=
pOperator
->
upstream
[
0
]
->
exec
(
pOperator
->
upstream
[
0
],
newgroup
);
...
@@ -8333,7 +8334,7 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) {
...
@@ -8333,7 +8334,7 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) {
doSetOperatorCompleted
(
pOperator
);
doSetOperatorCompleted
(
pOperator
);
break
;
break
;
}
}
// ensure result output buf
// ensure result output buf
if
(
pRes
->
info
.
rows
+
pBlock
->
info
.
rows
>
pInfo
->
outputCapacity
)
{
if
(
pRes
->
info
.
rows
+
pBlock
->
info
.
rows
>
pInfo
->
outputCapacity
)
{
int32_t
newSize
=
pRes
->
info
.
rows
+
pBlock
->
info
.
rows
;
int32_t
newSize
=
pRes
->
info
.
rows
+
pBlock
->
info
.
rows
;
for
(
int
i
=
0
;
i
<
taosArrayGetSize
(
pRes
->
pDataBlock
);
i
++
)
{
for
(
int
i
=
0
;
i
<
taosArrayGetSize
(
pRes
->
pDataBlock
);
i
++
)
{
...
@@ -8357,14 +8358,14 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) {
...
@@ -8357,14 +8358,14 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) {
for
(
int
j
=
0
;
j
<
taosArrayGetSize
(
pRes
->
pDataBlock
);
j
++
)
{
for
(
int
j
=
0
;
j
<
taosArrayGetSize
(
pRes
->
pDataBlock
);
j
++
)
{
SDistinctDataInfo
*
pDistDataInfo
=
taosArrayGet
(
pInfo
->
pDistinctDataInfo
,
j
);
// distinct meta info
SDistinctDataInfo
*
pDistDataInfo
=
taosArrayGet
(
pInfo
->
pDistinctDataInfo
,
j
);
// distinct meta info
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
pDistDataInfo
->
index
);
//src
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
pDistDataInfo
->
index
);
//src
SColumnInfoData
*
pResultColInfoData
=
taosArrayGet
(
pRes
->
pDataBlock
,
j
);
// dist
SColumnInfoData
*
pResultColInfoData
=
taosArrayGet
(
pRes
->
pDataBlock
,
j
);
// dist
char
*
val
=
((
char
*
)
pColInfoData
->
pData
)
+
pDistDataInfo
->
bytes
*
i
;
char
*
val
=
((
char
*
)
pColInfoData
->
pData
)
+
pDistDataInfo
->
bytes
*
i
;
char
*
start
=
pResultColInfoData
->
pData
+
pDistDataInfo
->
bytes
*
pInfo
->
pRes
->
info
.
rows
;
char
*
start
=
pResultColInfoData
->
pData
+
pDistDataInfo
->
bytes
*
pInfo
->
pRes
->
info
.
rows
;
memcpy
(
start
,
val
,
pDistDataInfo
->
bytes
);
memcpy
(
start
,
val
,
pDistDataInfo
->
bytes
);
}
}
pRes
->
info
.
rows
+=
1
;
pRes
->
info
.
rows
+=
1
;
}
}
}
}
if
(
pRes
->
info
.
rows
>=
pInfo
->
threshold
)
{
if
(
pRes
->
info
.
rows
>=
pInfo
->
threshold
)
{
...
@@ -8384,10 +8385,10 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat
...
@@ -8384,10 +8385,10 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat
pInfo
->
buf
=
NULL
;
pInfo
->
buf
=
NULL
;
pInfo
->
threshold
=
tsMaxNumOfDistinctResults
;
// distinct result threshold
pInfo
->
threshold
=
tsMaxNumOfDistinctResults
;
// distinct result threshold
pInfo
->
outputCapacity
=
4096
;
pInfo
->
outputCapacity
=
4096
;
pInfo
->
pDistinctDataInfo
=
taosArrayInit
(
numOfOutput
,
sizeof
(
SDistinctDataInfo
));
pInfo
->
pDistinctDataInfo
=
taosArrayInit
(
numOfOutput
,
sizeof
(
SDistinctDataInfo
));
pInfo
->
pSet
=
taosHashInit
(
64
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BINARY
),
false
,
HASH_NO_LOCK
);
pInfo
->
pSet
=
taosHashInit
(
64
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BINARY
),
false
,
HASH_NO_LOCK
);
pInfo
->
pRes
=
createOutputBuf
(
pExpr
,
numOfOutput
,
(
int32_t
)
pInfo
->
outputCapacity
);
pInfo
->
pRes
=
createOutputBuf
(
pExpr
,
numOfOutput
,
(
int32_t
)
pInfo
->
outputCapacity
);
if
(
pInfo
->
pDistinctDataInfo
==
NULL
||
pInfo
->
pSet
==
NULL
||
pInfo
->
pRes
==
NULL
)
{
if
(
pInfo
->
pDistinctDataInfo
==
NULL
||
pInfo
->
pSet
==
NULL
||
pInfo
->
pRes
==
NULL
)
{
goto
_clean
;
goto
_clean
;
}
}
...
@@ -8406,7 +8407,7 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat
...
@@ -8406,7 +8407,7 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat
pOperator
->
info
=
pInfo
;
pOperator
->
info
=
pInfo
;
pOperator
->
pRuntimeEnv
=
pRuntimeEnv
;
pOperator
->
pRuntimeEnv
=
pRuntimeEnv
;
pOperator
->
exec
=
hashDistinct
;
pOperator
->
exec
=
hashDistinct
;
pOperator
->
pExpr
=
pExpr
;
pOperator
->
pExpr
=
pExpr
;
pOperator
->
cleanup
=
destroyDistinctOperatorInfo
;
pOperator
->
cleanup
=
destroyDistinctOperatorInfo
;
appendUpstream
(
pOperator
,
upstream
);
appendUpstream
(
pOperator
,
upstream
);
...
@@ -8587,7 +8588,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
...
@@ -8587,7 +8588,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
pQueryMsg
->
window
.
ekey
=
htobe64
(
pQueryMsg
->
window
.
ekey
);
pQueryMsg
->
window
.
ekey
=
htobe64
(
pQueryMsg
->
window
.
ekey
);
pQueryMsg
->
range
.
skey
=
htobe64
(
pQueryMsg
->
range
.
skey
);
pQueryMsg
->
range
.
skey
=
htobe64
(
pQueryMsg
->
range
.
skey
);
pQueryMsg
->
range
.
ekey
=
htobe64
(
pQueryMsg
->
range
.
ekey
);
pQueryMsg
->
range
.
ekey
=
htobe64
(
pQueryMsg
->
range
.
ekey
);
pQueryMsg
->
interval
.
interval
=
htobe64
(
pQueryMsg
->
interval
.
interval
);
pQueryMsg
->
interval
.
interval
=
htobe64
(
pQueryMsg
->
interval
.
interval
);
pQueryMsg
->
interval
.
sliding
=
htobe64
(
pQueryMsg
->
interval
.
sliding
);
pQueryMsg
->
interval
.
sliding
=
htobe64
(
pQueryMsg
->
interval
.
sliding
);
pQueryMsg
->
interval
.
offset
=
htobe64
(
pQueryMsg
->
interval
.
offset
);
pQueryMsg
->
interval
.
offset
=
htobe64
(
pQueryMsg
->
interval
.
offset
);
...
@@ -8658,7 +8659,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
...
@@ -8658,7 +8659,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
if (code != TSDB_CODE_SUCCESS) {
if (code != TSDB_CODE_SUCCESS) {
goto _cleanup;
goto _cleanup;
}
}
*/
*/
}
}
if
(
pQueryMsg
->
colCondLen
>
0
)
{
if
(
pQueryMsg
->
colCondLen
>
0
)
{
...
@@ -9116,14 +9117,14 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) {
...
@@ -9116,14 +9117,14 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) {
if
(
pUdfInfo
->
path
)
{
if
(
pUdfInfo
->
path
)
{
unlink
(
pUdfInfo
->
path
);
unlink
(
pUdfInfo
->
path
);
}
}
tfree
(
pUdfInfo
->
path
);
tfree
(
pUdfInfo
->
path
);
pUdfInfo
->
path
=
strdup
(
path
);
pUdfInfo
->
path
=
strdup
(
path
);
if
(
pUdfInfo
->
handle
)
{
if
(
pUdfInfo
->
handle
)
{
taosCloseDll
(
pUdfInfo
->
handle
);
taosCloseDll
(
pUdfInfo
->
handle
);
}
}
pUdfInfo
->
handle
=
taosLoadDll
(
path
);
pUdfInfo
->
handle
=
taosLoadDll
(
path
);
if
(
NULL
==
pUdfInfo
->
handle
)
{
if
(
NULL
==
pUdfInfo
->
handle
)
{
...
@@ -9281,7 +9282,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
...
@@ -9281,7 +9282,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
int32_t
createQueryFilter
(
char
*
data
,
int32_t
len
,
void
**
pFilters
)
{
int32_t
createQueryFilter
(
char
*
data
,
int32_t
len
,
void
**
pFilters
)
{
tExprNode
*
expr
=
NULL
;
tExprNode
*
expr
=
NULL
;
TRY
(
TSDB_MAX_TAG_CONDITIONS
)
{
TRY
(
TSDB_MAX_TAG_CONDITIONS
)
{
expr
=
exprTreeFromBinary
(
data
,
len
);
expr
=
exprTreeFromBinary
(
data
,
len
);
}
CATCH
(
code
)
{
}
CATCH
(
code
)
{
...
@@ -10041,6 +10042,9 @@ static void doSetTagValueToResultBuf(char* output, const char* val, int16_t type
...
@@ -10041,6 +10042,9 @@ static void doSetTagValueToResultBuf(char* output, const char* val, int16_t type
static
int64_t
getQuerySupportBufSize
(
size_t
numOfTables
)
{
static
int64_t
getQuerySupportBufSize
(
size_t
numOfTables
)
{
size_t
s1
=
sizeof
(
STableQueryInfo
);
size_t
s1
=
sizeof
(
STableQueryInfo
);
// TODO: struct SHashNode is an internal implementation of
// hash table. The implementation should not leak here.
size_t
s2
=
sizeof
(
SHashNode
);
size_t
s2
=
sizeof
(
SHashNode
);
// size_t s3 = sizeof(STableCheckInfo); buffer consumption in tsdb
// size_t s3 = sizeof(STableCheckInfo); buffer consumption in tsdb
...
...
src/util/inc/hash.h
浏览文件 @
c4aa0be0
...
@@ -24,24 +24,18 @@ extern "C" {
...
@@ -24,24 +24,18 @@ extern "C" {
#include "hashfunc.h"
#include "hashfunc.h"
#include "tlockfree.h"
#include "tlockfree.h"
#define HASH_MAX_CAPACITY (1024 * 1024 * 16)
// TODO: SHashNode is an internal implementation and should not
#define HASH_DEFAULT_LOAD_FACTOR (0.75)
// be in the public header file.
#define HASH_INDEX(v, c) ((v) & ((c)-1))
typedef
void
(
*
_hash_free_fn_t
)(
void
*
param
);
typedef
struct
SHashNode
{
typedef
struct
SHashNode
{
struct
SHashNode
*
next
;
struct
SHashNode
*
next
;
uint32_t
hashVal
;
// the hash value of key
uint32_t
hashVal
;
// the hash value of key
uint32_t
dataLen
;
// length of data
uint32_t
dataLen
;
// length of data
uint32_t
keyLen
;
// length of the key
uint32_t
keyLen
;
// length of the key
int8_t
removed
;
// flag to indicate removed
int8_t
removed
;
// flag to indicate removed
int32_t
count
;
// reference count
int32_t
refCount
;
// reference count
char
data
[];
char
data
[];
}
SHashNode
;
}
SHashNode
;
#define GET_HASH_NODE_KEY(_n) ((char*)(_n) + sizeof(SHashNode) + (_n)->dataLen)
#define GET_HASH_NODE_DATA(_n) ((char*)(_n) + sizeof(SHashNode))
#define GET_HASH_PNODE(_n) ((SHashNode *)((char*)(_n) - sizeof(SHashNode)))
#define GET_HASH_PNODE(_n) ((SHashNode *)((char*)(_n) - sizeof(SHashNode)))
typedef
enum
SHashLockTypeE
{
typedef
enum
SHashLockTypeE
{
...
@@ -49,41 +43,24 @@ typedef enum SHashLockTypeE {
...
@@ -49,41 +43,24 @@ typedef enum SHashLockTypeE {
HASH_ENTRY_LOCK
=
1
,
HASH_ENTRY_LOCK
=
1
,
}
SHashLockTypeE
;
}
SHashLockTypeE
;
typedef
struct
SHashEntry
{
typedef
struct
SHashObj
SHashObj
;
int32_t
num
;
// number of elements in current entry
SRWLatch
latch
;
// entry latch
SHashNode
*
next
;
}
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
_hash_free_fn_t
freeFp
;
// hash node free callback function
_equal_fn_t
equalFp
;
// equal function
SRWLatch
lock
;
// read-write spin lock
SHashLockTypeE
type
;
// lock type
bool
enableUpdate
;
// enable update
SArray
*
pMemBlock
;
// memory block allocated for SHashEntry
}
SHashObj
;
/**
/**
* init
the
hash table
* init
ialize a
hash table
*
*
* @param capacity initial capacity of the hash table
* @param capacity initial capacity of the hash table
* @param fn hash function to generate the hash value
* @param fn hash function
* @param threadsafe thread safe or not
* @param update whether the hash table allows in place update
* @return
* @param type whether the hash table has per entry lock
* @return hash table object
*/
*/
SHashObj
*
taosHashInit
(
size_t
capacity
,
_hash_fn_t
fn
,
bool
update
,
SHashLockTypeE
type
);
SHashObj
*
taosHashInit
(
size_t
capacity
,
_hash_fn_t
fn
,
bool
update
,
SHashLockTypeE
type
);
/**
/**
* set equal func of the hash table
* set equal func of the hash table
* @param pHashObj
*
* @param equalFp
* @param pHashObj
* @param equalFp
* @return
* @return
*/
*/
void
taosHashSetEqualFp
(
SHashObj
*
pHashObj
,
_equal_fn_t
fp
);
void
taosHashSetEqualFp
(
SHashObj
*
pHashObj
,
_equal_fn_t
fp
);
...
@@ -92,6 +69,7 @@ void taosHashSetFreeFp(SHashObj *pHashObj, _hash_free_fn_t fp);
...
@@ -92,6 +69,7 @@ void taosHashSetFreeFp(SHashObj *pHashObj, _hash_free_fn_t fp);
/**
/**
* return the size of hash table
* return the size of hash table
*
* @param pHashObj
* @param pHashObj
* @return
* @return
*/
*/
...
@@ -99,73 +77,114 @@ int32_t taosHashGetSize(const SHashObj *pHashObj);
...
@@ -99,73 +77,114 @@ int32_t taosHashGetSize(const SHashObj *pHashObj);
/**
/**
* put element into hash table, if the element with the same key exists, update it
* put element into hash table, if the element with the same key exists, update it
* @param pHashObj
*
* @param key
* @param pHashObj hash table object
* @param keyLen
* @param key key
* @param data
* @param keyLen length of key
* @param size
* @param data data
* @return
* @param size size of data
* @return 0 if success, -1 otherwise
*/
*/
int32_t
taosHashPut
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
*
data
,
size_t
size
);
int32_t
taosHashPut
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
*
data
,
size_t
size
);
/**
/**
* return the payload data with the specified key
* return the payload data with the specified key
*
*
* @param pHashObj
* @param pHashObj
hash table object
* @param key
* @param key
key
* @param keyLen
* @param keyLen
length of key
* @return
* @return
pointer to data
*/
*/
void
*
taosHashGet
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
);
void
*
taosHashGet
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
);
/**
/**
* apply the udf before return the result
* Get the data associated with "key". Note that caller needs to make sure
* @param pHashObj
* "d" has enough capacity to accomodate the data.
* @param key
*
* @param keyLen
* @param pHashObj hash table object
* @param fp
* @param key key
* @param d
* @param keyLen length of key
* @return
* @param fp function to be called on hash node when the data is found
* @param d buffer
* @return pointer to data
*/
*/
void
*
taosHashGetClone
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
(
*
fp
)(
void
*
),
void
*
d
);
void
*
taosHashGetClone
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
(
*
fp
)(
void
*
),
void
*
d
);
/**
/**
* @param pHashObj
* Get the data associated with "key". Note that caller needs to take ownership
* @param key
* of the data "d" and make sure it is deallocated.
* @param keyLen
*
* @param fp
* @param pHashObj hash table object
* @param d
* @param key key
* @param sz
* @param keyLen length of key
* @return
* @param fp function to be called on hash node when the data is found
* @param d buffer
* @param sz size of the data buffer
* @return pointer to data
*/
*/
void
*
taosHashGetCloneExt
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
(
*
fp
)(
void
*
),
void
**
d
,
size_t
*
sz
);
void
*
taosHashGetCloneExt
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
(
*
fp
)(
void
*
),
void
**
d
,
size_t
*
sz
);
/**
/**
* remove item with the specified key
* remove item with the specified key
* @param pHashObj
*
* @param key
* @param pHashObj hash table object
* @param keyLen
* @param key key
* @param keyLen length of key
* @return 0 if success, -1 otherwise
*/
*/
int32_t
taosHashRemove
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
);
int32_t
taosHashRemove
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
);
/**
* remove item with the specified key
*
* @param pHashObj hash table object
* @param key key
* @param keyLen length of key
* @param data buffer for data
* @param dsize size of data buffer
* @return 0 if success, -1 otherwise
*/
int32_t
taosHashRemoveWithData
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
*
data
,
size_t
dsize
);
int32_t
taosHashRemoveWithData
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
*
data
,
size_t
dsize
);
int32_t
taosHashCondTraverse
(
SHashObj
*
pHashObj
,
bool
(
*
fp
)(
void
*
,
void
*
),
void
*
param
);
/**
* traverse through all objects in the hash table and apply "fp" on each node.
* If "fp" returns false when applied on top of a node, the node will also be
* removed from table.
*
* @param pHashObj hash table object
* @param fp function pointer applied on each node
* @param param parameter fed into "fp"
*/
void
taosHashCondTraverse
(
SHashObj
*
pHashObj
,
bool
(
*
fp
)(
void
*
,
void
*
),
void
*
param
);
/**
* clear the contents of the hash table
*
* @param pHashObj hash table object
*/
void
taosHashClear
(
SHashObj
*
pHashObj
);
void
taosHashClear
(
SHashObj
*
pHashObj
);
/**
/**
* clean up hash table
* clean up hash table
* @param handle
*
* @param pHashObj hash table object
*/
*/
void
taosHashCleanup
(
SHashObj
*
pHashObj
);
void
taosHashCleanup
(
SHashObj
*
pHashObj
);
/**
/**
* return the number of collisions in the hash table
*
*
* @param pHashObj
* @param pHashObj
hash table object
* @return
* @return
maximum number of collisions
*/
*/
int32_t
taosHashGetMaxOverflowLinkLength
(
const
SHashObj
*
pHashObj
);
int32_t
taosHashGetMaxOverflowLinkLength
(
SHashObj
*
pHashObj
);
/**
* return the consumed memory of the hash table
*
* @param pHashObj hash table object
* @return consumed memory of the hash table
*/
size_t
taosHashGetMemSize
(
const
SHashObj
*
pHashObj
);
size_t
taosHashGetMemSize
(
const
SHashObj
*
pHashObj
);
void
*
taosHashIterate
(
SHashObj
*
pHashObj
,
void
*
p
);
void
*
taosHashIterate
(
SHashObj
*
pHashObj
,
void
*
p
);
...
...
src/util/inc/hashfunc.h
浏览文件 @
c4aa0be0
...
@@ -22,6 +22,8 @@ typedef uint32_t (*_hash_fn_t)(const char *, uint32_t);
...
@@ -22,6 +22,8 @@ typedef uint32_t (*_hash_fn_t)(const char *, uint32_t);
typedef
int32_t
(
*
_equal_fn_t
)(
const
void
*
a
,
const
void
*
b
,
size_t
sz
);
typedef
int32_t
(
*
_equal_fn_t
)(
const
void
*
a
,
const
void
*
b
,
size_t
sz
);
typedef
void
(
*
_hash_free_fn_t
)(
void
*
param
);
/**
/**
* murmur hash algorithm
* murmur hash algorithm
* @key usually string
* @key usually string
...
...
src/util/src/hash.c
浏览文件 @
c4aa0be0
...
@@ -18,53 +18,117 @@
...
@@ -18,53 +18,117 @@
#include "tulog.h"
#include "tulog.h"
#include "taosdef.h"
#include "taosdef.h"
#define EXT_SIZE 1024
/*
* Macro definition
*/
#define HASH_NEED_RESIZE(_h) ((_h)->size >= (_h)->capacity * HASH_DEFAULT_LOAD_FACTOR)
#define HASH_MAX_CAPACITY (1024 * 1024 * 16)
#define HASH_DEFAULT_LOAD_FACTOR (0.75)
#define HASH_INDEX(v, c) ((v) & ((c)-1))
#define DO_FREE_HASH_NODE(_n) \
#define HASH_NEED_RESIZE(_h) ((_h)->size >= (_h)->capacity * HASH_DEFAULT_LOAD_FACTOR)
do { \
tfree(_n); \
} while (0)
#define FREE_HASH_NODE(_
h, _
n) \
#define FREE_HASH_NODE(_n) \
do { \
do { \
if ((_h)->freeFp) { \
tfree(_n); \
(_h)->freeFp(GET_HASH_NODE_DATA(_n)); \
} \
\
DO_FREE_HASH_NODE(_n); \
} while (0);
} while (0);
static
FORCE_INLINE
void
__wr_lock
(
void
*
lock
,
int32_t
type
)
{
#define GET_HASH_NODE_KEY(_n) ((char*)(_n) + sizeof(SHashNode) + (_n)->dataLen)
if
(
type
==
HASH_NO_LOCK
)
{
#define GET_HASH_NODE_DATA(_n) ((char*)(_n) + sizeof(SHashNode))
#define GET_HASH_PNODE(_n) ((SHashNode *)((char*)(_n) - sizeof(SHashNode)))
/*
* typedef
*/
typedef
struct
SHashEntry
{
int32_t
num
;
// number of elements in current entry
SRWLatch
latch
;
// entry latch
SHashNode
*
next
;
}
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
_equal_fn_t
equalFp
;
// equal function
_hash_free_fn_t
freeFp
;
// hash node free callback function
SRWLatch
lock
;
// read-write spin lock
SHashLockTypeE
type
;
// lock type
bool
enableUpdate
;
// enable update
SArray
*
pMemBlock
;
// memory block allocated for SHashEntry
}
SHashObj
;
/*
* Function definition
*/
static
FORCE_INLINE
void
taosHashWLock
(
SHashObj
*
pHashObj
)
{
if
(
pHashObj
->
type
==
HASH_NO_LOCK
)
{
return
;
}
taosWLockLatch
(
&
pHashObj
->
lock
);
}
static
FORCE_INLINE
void
taosHashWUnlock
(
SHashObj
*
pHashObj
)
{
if
(
pHashObj
->
type
==
HASH_NO_LOCK
)
{
return
;
}
taosWUnLockLatch
(
&
pHashObj
->
lock
);
}
static
FORCE_INLINE
void
taosHashRLock
(
SHashObj
*
pHashObj
)
{
if
(
pHashObj
->
type
==
HASH_NO_LOCK
)
{
return
;
}
taosRLockLatch
(
&
pHashObj
->
lock
);
}
static
FORCE_INLINE
void
taosHashRUnlock
(
SHashObj
*
pHashObj
)
{
if
(
pHashObj
->
type
==
HASH_NO_LOCK
)
{
return
;
}
taosRUnLockLatch
(
&
pHashObj
->
lock
);
}
static
FORCE_INLINE
void
taosHashEntryWLock
(
const
SHashObj
*
pHashObj
,
SHashEntry
*
pe
)
{
if
(
pHashObj
->
type
==
HASH_NO_LOCK
)
{
return
;
return
;
}
}
taosWLockLatch
(
lock
);
taosWLockLatch
(
&
pe
->
latch
);
}
}
static
FORCE_INLINE
void
__rd_lock
(
void
*
lock
,
int32_t
type
)
{
static
FORCE_INLINE
void
if
(
type
==
HASH_NO_LOCK
)
{
taosHashEntryWUnlock
(
const
SHashObj
*
pHashObj
,
SHashEntry
*
pe
)
{
if
(
pHashObj
->
type
==
HASH_NO_LOCK
)
{
return
;
return
;
}
}
taos
RLockLatch
(
lock
);
taos
WUnLockLatch
(
&
pe
->
latch
);
}
}
static
FORCE_INLINE
void
__rd_unlock
(
void
*
lock
,
int32_t
type
)
{
static
FORCE_INLINE
void
if
(
type
==
HASH_NO_LOCK
)
{
taosHashEntryRLock
(
const
SHashObj
*
pHashObj
,
SHashEntry
*
pe
)
{
if
(
pHashObj
->
type
==
HASH_NO_LOCK
)
{
return
;
return
;
}
}
taosR
UnLockLatch
(
lock
);
taosR
LockLatch
(
&
pe
->
latch
);
}
}
static
FORCE_INLINE
void
__wr_unlock
(
void
*
lock
,
int32_t
type
)
{
static
FORCE_INLINE
void
if
(
type
==
HASH_NO_LOCK
)
{
taosHashEntryRUnlock
(
const
SHashObj
*
pHashObj
,
SHashEntry
*
pe
)
{
if
(
pHashObj
->
type
==
HASH_NO_LOCK
)
{
return
;
return
;
}
}
taos
WUnLockLatch
(
lock
);
taos
RUnLockLatch
(
&
pe
->
latch
);
}
}
static
FORCE_INLINE
int32_t
taosHashCapacity
(
int32_t
length
)
{
static
FORCE_INLINE
int32_t
taosHashCapacity
(
int32_t
length
)
{
...
@@ -75,10 +139,13 @@ static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
...
@@ -75,10 +139,13 @@ static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
return
i
;
return
i
;
}
}
static
FORCE_INLINE
SHashNode
*
doSearchInEntryList
(
SHashObj
*
pHashObj
,
SHashEntry
*
pe
,
const
void
*
key
,
size_t
keyLen
,
uint32_t
hashVal
)
{
static
FORCE_INLINE
SHashNode
*
doSearchInEntryList
(
SHashObj
*
pHashObj
,
SHashEntry
*
pe
,
const
void
*
key
,
size_t
keyLen
,
uint32_t
hashVal
)
{
SHashNode
*
pNode
=
pe
->
next
;
SHashNode
*
pNode
=
pe
->
next
;
while
(
pNode
)
{
while
(
pNode
)
{
if
((
pNode
->
keyLen
==
keyLen
)
&&
((
*
(
pHashObj
->
equalFp
))(
GET_HASH_NODE_KEY
(
pNode
),
key
,
keyLen
)
==
0
)
&&
pNode
->
removed
==
0
)
{
if
((
pNode
->
keyLen
==
keyLen
)
&&
((
*
(
pHashObj
->
equalFp
))(
GET_HASH_NODE_KEY
(
pNode
),
key
,
keyLen
)
==
0
)
&&
pNode
->
removed
==
0
)
{
assert
(
pNode
->
hashVal
==
hashVal
);
assert
(
pNode
->
hashVal
==
hashVal
);
break
;
break
;
}
}
...
@@ -90,59 +157,57 @@ static FORCE_INLINE SHashNode *doSearchInEntryList(SHashObj *pHashObj, SHashEntr
...
@@ -90,59 +157,57 @@ static FORCE_INLINE SHashNode *doSearchInEntryList(SHashObj *pHashObj, SHashEntr
}
}
/**
/**
*
R
esize the hash list if the threshold is reached
*
r
esize the hash list if the threshold is reached
*
*
* @param pHashObj
* @param pHashObj
*/
*/
static
void
taosHashTableResize
(
SHashObj
*
pHashObj
);
static
void
taosHashTableResize
(
SHashObj
*
pHashObj
);
/**
/**
* allocate and initialize a hash node
*
* @param key key of object for hash, usually a null-terminated string
* @param key key of object for hash, usually a null-terminated string
* @param keyLen length of key
* @param keyLen length of key
* @param pData actually data. Requires a consecutive memory block, no pointer is allowed in pData.
* @param pData data to be stored in hash node
* Pointer copy causes memory access error.
* @param dsize size of data
* @param dsize size of data
* @return SHashNode
* @return SHashNode
*/
*/
static
SHashNode
*
doCreateHashNode
(
const
void
*
key
,
size_t
keyLen
,
const
void
*
pData
,
size_t
dsize
,
uint32_t
hashVal
);
static
SHashNode
*
doCreateHashNode
(
const
void
*
key
,
size_t
keyLen
,
const
void
*
pData
,
size_t
dsize
,
uint32_t
hashVal
);
/**
/**
*
U
pdate the hash node
*
u
pdate the hash node
*
*
* @param pNode hash node
* @param pHashObj hash table object
* @param key key for generate hash value
* @param pe hash table entry to operate on
* @param keyLen key length
* @param prev previous node
* @param pData actual data
* @param pNode the old node with requested key
* @param dsize size of actual data
* @param pNewNode the new node with requested key
* @return hash node
*/
*/
static
FORCE_INLINE
SHashNode
*
doUpdateHashNode
(
SHashObj
*
pHashObj
,
SHashEntry
*
pe
,
SHashNode
*
prev
,
SHashNode
*
pNode
,
SHashNode
*
pNewNode
)
{
static
FORCE_INLINE
void
doUpdateHashNode
(
SHashObj
*
pHashObj
,
SHashEntry
*
pe
,
SHashNode
*
prev
,
SHashNode
*
pNode
,
SHashNode
*
pNewNode
)
{
assert
(
pNode
->
keyLen
==
pNewNode
->
keyLen
);
assert
(
pNode
->
keyLen
==
pNewNode
->
keyLen
);
atomic_sub_fetch_32
(
&
pNode
->
c
ount
,
1
);
atomic_sub_fetch_32
(
&
pNode
->
refC
ount
,
1
);
if
(
prev
!=
NULL
)
{
if
(
prev
!=
NULL
)
{
prev
->
next
=
pNewNode
;
prev
->
next
=
pNewNode
;
}
else
{
}
else
{
pe
->
next
=
pNewNode
;
pe
->
next
=
pNewNode
;
}
}
if
(
pNode
->
c
ount
<=
0
)
{
if
(
pNode
->
refC
ount
<=
0
)
{
pNewNode
->
next
=
pNode
->
next
;
pNewNode
->
next
=
pNode
->
next
;
DO_
FREE_HASH_NODE
(
pNode
);
FREE_HASH_NODE
(
pNode
);
}
else
{
}
else
{
pNewNode
->
next
=
pNode
;
pNewNode
->
next
=
pNode
;
pe
->
num
++
;
pe
->
num
++
;
atomic_add_fetch_64
(
&
pHashObj
->
size
,
1
);
atomic_add_fetch_64
(
&
pHashObj
->
size
,
1
);
}
}
return
pNewNode
;
}
}
/**
/**
* insert the hash node at the front of the linked list
* insert the hash node at the front of the linked list
*
*
* @param pHashObj
* @param pHashObj
hash table object
* @param pNode
* @param pNode
the old node with requested key
*/
*/
static
void
pushfrontNodeInEntryList
(
SHashEntry
*
pEntry
,
SHashNode
*
pNode
);
static
void
pushfrontNodeInEntryList
(
SHashEntry
*
pEntry
,
SHashNode
*
pNode
);
...
@@ -155,13 +220,21 @@ static void pushfrontNodeInEntryList(SHashEntry *pEntry, SHashNode *pNode);
...
@@ -155,13 +220,21 @@ static void pushfrontNodeInEntryList(SHashEntry *pEntry, SHashNode *pNode);
static
FORCE_INLINE
bool
taosHashTableEmpty
(
const
SHashObj
*
pHashObj
);
static
FORCE_INLINE
bool
taosHashTableEmpty
(
const
SHashObj
*
pHashObj
);
/**
/**
* Get the next element in hash table for iterator
* initialize a hash table
* @param pIter
*
* @return
* @param capacity initial capacity of the hash table
* @param fn hash function
* @param update whether the hash table allows in place update
* @param type whether the hash table has per entry lock
* @return hash table object
*/
*/
SHashObj
*
taosHashInit
(
size_t
capacity
,
_hash_fn_t
fn
,
bool
update
,
SHashLockTypeE
type
)
{
SHashObj
*
taosHashInit
(
size_t
capacity
,
_hash_fn_t
fn
,
bool
update
,
SHashLockTypeE
type
)
{
assert
(
fn
!=
NULL
);
if
(
fn
==
NULL
)
{
uError
(
"hash table must have a valid hash function"
);
assert
(
0
);
return
NULL
;
}
if
(
capacity
==
0
)
{
if
(
capacity
==
0
)
{
capacity
=
4
;
capacity
=
4
;
}
}
...
@@ -174,28 +247,43 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTyp
...
@@ -174,28 +247,43 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTyp
// the max slots is not defined by user
// the max slots is not defined by user
pHashObj
->
capacity
=
taosHashCapacity
((
int32_t
)
capacity
);
pHashObj
->
capacity
=
taosHashCapacity
((
int32_t
)
capacity
);
assert
((
pHashObj
->
capacity
&
(
pHashObj
->
capacity
-
1
))
==
0
);
pHashObj
->
equalFp
=
memcmp
;
pHashObj
->
equalFp
=
memcmp
;
pHashObj
->
hashFp
=
fn
;
pHashObj
->
hashFp
=
fn
;
pHashObj
->
type
=
type
;
pHashObj
->
type
=
type
;
pHashObj
->
enableUpdate
=
update
;
pHashObj
->
enableUpdate
=
update
;
assert
((
pHashObj
->
capacity
&
(
pHashObj
->
capacity
-
1
))
==
0
);
pHashObj
->
hashList
=
(
SHashEntry
**
)
calloc
(
pHashObj
->
capacity
,
sizeof
(
void
*
));
pHashObj
->
hashList
=
(
SHashEntry
**
)
calloc
(
pHashObj
->
capacity
,
sizeof
(
void
*
));
if
(
pHashObj
->
hashList
==
NULL
)
{
if
(
pHashObj
->
hashList
==
NULL
)
{
free
(
pHashObj
);
free
(
pHashObj
);
uError
(
"failed to allocate memory, reason:%s"
,
strerror
(
errno
));
uError
(
"failed to allocate memory, reason:%s"
,
strerror
(
errno
));
return
NULL
;
return
NULL
;
}
else
{
}
pHashObj
->
pMemBlock
=
taosArrayInit
(
8
,
sizeof
(
void
*
));
void
*
p
=
calloc
(
pHashObj
->
capacity
,
sizeof
(
SHashEntry
));
pHashObj
->
pMemBlock
=
taosArrayInit
(
8
,
sizeof
(
void
*
));
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
capacity
;
++
i
)
{
if
(
pHashObj
->
pMemBlock
==
NULL
)
{
pHashObj
->
hashList
[
i
]
=
(
void
*
)((
char
*
)
p
+
i
*
sizeof
(
SHashEntry
));
free
(
pHashObj
->
hashList
);
}
free
(
pHashObj
);
uError
(
"failed to allocate memory, reason:%s"
,
strerror
(
errno
));
return
NULL
;
}
taosArrayPush
(
pHashObj
->
pMemBlock
,
&
p
);
void
*
p
=
calloc
(
pHashObj
->
capacity
,
sizeof
(
SHashEntry
));
if
(
p
==
NULL
)
{
taosArrayDestroy
(
&
pHashObj
->
pMemBlock
);
free
(
pHashObj
->
hashList
);
free
(
pHashObj
);
uError
(
"failed to allocate memory, reason:%s"
,
strerror
(
errno
));
return
NULL
;
}
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
capacity
;
++
i
)
{
pHashObj
->
hashList
[
i
]
=
(
void
*
)((
char
*
)
p
+
i
*
sizeof
(
SHashEntry
));
}
}
taosArrayPush
(
pHashObj
->
pMemBlock
,
&
p
);
return
pHashObj
;
return
pHashObj
;
}
}
...
@@ -212,7 +300,7 @@ void taosHashSetFreeFp(SHashObj *pHashObj, _hash_free_fn_t fp) {
...
@@ -212,7 +300,7 @@ void taosHashSetFreeFp(SHashObj *pHashObj, _hash_free_fn_t fp) {
}
}
int32_t
taosHashGetSize
(
const
SHashObj
*
pHashObj
)
{
int32_t
taosHashGetSize
(
const
SHashObj
*
pHashObj
)
{
if
(
!
pHashObj
)
{
if
(
pHashObj
==
NULL
)
{
return
0
;
return
0
;
}
}
return
(
int32_t
)
atomic_load_64
(
&
pHashObj
->
size
);
return
(
int32_t
)
atomic_load_64
(
&
pHashObj
->
size
);
...
@@ -223,6 +311,10 @@ static FORCE_INLINE bool taosHashTableEmpty(const SHashObj *pHashObj) {
...
@@ -223,6 +311,10 @@ static FORCE_INLINE bool taosHashTableEmpty(const SHashObj *pHashObj) {
}
}
int32_t
taosHashPut
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
*
data
,
size_t
size
)
{
int32_t
taosHashPut
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
*
data
,
size_t
size
)
{
if
(
pHashObj
==
NULL
||
key
==
NULL
||
keyLen
==
0
||
data
==
NULL
||
size
==
0
)
{
return
-
1
;
}
uint32_t
hashVal
=
(
*
pHashObj
->
hashFp
)(
key
,
(
uint32_t
)
keyLen
);
uint32_t
hashVal
=
(
*
pHashObj
->
hashFp
)(
key
,
(
uint32_t
)
keyLen
);
SHashNode
*
pNewNode
=
doCreateHashNode
(
key
,
keyLen
,
data
,
size
,
hashVal
);
SHashNode
*
pNewNode
=
doCreateHashNode
(
key
,
keyLen
,
data
,
size
,
hashVal
);
if
(
pNewNode
==
NULL
)
{
if
(
pNewNode
==
NULL
)
{
...
@@ -231,19 +323,17 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
...
@@ -231,19 +323,17 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
// need the resize process, write lock applied
// need the resize process, write lock applied
if
(
HASH_NEED_RESIZE
(
pHashObj
))
{
if
(
HASH_NEED_RESIZE
(
pHashObj
))
{
__wr_lock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashWLock
(
pHashObj
);
taosHashTableResize
(
pHashObj
);
taosHashTableResize
(
pHashObj
);
__wr_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashWUnlock
(
pHashObj
);
}
}
__rd_lock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRLock
(
pHashObj
);
int32_t
slot
=
HASH_INDEX
(
hashVal
,
pHashObj
->
capacity
);
int32_t
slot
=
HASH_INDEX
(
hashVal
,
pHashObj
->
capacity
);
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosHashEntryWLock
(
pHashObj
,
pe
);
taosWLockLatch
(
&
pe
->
latch
);
}
SHashNode
*
pNode
=
pe
->
next
;
SHashNode
*
pNode
=
pe
->
next
;
if
(
pe
->
num
>
0
)
{
if
(
pe
->
num
>
0
)
{
...
@@ -254,7 +344,9 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
...
@@ -254,7 +344,9 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
SHashNode
*
prev
=
NULL
;
SHashNode
*
prev
=
NULL
;
while
(
pNode
)
{
while
(
pNode
)
{
if
((
pNode
->
keyLen
==
keyLen
)
&&
((
*
(
pHashObj
->
equalFp
))(
GET_HASH_NODE_KEY
(
pNode
),
key
,
keyLen
)
==
0
)
&&
pNode
->
removed
==
0
)
{
if
((
pNode
->
keyLen
==
keyLen
)
&&
(
*
(
pHashObj
->
equalFp
))(
GET_HASH_NODE_KEY
(
pNode
),
key
,
keyLen
)
==
0
&&
pNode
->
removed
==
0
)
{
assert
(
pNode
->
hashVal
==
hashVal
);
assert
(
pNode
->
hashVal
==
hashVal
);
break
;
break
;
}
}
...
@@ -267,18 +359,12 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
...
@@ -267,18 +359,12 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
// no data in hash table with the specified key, add it into hash table
// no data in hash table with the specified key, add it into hash table
pushfrontNodeInEntryList
(
pe
,
pNewNode
);
pushfrontNodeInEntryList
(
pe
,
pNewNode
);
if
(
pe
->
num
==
0
)
{
assert
(
pe
->
next
!=
NULL
);
assert
(
pe
->
next
==
NULL
);
}
else
{
assert
(
pe
->
next
!=
NULL
);
}
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosHashEntryWUnlock
(
pHashObj
,
pe
);
taosWUnLockLatch
(
&
pe
->
latch
);
}
// enable resize
// enable resize
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRUnlock
(
pHashObj
);
atomic_add_fetch_64
(
&
pHashObj
->
size
,
1
);
atomic_add_fetch_64
(
&
pHashObj
->
size
,
1
);
return
0
;
return
0
;
...
@@ -287,15 +373,13 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
...
@@ -287,15 +373,13 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
if
(
pHashObj
->
enableUpdate
)
{
if
(
pHashObj
->
enableUpdate
)
{
doUpdateHashNode
(
pHashObj
,
pe
,
prev
,
pNode
,
pNewNode
);
doUpdateHashNode
(
pHashObj
,
pe
,
prev
,
pNode
,
pNewNode
);
}
else
{
}
else
{
DO_
FREE_HASH_NODE
(
pNewNode
);
FREE_HASH_NODE
(
pNewNode
);
}
}
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosHashEntryWUnlock
(
pHashObj
,
pe
);
taosWUnLockLatch
(
&
pe
->
latch
);
}
// enable resize
// enable resize
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRUnlock
(
pHashObj
);
return
pHashObj
->
enableUpdate
?
0
:
-
1
;
return
pHashObj
->
enableUpdate
?
0
:
-
1
;
}
}
...
@@ -306,30 +390,27 @@ void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen) {
...
@@ -306,30 +390,27 @@ void *taosHashGet(SHashObj *pHashObj, const void *key, size_t keyLen) {
}
}
//TODO(yihaoDeng), merge with taosHashGetClone
//TODO(yihaoDeng), merge with taosHashGetClone
void
*
taosHashGetCloneExt
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
(
*
fp
)(
void
*
),
void
**
d
,
size_t
*
sz
)
{
void
*
taosHashGetCloneExt
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
(
*
fp
)(
void
*
),
void
**
d
,
size_t
*
sz
)
{
if
(
taosHashTableEmpty
(
pHashObj
)
||
keyLen
==
0
||
key
==
NULL
)
{
if
(
pHashObj
==
NULL
||
taosHashTableEmpty
(
pHashObj
)
||
keyLen
==
0
||
key
==
NULL
)
{
return
NULL
;
return
NULL
;
}
}
uint32_t
hashVal
=
(
*
pHashObj
->
hashFp
)(
key
,
(
uint32_t
)
keyLen
);
uint32_t
hashVal
=
(
*
pHashObj
->
hashFp
)(
key
,
(
uint32_t
)
keyLen
);
// only add the read lock to disable the resize process
// only add the read lock to disable the resize process
__rd_lock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRLock
(
pHashObj
);
int32_t
slot
=
HASH_INDEX
(
hashVal
,
pHashObj
->
capacity
);
int32_t
slot
=
HASH_INDEX
(
hashVal
,
pHashObj
->
capacity
);
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
// no data, return directly
// no data, return directly
if
(
atomic_load_32
(
&
pe
->
num
)
==
0
)
{
if
(
atomic_load_32
(
&
pe
->
num
)
==
0
)
{
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRUnlock
(
pHashObj
);
return
NULL
;
return
NULL
;
}
}
char
*
data
=
NULL
;
char
*
data
=
NULL
;
// lock entry
taosHashEntryRLock
(
pHashObj
,
pe
);
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosRLockLatch
(
&
pe
->
latch
);
}
if
(
pe
->
num
>
0
)
{
if
(
pe
->
num
>
0
)
{
assert
(
pe
->
next
!=
NULL
);
assert
(
pe
->
next
!=
NULL
);
...
@@ -342,56 +423,47 @@ void* taosHashGetCloneExt(SHashObj *pHashObj, const void *key, size_t keyLen, vo
...
@@ -342,56 +423,47 @@ void* taosHashGetCloneExt(SHashObj *pHashObj, const void *key, size_t keyLen, vo
if
(
fp
!=
NULL
)
{
if
(
fp
!=
NULL
)
{
fp
(
GET_HASH_NODE_DATA
(
pNode
));
fp
(
GET_HASH_NODE_DATA
(
pNode
));
}
}
if
(
*
d
==
NULL
)
{
if
(
*
d
==
NULL
)
{
*
sz
=
pNode
->
dataLen
+
EXT_SIZE
;
*
sz
=
pNode
->
dataLen
;
*
d
=
calloc
(
1
,
*
sz
);
*
d
=
calloc
(
1
,
*
sz
);
}
else
if
(
*
sz
<
pNode
->
dataLen
){
}
else
if
(
*
sz
<
pNode
->
dataLen
){
*
sz
=
pNode
->
dataLen
+
EXT_SIZE
;
*
sz
=
pNode
->
dataLen
;
*
d
=
realloc
(
*
d
,
*
sz
);
*
d
=
realloc
(
*
d
,
*
sz
);
}
}
memcpy
((
char
*
)(
*
d
),
GET_HASH_NODE_DATA
(
pNode
),
pNode
->
dataLen
);
memcpy
((
char
*
)(
*
d
),
GET_HASH_NODE_DATA
(
pNode
),
pNode
->
dataLen
);
// just make runtime happy
if
((
*
sz
)
-
pNode
->
dataLen
>
0
)
{
memset
((
char
*
)(
*
d
)
+
pNode
->
dataLen
,
0
,
(
*
sz
)
-
pNode
->
dataLen
);
}
data
=
GET_HASH_NODE_DATA
(
pNode
);
data
=
GET_HASH_NODE_DATA
(
pNode
);
}
}
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosHashEntryRUnlock
(
pHashObj
,
pe
);
taosRUnLockLatch
(
&
pe
->
latch
);
taosHashRUnlock
(
pHashObj
);
}
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
return
data
;
return
data
;
}
}
void
*
taosHashGetClone
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
(
*
fp
)(
void
*
),
void
*
d
)
{
void
*
taosHashGetClone
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
(
*
fp
)(
void
*
),
void
*
d
)
{
if
(
taosHashTableEmpty
(
pHashObj
)
||
keyLen
==
0
||
key
==
NULL
)
{
if
(
pHashObj
==
NULL
||
taosHashTableEmpty
(
pHashObj
)
||
keyLen
==
0
||
key
==
NULL
)
{
return
NULL
;
return
NULL
;
}
}
uint32_t
hashVal
=
(
*
pHashObj
->
hashFp
)(
key
,
(
uint32_t
)
keyLen
);
uint32_t
hashVal
=
(
*
pHashObj
->
hashFp
)(
key
,
(
uint32_t
)
keyLen
);
// only add the read lock to disable the resize process
// only add the read lock to disable the resize process
__rd_lock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRLock
(
pHashObj
);
int32_t
slot
=
HASH_INDEX
(
hashVal
,
pHashObj
->
capacity
);
int32_t
slot
=
HASH_INDEX
(
hashVal
,
pHashObj
->
capacity
);
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
// no data, return directly
// no data, return directly
if
(
atomic_load_32
(
&
pe
->
num
)
==
0
)
{
if
(
atomic_load_32
(
&
pe
->
num
)
==
0
)
{
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRUnlock
(
pHashObj
);
return
NULL
;
return
NULL
;
}
}
char
*
data
=
NULL
;
char
*
data
=
NULL
;
// lock entry
taosHashEntryRLock
(
pHashObj
,
pe
);
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosRLockLatch
(
&
pe
->
latch
);
}
if
(
pe
->
num
>
0
)
{
if
(
pe
->
num
>
0
)
{
assert
(
pe
->
next
!=
NULL
);
assert
(
pe
->
next
!=
NULL
);
...
@@ -412,11 +484,9 @@ void* taosHashGetClone(SHashObj *pHashObj, const void *key, size_t keyLen, void
...
@@ -412,11 +484,9 @@ void* taosHashGetClone(SHashObj *pHashObj, const void *key, size_t keyLen, void
data
=
GET_HASH_NODE_DATA
(
pNode
);
data
=
GET_HASH_NODE_DATA
(
pNode
);
}
}
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosHashEntryRUnlock
(
pHashObj
,
pe
);
taosRUnLockLatch
(
&
pe
->
latch
);
taosHashRUnlock
(
pHashObj
);
}
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
return
data
;
return
data
;
}
}
...
@@ -425,28 +495,26 @@ int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen) {
...
@@ -425,28 +495,26 @@ int32_t taosHashRemove(SHashObj *pHashObj, const void *key, size_t keyLen) {
}
}
int32_t
taosHashRemoveWithData
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
*
data
,
size_t
dsize
)
{
int32_t
taosHashRemoveWithData
(
SHashObj
*
pHashObj
,
const
void
*
key
,
size_t
keyLen
,
void
*
data
,
size_t
dsize
)
{
if
(
pHashObj
==
NULL
||
taosHashTableEmpty
(
pHashObj
))
{
if
(
pHashObj
==
NULL
||
taosHashTableEmpty
(
pHashObj
)
||
key
==
NULL
||
keyLen
==
0
)
{
return
-
1
;
return
-
1
;
}
}
uint32_t
hashVal
=
(
*
pHashObj
->
hashFp
)(
key
,
(
uint32_t
)
keyLen
);
uint32_t
hashVal
=
(
*
pHashObj
->
hashFp
)(
key
,
(
uint32_t
)
keyLen
);
// disable the resize process
// disable the resize process
__rd_lock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRLock
(
pHashObj
);
int32_t
slot
=
HASH_INDEX
(
hashVal
,
pHashObj
->
capacity
);
int32_t
slot
=
HASH_INDEX
(
hashVal
,
pHashObj
->
capacity
);
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosHashEntryWLock
(
pHashObj
,
pe
);
taosWLockLatch
(
&
pe
->
latch
);
}
// double check after locked
// double check after locked
if
(
pe
->
num
==
0
)
{
if
(
pe
->
num
==
0
)
{
assert
(
pe
->
next
==
NULL
);
assert
(
pe
->
next
==
NULL
);
taosWUnLockLatch
(
&
pe
->
latch
);
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashEntryWUnlock
(
pHashObj
,
pe
);
taosHashRUnlock
(
pHashObj
);
return
-
1
;
return
-
1
;
}
}
...
@@ -455,49 +523,46 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe
...
@@ -455,49 +523,46 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe
SHashNode
*
prevNode
=
NULL
;
SHashNode
*
prevNode
=
NULL
;
while
(
pNode
)
{
while
(
pNode
)
{
if
((
pNode
->
keyLen
==
keyLen
)
&&
((
*
(
pHashObj
->
equalFp
))(
GET_HASH_NODE_KEY
(
pNode
),
key
,
keyLen
)
==
0
)
&&
pNode
->
removed
==
0
)
if
((
pNode
->
keyLen
==
keyLen
)
&&
break
;
((
*
(
pHashObj
->
equalFp
))(
GET_HASH_NODE_KEY
(
pNode
),
key
,
keyLen
)
==
0
)
&&
pNode
->
removed
==
0
)
{
prevNode
=
pNode
;
code
=
0
;
// it is found
pNode
=
pNode
->
next
;
}
atomic_sub_fetch_32
(
&
pNode
->
refCount
,
1
);
pNode
->
removed
=
1
;
if
(
pNode
->
refCount
<=
0
)
{
if
(
prevNode
==
NULL
)
{
pe
->
next
=
pNode
->
next
;
}
else
{
prevNode
->
next
=
pNode
->
next
;
}
if
(
pNode
)
{
if
(
data
)
memcpy
(
data
,
GET_HASH_NODE_DATA
(
pNode
),
dsize
);
code
=
0
;
// it is found
atomic_sub_fetch_32
(
&
pNode
->
count
,
1
);
pe
->
num
--
;
pNode
->
removed
=
1
;
atomic_sub_fetch_64
(
&
pHashObj
->
size
,
1
);
if
(
pNode
->
count
<=
0
)
{
FREE_HASH_NODE
(
pNode
);
if
(
prevNode
)
{
prevNode
->
next
=
pNode
->
next
;
}
else
{
pe
->
next
=
pNode
->
next
;
}
}
}
else
{
if
(
data
)
memcpy
(
data
,
GET_HASH_NODE_DATA
(
pNode
),
dsize
);
prevNode
=
pNode
;
pNode
=
pNode
->
next
;
pe
->
num
--
;
atomic_sub_fetch_64
(
&
pHashObj
->
size
,
1
);
FREE_HASH_NODE
(
pHashObj
,
pNode
);
}
}
}
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosWUnLockLatch
(
&
pe
->
latch
);
}
}
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashEntryWUnlock
(
pHashObj
,
pe
);
taosHashRUnlock
(
pHashObj
);
return
code
;
return
code
;
}
}
int32_t
taosHashCondTraverse
(
SHashObj
*
pHashObj
,
bool
(
*
fp
)(
void
*
,
void
*
),
void
*
param
)
{
void
taosHashCondTraverse
(
SHashObj
*
pHashObj
,
bool
(
*
fp
)(
void
*
,
void
*
),
void
*
param
)
{
if
(
pHashObj
==
NULL
||
taosHashTableEmpty
(
pHashObj
))
{
if
(
pHashObj
==
NULL
||
taosHashTableEmpty
(
pHashObj
)
||
fp
==
NULL
)
{
return
0
;
return
;
}
}
// disable the resize process
// disable the resize process
__rd_lock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRLock
(
pHashObj
);
int32_t
numOfEntries
=
(
int32_t
)
pHashObj
->
capacity
;
int32_t
numOfEntries
=
(
int32_t
)
pHashObj
->
capacity
;
for
(
int32_t
i
=
0
;
i
<
numOfEntries
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
numOfEntries
;
++
i
)
{
...
@@ -506,63 +571,32 @@ int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), voi
...
@@ -506,63 +571,32 @@ int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), voi
continue
;
continue
;
}
}
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosHashEntryWLock
(
pHashObj
,
pEntry
);
taosWLockLatch
(
&
pEntry
->
latch
);
}
// todo remove the first node
SHashNode
*
pNode
=
NULL
;
while
((
pNode
=
pEntry
->
next
)
!=
NULL
)
{
if
(
fp
&&
(
!
fp
(
param
,
GET_HASH_NODE_DATA
(
pNode
))))
{
pEntry
->
num
-=
1
;
atomic_sub_fetch_64
(
&
pHashObj
->
size
,
1
);
pEntry
->
next
=
pNode
->
next
;
if
(
pEntry
->
num
==
0
)
{
assert
(
pEntry
->
next
==
NULL
);
}
else
{
assert
(
pEntry
->
next
!=
NULL
);
}
FREE_HASH_NODE
(
pHashObj
,
pNode
);
SHashNode
*
pPrevNode
=
NULL
;
SHashNode
*
pNode
=
pEntry
->
next
;
while
(
pNode
!=
NULL
)
{
if
(
fp
(
param
,
GET_HASH_NODE_DATA
(
pNode
)))
{
pPrevNode
=
pNode
;
pNode
=
pNode
->
next
;
}
else
{
}
else
{
break
;
if
(
pPrevNode
==
NULL
)
{
}
pEntry
->
next
=
pNode
->
next
;
}
// handle the following node
if
(
pNode
!=
NULL
)
{
assert
(
pNode
==
pEntry
->
next
);
SHashNode
*
pNext
=
NULL
;
while
((
pNext
=
pNode
->
next
)
!=
NULL
)
{
// not qualified, remove it
if
(
fp
&&
(
!
fp
(
param
,
GET_HASH_NODE_DATA
(
pNext
))))
{
pNode
->
next
=
pNext
->
next
;
pEntry
->
num
-=
1
;
atomic_sub_fetch_64
(
&
pHashObj
->
size
,
1
);
if
(
pEntry
->
num
==
0
)
{
assert
(
pEntry
->
next
==
NULL
);
}
else
{
assert
(
pEntry
->
next
!=
NULL
);
}
FREE_HASH_NODE
(
pHashObj
,
pNext
);
}
else
{
}
else
{
p
Node
=
pN
ext
;
p
PrevNode
->
next
=
pNode
->
n
ext
;
}
}
pEntry
->
num
-=
1
;
atomic_sub_fetch_64
(
&
pHashObj
->
size
,
1
);
SHashNode
*
next
=
pNode
->
next
;
FREE_HASH_NODE
(
pNode
);
pNode
=
next
;
}
}
}
}
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosHashEntryWUnlock
(
pHashObj
,
pEntry
);
taosWUnLockLatch
(
&
pEntry
->
latch
);
}
}
}
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRUnlock
(
pHashObj
);
return
0
;
}
}
void
taosHashClear
(
SHashObj
*
pHashObj
)
{
void
taosHashClear
(
SHashObj
*
pHashObj
)
{
...
@@ -572,12 +606,12 @@ void taosHashClear(SHashObj *pHashObj) {
...
@@ -572,12 +606,12 @@ void taosHashClear(SHashObj *pHashObj) {
SHashNode
*
pNode
,
*
pNext
;
SHashNode
*
pNode
,
*
pNext
;
__wr_lock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashWLock
(
pHashObj
);
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
capacity
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
capacity
;
++
i
)
{
SHashEntry
*
pEntry
=
pHashObj
->
hashList
[
i
];
SHashEntry
*
pEntry
=
pHashObj
->
hashList
[
i
];
if
(
pEntry
->
num
==
0
)
{
if
(
pEntry
->
num
==
0
)
{
assert
(
pEntry
->
next
==
0
);
assert
(
pEntry
->
next
==
NULL
);
continue
;
continue
;
}
}
...
@@ -586,7 +620,7 @@ void taosHashClear(SHashObj *pHashObj) {
...
@@ -586,7 +620,7 @@ void taosHashClear(SHashObj *pHashObj) {
while
(
pNode
)
{
while
(
pNode
)
{
pNext
=
pNode
->
next
;
pNext
=
pNode
->
next
;
FREE_HASH_NODE
(
p
HashObj
,
p
Node
);
FREE_HASH_NODE
(
pNode
);
pNode
=
pNext
;
pNode
=
pNext
;
}
}
...
@@ -596,7 +630,7 @@ void taosHashClear(SHashObj *pHashObj) {
...
@@ -596,7 +630,7 @@ void taosHashClear(SHashObj *pHashObj) {
}
}
pHashObj
->
size
=
0
;
pHashObj
->
size
=
0
;
__wr_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashWUnlock
(
pHashObj
);
}
}
// the input paras should be SHashObj **, so the origin input will be set by tfree(*pHashObj)
// the input paras should be SHashObj **, so the origin input will be set by tfree(*pHashObj)
...
@@ -616,25 +650,28 @@ void taosHashCleanup(SHashObj *pHashObj) {
...
@@ -616,25 +650,28 @@ void taosHashCleanup(SHashObj *pHashObj) {
}
}
taosArrayDestroy
(
&
pHashObj
->
pMemBlock
);
taosArrayDestroy
(
&
pHashObj
->
pMemBlock
);
free
(
pHashObj
);
memset
(
pHashObj
,
0
,
sizeof
(
SHashObj
));
tfree
(
pHashObj
);
}
}
// for profile only
// for profile only
int32_t
taosHashGetMaxOverflowLinkLength
(
const
SHashObj
*
pHashObj
)
{
int32_t
taosHashGetMaxOverflowLinkLength
(
SHashObj
*
pHashObj
)
{
if
(
pHashObj
==
NULL
||
taosHashTableEmpty
(
pHashObj
))
{
if
(
pHashObj
==
NULL
||
taosHashTableEmpty
(
pHashObj
))
{
return
0
;
return
0
;
}
}
int32_t
num
=
0
;
int32_t
num
=
0
;
taosHashRLock
(
pHashObj
);
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
size
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
size
;
++
i
)
{
SHashEntry
*
pEntry
=
pHashObj
->
hashList
[
i
];
SHashEntry
*
pEntry
=
pHashObj
->
hashList
[
i
];
// fine grain per entry lock is not held since this is used
// for profiling only and doesn't need an accurate count.
if
(
num
<
pEntry
->
num
)
{
if
(
num
<
pEntry
->
num
)
{
num
=
pEntry
->
num
;
num
=
pEntry
->
num
;
}
}
}
}
taosHashRUnlock
(
pHashObj
);
return
num
;
return
num
;
}
}
...
@@ -644,27 +681,23 @@ void taosHashTableResize(SHashObj *pHashObj) {
...
@@ -644,27 +681,23 @@ void taosHashTableResize(SHashObj *pHashObj) {
return
;
return
;
}
}
// double the original capacity
int32_t
newCapacity
=
(
int32_t
)(
pHashObj
->
capacity
<<
1u
);
SHashNode
*
pNode
=
NULL
;
if
(
newCapacity
>
HASH_MAX_CAPACITY
)
{
SHashNode
*
pNext
=
NULL
;
uDebug
(
"current capacity:%zu, maximum capacity:%d, no resize applied due to limitation is reached"
,
pHashObj
->
capacity
,
HASH_MAX_CAPACITY
);
int32_t
newSize
=
(
int32_t
)(
pHashObj
->
capacity
<<
1u
);
if
(
newSize
>
HASH_MAX_CAPACITY
)
{
// uDebug("current capacity:%d, maximum capacity:%d, no resize applied due to limitation is reached",
// pHashObj->capacity, HASH_MAX_CAPACITY);
return
;
return
;
}
}
int64_t
st
=
taosGetTimestampUs
();
int64_t
st
=
taosGetTimestampUs
();
void
*
pNewEntryList
=
realloc
(
pHashObj
->
hashList
,
sizeof
(
void
*
)
*
new
Size
);
void
*
pNewEntryList
=
realloc
(
pHashObj
->
hashList
,
sizeof
(
void
*
)
*
new
Capacity
);
if
(
pNewEntryList
==
NULL
)
{
// todo handle error
if
(
pNewEntryList
==
NULL
)
{
// uDebug("cache resize failed due to out of memory, capacity remain:%d
", pHashObj->capacity);
uDebug
(
"cache resize failed due to out of memory, capacity remain:%zu
"
,
pHashObj
->
capacity
);
return
;
return
;
}
}
pHashObj
->
hashList
=
pNewEntryList
;
pHashObj
->
hashList
=
pNewEntryList
;
size_t
inc
=
new
Size
-
pHashObj
->
capacity
;
size_t
inc
=
new
Capacity
-
pHashObj
->
capacity
;
void
*
p
=
calloc
(
inc
,
sizeof
(
SHashEntry
));
void
*
p
=
calloc
(
inc
,
sizeof
(
SHashEntry
));
for
(
int32_t
i
=
0
;
i
<
inc
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
inc
;
++
i
)
{
...
@@ -673,78 +706,46 @@ void taosHashTableResize(SHashObj *pHashObj) {
...
@@ -673,78 +706,46 @@ void taosHashTableResize(SHashObj *pHashObj) {
taosArrayPush
(
pHashObj
->
pMemBlock
,
&
p
);
taosArrayPush
(
pHashObj
->
pMemBlock
,
&
p
);
pHashObj
->
capacity
=
newSize
;
pHashObj
->
capacity
=
newCapacity
;
for
(
int32_t
i
=
0
;
i
<
pHashObj
->
capacity
;
++
i
)
{
for
(
int32_t
idx
=
0
;
idx
<
pHashObj
->
capacity
;
++
idx
)
{
SHashEntry
*
pe
=
pHashObj
->
hashList
[
i
];
SHashEntry
*
pe
=
pHashObj
->
hashList
[
idx
];
SHashNode
*
pNode
;
if
(
pe
->
num
==
0
)
{
SHashNode
*
pNext
;
assert
(
pe
->
next
==
NULL
);
SHashNode
*
pPrev
=
NULL
;
}
else
{
assert
(
pe
->
next
!=
NULL
);
}
if
(
pe
->
num
==
0
)
{
if
(
pe
->
num
==
0
)
{
assert
(
pe
->
next
==
NULL
);
assert
(
pe
->
next
==
NULL
);
continue
;
continue
;
}
}
while
((
pNode
=
pe
->
next
)
!=
NULL
)
{
pNode
=
pe
->
next
;
int32_t
j
=
HASH_INDEX
(
pNode
->
hashVal
,
pHashObj
->
capacity
);
if
(
j
!=
i
)
{
pe
->
num
-=
1
;
pe
->
next
=
pNode
->
next
;
if
(
pe
->
num
==
0
)
{
assert
(
pe
->
next
==
NULL
);
}
else
{
assert
(
pe
->
next
!=
NULL
);
}
SHashEntry
*
pNewEntry
=
pHashObj
->
hashList
[
j
];
pushfrontNodeInEntryList
(
pNewEntry
,
pNode
);
}
else
{
break
;
}
}
if
(
pNode
!=
NULL
)
{
while
((
pNext
=
pNode
->
next
)
!=
NULL
)
{
int32_t
j
=
HASH_INDEX
(
pNext
->
hashVal
,
pHashObj
->
capacity
);
if
(
j
!=
i
)
{
pe
->
num
-=
1
;
pNode
->
next
=
pNext
->
next
;
pNext
->
next
=
NULL
;
// added into new slot
assert
(
pNode
!=
NULL
);
SHashEntry
*
pNewEntry
=
pHashObj
->
hashList
[
j
];
if
(
pNewEntry
->
num
==
0
)
{
assert
(
pNewEntry
->
next
==
NULL
);
}
else
{
assert
(
pNewEntry
->
next
!=
NULL
);
}
pushfrontNodeInEntryList
(
pNewEntry
,
pNext
);
while
(
pNode
!=
NULL
)
{
int32_t
newIdx
=
HASH_INDEX
(
pNode
->
hashVal
,
pHashObj
->
capacity
);
pNext
=
pNode
->
next
;
if
(
newIdx
!=
idx
)
{
pe
->
num
-=
1
;
if
(
pPrev
==
NULL
)
{
pe
->
next
=
pNext
;
}
else
{
}
else
{
p
Node
=
pNext
;
p
Prev
->
next
=
pNext
;
}
}
}
if
(
pe
->
num
==
0
)
{
SHashEntry
*
pNewEntry
=
pHashObj
->
hashList
[
newIdx
];
assert
(
pe
->
next
==
NULL
);
pushfrontNodeInEntryList
(
pNewEntry
,
pNode
);
}
else
{
}
else
{
assert
(
pe
->
next
!=
NULL
)
;
pPrev
=
pNode
;
}
}
pNode
=
pNext
;
}
}
}
}
int64_t
et
=
taosGetTimestampUs
();
int64_t
et
=
taosGetTimestampUs
();
uDebug
(
"hash table resize completed, new capacity:%d, load factor:%f, elapsed time:%fms"
,
(
int32_t
)
pHashObj
->
capacity
,
uDebug
(
"hash table resize completed, new capacity:%d, load factor:%f, elapsed time:%fms"
,
(
int32_t
)
pHashObj
->
capacity
,
((
double
)
pHashObj
->
size
)
/
pHashObj
->
capacity
,
(
et
-
st
)
/
1000
.
0
);
((
double
)
pHashObj
->
size
)
/
pHashObj
->
capacity
,
(
et
-
st
)
/
1000
.
0
);
}
}
SHashNode
*
doCreateHashNode
(
const
void
*
key
,
size_t
keyLen
,
const
void
*
pData
,
size_t
dsize
,
uint32_t
hashVal
)
{
SHashNode
*
doCreateHashNode
(
const
void
*
key
,
size_t
keyLen
,
const
void
*
pData
,
size_t
dsize
,
uint32_t
hashVal
)
{
...
@@ -757,8 +758,8 @@ SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, s
...
@@ -757,8 +758,8 @@ SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, s
pNewNode
->
keyLen
=
(
uint32_t
)
keyLen
;
pNewNode
->
keyLen
=
(
uint32_t
)
keyLen
;
pNewNode
->
hashVal
=
hashVal
;
pNewNode
->
hashVal
=
hashVal
;
pNewNode
->
dataLen
=
(
uint32_t
)
dsize
;
pNewNode
->
dataLen
=
(
uint32_t
)
dsize
;
pNewNode
->
c
ount
=
1
;
pNewNode
->
refC
ount
=
1
;
pNewNode
->
removed
=
0
;
pNewNode
->
removed
=
0
;
pNewNode
->
next
=
NULL
;
pNewNode
->
next
=
NULL
;
...
@@ -805,40 +806,37 @@ static void *taosHashReleaseNode(SHashObj *pHashObj, void *p, int *slot) {
...
@@ -805,40 +806,37 @@ static void *taosHashReleaseNode(SHashObj *pHashObj, void *p, int *slot) {
*
slot
=
HASH_INDEX
(
pOld
->
hashVal
,
pHashObj
->
capacity
);
*
slot
=
HASH_INDEX
(
pOld
->
hashVal
,
pHashObj
->
capacity
);
SHashEntry
*
pe
=
pHashObj
->
hashList
[
*
slot
];
SHashEntry
*
pe
=
pHashObj
->
hashList
[
*
slot
];
// lock entry
taosHashEntryWLock
(
pHashObj
,
pe
);
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosWLockLatch
(
&
pe
->
latch
);
}
SHashNode
*
pNode
=
pe
->
next
;
SHashNode
*
pNode
=
pe
->
next
;
while
(
pNode
)
{
while
(
pNode
)
{
if
(
pNode
==
pOld
)
if
(
pNode
==
pOld
)
break
;
break
;
prevNode
=
pNode
;
prevNode
=
pNode
;
pNode
=
pNode
->
next
;
pNode
=
pNode
->
next
;
}
}
if
(
pNode
)
{
if
(
pNode
)
{
pNode
=
pNode
->
next
;
pNode
=
pNode
->
next
;
while
(
pNode
)
{
while
(
pNode
)
{
if
(
pNode
->
removed
==
0
)
break
;
if
(
pNode
->
removed
==
0
)
break
;
pNode
=
pNode
->
next
;
pNode
=
pNode
->
next
;
}
}
atomic_sub_fetch_32
(
&
pOld
->
c
ount
,
1
);
atomic_sub_fetch_32
(
&
pOld
->
refC
ount
,
1
);
if
(
pOld
->
c
ount
<=
0
)
{
if
(
pOld
->
refC
ount
<=
0
)
{
if
(
prevNode
)
{
if
(
prevNode
)
{
prevNode
->
next
=
pOld
->
next
;
prevNode
->
next
=
pOld
->
next
;
}
else
{
}
else
{
pe
->
next
=
pOld
->
next
;
pe
->
next
=
pOld
->
next
;
}
}
pe
->
num
--
;
pe
->
num
--
;
atomic_sub_fetch_64
(
&
pHashObj
->
size
,
1
);
atomic_sub_fetch_64
(
&
pHashObj
->
size
,
1
);
FREE_HASH_NODE
(
p
HashObj
,
p
Old
);
FREE_HASH_NODE
(
pOld
);
}
}
}
else
{
}
else
{
uError
(
"pNode:%p data:%p is not there!!!"
,
pNode
,
p
);
uError
(
"pNode:%p data:%p is not there!!!"
,
pNode
,
p
);
}
}
...
@@ -847,22 +845,20 @@ static void *taosHashReleaseNode(SHashObj *pHashObj, void *p, int *slot) {
...
@@ -847,22 +845,20 @@ static void *taosHashReleaseNode(SHashObj *pHashObj, void *p, int *slot) {
}
}
void
*
taosHashIterate
(
SHashObj
*
pHashObj
,
void
*
p
)
{
void
*
taosHashIterate
(
SHashObj
*
pHashObj
,
void
*
p
)
{
if
(
pHashObj
==
NULL
)
return
NULL
;
if
(
pHashObj
==
NULL
)
return
NULL
;
int
slot
=
0
;
int
slot
=
0
;
char
*
data
=
NULL
;
char
*
data
=
NULL
;
// only add the read lock to disable the resize process
// only add the read lock to disable the resize process
__rd_lock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRLock
(
pHashObj
);
SHashNode
*
pNode
=
NULL
;
SHashNode
*
pNode
=
NULL
;
if
(
p
)
{
if
(
p
)
{
pNode
=
taosHashReleaseNode
(
pHashObj
,
p
,
&
slot
);
pNode
=
taosHashReleaseNode
(
pHashObj
,
p
,
&
slot
);
if
(
pNode
==
NULL
)
{
if
(
pNode
==
NULL
)
{
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosHashEntryWUnlock
(
pHashObj
,
pe
);
taosWUnLockLatch
(
&
pe
->
latch
);
}
slot
=
slot
+
1
;
slot
=
slot
+
1
;
}
}
...
@@ -872,10 +868,7 @@ void *taosHashIterate(SHashObj *pHashObj, void *p) {
...
@@ -872,10 +868,7 @@ void *taosHashIterate(SHashObj *pHashObj, void *p) {
for
(;
slot
<
pHashObj
->
capacity
;
++
slot
)
{
for
(;
slot
<
pHashObj
->
capacity
;
++
slot
)
{
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
// lock entry
taosHashEntryWLock
(
pHashObj
,
pe
);
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosWLockLatch
(
&
pe
->
latch
);
}
pNode
=
pe
->
next
;
pNode
=
pe
->
next
;
while
(
pNode
)
{
while
(
pNode
)
{
...
@@ -885,22 +878,18 @@ void *taosHashIterate(SHashObj *pHashObj, void *p) {
...
@@ -885,22 +878,18 @@ void *taosHashIterate(SHashObj *pHashObj, void *p) {
if
(
pNode
)
break
;
if
(
pNode
)
break
;
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosHashEntryWUnlock
(
pHashObj
,
pe
);
taosWUnLockLatch
(
&
pe
->
latch
);
}
}
}
}
}
if
(
pNode
)
{
if
(
pNode
)
{
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
atomic_add_fetch_32
(
&
pNode
->
c
ount
,
1
);
atomic_add_fetch_32
(
&
pNode
->
refC
ount
,
1
);
data
=
GET_HASH_NODE_DATA
(
pNode
);
data
=
GET_HASH_NODE_DATA
(
pNode
);
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosHashEntryWUnlock
(
pHashObj
,
pe
);
taosWUnLockLatch
(
&
pe
->
latch
);
}
}
}
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRUnlock
(
pHashObj
);
return
data
;
return
data
;
}
}
...
@@ -909,15 +898,13 @@ void taosHashCancelIterate(SHashObj *pHashObj, void *p) {
...
@@ -909,15 +898,13 @@ void taosHashCancelIterate(SHashObj *pHashObj, void *p) {
if
(
pHashObj
==
NULL
||
p
==
NULL
)
return
;
if
(
pHashObj
==
NULL
||
p
==
NULL
)
return
;
// only add the read lock to disable the resize process
// only add the read lock to disable the resize process
__rd_lock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashRLock
(
pHashObj
);
int
slot
;
int
slot
;
taosHashReleaseNode
(
pHashObj
,
p
,
&
slot
);
taosHashReleaseNode
(
pHashObj
,
p
,
&
slot
);
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosWUnLockLatch
(
&
pe
->
latch
);
}
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
taosHashEntryWUnlock
(
pHashObj
,
pe
);
taosHashRUnlock
(
pHashObj
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录