Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
m0_53320357
TDengine
提交
b6f64b3f
TDengine
项目概览
m0_53320357
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b6f64b3f
编写于
4月 16, 2020
作者:
H
hjxilinx
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[td-98] add qsort and move to algo file
上级
130d4cd2
变更
18
展开全部
隐藏空白更改
内联
并排
Showing
18 changed file
with
643 addition
and
401 deletion
+643
-401
src/query/inc/qextbuffer.h
src/query/inc/qextbuffer.h
+13
-17
src/query/inc/queryExecutor.h
src/query/inc/queryExecutor.h
+2
-2
src/query/src/qast.c
src/query/src/qast.c
+1
-1
src/query/src/qextbuffer.c
src/query/src/qextbuffer.c
+5
-5
src/query/src/queryExecutor.c
src/query/src/queryExecutor.c
+117
-113
src/util/inc/talgo.h
src/util/inc/talgo.h
+30
-0
src/util/inc/tskiplist.h
src/util/inc/tskiplist.h
+1
-1
src/util/src/hash.c
src/util/src/hash.c
+0
-2
src/util/src/talgo.c
src/util/src/talgo.c
+213
-0
src/util/src/tskiplist.c
src/util/src/tskiplist.c
+1
-1
src/util/src/tutil.c
src/util/src/tutil.c
+0
-69
src/util/tests/skiplistTest.cpp
src/util/tests/skiplistTest.cpp
+6
-6
src/vnode/tsdb/inc/tsdb.h
src/vnode/tsdb/inc/tsdb.h
+9
-4
src/vnode/tsdb/inc/tsdbMain.h
src/vnode/tsdb/inc/tsdbMain.h
+1
-0
src/vnode/tsdb/src/tsdbMain.c
src/vnode/tsdb/src/tsdbMain.c
+1
-1
src/vnode/tsdb/src/tsdbMeta.c
src/vnode/tsdb/src/tsdbMeta.c
+24
-8
src/vnode/tsdb/src/tsdbRead.c
src/vnode/tsdb/src/tsdbRead.c
+208
-160
tests/examples/c/demo.c
tests/examples/c/demo.c
+11
-11
未找到文件。
src/query/inc/qextbuffer.h
浏览文件 @
b6f64b3f
...
...
@@ -19,9 +19,14 @@
extern
"C"
{
#endif
#include "os.h"
#include "taosmsg.h"
#include "tarray.h"
#include "tutil.h"
#include "dataformat.h"
#include "talgo.h"
#define DEFAULT_PAGE_SIZE 16384 // 16k larger than the SHistoInfo
#define MIN_BUFFER_SIZE (1 << 19)
...
...
@@ -55,12 +60,12 @@ typedef struct tFlushoutData {
tFlushoutInfo
*
pFlushoutInfo
;
}
tFlushoutData
;
typedef
struct
SFileInfo
{
typedef
struct
S
Ext
FileInfo
{
uint32_t
nFileSize
;
// in pages
uint32_t
pageSize
;
uint32_t
numOfElemsInFile
;
tFlushoutData
flushoutData
;
}
SFileInfo
;
}
S
Ext
FileInfo
;
typedef
struct
tFilePage
{
uint64_t
numOfElems
;
...
...
@@ -109,26 +114,17 @@ typedef struct tExtMemBuffer {
char
*
path
;
FILE
*
file
;
SFileInfo
fileMeta
;
S
Ext
FileInfo
fileMeta
;
SColumnModel
*
pColumnModel
;
EXT_BUFFER_FLUSH_MODEL
flushModel
;
}
tExtMemBuffer
;
typedef
struct
tTagSchema
{
struct
SSchema
*
pSchema
;
int32_t
numOfCols
;
int32_t
colOffset
[];
}
tTagSchema
;
typedef
struct
tSidSet
{
int32_t
numOfSids
;
int32_t
numOfSubSet
;
STableIdInfo
**
pTableIdList
;
int32_t
*
starterPos
;
// position of each subgroup, generated according to
SColumnModel
*
pColumnModel
;
SColumnOrderInfo
orderIdx
;
}
tSidSet
;
//typedef struct tTagSchema {
// struct SSchema *pSchema;
// int32_t numOfCols;
// int32_t colOffset[];
//} tTagSchema;
/**
*
...
...
src/query/inc/queryExecutor.h
浏览文件 @
b6f64b3f
...
...
@@ -39,7 +39,7 @@ typedef int32_t (*__block_search_fn_t)(char* data, int32_t num, int64_t key, int
typedef
struct
SSqlGroupbyExpr
{
int16_t
tableIndex
;
int16_t
numOfGroupCols
;
SColIndex
columnInfo
[
TSDB_MAX_TAGS
];
// group by columns information
SColIndex
*
columnInfo
;
// group by columns information
int16_t
orderIndex
;
// order by column index
int16_t
orderType
;
// order by type: asc/desc
}
SSqlGroupbyExpr
;
...
...
@@ -171,7 +171,7 @@ typedef struct SQInfo {
int32_t
pointsInterpo
;
int32_t
code
;
// error code to returned to client
sem_t
dataReady
;
SArray
*
pTable
IdList
;
// table id list
SArray
*
pTable
List
;
// table id list
void
*
tsdb
;
SQueryRuntimeEnv
runtimeEnv
;
...
...
src/query/src/qast.c
浏览文件 @
b6f64b3f
...
...
@@ -869,7 +869,7 @@ void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, S
if
(
pQueryInfo
->
colIndex
==
0
&&
pQueryInfo
->
optr
!=
TSDB_RELATION_LIKE
)
{
SQueryCond
cond
=
{
0
};
/*int32_t ret = */
setQueryCond
(
pQueryInfo
,
&
cond
);
/*int32_t ret = */
setQueryCond
(
pQueryInfo
,
&
cond
);
tQueryOnSkipList
(
pSkipList
,
&
cond
,
pQueryInfo
->
q
.
nType
,
result
);
}
else
{
/* Brutal force scan the whole skip list to find the appropriate result,
...
...
src/query/src/qextbuffer.c
浏览文件 @
b6f64b3f
...
...
@@ -43,7 +43,7 @@ tExtMemBuffer* createExtMemBuffer(int32_t inMemSize, int32_t elemSize, SColumnMo
pMemBuffer
->
path
=
strdup
(
name
);
pTrace
(
"create tmp file:%s"
,
pMemBuffer
->
path
);
SFileInfo
*
pFMeta
=
&
pMemBuffer
->
fileMeta
;
S
Ext
FileInfo
*
pFMeta
=
&
pMemBuffer
->
fileMeta
;
pFMeta
->
pageSize
=
DEFAULT_PAGE_SIZE
;
...
...
@@ -63,7 +63,7 @@ void* destoryExtMemBuffer(tExtMemBuffer *pMemBuffer) {
}
// release flush out info link
SFileInfo
*
pFileMeta
=
&
pMemBuffer
->
fileMeta
;
S
Ext
FileInfo
*
pFileMeta
=
&
pMemBuffer
->
fileMeta
;
if
(
pFileMeta
->
flushoutData
.
nAllocSize
!=
0
&&
pFileMeta
->
flushoutData
.
pFlushoutInfo
!=
NULL
)
{
tfree
(
pFileMeta
->
flushoutData
.
pFlushoutInfo
);
}
...
...
@@ -97,7 +97,7 @@ void* destoryExtMemBuffer(tExtMemBuffer *pMemBuffer) {
/*
* alloc more memory for flush out info entries.
*/
static
bool
allocFlushoutInfoEntries
(
SFileInfo
*
pFileMeta
)
{
static
bool
allocFlushoutInfoEntries
(
S
Ext
FileInfo
*
pFileMeta
)
{
pFileMeta
->
flushoutData
.
nAllocSize
=
pFileMeta
->
flushoutData
.
nAllocSize
<<
1
;
tFlushoutInfo
*
tmp
=
(
tFlushoutInfo
*
)
realloc
(
pFileMeta
->
flushoutData
.
pFlushoutInfo
,
...
...
@@ -208,7 +208,7 @@ int16_t tExtMemBufferPut(tExtMemBuffer *pMemBuffer, void *data, int32_t numOfRow
}
static
bool
tExtMemBufferUpdateFlushoutInfo
(
tExtMemBuffer
*
pMemBuffer
)
{
SFileInfo
*
pFileMeta
=
&
pMemBuffer
->
fileMeta
;
S
Ext
FileInfo
*
pFileMeta
=
&
pMemBuffer
->
fileMeta
;
if
(
pMemBuffer
->
flushModel
==
MULTIPLE_APPEND_MODEL
)
{
if
(
pFileMeta
->
flushoutData
.
nLength
==
pFileMeta
->
flushoutData
.
nAllocSize
&&
!
allocFlushoutInfoEntries
(
pFileMeta
))
{
...
...
@@ -238,7 +238,7 @@ static bool tExtMemBufferUpdateFlushoutInfo(tExtMemBuffer *pMemBuffer) {
}
static
void
tExtMemBufferClearFlushoutInfo
(
tExtMemBuffer
*
pMemBuffer
)
{
SFileInfo
*
pFileMeta
=
&
pMemBuffer
->
fileMeta
;
S
Ext
FileInfo
*
pFileMeta
=
&
pMemBuffer
->
fileMeta
;
pFileMeta
->
flushoutData
.
nLength
=
0
;
memset
(
pFileMeta
->
flushoutData
.
pFlushoutInfo
,
0
,
sizeof
(
tFlushoutInfo
)
*
pFileMeta
->
flushoutData
.
nAllocSize
);
...
...
src/query/src/queryExecutor.c
浏览文件 @
b6f64b3f
此差异已折叠。
点击以展开。
src/util/inc/talgo.h
0 → 100644
浏览文件 @
b6f64b3f
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TDENGINE_TALGO_H
#define TDENGINE_TALGO_H
#ifdef __cplusplus
extern
"C"
{
#endif
typedef
int32_t
(
*
__ext_compar_fn_t
)(
const
void
*
p1
,
const
void
*
p2
,
const
void
*
param
);
void
tqsort
(
void
*
src
,
size_t
numOfElem
,
size_t
size
,
const
void
*
param
,
__ext_compar_fn_t
comparFn
);
#ifdef __cplusplus
}
#endif
#endif // TDENGINE_TALGO_H
src/util/inc/tskiplist.h
浏览文件 @
b6f64b3f
...
...
@@ -159,7 +159,7 @@ void *tSkipListDestroy(SSkipList *pSkipList);
* @param level
* @param headSize
*/
void
tSkipList
Rand
NodeInfo
(
SSkipList
*
pSkipList
,
int32_t
*
level
,
int32_t
*
headSize
);
void
tSkipList
New
NodeInfo
(
SSkipList
*
pSkipList
,
int32_t
*
level
,
int32_t
*
headSize
);
/**
* put the skip list node into the skip list.
...
...
src/util/src/hash.c
浏览文件 @
b6f64b3f
...
...
@@ -461,9 +461,7 @@ void taosHashRemove(SHashObj *pHashObj, const char *key, size_t keyLen) {
pNode
->
next
=
NULL
;
pNode
->
prev
=
NULL
;
pTrace
(
"key:%s %p remove from hash table"
,
pNode
->
key
,
pNode
);
tfree
(
pNode
);
__unlock
(
pHashObj
->
lock
);
}
...
...
src/util/src/talgo.c
0 → 100644
浏览文件 @
b6f64b3f
#include "os.h"
#include "tutil.h"
#include "talgo.h"
#define doswap(__left, __right, __size, __buf) do {\
memcpy((__buf), (__left), (__size));\
memcpy((__left), (__right),(__size));\
memcpy((__right), (__buf), (__size));\
} while (0);
#define elePtrAt(base, size, idx) (void *)((char *)(base) + (size) * (idx))
static
void
median
(
void
*
src
,
size_t
size
,
size_t
s
,
size_t
e
,
const
void
*
param
,
__ext_compar_fn_t
comparFn
,
void
*
buf
)
{
int32_t
mid
=
((
e
-
s
)
>>
1u
)
+
s
;
if
(
comparFn
(
elePtrAt
(
src
,
size
,
mid
),
elePtrAt
(
src
,
size
,
s
),
param
)
==
1
)
{
doswap
(
elePtrAt
(
src
,
size
,
mid
),
elePtrAt
(
src
,
size
,
s
),
size
,
buf
);
}
if
(
comparFn
(
elePtrAt
(
src
,
size
,
mid
),
elePtrAt
(
src
,
size
,
e
),
param
)
==
1
)
{
doswap
(
elePtrAt
(
src
,
size
,
mid
),
elePtrAt
(
src
,
size
,
s
),
size
,
buf
);
doswap
(
elePtrAt
(
src
,
size
,
mid
),
elePtrAt
(
src
,
size
,
e
),
size
,
buf
);
}
else
if
(
comparFn
(
elePtrAt
(
src
,
size
,
s
),
elePtrAt
(
src
,
size
,
e
),
param
)
==
1
)
{
doswap
(
elePtrAt
(
src
,
size
,
s
),
elePtrAt
(
src
,
size
,
e
),
size
,
buf
);
}
assert
(
comparFn
(
elePtrAt
(
src
,
size
,
mid
),
elePtrAt
(
src
,
size
,
s
),
param
)
<=
0
&&
comparFn
(
elePtrAt
(
src
,
size
,
s
),
elePtrAt
(
src
,
size
,
e
),
param
)
<=
0
);
#ifdef _DEBUG_VIEW
tTagsPrints
(
src
[
s
],
pOrderDesc
->
pColumnModel
,
&
pOrderDesc
->
orderIdx
);
tTagsPrints
(
src
[
mid
],
pOrderDesc
->
pColumnModel
,
&
pOrderDesc
->
orderIdx
);
tTagsPrints
(
src
[
e
],
pOrderDesc
->
pColumnModel
,
&
pOrderDesc
->
orderIdx
);
#endif
}
static
void
tInsertSort
(
void
*
src
,
size_t
size
,
int32_t
s
,
int32_t
e
,
const
void
*
param
,
__ext_compar_fn_t
comparFn
,
void
*
buf
)
{
for
(
int32_t
i
=
s
+
1
;
i
<=
e
;
++
i
)
{
for
(
int32_t
j
=
i
;
j
>
s
;
--
j
)
{
if
(
comparFn
(
elePtrAt
(
src
,
size
,
j
),
elePtrAt
(
src
,
size
,
j
-
1
),
param
)
==
-
1
)
{
doswap
(
elePtrAt
(
src
,
size
,
j
),
elePtrAt
(
src
,
size
,
j
-
1
),
size
,
buf
);
}
else
{
break
;
}
}
}
}
void
tqsortImpl
(
void
*
src
,
int32_t
start
,
int32_t
end
,
size_t
size
,
const
void
*
param
,
__ext_compar_fn_t
comparFn
,
void
*
buf
)
{
// short array sort, incur another sort procedure instead of quick sort process
const
int32_t
THRESHOLD_SIZE
=
6
;
if
(
end
-
start
+
1
<=
THRESHOLD_SIZE
)
{
tInsertSort
(
src
,
size
,
start
,
end
,
param
,
comparFn
,
buf
);
return
;
}
median
(
src
,
size
,
start
,
end
,
param
,
comparFn
,
buf
);
int32_t
s
=
start
,
e
=
end
;
int32_t
endRightS
=
end
,
startLeftS
=
start
;
while
(
s
<
e
)
{
while
(
e
>
s
)
{
int32_t
ret
=
comparFn
(
elePtrAt
(
src
,
size
,
e
),
elePtrAt
(
src
,
size
,
s
),
param
);
if
(
ret
<
0
)
{
break
;
}
//move the data that equals to pivotal value to the right end of the list
if
(
ret
==
0
&&
e
!=
endRightS
)
{
doswap
(
elePtrAt
(
src
,
size
,
e
),
elePtrAt
(
src
,
size
,
endRightS
),
size
,
buf
);
endRightS
--
;
}
e
--
;
}
if
(
e
!=
s
)
{
doswap
(
elePtrAt
(
src
,
size
,
e
),
elePtrAt
(
src
,
size
,
s
),
size
,
buf
);
}
while
(
s
<
e
)
{
int32_t
ret
=
comparFn
(
elePtrAt
(
src
,
size
,
s
),
elePtrAt
(
src
,
size
,
e
),
param
);
if
(
ret
>
0
)
{
break
;
}
if
(
ret
==
0
&&
s
!=
startLeftS
)
{
doswap
(
elePtrAt
(
src
,
size
,
s
),
elePtrAt
(
src
,
size
,
startLeftS
),
size
,
buf
);
startLeftS
++
;
}
s
++
;
}
if
(
e
!=
s
)
{
doswap
(
elePtrAt
(
src
,
size
,
s
),
elePtrAt
(
src
,
size
,
e
),
size
,
buf
);
}
}
int32_t
rightPartStart
=
e
+
1
;
if
(
endRightS
!=
end
&&
e
<
end
)
{
int32_t
left
=
rightPartStart
;
int32_t
right
=
end
;
while
(
right
>
endRightS
&&
left
<=
endRightS
)
{
doswap
(
elePtrAt
(
src
,
size
,
left
),
elePtrAt
(
src
,
size
,
right
),
size
,
buf
);
left
++
;
right
--
;
}
rightPartStart
+=
(
end
-
endRightS
);
}
int32_t
leftPartEnd
=
e
-
1
;
if
(
startLeftS
!=
end
&&
s
>
start
)
{
int32_t
left
=
start
;
int32_t
right
=
leftPartEnd
;
while
(
left
<
startLeftS
&&
right
>=
startLeftS
)
{
doswap
(
elePtrAt
(
src
,
size
,
left
),
elePtrAt
(
src
,
size
,
right
),
size
,
buf
);
left
++
;
right
--
;
}
leftPartEnd
-=
(
startLeftS
-
start
);
}
if
(
leftPartEnd
>
start
)
{
tqsortImpl
(
src
,
size
,
start
,
leftPartEnd
,
param
,
comparFn
,
buf
);
}
if
(
rightPartStart
<
end
)
{
tqsortImpl
(
src
,
size
,
rightPartStart
,
end
,
param
,
comparFn
,
buf
);
}
}
void
tqsort
(
void
*
src
,
size_t
numOfElem
,
size_t
size
,
const
void
*
param
,
__ext_compar_fn_t
comparFn
)
{
char
*
buf
=
calloc
(
1
,
size
);
// prepare the swap buffer
tqsortImpl
(
src
,
0
,
numOfElem
-
1
,
size
,
param
,
comparFn
,
buf
);
tfree
(
buf
);
}
void
*
taosbsearch
(
const
void
*
key
,
const
void
*
base
,
size_t
nmemb
,
size_t
size
,
int
(
*
compar
)(
const
void
*
,
const
void
*
),
int
flags
)
{
// TODO: need to check the correctness of this function
int
l
=
0
;
int
r
=
nmemb
;
int
idx
=
0
;
int
comparison
;
if
(
flags
==
TD_EQ
)
{
return
bsearch
(
key
,
base
,
nmemb
,
size
,
compar
);
}
else
if
(
flags
==
TD_GE
)
{
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
0
))
<=
0
)
return
elePtrAt
(
base
,
size
,
0
);
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
nmemb
-
1
))
>
0
)
return
NULL
;
while
(
l
<
r
)
{
idx
=
(
l
+
r
)
/
2
;
comparison
=
(
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
idx
));
if
(
comparison
<
0
)
{
r
=
idx
;
}
else
if
(
comparison
>
0
)
{
l
=
idx
+
1
;
}
else
{
return
elePtrAt
(
base
,
size
,
idx
);
}
}
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
idx
))
<
0
)
{
return
elePtrAt
(
base
,
size
,
idx
);
}
else
{
if
(
idx
+
1
>
nmemb
-
1
)
{
return
NULL
;
}
else
{
return
elePtrAt
(
base
,
size
,
idx
+
1
);
}
}
}
else
if
(
flags
==
TD_LE
)
{
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
nmemb
-
1
))
>=
0
)
return
elePtrAt
(
base
,
size
,
nmemb
-
1
);
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
0
))
<
0
)
return
NULL
;
while
(
l
<
r
)
{
idx
=
(
l
+
r
)
/
2
;
comparison
=
(
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
idx
));
if
(
comparison
<
0
)
{
r
=
idx
;
}
else
if
(
comparison
>
0
)
{
l
=
idx
+
1
;
}
else
{
return
elePtrAt
(
base
,
size
,
idx
);
}
}
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
idx
))
>
0
)
{
return
elePtrAt
(
base
,
size
,
idx
);
}
else
{
if
(
idx
==
0
)
{
return
NULL
;
}
else
{
return
elePtrAt
(
base
,
size
,
idx
-
1
);
}
}
}
else
{
assert
(
0
);
return
NULL
;
}
return
NULL
;
}
src/util/src/tskiplist.c
浏览文件 @
b6f64b3f
...
...
@@ -190,7 +190,7 @@ void *tSkipListDestroy(SSkipList *pSkipList) {
return
NULL
;
}
void
tSkipList
Rand
NodeInfo
(
SSkipList
*
pSkipList
,
int32_t
*
level
,
int32_t
*
headSize
)
{
void
tSkipList
New
NodeInfo
(
SSkipList
*
pSkipList
,
int32_t
*
level
,
int32_t
*
headSize
)
{
if
(
pSkipList
==
NULL
)
{
return
;
}
...
...
src/util/src/tutil.c
浏览文件 @
b6f64b3f
...
...
@@ -618,72 +618,3 @@ char *taosCharsetReplace(char *charsetstr) {
return
strdup
(
charsetstr
);
}
#define elePtrAt(base, size, idx) (void *)((char *)(base) + (size) * (idx))
void
*
taosbsearch
(
const
void
*
key
,
const
void
*
base
,
size_t
nmemb
,
size_t
size
,
int
(
*
compar
)(
const
void
*
,
const
void
*
),
int
flags
)
{
// TODO: need to check the correctness of this function
int
l
=
0
;
int
r
=
nmemb
;
int
idx
=
0
;
int
comparison
;
if
(
flags
==
TD_EQ
)
{
return
bsearch
(
key
,
base
,
nmemb
,
size
,
compar
);
}
else
if
(
flags
==
TD_GE
)
{
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
0
))
<=
0
)
return
elePtrAt
(
base
,
size
,
0
);
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
nmemb
-
1
))
>
0
)
return
NULL
;
while
(
l
<
r
)
{
idx
=
(
l
+
r
)
/
2
;
comparison
=
(
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
idx
));
if
(
comparison
<
0
)
{
r
=
idx
;
}
else
if
(
comparison
>
0
)
{
l
=
idx
+
1
;
}
else
{
return
elePtrAt
(
base
,
size
,
idx
);
}
}
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
idx
))
<
0
)
{
return
elePtrAt
(
base
,
size
,
idx
);
}
else
{
if
(
idx
+
1
>
nmemb
-
1
)
{
return
NULL
;
}
else
{
return
elePtrAt
(
base
,
size
,
idx
+
1
);
}
}
}
else
if
(
flags
==
TD_LE
)
{
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
nmemb
-
1
))
>=
0
)
return
elePtrAt
(
base
,
size
,
nmemb
-
1
);
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
0
))
<
0
)
return
NULL
;
while
(
l
<
r
)
{
idx
=
(
l
+
r
)
/
2
;
comparison
=
(
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
idx
));
if
(
comparison
<
0
)
{
r
=
idx
;
}
else
if
(
comparison
>
0
)
{
l
=
idx
+
1
;
}
else
{
return
elePtrAt
(
base
,
size
,
idx
);
}
}
if
((
*
compar
)(
key
,
elePtrAt
(
base
,
size
,
idx
))
>
0
)
{
return
elePtrAt
(
base
,
size
,
idx
);
}
else
{
if
(
idx
==
0
)
{
return
NULL
;
}
else
{
return
elePtrAt
(
base
,
size
,
idx
-
1
);
}
}
}
else
{
assert
(
0
);
return
NULL
;
}
return
NULL
;
}
src/util/tests/skiplistTest.cpp
浏览文件 @
b6f64b3f
...
...
@@ -28,7 +28,7 @@ void doubleSkipListTest() {
int32_t
level
=
0
;
int32_t
size
=
0
;
tSkipList
Rand
NodeInfo
(
pSkipList
,
&
level
,
&
size
);
tSkipList
New
NodeInfo
(
pSkipList
,
&
level
,
&
size
);
auto
d
=
(
SSkipListNode
*
)
calloc
(
1
,
size
+
sizeof
(
double
)
*
2
);
d
->
level
=
level
;
...
...
@@ -81,7 +81,7 @@ void randKeyTest() {
int32_t
level
=
0
;
int32_t
s
=
0
;
tSkipList
Rand
NodeInfo
(
pSkipList
,
&
level
,
&
s
);
tSkipList
New
NodeInfo
(
pSkipList
,
&
level
,
&
s
);
auto
d
=
(
SSkipListNode
*
)
calloc
(
1
,
s
+
sizeof
(
int32_t
)
*
2
);
d
->
level
=
level
;
...
...
@@ -112,7 +112,7 @@ void stringKeySkiplistTest() {
int32_t
level
=
0
;
int32_t
headsize
=
0
;
tSkipList
Rand
NodeInfo
(
pSkipList
,
&
level
,
&
headsize
);
tSkipList
New
NodeInfo
(
pSkipList
,
&
level
,
&
headsize
);
auto
pNode
=
(
SSkipListNode
*
)
calloc
(
1
,
headsize
+
max_key_size
+
sizeof
(
double
));
pNode
->
level
=
level
;
...
...
@@ -124,7 +124,7 @@ void stringKeySkiplistTest() {
tSkipListPut
(
pSkipList
,
pNode
);
tSkipList
Rand
NodeInfo
(
pSkipList
,
&
level
,
&
headsize
);
tSkipList
New
NodeInfo
(
pSkipList
,
&
level
,
&
headsize
);
pNode
=
(
SSkipListNode
*
)
calloc
(
1
,
headsize
+
max_key_size
+
sizeof
(
double
));
pNode
->
level
=
level
;
...
...
@@ -164,7 +164,7 @@ void stringKeySkiplistTest() {
int32_t
total
=
10000
;
for
(
int32_t
i
=
0
;
i
<
total
;
++
i
)
{
int32_t
n
=
sprintf
(
k
,
"abc_%d_%d"
,
i
,
i
);
tSkipList
Rand
NodeInfo
(
pSkipList
,
&
level
,
&
headsize
);
tSkipList
New
NodeInfo
(
pSkipList
,
&
level
,
&
headsize
);
auto
pNode
=
(
SSkipListNode
*
)
calloc
(
1
,
headsize
+
20
+
sizeof
(
double
));
pNode
->
level
=
level
;
...
...
@@ -222,7 +222,7 @@ void skiplistPerformanceTest() {
char
*
p
=
total
;
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
tSkipList
Rand
NodeInfo
(
pSkipList
,
&
level
,
&
headsize
);
tSkipList
New
NodeInfo
(
pSkipList
,
&
level
,
&
headsize
);
SSkipListNode
*
d
=
(
SSkipListNode
*
)
p
;
p
+=
headsize
+
sizeof
(
double
)
*
2
;
...
...
src/vnode/tsdb/inc/tsdb.h
浏览文件 @
b6f64b3f
...
...
@@ -181,8 +181,10 @@ int32_t tsdbInsertData(tsdb_repo_t *pRepo, SSubmitMsg *pMsg);
typedef
void
*
tsdb_query_handle_t
;
// Use void to hide implementation details
// typedef struct {
// } SColumnFilterInfo;
typedef
struct
STableGroupList
{
// qualified table object list in group
SArray
*
pGroupList
;
int32_t
numOfTables
;
}
STableGroupList
;
// query condition to build vnode iterator
typedef
struct
STsdbQueryCond
{
...
...
@@ -233,7 +235,7 @@ typedef void *tsdbpos_t;
* @param pTableList table sid list
* @return
*/
tsdb_query_handle_t
*
tsdbQuery
ByTableId
(
tsdb_repo_t
*
tsdb
,
STsdbQueryCond
*
pCond
,
SArray
*
idList
,
SArray
*
pColumnInfo
);
tsdb_query_handle_t
*
tsdbQuery
Tables
(
tsdb_repo_t
*
tsdb
,
STsdbQueryCond
*
pCond
,
SArray
*
idList
,
SArray
*
pColumnInfo
);
/**
* move to next block
...
...
@@ -335,7 +337,10 @@ SArray *tsdbGetTableList(tsdb_query_handle_t *pQueryHandle);
* @param pTagCond. tag query condition
*
*/
int32_t
tsdbQueryTags
(
tsdb_repo_t
*
tsdb
,
int64_t
uid
,
const
char
*
pTagCond
,
size_t
len
,
SArray
*
list
);
int32_t
tsdbQueryTags
(
tsdb_repo_t
*
tsdb
,
int64_t
uid
,
const
char
*
pTagCond
,
size_t
len
,
SArray
**
pGroupList
,
SColIndex
*
pColIndex
,
int32_t
numOfCols
);
int32_t
tsdbGetOneTableGroup
(
tsdb_repo_t
*
tsdb
,
int64_t
uid
,
SArray
**
pGroupList
);
/**
* clean up the query handle
...
...
src/vnode/tsdb/inc/tsdbMain.h
浏览文件 @
b6f64b3f
...
...
@@ -100,6 +100,7 @@ typedef struct {
STsdbMeta
*
tsdbInitMeta
(
char
*
rootDir
,
int32_t
maxTables
);
int32_t
tsdbFreeMeta
(
STsdbMeta
*
pMeta
);
STSchema
*
tsdbGetTableSchema
(
STsdbMeta
*
pMeta
,
STable
*
pTable
);
STSchema
*
tsdbGetTableTagSchema
(
STsdbMeta
*
pMeta
,
STable
*
pTable
);
// ---- Operation on STable
#define TSDB_TABLE_ID(pTable) ((pTable)->tableId)
...
...
src/vnode/tsdb/src/tsdbMain.c
浏览文件 @
b6f64b3f
...
...
@@ -704,7 +704,7 @@ static int32_t tdInsertRowToTable(STsdbRepo *pRepo, SDataRow row, STable *pTable
pTable
->
mem
->
keyLast
=
0
;
}
tSkipList
Rand
NodeInfo
(
pTable
->
mem
->
pData
,
&
level
,
&
headSize
);
tSkipList
New
NodeInfo
(
pTable
->
mem
->
pData
,
&
level
,
&
headSize
);
TSKEY
key
=
dataRowKey
(
row
);
// printf("insert:%lld, size:%d\n", key, pTable->mem->numOfPoints);
...
...
src/vnode/tsdb/src/tsdbMeta.c
浏览文件 @
b6f64b3f
...
...
@@ -105,8 +105,9 @@ int tsdbRestoreTable(void *pHandle, void *cont, int contLen) {
if
(
pTable
==
NULL
)
return
-
1
;
if
(
pTable
->
type
==
TSDB_SUPER_TABLE
)
{
pTable
->
pIndex
=
tSkipListCreate
(
TSDB_SUPER_TABLE_SL_LEVEL
,
TSDB_DATA_TYPE_TIMESTAMP
,
sizeof
(
int64_t
),
1
,
0
,
0
,
getTagIndexKey
);
STColumn
*
pColSchema
=
schemaColAt
(
pTable
->
tagSchema
,
0
);
pTable
->
pIndex
=
tSkipListCreate
(
TSDB_SUPER_TABLE_SL_LEVEL
,
pColSchema
->
type
,
pColSchema
->
bytes
,
1
,
0
,
0
,
getTagIndexKey
);
}
tsdbAddTableToMeta
(
pMeta
,
pTable
,
false
);
...
...
@@ -201,6 +202,18 @@ STSchema *tsdbGetTableSchema(STsdbMeta *pMeta, STable *pTable) {
}
}
STSchema
*
tsdbGetTableTagSchema
(
STsdbMeta
*
pMeta
,
STable
*
pTable
)
{
if
(
pTable
->
type
==
TSDB_SUPER_TABLE
)
{
return
pTable
->
tagSchema
;
}
else
if
(
pTable
->
type
==
TSDB_CHILD_TABLE
)
{
STable
*
pSuper
=
tsdbGetTableByUid
(
pMeta
,
pTable
->
superUid
);
if
(
pSuper
==
NULL
)
return
NULL
;
return
pSuper
->
tagSchema
;
}
else
{
return
NULL
;
}
}
int32_t
tsdbCreateTableImpl
(
STsdbMeta
*
pMeta
,
STableCfg
*
pCfg
)
{
if
(
tsdbCheckTableCfg
(
pCfg
)
<
0
)
return
-
1
;
...
...
@@ -222,8 +235,11 @@ int32_t tsdbCreateTableImpl(STsdbMeta *pMeta, STableCfg *pCfg) {
super
->
schema
=
tdDupSchema
(
pCfg
->
schema
);
super
->
tagSchema
=
tdDupSchema
(
pCfg
->
tagSchema
);
super
->
tagVal
=
tdDataRowDup
(
pCfg
->
tagValues
);
super
->
pIndex
=
tSkipListCreate
(
TSDB_SUPER_TABLE_SL_LEVEL
,
TSDB_DATA_TYPE_TIMESTAMP
,
sizeof
(
int64_t
),
1
,
0
,
0
,
getTagIndexKey
);
// Allow duplicate key, no lock
// index the first tag column
STColumn
*
pColSchema
=
schemaColAt
(
super
->
tagSchema
,
0
);
super
->
pIndex
=
tSkipListCreate
(
TSDB_SUPER_TABLE_SL_LEVEL
,
pColSchema
->
type
,
pColSchema
->
bytes
,
1
,
0
,
0
,
getTagIndexKey
);
// Allow duplicate key, no lock
if
(
super
->
pIndex
==
NULL
)
{
tdFreeSchema
(
super
->
schema
);
...
...
@@ -411,11 +427,11 @@ static int tsdbAddTableIntoIndex(STsdbMeta *pMeta, STable *pTable) {
int32_t
level
=
0
;
int32_t
headSize
=
0
;
// first tag column
STColumn
*
s
=
schemaColAt
(
pSTable
->
tagSchema
,
0
);
tSkipListNewNodeInfo
(
pSTable
->
pIndex
,
&
level
,
&
headSize
);
tSkipListRandNodeInfo
(
pSTable
->
pIndex
,
&
level
,
&
headSize
);
SSkipListNode
*
pNode
=
calloc
(
1
,
headSize
+
s
->
bytes
+
POINTER_BYTES
);
// NOTE: do not allocate the space for key, since in each skip list node, only keep the pointer to pTable, not the
// actual key value, and the key value will be retrieved during query through the pTable and getTagIndexKey function
SSkipListNode
*
pNode
=
calloc
(
1
,
headSize
+
POINTER_BYTES
);
pNode
->
level
=
level
;
SSkipList
*
list
=
pSTable
->
pIndex
;
...
...
src/vnode/tsdb/src/tsdbRead.c
浏览文件 @
b6f64b3f
...
...
@@ -15,10 +15,12 @@
#include "os.h"
#include "talgo.h"
#include "tlog.h"
#include "tutil.h"
#include "../../../query/inc/qast.h"
#include "../../../query/inc/qextbuffer.h"
#include "../../../query/inc/tlosertree.h"
#include "../../../query/inc/tsqlfunction.h"
#include "tsdb.h"
...
...
@@ -141,9 +143,8 @@ static void tsdbInitCompBlockLoadInfo(SLoadCompBlockInfo* pCompBlockLoadInfo) {
pCompBlockLoadInfo
->
fileListIndex
=
-
1
;
}
tsdb_query_handle_t
*
tsdbQuery
ByTableId
(
tsdb_repo_t
*
tsdb
,
STsdbQueryCond
*
pCond
,
SArray
*
id
List
,
SArray
*
pColumnInfo
)
{
tsdb_query_handle_t
*
tsdbQuery
Tables
(
tsdb_repo_t
*
tsdb
,
STsdbQueryCond
*
pCond
,
SArray
*
group
List
,
SArray
*
pColumnInfo
)
{
// todo 1. filter not exist table
// todo 2. add the reference count for each table that is involved in query
STsdbQueryHandle
*
pQueryHandle
=
calloc
(
1
,
sizeof
(
STsdbQueryHandle
));
...
...
@@ -156,26 +157,26 @@ tsdb_query_handle_t* tsdbQueryByTableId(tsdb_repo_t* tsdb, STsdbQueryCond* pCond
pQueryHandle
->
isFirstSlot
=
true
;
pQueryHandle
->
cur
.
fid
=
-
1
;
size_t
size
=
taosArrayGetSize
(
id
List
);
size_t
size
=
taosArrayGetSize
(
group
List
);
assert
(
size
>=
1
);
pQueryHandle
->
pTableCheckInfo
=
taosArrayInit
(
size
,
sizeof
(
STableCheckInfo
));
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
STableId
id
=
*
(
STableId
*
)
taosArrayGet
(
idList
,
i
);
STable
*
pTable
=
tsdbGetTableByUid
(
tsdbGetMeta
(
tsdb
),
id
.
uid
);
if
(
pTable
==
NULL
)
{
dError
(
"%p failed to get table, error uid:%"
PRIu64
,
pQueryHandle
,
id
.
uid
);
continue
;
}
STableCheckInfo
info
=
{
.
lastKey
=
pQueryHandle
->
window
.
skey
,
.
tableId
=
id
,
.
pTableObj
=
pTable
,
};
SArray
*
group
=
*
(
SArray
**
)
taosArrayGet
(
groupList
,
i
);
taosArrayPush
(
pQueryHandle
->
pTableCheckInfo
,
&
info
);
size_t
gsize
=
taosArrayGetSize
(
group
);
for
(
int32_t
j
=
0
;
j
<
gsize
;
++
j
)
{
STable
*
pTable
=
*
(
STable
**
)
taosArrayGet
(
group
,
j
);
assert
(
pTable
!=
NULL
);
STableCheckInfo
info
=
{
.
lastKey
=
pQueryHandle
->
window
.
skey
,
.
tableId
=
pTable
->
tableId
,
.
pTableObj
=
pTable
,
};
taosArrayPush
(
pQueryHandle
->
pTableCheckInfo
,
&
info
);
}
}
dTrace
(
"%p total numOfTable:%d in query"
,
pQueryHandle
,
taosArrayGetSize
(
pQueryHandle
->
pTableCheckInfo
));
...
...
@@ -208,7 +209,8 @@ tsdb_query_handle_t* tsdbQueryByTableId(tsdb_repo_t* tsdb, STsdbQueryCond* pCond
}
static
bool
hasMoreDataInCache
(
STsdbQueryHandle
*
pHandle
)
{
assert
(
pHandle
->
activeIndex
==
0
&&
taosArrayGetSize
(
pHandle
->
pTableCheckInfo
)
==
1
);
size_t
size
=
taosArrayGetSize
(
pHandle
->
pTableCheckInfo
);
assert
(
pHandle
->
activeIndex
<
size
&&
pHandle
->
activeIndex
>=
0
&&
size
>=
1
);
pHandle
->
cur
.
fid
=
-
1
;
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
pHandle
->
pTableCheckInfo
,
pHandle
->
activeIndex
);
...
...
@@ -312,7 +314,7 @@ static int32_t getFileCompInfo(STsdbQueryHandle* pQueryHandle, int32_t* numOfBlo
SCompIdx
*
compIndex
=
&
pQueryHandle
->
compIndex
[
pCheckInfo
->
tableId
.
tid
];
if
(
compIndex
->
len
==
0
||
compIndex
->
numOfSuperBlocks
==
0
)
{
// no data block in this file, try next file
assert
(
0
);
continue
;
//no data blocks in the file belongs to pCheckInfo->pTable
}
else
{
if
(
pCheckInfo
->
compSize
<
compIndex
->
len
)
{
assert
(
compIndex
->
len
>
0
);
...
...
@@ -488,61 +490,6 @@ static bool loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* pBlock
return
pQueryHandle
->
realNumOfRows
>
0
;
}
//bool moveToNextBlock(STsdbQueryHandle* pQueryHandle, int32_t step) {
// SQueryFilePos* cur = &pQueryHandle->cur;
//
// if (pQueryHandle->cur.fid >= 0) {
// /*
// * 1. ascending order. The last data block of data file
// * 2. descending order. The first block of file
// */
// STableCheckInfo* pCheckInfo = taosArrayGet(pQueryHandle->pTableCheckInfo, pQueryHandle->activeIndex);
// int32_t tid = pCheckInfo->tableId.tid;
//
// if ((step == QUERY_ASC_FORWARD_STEP &&
// (pQueryHandle->cur.slot == pQueryHandle->compIndex[tid].numOfSuperBlocks - 1)) ||
// (step == QUERY_DESC_FORWARD_STEP && (pQueryHandle->cur.slot == 0))) {
// // temporarily keep the position value, in case of no data qualified when move forwards(backwards)
// // SQueryFilePos save = pQueryHandle->cur;
// pQueryHandle->pFileGroup = tsdbGetFileGroupNext(&pQueryHandle->fileIter);
//
// int32_t fid = -1;
// int32_t numOfBlocks = 0;
//
// if (pQueryHandle->pFileGroup != NULL) {
// if ((fid = getFileCompInfo(pQueryHandle, &numOfBlocks, 1)) < 0) {
// } else {
// cur->slot = (step == QUERY_ASC_FORWARD_STEP) ? 0 : pQueryHandle->numOfBlocks - 1;
// cur->pos = (step == QUERY_ASC_FORWARD_STEP) ? 0 : pQueryHandle->pBlock[cur->slot].numOfPoints - 1;
//
// SCompBlock* pBlock = &pCheckInfo->pCompInfo->blocks[cur->slot];
// cur->fid = pQueryHandle->pFileGroup->fileId;
// assert(cur->pos >= 0 && cur->fid >= 0 && cur->slot >= 0);
//
// if (pBlock->keyFirst > pQueryHandle->window.ekey) { // done
// return false;
// }
//
// return loadFileDataBlock(pQueryHandle, pBlock, pCheckInfo);
// }
// } else { // check data in cache
// pQueryHandle->cur.fid = -1;
// return hasMoreDataInCache(pQueryHandle);
// }
// } else { // next block in the same file
// cur->slot += step;
//
// SCompBlock* pBlock = &pCheckInfo->pCompInfo->blocks[cur->slot];
// cur->pos = (step == QUERY_ASC_FORWARD_STEP) ? 0 : pBlock->numOfPoints - 1;
// return loadFileDataBlock(pQueryHandle, pBlock, pCheckInfo);
// }
// } else { // data in cache
// return hasMoreDataInCache(pQueryHandle);
// }
//
// return false;
//}
static
int
vnodeBinarySearchKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
)
{
int
firstPos
,
lastPos
,
midPos
=
-
1
;
int
numOfPoints
;
...
...
@@ -732,71 +679,6 @@ int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) {
return
midPos
;
}
//static bool getQualifiedDataBlock(STsdbQueryHandle* pQueryHandle, STableCheckInfo* pCheckInfo, int32_t type) {
// STsdbFileH* pFileHandle = tsdbGetFile(pQueryHandle->pTsdb);
// int32_t fid = getFileIdFromKey(pCheckInfo->lastKey);
//
// tsdbInitFileGroupIter(pFileHandle, &pQueryHandle->fileIter, TSDB_FGROUP_ITER_FORWARD);
// tsdbSeekFileGroupIter(&pQueryHandle->fileIter, fid);
// pQueryHandle->pFileGroup = tsdbGetFileGroupNext(&pQueryHandle->fileIter);
//
// SQueryFilePos* cur = &pQueryHandle->cur;
//
// int32_t tid = pCheckInfo->tableId.tid;
// int32_t numOfBlocks = 0;
//
// while (pQueryHandle->pFileGroup != NULL) {
// if (getFileCompInfo(pQueryHandle, &numOfBlocks, 1) != TSDB_CODE_SUCCESS) {
// break;
// }
//
// assert(pCheckInfo->numOfBlocks >= 0);
//
// // no data block in current file, try next
// if (pCheckInfo->numOfBlocks > 0) {
// cur->fid = pQueryHandle->pFileGroup->fileId;
// break;
// }
//
// dTrace("%p no data block in file, fid:%d, tid:%d, try next, %p", pQueryHandle, pQueryHandle->pFileGroup->fileId,
// tid, pQueryHandle->qinfo);
//
// pQueryHandle->pFileGroup = tsdbGetFileGroupNext(&pQueryHandle->fileIter);
// }
//
// if (pCheckInfo->numOfBlocks == 0) {
// return false;
// }
//
// cur->slot = 0; // always start from the first slot
// SCompBlock* pBlock = &pCheckInfo->pCompInfo->blocks[cur->slot];
// return loadFileDataBlock(pQueryHandle, pBlock, pCheckInfo);
//}
//static UNUSED_FUNC bool hasMoreDataForSingleTable(STsdbQueryHandle* pHandle) {
// assert(pHandle->activeIndex == 0 && taosArrayGetSize(pHandle->pTableCheckInfo) == 1);
//
// STsdbFileH* pFileHandle = tsdbGetFile(pHandle->pTsdb);
// STableCheckInfo* pCheckInfo = taosArrayGet(pHandle->pTableCheckInfo, pHandle->activeIndex);
//
// if (!pCheckInfo->checkFirstFileBlock) {
// pCheckInfo->checkFirstFileBlock = true;
//
// if (pFileHandle != NULL) {
// bool found = getQualifiedDataBlock(pHandle, pCheckInfo, 1);
// if (found) {
// return true;
// }
// }
//
// // no data in file, try cache
// pHandle->cur.fid = -1;
// return hasMoreDataInCache(pHandle);
// } else { // move to next data block in file or in cache
// return moveToNextBlock(pHandle, 1);
// }
//}
static
void
cleanBlockOrderSupporter
(
SBlockOrderSupporter
*
pSupporter
,
int32_t
numOfTables
)
{
tfree
(
pSupporter
->
numOfBlocksPerMeter
);
tfree
(
pSupporter
->
blockIndexArray
);
...
...
@@ -862,23 +744,26 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO
}
int32_t
cnt
=
0
;
int32_t
numOfQual
Meter
s
=
0
;
int32_t
numOfQual
Table
s
=
0
;
for
(
int32_t
j
=
0
;
j
<
numOfTables
;
++
j
)
{
STableCheckInfo
*
pTableCheck
=
(
STableCheckInfo
*
)
taosArrayGet
(
pQueryHandle
->
pTableCheckInfo
,
j
);
if
(
pTableCheck
->
numOfBlocks
<=
0
)
{
continue
;
}
SCompBlock
*
pBlock
=
pTableCheck
->
pCompInfo
->
blocks
;
sup
.
numOfBlocksPerMeter
[
numOfQual
Meter
s
]
=
pTableCheck
->
numOfBlocks
;
sup
.
numOfBlocksPerMeter
[
numOfQual
Table
s
]
=
pTableCheck
->
numOfBlocks
;
char
*
buf
=
calloc
(
1
,
sizeof
(
STableBlockInfo
)
*
pTableCheck
->
numOfBlocks
);
if
(
buf
==
NULL
)
{
cleanBlockOrderSupporter
(
&
sup
,
numOfQual
Meter
s
);
cleanBlockOrderSupporter
(
&
sup
,
numOfQual
Table
s
);
return
TSDB_CODE_SERV_OUT_OF_MEMORY
;
}
sup
.
pDataBlockInfo
[
numOfQual
Meter
s
]
=
(
STableBlockInfo
*
)
buf
;
sup
.
pDataBlockInfo
[
numOfQual
Table
s
]
=
(
STableBlockInfo
*
)
buf
;
for
(
int32_t
k
=
0
;
k
<
pTableCheck
->
numOfBlocks
;
++
k
)
{
STableBlockInfo
*
pBlockInfoEx
=
&
sup
.
pDataBlockInfo
[
numOfQual
Meter
s
][
k
];
STableBlockInfo
*
pBlockInfoEx
=
&
sup
.
pDataBlockInfo
[
numOfQual
Table
s
][
k
];
pBlockInfoEx
->
pBlock
.
compBlock
=
&
pBlock
[
k
];
pBlockInfoEx
->
pBlock
.
fields
=
NULL
;
...
...
@@ -889,13 +774,13 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO
cnt
++
;
}
numOfQual
Meter
s
++
;
numOfQual
Table
s
++
;
}
dTrace
(
"%p create data blocks info struct completed
"
,
pQueryHandle
);
dTrace
(
"%p create data blocks info struct completed
, %d blocks in %d tables"
,
pQueryHandle
,
cnt
,
numOfQualTables
);
assert
(
cnt
<=
numOfBlocks
&&
numOfQual
Meter
s
<=
numOfTables
);
// the pMeterDataInfo[j]->numOfBlocks may be 0
sup
.
numOfTables
=
numOfQual
Meter
s
;
assert
(
cnt
<=
numOfBlocks
&&
numOfQual
Table
s
<=
numOfTables
);
// the pMeterDataInfo[j]->numOfBlocks may be 0
sup
.
numOfTables
=
numOfQual
Table
s
;
SLoserTreeInfo
*
pTree
=
NULL
;
uint8_t
ret
=
tLoserTreeCreate
(
&
pTree
,
sup
.
numOfTables
,
&
sup
,
dataBlockOrderCompar
);
...
...
@@ -1256,11 +1141,11 @@ static int32_t getAllTableIdList(STsdbRepo* tsdb, int64_t uid, SArray* list) {
SSkipListIterator
*
iter
=
tSkipListCreateIter
(
pTable
->
pIndex
);
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
STable
*
t
=
*
(
STable
**
)
SL_GET_NODE_DATA
(
pNode
);
taosArrayPush
(
list
,
&
t
->
tableId
);
STable
*
t
=
*
(
STable
**
)
SL_GET_NODE_DATA
(
pNode
);
taosArrayPush
(
list
,
t
);
}
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -1348,6 +1233,132 @@ void filterPrepare(void* expr, void* param) {
tVariantTypeSetType
(
&
pInfo
->
q
,
pInfo
->
sch
.
type
);
}
int32_t
doCompare
(
const
char
*
f1
,
const
char
*
f2
,
int32_t
type
,
size_t
size
)
{
switch
(
type
)
{
case
TSDB_DATA_TYPE_INT
:
DEFAULT_COMP
(
GET_INT32_VAL
(
f1
),
GET_INT32_VAL
(
f2
));
case
TSDB_DATA_TYPE_DOUBLE
:
DEFAULT_COMP
(
GET_DOUBLE_VAL
(
f1
),
GET_DOUBLE_VAL
(
f2
));
case
TSDB_DATA_TYPE_FLOAT
:
DEFAULT_COMP
(
GET_FLOAT_VAL
(
f1
),
GET_FLOAT_VAL
(
f2
));
case
TSDB_DATA_TYPE_BIGINT
:
DEFAULT_COMP
(
GET_INT64_VAL
(
f1
),
GET_INT64_VAL
(
f2
));
case
TSDB_DATA_TYPE_SMALLINT
:
DEFAULT_COMP
(
GET_INT16_VAL
(
f1
),
GET_INT16_VAL
(
f2
));
case
TSDB_DATA_TYPE_TINYINT
:
case
TSDB_DATA_TYPE_BOOL
:
DEFAULT_COMP
(
GET_INT8_VAL
(
f1
),
GET_INT8_VAL
(
f2
));
case
TSDB_DATA_TYPE_NCHAR
:
{
int32_t
ret
=
wcsncmp
((
wchar_t
*
)
f1
,
(
wchar_t
*
)
f2
,
size
/
TSDB_NCHAR_SIZE
);
if
(
ret
==
0
)
{
return
ret
;
}
return
(
ret
<
0
)
?
-
1
:
1
;
}
default:
{
int32_t
ret
=
strncmp
(
f1
,
f2
,
(
size_t
)
size
);
if
(
ret
==
0
)
{
return
ret
;
}
return
(
ret
<
0
)
?
-
1
:
1
;
}
}
}
typedef
struct
STableGroupSupporter
{
int32_t
numOfCols
;
SColIndex
*
pCols
;
STSchema
*
pTagSchema
;
}
STableGroupSupporter
;
int32_t
tableGroupComparFn
(
const
void
*
p1
,
const
void
*
p2
,
const
void
*
param
)
{
STableGroupSupporter
*
pTableGroupSupp
=
(
STableGroupSupporter
*
)
param
;
STable
*
pTable1
=
*
(
STable
**
)
p1
;
STable
*
pTable2
=
*
(
STable
**
)
p2
;
for
(
int32_t
i
=
0
;
i
<
pTableGroupSupp
->
numOfCols
;
++
i
)
{
SColIndex
*
pColIndex
=
&
pTableGroupSupp
->
pCols
[
i
];
int32_t
colIndex
=
pColIndex
->
colIndex
;
char
*
f1
=
NULL
;
char
*
f2
=
NULL
;
int32_t
type
=
0
;
int32_t
bytes
=
0
;
if
(
colIndex
==
-
1
)
{
// table name, todo fix me
// f1 = s1->tags;
// f2 = s2->tags;
type
=
TSDB_DATA_TYPE_BINARY
;
bytes
=
TSDB_TABLE_NAME_LEN
;
}
else
{
f1
=
dataRowTuple
(
pTable1
->
tagVal
);
f2
=
dataRowTuple
(
pTable2
->
tagVal
);
type
=
schemaColAt
(
pTableGroupSupp
->
pTagSchema
,
colIndex
)
->
type
;
bytes
=
schemaColAt
(
pTableGroupSupp
->
pTagSchema
,
colIndex
)
->
bytes
;
}
int32_t
ret
=
doCompare
(
f1
,
f2
,
type
,
bytes
);
if
(
ret
==
0
)
{
continue
;
}
else
{
return
ret
;
}
}
return
0
;
}
void
createTableGroupImpl
(
SArray
*
pGroups
,
STable
**
pTables
,
size_t
numOfTables
,
STableGroupSupporter
*
pSupp
,
__ext_compar_fn_t
compareFn
)
{
SArray
*
g
=
taosArrayInit
(
16
,
POINTER_BYTES
);
taosArrayPush
(
g
,
&
pTables
[
0
]);
for
(
int32_t
i
=
1
;
i
<
numOfTables
;
++
i
)
{
int32_t
ret
=
compareFn
(
&
pTables
[
i
-
1
],
&
pTables
[
i
],
pSupp
);
assert
(
ret
==
0
||
ret
==
-
1
);
if
(
ret
==
0
)
{
taosArrayPush
(
g
,
&
pTables
[
i
]);
}
else
{
taosArrayPush
(
pGroups
,
&
g
);
// current group is ended, start a new group
g
=
taosArrayInit
(
16
,
POINTER_BYTES
);
taosArrayPush
(
g
,
&
pTables
[
i
]);
}
}
}
SArray
*
createTableGroup
(
SArray
*
pTableList
,
STSchema
*
pTagSchema
,
SColIndex
*
pCols
,
int32_t
numOfOrderCols
)
{
assert
(
pTableList
!=
NULL
&&
taosArrayGetSize
(
pTableList
)
>
0
);
SArray
*
pTableGroup
=
taosArrayInit
(
1
,
POINTER_BYTES
);
size_t
size
=
taosArrayGetSize
(
pTableList
);
if
(
size
==
0
)
{
pTrace
(
"no qualified tables"
);
return
pTableGroup
;
}
if
(
numOfOrderCols
==
0
||
size
==
1
)
{
// no group by tags clause or only one table
taosArrayPush
(
pTableGroup
,
pTableList
);
pTrace
(
"all %d tables belong to one group"
,
size
);
#ifdef _DEBUG_VIEW
tSidSetDisplay
(
pTableGroup
);
#endif
}
else
{
STableGroupSupporter
*
pSupp
=
(
STableGroupSupporter
*
)
calloc
(
1
,
sizeof
(
STableGroupSupporter
));
pSupp
->
numOfCols
=
numOfOrderCols
;
pSupp
->
pTagSchema
=
pTagSchema
;
pSupp
->
pCols
=
pCols
;
tqsort
(
pTableList
->
pData
,
size
,
POINTER_BYTES
,
pSupp
,
tableGroupComparFn
);
createTableGroupImpl
(
pTableGroup
,
pTableList
->
pData
,
size
,
pSupp
,
tableGroupComparFn
);
#ifdef _DEBUG_VIEW
tSidSetDisplay
(
pTableGroup
);
#endif
tfree
(
pSupp
);
}
return
pTableGroup
;
}
bool
tSkipListNodeFilterCallback
(
const
void
*
pNode
,
void
*
param
)
{
tQueryInfo
*
pInfo
=
(
tQueryInfo
*
)
param
;
...
...
@@ -1419,13 +1430,29 @@ static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr)
return
TSDB_CODE_SUCCESS
;
}
int32_t
tsdbQueryTags
(
tsdb_repo_t
*
tsdb
,
int64_t
uid
,
const
char
*
pTagCond
,
size_t
len
,
SArray
*
res
)
{
if
(
pTagCond
==
NULL
||
len
==
0
)
{
// no condition, all tables created according to this stable are involved
return
getAllTableIdList
(
tsdb
,
uid
,
res
);
}
int32_t
tsdbQueryTags
(
tsdb_repo_t
*
tsdb
,
int64_t
uid
,
const
char
*
pTagCond
,
size_t
len
,
SArray
**
pGroupList
,
SColIndex
*
pColIndex
,
int32_t
numOfCols
)
{
STable
*
pSTable
=
tsdbGetTableByUid
(
tsdbGetMeta
(
tsdb
),
uid
);
assert
(
pSTable
!=
NULL
);
if
(
pSTable
==
NULL
)
{
dError
(
"failed to get stable, uid:%"
PRIu64
,
uid
);
return
TSDB_CODE_INVALID_TABLE_ID
;
}
SArray
*
res
=
taosArrayInit
(
8
,
POINTER_BYTES
);
STSchema
*
pTagSchema
=
tsdbGetTableTagSchema
(
tsdbGetMeta
(
tsdb
),
pSTable
);
if
(
pTagCond
==
NULL
||
len
==
0
)
{
// no tags condition, all tables created according to this stable are involved
int32_t
ret
=
getAllTableIdList
(
tsdb
,
uid
,
res
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
taosArrayDestroy
(
res
);
return
ret
;
}
*
pGroupList
=
createTableGroup
(
res
,
pTagSchema
,
pColIndex
,
numOfCols
);
taosArrayDestroy
(
res
);
return
ret
;
}
tExprNode
*
pExprNode
=
NULL
;
int32_t
ret
=
TSDB_CODE_SUCCESS
;
...
...
@@ -1433,12 +1460,33 @@ int32_t tsdbQueryTags(tsdb_repo_t* tsdb, int64_t uid, const char* pTagCond, size
// failed to build expression, no result, return immediately
if
((
ret
=
exprTreeFromBinary
(
pTagCond
,
len
,
&
pExprNode
)
!=
TSDB_CODE_SUCCESS
)
||
(
pExprNode
==
NULL
))
{
dError
(
"stable:%"
PRIu64
", failed to deserialize expression tree, error exists"
,
uid
);
taosArrayDestroy
(
res
);
return
ret
;
}
return
doQueryTableList
(
pSTable
,
res
,
pExprNode
);
doQueryTableList
(
pSTable
,
res
,
pExprNode
);
*
pGroupList
=
createTableGroup
(
res
,
pTagSchema
,
pColIndex
,
numOfCols
);
taosArrayDestroy
(
res
);
return
ret
;
}
int32_t
tsdbGetOneTableGroup
(
tsdb_repo_t
*
tsdb
,
int64_t
uid
,
SArray
**
pGroupList
)
{
STable
*
pTable
=
tsdbGetTableByUid
(
tsdbGetMeta
(
tsdb
),
uid
);
if
(
pTable
==
NULL
)
{
return
TSDB_CODE_INVALID_TABLE_ID
;
}
//todo assert table type, add the table ref count
*
pGroupList
=
taosArrayInit
(
1
,
POINTER_BYTES
);
SArray
*
group
=
taosArrayInit
(
1
,
POINTER_BYTES
);
taosArrayPush
(
group
,
&
pTable
);
taosArrayPush
(
*
pGroupList
,
&
group
);
return
TSDB_CODE_SUCCESS
;
}
void
tsdbCleanupQueryHandle
(
tsdb_query_handle_t
queryHandle
)
{
STsdbQueryHandle
*
pQueryHandle
=
(
STsdbQueryHandle
*
)
queryHandle
;
if
(
pQueryHandle
==
NULL
)
{
...
...
tests/examples/c/demo.c
浏览文件 @
b6f64b3f
...
...
@@ -75,17 +75,17 @@ int main(int argc, char *argv[]) {
doQuery
(
taos
,
"create database if not exists test"
);
doQuery
(
taos
,
"use test"
);
doQuery
(
taos
,
"create table if not exists tm0 (ts timestamp, k int);"
);
doQuery
(
taos
,
"insert into tm0 values('2020-1-1 1:1:1', 1);"
);
doQuery
(
taos
,
"insert into tm0 values('2020-1-1 1:1:2', 2);"
);
doQuery
(
taos
,
"insert into tm0 values('2020-1-1 1:1:3', 3);"
);
doQuery
(
taos
,
"insert into tm0 values('2020-1-1 1:1:4', 4);"
);
doQuery
(
taos
,
"insert into tm0 values('2020-1-1 1:1:5', 5);"
);
doQuery
(
taos
,
"insert into tm0 values('2020-1-1 1:1:6', 6);"
);
doQuery
(
taos
,
"insert into tm0 values('2020-1-1 1:1:7', 7);"
);
doQuery
(
taos
,
"insert into tm0 values('2020-1-1 1:1:8', 8);"
);
doQuery
(
taos
,
"insert into tm0 values('2020-1-1 1:1:9', 9);"
);
doQuery
(
taos
,
"select
* from tm0;
"
);
//
doQuery(taos, "create table if not exists tm0 (ts timestamp, k int);");
//
doQuery(taos, "insert into tm0 values('2020-1-1 1:1:1', 1);");
//
doQuery(taos, "insert into tm0 values('2020-1-1 1:1:2', 2);");
//
doQuery(taos, "insert into tm0 values('2020-1-1 1:1:3', 3);");
//
doQuery(taos, "insert into tm0 values('2020-1-1 1:1:4', 4);");
//
doQuery(taos, "insert into tm0 values('2020-1-1 1:1:5', 5);");
//
doQuery(taos, "insert into tm0 values('2020-1-1 1:1:6', 6);");
//
doQuery(taos, "insert into tm0 values('2020-1-1 1:1:7', 7);");
//
doQuery(taos, "insert into tm0 values('2020-1-1 1:1:8', 8);");
//
doQuery(taos, "insert into tm0 values('2020-1-1 1:1:9', 9);");
doQuery
(
taos
,
"select
sum(k),count(*) from m1 group by a
"
);
taos_close
(
taos
);
return
0
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录