Merge remote-tracking branch 'origin/3.0' into feature/dnode3
This commit is contained in:
commit
e9bfd8a4bb
|
@ -50,6 +50,11 @@ if(${BUILD_WITH_LUCENE})
|
||||||
cat("${CMAKE_SUPPORT_DIR}/lucene_CMakeLists.txt.in" ${DEPS_TMP_FILE})
|
cat("${CMAKE_SUPPORT_DIR}/lucene_CMakeLists.txt.in" ${DEPS_TMP_FILE})
|
||||||
endif(${BUILD_WITH_LUCENE})
|
endif(${BUILD_WITH_LUCENE})
|
||||||
|
|
||||||
|
## NuRaft
|
||||||
|
if(${BUILD_WITH_NURAFT})
|
||||||
|
cat("${CMAKE_SUPPORT_DIR}/nuraft_CMakeLists.txt.in" ${DEPS_TMP_FILE})
|
||||||
|
endif(${BUILD_WITH_NURAFT})
|
||||||
|
|
||||||
## download dependencies
|
## download dependencies
|
||||||
configure_file(${DEPS_TMP_FILE} "${CMAKE_SOURCE_DIR}/deps/deps-download/CMakeLists.txt")
|
configure_file(${DEPS_TMP_FILE} "${CMAKE_SOURCE_DIR}/deps/deps-download/CMakeLists.txt")
|
||||||
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
|
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
|
||||||
|
@ -69,4 +74,7 @@ target_include_directories(api INTERFACE "include/client")
|
||||||
# src
|
# src
|
||||||
add_subdirectory(source)
|
add_subdirectory(source)
|
||||||
|
|
||||||
|
# docs
|
||||||
|
add_subdirectory(docs)
|
||||||
|
|
||||||
# tests (TODO)
|
# tests (TODO)
|
||||||
|
|
|
@ -142,7 +142,7 @@ pipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// stage('Parallel test stage') {
|
// stage('Parallel test stage') {
|
||||||
// //only build pr
|
// skip defaultCheckout
|
||||||
// options { skipDefaultCheckout() }
|
// options { skipDefaultCheckout() }
|
||||||
// when {
|
// when {
|
||||||
// allOf{
|
// allOf{
|
||||||
|
|
|
@ -16,7 +16,7 @@ option(
|
||||||
option(
|
option(
|
||||||
BUILD_WITH_ROCKSDB
|
BUILD_WITH_ROCKSDB
|
||||||
"If build with rocksdb"
|
"If build with rocksdb"
|
||||||
OFF
|
ON
|
||||||
)
|
)
|
||||||
|
|
||||||
option(
|
option(
|
||||||
|
@ -25,8 +25,20 @@ option(
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
|
|
||||||
|
option(
|
||||||
|
BUILD_WITH_NURAFT
|
||||||
|
"If build with NuRaft"
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
|
||||||
option(
|
option(
|
||||||
BUILD_DEPENDENCY_TESTS
|
BUILD_DEPENDENCY_TESTS
|
||||||
"If build dependency tests"
|
"If build dependency tests"
|
||||||
OFF
|
OFF
|
||||||
|
)
|
||||||
|
|
||||||
|
option(
|
||||||
|
BUILD_DOCS
|
||||||
|
"If use doxygen build documents"
|
||||||
|
ON
|
||||||
)
|
)
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
# NuRaft
|
||||||
|
ExternalProject_Add(NuRaft
|
||||||
|
GIT_REPOSITORY https://github.com/eBay/NuRaft.git
|
||||||
|
GIT_TAG v1.3.0
|
||||||
|
SOURCE_DIR "${CMAKE_SOURCE_DIR}/deps/nuraft"
|
||||||
|
BINARY_DIR "${CMAKE_SOURCE_DIR}/deps/nuraft"
|
||||||
|
CONFIGURE_COMMAND "./prepare.sh"
|
||||||
|
BUILD_COMMAND ""
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
TEST_COMMAND ""
|
||||||
|
)
|
|
@ -67,6 +67,12 @@ if(${BUILD_WITH_LUCENE})
|
||||||
add_subdirectory(lucene)
|
add_subdirectory(lucene)
|
||||||
endif(${BUILD_WITH_LUCENE})
|
endif(${BUILD_WITH_LUCENE})
|
||||||
|
|
||||||
|
# NuRaft
|
||||||
|
if(${BUILD_WITH_NURAFT})
|
||||||
|
add_subdirectory(nuraft)
|
||||||
|
endif(${BUILD_WITH_NURAFT})
|
||||||
|
|
||||||
|
|
||||||
# ================================================================================================
|
# ================================================================================================
|
||||||
# DEPENDENCY TEST
|
# DEPENDENCY TEST
|
||||||
# ================================================================================================
|
# ================================================================================================
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Generate API documentation
|
||||||
|
## https://vicrucann.github.io/tutorials/quick-cmake-doxygen/
|
||||||
|
if(${BUILD_DOCS})
|
||||||
|
find_package(Doxygen)
|
||||||
|
if (DOXYGEN_FOUND)
|
||||||
|
# Build the doc
|
||||||
|
set(DOXYGEN_IN ${CMAKE_SOURCE_DIR}/docs/Doxyfile.in)
|
||||||
|
set(DOXYGEN_OUT ${CMAKE_BINARY_DIR}/Doxyfile)
|
||||||
|
|
||||||
|
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
|
||||||
|
message("Doxygen build start")
|
||||||
|
|
||||||
|
add_custom_target(
|
||||||
|
tdengine_doxygen ALL
|
||||||
|
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
COMMENT "Generating API doxumentation with Doxygen"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
else(DOXYGEN_FOUND)
|
||||||
|
message("Doxygen need to be installed to generate the doxygen documentation")
|
||||||
|
endif(DOXYGEN_FOUND)
|
||||||
|
endif(${BUILD_DOCS})
|
File diff suppressed because it is too large
Load Diff
|
@ -19,7 +19,7 @@
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
|
#include "tvariant.h"
|
||||||
//typedef struct STimeWindow {
|
//typedef struct STimeWindow {
|
||||||
// TSKEY skey;
|
// TSKEY skey;
|
||||||
// TSKEY ekey;
|
// TSKEY ekey;
|
||||||
|
@ -66,4 +66,59 @@ typedef struct SColumnInfoData {
|
||||||
char *pData; // the corresponding block data in memory
|
char *pData; // the corresponding block data in memory
|
||||||
} SColumnInfoData;
|
} SColumnInfoData;
|
||||||
|
|
||||||
|
//======================================================================================================================
|
||||||
|
// the following structure shared by parser and executor
|
||||||
|
typedef struct SColumn {
|
||||||
|
uint64_t uid;
|
||||||
|
char name[TSDB_COL_NAME_LEN];
|
||||||
|
int8_t flag; // column type: normal column, tag, or user-input column (integer/float/string)
|
||||||
|
SColumnInfo info;
|
||||||
|
} SColumn;
|
||||||
|
|
||||||
|
typedef struct SLimit {
|
||||||
|
int64_t limit;
|
||||||
|
int64_t offset;
|
||||||
|
} SLimit;
|
||||||
|
|
||||||
|
typedef struct SOrder {
|
||||||
|
uint32_t order;
|
||||||
|
int32_t orderColId;
|
||||||
|
} SOrder;
|
||||||
|
|
||||||
|
typedef struct SGroupbyExpr {
|
||||||
|
SArray* columnInfo; // SArray<SColIndex>, group by columns information
|
||||||
|
bool groupbyTag; // group by tag or column
|
||||||
|
} SGroupbyExpr;
|
||||||
|
|
||||||
|
// the structure for sql function in select clause
|
||||||
|
typedef struct SSqlExpr {
|
||||||
|
char token[TSDB_COL_NAME_LEN]; // original token
|
||||||
|
SSchema resSchema;
|
||||||
|
|
||||||
|
int32_t numOfCols;
|
||||||
|
SColumn* pColumns; // data columns that are required by query
|
||||||
|
int32_t interBytes; // inter result buffer size
|
||||||
|
int16_t numOfParams; // argument value of each function
|
||||||
|
SVariant param[3]; // parameters are not more than 3
|
||||||
|
} SSqlExpr;
|
||||||
|
|
||||||
|
typedef struct SExprInfo {
|
||||||
|
struct SSqlExpr base;
|
||||||
|
struct tExprNode *pExpr;
|
||||||
|
} SExprInfo;
|
||||||
|
|
||||||
|
typedef struct SStateWindow {
|
||||||
|
SColumn col;
|
||||||
|
} SStateWindow;
|
||||||
|
|
||||||
|
typedef struct SSessionWindow {
|
||||||
|
int64_t gap; // gap between two session window(in microseconds)
|
||||||
|
SColumn col;
|
||||||
|
} SSessionWindow;
|
||||||
|
|
||||||
|
#define QUERY_ASC_FORWARD_STEP 1
|
||||||
|
#define QUERY_DESC_FORWARD_STEP -1
|
||||||
|
|
||||||
|
#define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
|
||||||
|
|
||||||
#endif // TDENGINE_COMMON_H
|
#endif // TDENGINE_COMMON_H
|
||||||
|
|
|
@ -204,14 +204,14 @@ enum _mgmt_table {
|
||||||
#define TSDB_COL_NORMAL 0x0u // the normal column of the table
|
#define TSDB_COL_NORMAL 0x0u // the normal column of the table
|
||||||
#define TSDB_COL_TAG 0x1u // the tag column type
|
#define TSDB_COL_TAG 0x1u // the tag column type
|
||||||
#define TSDB_COL_UDC 0x2u // the user specified normal string column, it is a dummy column
|
#define TSDB_COL_UDC 0x2u // the user specified normal string column, it is a dummy column
|
||||||
#define TSDB_COL_NULL 0x4u // the column filter NULL or not
|
#define TSDB_COL_TMP 0x4u // internal column generated by the previous operators
|
||||||
|
#define TSDB_COL_NULL 0x8u // the column filter NULL or not
|
||||||
|
|
||||||
#define TSDB_COL_IS_TAG(f) (((f&(~(TSDB_COL_NULL)))&TSDB_COL_TAG) != 0)
|
#define TSDB_COL_IS_TAG(f) (((f&(~(TSDB_COL_NULL)))&TSDB_COL_TAG) != 0)
|
||||||
#define TSDB_COL_IS_NORMAL_COL(f) ((f&(~(TSDB_COL_NULL))) == TSDB_COL_NORMAL)
|
#define TSDB_COL_IS_NORMAL_COL(f) ((f&(~(TSDB_COL_NULL))) == TSDB_COL_NORMAL)
|
||||||
#define TSDB_COL_IS_UD_COL(f) ((f&(~(TSDB_COL_NULL))) == TSDB_COL_UDC)
|
#define TSDB_COL_IS_UD_COL(f) ((f&(~(TSDB_COL_NULL))) == TSDB_COL_UDC)
|
||||||
#define TSDB_COL_REQ_NULL(f) (((f)&TSDB_COL_NULL) != 0)
|
#define TSDB_COL_REQ_NULL(f) (((f)&TSDB_COL_NULL) != 0)
|
||||||
|
|
||||||
|
|
||||||
extern char *taosMsg[];
|
extern char *taosMsg[];
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
@ -489,11 +489,6 @@ typedef struct SInterval {
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
} SInterval;
|
} SInterval;
|
||||||
|
|
||||||
typedef struct SSessionWindow {
|
|
||||||
int64_t gap; // gap between two session window(in microseconds)
|
|
||||||
int32_t primaryColId; // primary timestamp column
|
|
||||||
} SSessionWindow;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SMsgHead head;
|
SMsgHead head;
|
||||||
char version[TSDB_VERSION_LEN];
|
char version[TSDB_VERSION_LEN];
|
||||||
|
@ -518,7 +513,7 @@ typedef struct {
|
||||||
int16_t orderColId;
|
int16_t orderColId;
|
||||||
int16_t numOfCols; // the number of columns will be load from vnode
|
int16_t numOfCols; // the number of columns will be load from vnode
|
||||||
SInterval interval;
|
SInterval interval;
|
||||||
SSessionWindow sw; // session window
|
// SSessionWindow sw; // session window
|
||||||
uint16_t tagCondLen; // tag length in current query
|
uint16_t tagCondLen; // tag length in current query
|
||||||
uint16_t colCondLen; // column length in current query
|
uint16_t colCondLen; // column length in current query
|
||||||
int16_t numOfGroupCols; // num of group by columns
|
int16_t numOfGroupCols; // num of group by columns
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#ifndef TDENGINE_TNAME_H
|
#ifndef TDENGINE_TNAME_H
|
||||||
#define TDENGINE_TNAME_H
|
#define TDENGINE_TNAME_H
|
||||||
|
|
||||||
|
#include "taosmsg.h"
|
||||||
|
|
||||||
#define TSDB_DB_NAME_T 1
|
#define TSDB_DB_NAME_T 1
|
||||||
#define TSDB_TABLE_NAME_T 2
|
#define TSDB_TABLE_NAME_T 2
|
||||||
|
|
||||||
|
@ -52,6 +54,8 @@ int32_t tNameFromString(SName* dst, const char* str, uint32_t type);
|
||||||
|
|
||||||
int32_t tNameSetAcctId(SName* dst, const char* acct);
|
int32_t tNameSetAcctId(SName* dst, const char* acct);
|
||||||
|
|
||||||
|
SSchema* tGetTbnameColumnSchema();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int32_t tNameSetDbName(SName* dst, const char* acct, SToken* dbToken);
|
int32_t tNameSetDbName(SName* dst, const char* acct, SToken* dbToken);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_TREQUEST_H_
|
||||||
|
#define _TD_TREQUEST_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ------------------------ TYPES EXPOSED ------------------------ */
|
||||||
|
typedef struct SRequest SRequest;
|
||||||
|
typedef struct SReqBatch SReqBatch;
|
||||||
|
typedef struct SReqBatchIter SReqBatchIter;
|
||||||
|
|
||||||
|
// SRequest
|
||||||
|
|
||||||
|
// SReqBatch
|
||||||
|
|
||||||
|
// SReqBatchIter
|
||||||
|
void tdInitRBIter(SReqBatchIter *pIter, SReqBatch *pReqBatch);
|
||||||
|
const SRequest *tdRBIterNext(SReqBatchIter *pIter);
|
||||||
|
void tdClearRBIter(SReqBatchIter *pIter);
|
||||||
|
|
||||||
|
/* ------------------------ TYPES DEFINITION ------------------------ */
|
||||||
|
struct SReqBatchIter {
|
||||||
|
int iReq;
|
||||||
|
SReqBatch *pReqBatch;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_TREQUEST_H_*/
|
|
@ -21,7 +21,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taosdef.h"
|
#include "tdef.h"
|
||||||
#include "tvariant.h"
|
#include "tvariant.h"
|
||||||
|
|
||||||
#define MEM_BUF_SIZE (1 << 20)
|
#define MEM_BUF_SIZE (1 << 20)
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_META_IMPL_H_
|
||||||
|
#define _TD_META_IMPL_H_
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
|
#include "taosmsg.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
typedef uint64_t tb_uid_t;
|
||||||
|
|
||||||
|
/* ------------------------ SMetaOptions ------------------------ */
|
||||||
|
struct SMetaOptions {
|
||||||
|
size_t lruCacheSize; // LRU cache size
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------------------ STbOptions ------------------------ */
|
||||||
|
#define META_NORMAL_TABLE ((uint8_t)1)
|
||||||
|
#define META_SUPER_TABLE ((uint8_t)2)
|
||||||
|
#define META_CHILD_TABLE ((uint8_t)3)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
} SSMAOptions;
|
||||||
|
|
||||||
|
// super table options
|
||||||
|
typedef struct {
|
||||||
|
tb_uid_t uid;
|
||||||
|
STSchema* pSchema;
|
||||||
|
STSchema* pTagSchema;
|
||||||
|
} SSTbOptions;
|
||||||
|
|
||||||
|
// child table options
|
||||||
|
typedef struct {
|
||||||
|
tb_uid_t suid;
|
||||||
|
SKVRow tags;
|
||||||
|
} SCTbOptions;
|
||||||
|
|
||||||
|
// normal table options
|
||||||
|
typedef struct {
|
||||||
|
STSchema* pSchame;
|
||||||
|
} SNTbOptions;
|
||||||
|
|
||||||
|
struct STbOptions {
|
||||||
|
uint8_t type;
|
||||||
|
char* name;
|
||||||
|
uint32_t ttl; // time to live in (SECONDS)
|
||||||
|
SSMAOptions bsma; // Block-wise sma
|
||||||
|
union {
|
||||||
|
SSTbOptions stbOptions;
|
||||||
|
SNTbOptions ntbOptions;
|
||||||
|
SCTbOptions ctbOptions;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_META_IMPL_H_*/
|
|
@ -16,81 +16,36 @@
|
||||||
#ifndef _TD_META_H_
|
#ifndef _TD_META_H_
|
||||||
#define _TD_META_H_
|
#define _TD_META_H_
|
||||||
|
|
||||||
#include "taosmsg.h"
|
#include "impl/metaImpl.h"
|
||||||
|
|
||||||
#include "os.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ------------------------ APIs Exposed ------------------------ */
|
|
||||||
|
|
||||||
// Types exported
|
// Types exported
|
||||||
typedef uint64_t tb_uid_t;
|
typedef struct SMeta SMeta;
|
||||||
typedef struct SMeta SMeta;
|
typedef struct SMetaOptions SMetaOptions;
|
||||||
typedef struct SMetaOpts SMetaOpts;
|
typedef struct STbOptions STbOptions;
|
||||||
typedef struct SMetaQueryHandle SMetaQueryHandle;
|
|
||||||
typedef struct SMetaQueryOpts SMetaQueryOpts;
|
|
||||||
typedef struct STableOpts STableOpts;
|
|
||||||
|
|
||||||
// SMeta operations
|
// SMeta operations
|
||||||
int metaCreate(const char *path);
|
SMeta *metaOpen(const char *path, const SMetaOptions *);
|
||||||
void metaDestroy(const char *path);
|
|
||||||
SMeta *metaOpen(SMetaOpts *);
|
|
||||||
void metaClose(SMeta *);
|
void metaClose(SMeta *);
|
||||||
int metaCreateTable(SMeta *, const STableOpts *);
|
void metaRemove(const char *path);
|
||||||
int metaDropTable(SMeta *, uint64_t tuid_t);
|
int metaCreateTable(SMeta *pMeta, const STbOptions *);
|
||||||
int metaAlterTable(SMeta *, void *);
|
int metaDropTable(SMeta *pMeta, tb_uid_t uid);
|
||||||
int metaCommit(SMeta *);
|
int metaCommit(SMeta *);
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
SMetaOpts *metaOptionsCreate();
|
void metaOptionsInit(SMetaOptions *);
|
||||||
void metaOptionsDestroy(SMetaOpts *);
|
void metaOptionsClear(SMetaOptions *);
|
||||||
void metaOptionsSetCache(SMetaOpts *, size_t capacity);
|
|
||||||
|
|
||||||
// SMetaQueryHandle
|
|
||||||
SMetaQueryHandle *metaQueryHandleCreate(SMetaQueryOpts *);
|
|
||||||
void metaQueryHandleDestroy(SMetaQueryHandle *);
|
|
||||||
|
|
||||||
// SMetaQueryOpts
|
|
||||||
SMetaQueryOpts *metaQueryOptionsCreate();
|
|
||||||
void metaQueryOptionsDestroy(SMetaQueryOpts *);
|
|
||||||
|
|
||||||
// STableOpts
|
// STableOpts
|
||||||
#define META_TABLE_OPTS_DECLARE(name) STableOpts name = {0}
|
#define META_TABLE_OPTS_DECLARE(name) STableOpts name = {0}
|
||||||
void metaNormalTableOptsInit(STableOpts *, const char *name, const STSchema *pSchema);
|
void metaNormalTableOptsInit(STbOptions *, const char *name, const STSchema *pSchema);
|
||||||
void metaSuperTableOptsInit(STableOpts *, const char *name, tb_uid_t uid, const STSchema *pSchema,
|
void metaSuperTableOptsInit(STbOptions *, const char *name, tb_uid_t uid, const STSchema *pSchema,
|
||||||
const STSchema *pTagSchema);
|
const STSchema *pTagSchema);
|
||||||
void metaChildTableOptsInit(STableOpts *, const char *name, tb_uid_t suid, const SKVRow tags);
|
void metaChildTableOptsInit(STbOptions *, const char *name, tb_uid_t suid, const SKVRow tags);
|
||||||
void metaTableOptsClear(STableOpts *);
|
void metaTableOptsClear(STbOptions *);
|
||||||
|
|
||||||
/* ------------------------ Impl should hidden ------------------------ */
|
|
||||||
typedef enum { META_INIT_TABLE = 0, META_SUPER_TABLE = 1, META_CHILD_TABLE = 2, META_NORMAL_TABLE = 3 } EMetaTableT;
|
|
||||||
typedef struct SSuperTableOpts {
|
|
||||||
tb_uid_t uid;
|
|
||||||
STSchema *pSchema; // (ts timestamp, a int)
|
|
||||||
STSchema *pTagSchema; // (tag1 binary(10), tag2 int)
|
|
||||||
} SSuperTableOpts;
|
|
||||||
|
|
||||||
typedef struct SChildTableOpts {
|
|
||||||
tb_uid_t suid; // super table uid
|
|
||||||
SKVRow tags; // tag value of the child table
|
|
||||||
} SChildTableOpts;
|
|
||||||
|
|
||||||
typedef struct SNormalTableOpts {
|
|
||||||
STSchema *pSchema;
|
|
||||||
} SNormalTableOpts;
|
|
||||||
|
|
||||||
struct STableOpts {
|
|
||||||
int8_t type;
|
|
||||||
char * name;
|
|
||||||
union {
|
|
||||||
SSuperTableOpts superOpts;
|
|
||||||
SChildTableOpts childOpts;
|
|
||||||
SNormalTableOpts normalOpts;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,6 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
#define TQ_ACTION_INSERT 0x7f7f7f7fULL
|
|
||||||
#define TQ_ACTION_DELETE 0x80808080ULL
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct STsdbOptions {
|
struct STsdbOptions {
|
||||||
|
size_t lruCacheSize;
|
||||||
/* TODO */
|
/* TODO */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,14 +17,80 @@
|
||||||
#define _TD_VNODE_H_
|
#define _TD_VNODE_H_
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taosmsg.h"
|
#include "trequest.h"
|
||||||
#include "trpc.h"
|
|
||||||
|
#include "meta.h"
|
||||||
|
#include "tq.h"
|
||||||
|
#include "tsdb.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct SVnode SVnode;
|
/* ------------------------ TYPES EXPOSED ------------------------ */
|
||||||
|
typedef struct SVnode SVnode;
|
||||||
|
typedef struct SVnodeOptions SVnodeOptions;
|
||||||
|
|
||||||
|
/* ------------------------ SVnode ------------------------ */
|
||||||
|
SVnode *vnodeOpen(const char *path, const SVnodeOptions *pVnodeOptions);
|
||||||
|
void vnodeClose(SVnode *pVnode);
|
||||||
|
void vnodeDestroy(const char *path);
|
||||||
|
int vnodeProcessWriteReqs(SVnode *pVnode, SReqBatch *pReqBatch);
|
||||||
|
int vnodeApplyWriteRequest(SVnode *pVnode, const SRequest *pRequest);
|
||||||
|
int vnodeProcessReadReq(SVnode *pVnode, SRequest *pReq);
|
||||||
|
int vnodeProcessSyncReq(SVnode *pVnode, SRequest *pReq);
|
||||||
|
|
||||||
|
/* ------------------------ SVnodeOptions ------------------------ */
|
||||||
|
void vnodeOptionsInit(SVnodeOptions *);
|
||||||
|
void vnodeOptionsClear(SVnodeOptions *);
|
||||||
|
|
||||||
|
/* ------------------------ STRUCT DEFINITIONS ------------------------ */
|
||||||
|
struct SVnodeOptions {
|
||||||
|
/**
|
||||||
|
* @brief write buffer size in BYTES
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint64_t wsize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief time to live of tables in this vnode
|
||||||
|
* in SECONDS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint32_t ttl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief if time-series requests eventual consistency
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool isWeak;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief if the allocator is heap allcator or arena allocator
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool isHeapAllocator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief TSDB options
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
STsdbOptions tsdbOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief META options
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
SMetaOptions metaOptions;
|
||||||
|
// STqOptions tqOptions; // TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------------------ FOR COMPILE ------------------------ */
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
#include "taosmsg.h"
|
||||||
|
#include "trpc.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char db[TSDB_FULL_DB_NAME_LEN];
|
char db[TSDB_FULL_DB_NAME_LEN];
|
||||||
|
@ -71,8 +137,6 @@ typedef struct {
|
||||||
int32_t vnodeInit(SVnodePara);
|
int32_t vnodeInit(SVnodePara);
|
||||||
void vnodeCleanup();
|
void vnodeCleanup();
|
||||||
|
|
||||||
SVnode *vnodeOpen(int32_t vgId, const char *path);
|
|
||||||
void vnodeClose(SVnode *pVnode);
|
|
||||||
int32_t vnodeAlter(SVnode *pVnode, const SVnodeCfg *pCfg);
|
int32_t vnodeAlter(SVnode *pVnode, const SVnodeCfg *pCfg);
|
||||||
SVnode *vnodeCreate(int32_t vgId, const char *path, const SVnodeCfg *pCfg);
|
SVnode *vnodeCreate(int32_t vgId, const char *path, const SVnodeCfg *pCfg);
|
||||||
void vnodeDrop(SVnode *pVnode);
|
void vnodeDrop(SVnode *pVnode);
|
||||||
|
@ -86,6 +150,8 @@ int32_t vnodeAppendMsg(SVnodeMsg *pMsg, SRpcMsg *pRpcMsg);
|
||||||
void vnodeCleanupMsg(SVnodeMsg *pMsg);
|
void vnodeCleanupMsg(SVnodeMsg *pMsg);
|
||||||
void vnodeProcessMsg(SVnode *pVnode, SVnodeMsg *pMsg, EVnMsgType msgType);
|
void vnodeProcessMsg(SVnode *pVnode, SVnodeMsg *pMsg, EVnMsgType msgType);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,8 +26,8 @@ extern "C" {
|
||||||
|
|
||||||
#define MAX_INTERVAL_TIME_WINDOW 1000000 // maximum allowed time windows in final results
|
#define MAX_INTERVAL_TIME_WINDOW 1000000 // maximum allowed time windows in final results
|
||||||
|
|
||||||
#define FUNCTION_SCALAR 1
|
#define FUNCTION_TYPE_SCALAR 1
|
||||||
#define FUNCTION_AGG 2
|
#define FUNCTION_TYPE_AGG 2
|
||||||
|
|
||||||
#define TOP_BOTTOM_QUERY_LIMIT 100
|
#define TOP_BOTTOM_QUERY_LIMIT 100
|
||||||
#define FUNCTIONS_NAME_MAX_LENGTH 16
|
#define FUNCTIONS_NAME_MAX_LENGTH 16
|
||||||
|
@ -78,13 +78,30 @@ extern "C" {
|
||||||
#define FUNCTION_MODE 36
|
#define FUNCTION_MODE 36
|
||||||
#define FUNCTION_SAMPLE 37
|
#define FUNCTION_SAMPLE 37
|
||||||
|
|
||||||
|
#define FUNCTION_COV 38
|
||||||
|
|
||||||
|
// determine the real data need to calculated the result
|
||||||
|
enum {
|
||||||
|
BLK_DATA_NO_NEEDED = 0x0,
|
||||||
|
BLK_DATA_STATIS_NEEDED = 0x1,
|
||||||
|
BLK_DATA_ALL_NEEDED = 0x3,
|
||||||
|
BLK_DATA_DISCARD = 0x4, // discard current data block since it is not qualified for filter
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MASTER_SCAN = 0x0u,
|
||||||
|
REVERSE_SCAN = 0x1u,
|
||||||
|
REPEAT_SCAN = 0x2u, //repeat scan belongs to the master scan
|
||||||
|
MERGE_STAGE = 0x20u,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct SPoint1 {
|
typedef struct SPoint1 {
|
||||||
int64_t key;
|
int64_t key;
|
||||||
union{double val; char* ptr;};
|
union{double val; char* ptr;};
|
||||||
} SPoint1;
|
} SPoint1;
|
||||||
|
|
||||||
struct SQLFunctionCtx;
|
struct SQLFunctionCtx;
|
||||||
struct SResultRowCellInfo;
|
struct SResultRowEntryInfo;
|
||||||
|
|
||||||
//for selectivity query, the corresponding tag value is assigned if the data is qualified
|
//for selectivity query, the corresponding tag value is assigned if the data is qualified
|
||||||
typedef struct SExtTagsInfo {
|
typedef struct SExtTagsInfo {
|
||||||
|
@ -93,6 +110,23 @@ typedef struct SExtTagsInfo {
|
||||||
struct SQLFunctionCtx **pTagCtxList;
|
struct SQLFunctionCtx **pTagCtxList;
|
||||||
} SExtTagsInfo;
|
} SExtTagsInfo;
|
||||||
|
|
||||||
|
typedef struct SResultDataInfo {
|
||||||
|
int16_t type;
|
||||||
|
int16_t bytes;
|
||||||
|
int32_t intermediateBytes;
|
||||||
|
} SResultDataInfo;
|
||||||
|
|
||||||
|
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
|
||||||
|
|
||||||
|
typedef struct SFunctionFpSet {
|
||||||
|
bool (*init)(struct SQLFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo); // setup the execute environment
|
||||||
|
void (*addInput)(struct SQLFunctionCtx *pCtx);
|
||||||
|
|
||||||
|
// finalizer must be called after all exec has been executed to generated final result.
|
||||||
|
void (*finalize)(struct SQLFunctionCtx *pCtx);
|
||||||
|
void (*combine)(struct SQLFunctionCtx *pCtx);
|
||||||
|
} SFunctionFpSet;
|
||||||
|
|
||||||
// sql function runtime context
|
// sql function runtime context
|
||||||
typedef struct SQLFunctionCtx {
|
typedef struct SQLFunctionCtx {
|
||||||
int32_t size; // number of rows
|
int32_t size; // number of rows
|
||||||
|
@ -101,9 +135,7 @@ typedef struct SQLFunctionCtx {
|
||||||
int16_t inputType;
|
int16_t inputType;
|
||||||
int16_t inputBytes;
|
int16_t inputBytes;
|
||||||
|
|
||||||
int16_t outputType;
|
SResultDataInfo resDataInfo;
|
||||||
int16_t outputBytes; // size of results, determined by function and input column data type
|
|
||||||
int32_t interBufBytes; // internal buffer size
|
|
||||||
bool hasNull; // null value exist in current block
|
bool hasNull; // null value exist in current block
|
||||||
bool requireNull; // require null in some function
|
bool requireNull; // require null in some function
|
||||||
bool stableQuery;
|
bool stableQuery;
|
||||||
|
@ -117,18 +149,21 @@ typedef struct SQLFunctionCtx {
|
||||||
void *ptsOutputBuf; // corresponding output buffer for timestamp of each result, e.g., top/bottom*/
|
void *ptsOutputBuf; // corresponding output buffer for timestamp of each result, e.g., top/bottom*/
|
||||||
SVariant tag;
|
SVariant tag;
|
||||||
|
|
||||||
bool isSmaSet;
|
bool isAggSet;
|
||||||
SColumnDataAgg sma;
|
SColumnDataAgg agg;
|
||||||
struct SResultRowCellInfo *resultInfo;
|
struct SResultRowEntryInfo *resultInfo;
|
||||||
SExtTagsInfo tagInfo;
|
SExtTagsInfo tagInfo;
|
||||||
SPoint1 start;
|
SPoint1 start;
|
||||||
SPoint1 end;
|
SPoint1 end;
|
||||||
|
|
||||||
|
SFunctionFpSet* fpSet;
|
||||||
} SQLFunctionCtx;
|
} SQLFunctionCtx;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TEXPR_NODE_DUMMY = 0x0,
|
TEXPR_NODE_DUMMY = 0x0,
|
||||||
TEXPR_BINARYEXPR_NODE= 0x1,
|
TEXPR_BINARYEXPR_NODE= 0x1,
|
||||||
TEXPR_UNARYEXPR_NODE = 0x2,
|
TEXPR_UNARYEXPR_NODE = 0x2,
|
||||||
|
TEXPR_FUNCTION_NODE = 0x3,
|
||||||
TEXPR_COL_NODE = 0x4,
|
TEXPR_COL_NODE = 0x4,
|
||||||
TEXPR_VALUE_NODE = 0x8,
|
TEXPR_VALUE_NODE = 0x8,
|
||||||
};
|
};
|
||||||
|
@ -137,10 +172,7 @@ typedef struct tExprNode {
|
||||||
uint8_t nodeType;
|
uint8_t nodeType;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
union {
|
int32_t optr; // binary operator
|
||||||
int32_t optr; // binary operator
|
|
||||||
int32_t functionId;// unary operator
|
|
||||||
};
|
|
||||||
void *info; // support filter operation on this expression only available for leaf node
|
void *info; // support filter operation on this expression only available for leaf node
|
||||||
struct tExprNode *pLeft; // left child pointer
|
struct tExprNode *pLeft; // left child pointer
|
||||||
struct tExprNode *pRight; // right child pointer
|
struct tExprNode *pRight; // right child pointer
|
||||||
|
@ -148,44 +180,52 @@ typedef struct tExprNode {
|
||||||
|
|
||||||
SSchema *pSchema;// column node
|
SSchema *pSchema;// column node
|
||||||
struct SVariant *pVal; // value node
|
struct SVariant *pVal; // value node
|
||||||
|
|
||||||
|
struct {// function node
|
||||||
|
char functionName[FUNCTIONS_NAME_MAX_LENGTH];
|
||||||
|
// int32_t functionId;
|
||||||
|
int32_t num;
|
||||||
|
|
||||||
|
// Note that the attribute of pChild is not the parameter of function, it is the columns that involved in the
|
||||||
|
// calculation instead.
|
||||||
|
// E.g., Cov(col1, col2), the column information, w.r.t. the col1 and col2, is kept in pChild nodes.
|
||||||
|
// The concat function, concat(col1, col2), is a binary scalar
|
||||||
|
// operator and is kept in the attribute of _node.
|
||||||
|
struct tExprNode **pChild;
|
||||||
|
} _function;
|
||||||
};
|
};
|
||||||
} tExprNode;
|
} tExprNode;
|
||||||
|
|
||||||
|
//TODO create?
|
||||||
void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
|
void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
|
||||||
void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *));
|
void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *));
|
||||||
|
|
||||||
typedef struct SAggFunctionInfo {
|
typedef struct SAggFunctionInfo {
|
||||||
char name[FUNCTIONS_NAME_MAX_LENGTH];
|
char name[FUNCTIONS_NAME_MAX_LENGTH];
|
||||||
int8_t type; // Scalar function or aggregation function
|
int8_t type; // Scalar function or aggregation function
|
||||||
uint8_t functionId; // Function Id
|
uint32_t functionId; // Function Id
|
||||||
int8_t sFunctionId; // Transfer function for super table query
|
int8_t sFunctionId; // Transfer function for super table query
|
||||||
uint16_t status;
|
uint16_t status;
|
||||||
|
|
||||||
bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowCellInfo* pResultCellInfo); // setup the execute environment
|
bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo); // setup the execute environment
|
||||||
void (*exec)(SQLFunctionCtx *pCtx);
|
void (*addInput)(SQLFunctionCtx *pCtx);
|
||||||
|
|
||||||
// finalizer must be called after all exec has been executed to generated final result.
|
// finalizer must be called after all exec has been executed to generated final result.
|
||||||
void (*xFinalize)(SQLFunctionCtx *pCtx);
|
void (*finalize)(SQLFunctionCtx *pCtx);
|
||||||
void (*mergeFunc)(SQLFunctionCtx *pCtx);
|
void (*combine)(SQLFunctionCtx *pCtx);
|
||||||
|
|
||||||
int32_t (*dataReqFunc)(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId);
|
int32_t (*dataReqFunc)(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId);
|
||||||
} SAggFunctionInfo;
|
} SAggFunctionInfo;
|
||||||
|
|
||||||
|
struct SScalarFuncParam;
|
||||||
|
|
||||||
typedef struct SScalarFunctionInfo {
|
typedef struct SScalarFunctionInfo {
|
||||||
char name[FUNCTIONS_NAME_MAX_LENGTH];
|
char name[FUNCTIONS_NAME_MAX_LENGTH];
|
||||||
int8_t type; // scalar function or aggregation function
|
int8_t type; // scalar function or aggregation function
|
||||||
uint8_t functionId; // index of scalar function
|
uint32_t functionId; // index of scalar function
|
||||||
|
void (*process)(struct SScalarFuncParam* pOutput, size_t numOfInput, const struct SScalarFuncParam *pInput);
|
||||||
bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowCellInfo* pResultCellInfo); // setup the execute environment
|
|
||||||
void (*exec)(SQLFunctionCtx *pCtx);
|
|
||||||
} SScalarFunctionInfo;
|
} SScalarFunctionInfo;
|
||||||
|
|
||||||
typedef struct SResultDataInfo {
|
|
||||||
int16_t type;
|
|
||||||
int16_t bytes;
|
|
||||||
int32_t intermediateBytes;
|
|
||||||
} SResultDataInfo;
|
|
||||||
|
|
||||||
typedef struct SMultiFunctionsDesc {
|
typedef struct SMultiFunctionsDesc {
|
||||||
bool stableQuery;
|
bool stableQuery;
|
||||||
bool groupbyColumn;
|
bool groupbyColumn;
|
||||||
|
@ -195,11 +235,12 @@ typedef struct SMultiFunctionsDesc {
|
||||||
bool hasFilter;
|
bool hasFilter;
|
||||||
bool onlyTagQuery;
|
bool onlyTagQuery;
|
||||||
bool orderProjectQuery;
|
bool orderProjectQuery;
|
||||||
bool stateWindow;
|
|
||||||
bool globalMerge;
|
bool globalMerge;
|
||||||
bool multigroupResult;
|
bool multigroupResult;
|
||||||
bool blockDistribution;
|
bool blockDistribution;
|
||||||
|
bool stateWindow;
|
||||||
bool timewindow;
|
bool timewindow;
|
||||||
|
bool sessionWindow;
|
||||||
bool topbotQuery;
|
bool topbotQuery;
|
||||||
bool interpQuery;
|
bool interpQuery;
|
||||||
bool distinct;
|
bool distinct;
|
||||||
|
@ -215,16 +256,61 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
||||||
* @param len
|
* @param len
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int32_t qIsBuiltinFunction(const char* name, int32_t len);
|
int32_t qIsBuiltinFunction(const char* name, int32_t len, bool* scalarFunction);
|
||||||
|
|
||||||
bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* functionId);
|
bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* functionId);
|
||||||
|
|
||||||
const char* qGetFunctionName(int32_t functionId);
|
bool qIsAggregateFunction(const char* functionName);
|
||||||
|
|
||||||
|
tExprNode* exprTreeFromBinary(const void* data, size_t size);
|
||||||
|
|
||||||
void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc);
|
void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc);
|
||||||
|
|
||||||
tExprNode* exprdup(tExprNode* pTree);
|
tExprNode* exprdup(tExprNode* pTree);
|
||||||
|
|
||||||
|
void resetResultRowEntryResult(SQLFunctionCtx* pCtx, int32_t num);
|
||||||
|
void cleanupResultRowEntry(struct SResultRowEntryInfo* pCell);
|
||||||
|
int32_t getNumOfResult(SQLFunctionCtx* pCtx, int32_t num);
|
||||||
|
bool isRowEntryCompleted(struct SResultRowEntryInfo* pEntry);
|
||||||
|
bool isRowEntryInitialized(struct SResultRowEntryInfo* pEntry);
|
||||||
|
|
||||||
|
struct SScalarFunctionSupport* createScalarFuncSupport(int32_t num);
|
||||||
|
void destroyScalarFuncSupport(struct SScalarFunctionSupport* pSupport, int32_t num);
|
||||||
|
struct SScalarFunctionSupport* getScalarFuncSupport(struct SScalarFunctionSupport* pSupport, int32_t index);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// fill api
|
||||||
|
struct SFillInfo;
|
||||||
|
struct SFillColInfo;
|
||||||
|
|
||||||
|
typedef struct SPoint {
|
||||||
|
int64_t key;
|
||||||
|
void * val;
|
||||||
|
} SPoint;
|
||||||
|
|
||||||
|
void taosFillSetStartInfo(struct SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey);
|
||||||
|
void taosResetFillInfo(struct SFillInfo* pFillInfo, TSKEY startTimestamp);
|
||||||
|
void taosFillSetInputDataBlock(struct SFillInfo* pFillInfo, const struct SSDataBlock* pInput);
|
||||||
|
struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, const int64_t* fillVal);
|
||||||
|
bool taosFillHasMoreResults(struct SFillInfo* pFillInfo);
|
||||||
|
|
||||||
|
struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
|
||||||
|
int64_t slidingTime, int8_t slidingUnit, int8_t precision, int32_t fillType,
|
||||||
|
struct SFillColInfo* pFillCol, void* handle);
|
||||||
|
|
||||||
|
void* taosDestroyFillInfo(struct SFillInfo *pFillInfo);
|
||||||
|
int64_t taosFillResultDataBlock(struct SFillInfo* pFillInfo, void** output, int32_t capacity);
|
||||||
|
int64_t getFillInfoStart(struct SFillInfo *pFillInfo);
|
||||||
|
|
||||||
|
int32_t taosGetLinearInterpolationVal(SPoint* point, int32_t outputType, SPoint* point1, SPoint* point2, int32_t inputType);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// udf api
|
||||||
|
struct SUdfInfo;
|
||||||
|
|
||||||
|
void qAddUdfInfo(uint64_t id, struct SUdfInfo* pUdfInfo);
|
||||||
|
void qRemoveUdfInfo(uint64_t id, struct SUdfInfo* pUdfInfo);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,50 +26,6 @@ extern "C" {
|
||||||
#include "tvariant.h"
|
#include "tvariant.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
|
|
||||||
typedef struct SColumn {
|
|
||||||
uint64_t tableUid;
|
|
||||||
int32_t columnIndex;
|
|
||||||
SColumnInfo info;
|
|
||||||
} SColumn;
|
|
||||||
|
|
||||||
// the structure for sql function in select clause
|
|
||||||
typedef struct SSqlExpr {
|
|
||||||
char token[TSDB_COL_NAME_LEN]; // original token
|
|
||||||
SSchema resSchema;
|
|
||||||
SColIndex colInfo;
|
|
||||||
uint64_t uid; // table uid, todo refactor use the pointer
|
|
||||||
int32_t interBytes; // inter result buffer size
|
|
||||||
int16_t numOfParams; // argument value of each function
|
|
||||||
SVariant param[3]; // parameters are not more than 3
|
|
||||||
} SSqlExpr;
|
|
||||||
|
|
||||||
typedef struct SExprInfo {
|
|
||||||
SSqlExpr base;
|
|
||||||
struct tExprNode *pExpr;
|
|
||||||
} SExprInfo;
|
|
||||||
|
|
||||||
//typedef struct SInterval {
|
|
||||||
// int32_t tz; // query client timezone
|
|
||||||
// char intervalUnit;
|
|
||||||
// char slidingUnit;
|
|
||||||
// char offsetUnit;
|
|
||||||
// int64_t interval;
|
|
||||||
// int64_t sliding;
|
|
||||||
// int64_t offset;
|
|
||||||
//} SInterval;
|
|
||||||
//
|
|
||||||
//typedef struct SSessionWindow {
|
|
||||||
// int64_t gap; // gap between two session window(in microseconds)
|
|
||||||
// int32_t primaryColId; // primary timestamp column
|
|
||||||
//} SSessionWindow;
|
|
||||||
|
|
||||||
typedef struct SGroupbyExpr {
|
|
||||||
int16_t tableIndex;
|
|
||||||
SArray* columnInfo; // SArray<SColIndex>, group by columns information
|
|
||||||
int16_t orderIndex; // order by column index
|
|
||||||
int16_t orderType; // order by type: asc/desc
|
|
||||||
} SGroupbyExpr;
|
|
||||||
|
|
||||||
typedef struct SField {
|
typedef struct SField {
|
||||||
char name[TSDB_COL_NAME_LEN];
|
char name[TSDB_COL_NAME_LEN];
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
@ -82,16 +38,6 @@ typedef struct SFieldInfo {
|
||||||
SArray *internalField; // SArray<SInternalField>
|
SArray *internalField; // SArray<SInternalField>
|
||||||
} SFieldInfo;
|
} SFieldInfo;
|
||||||
|
|
||||||
typedef struct SLimit {
|
|
||||||
int64_t limit;
|
|
||||||
int64_t offset;
|
|
||||||
} SLimit;
|
|
||||||
|
|
||||||
typedef struct SOrder {
|
|
||||||
uint32_t order;
|
|
||||||
int32_t orderColId;
|
|
||||||
} SOrder;
|
|
||||||
|
|
||||||
typedef struct SCond {
|
typedef struct SCond {
|
||||||
uint64_t uid;
|
uint64_t uid;
|
||||||
int32_t len; // length of tag query condition data
|
int32_t len; // length of tag query condition data
|
||||||
|
@ -120,12 +66,6 @@ typedef struct STagCond {
|
||||||
typedef struct STableMetaInfo {
|
typedef struct STableMetaInfo {
|
||||||
STableMeta *pTableMeta; // table meta, cached in client side and acquired by name
|
STableMeta *pTableMeta; // table meta, cached in client side and acquired by name
|
||||||
SVgroupsInfo *vgroupList;
|
SVgroupsInfo *vgroupList;
|
||||||
|
|
||||||
/*
|
|
||||||
* 1. keep the vgroup index during the multi-vnode super table projection query
|
|
||||||
* 2. keep the vgroup index for multi-vnode insertion
|
|
||||||
*/
|
|
||||||
int32_t vgroupIndex;
|
|
||||||
SName name;
|
SName name;
|
||||||
char aliasName[TSDB_TABLE_NAME_LEN]; // alias name of table specified in query sql
|
char aliasName[TSDB_TABLE_NAME_LEN]; // alias name of table specified in query sql
|
||||||
SArray *tagColList; // SArray<SColumn*>, involved tag columns
|
SArray *tagColList; // SArray<SColumn*>, involved tag columns
|
||||||
|
@ -137,11 +77,11 @@ typedef struct SQueryStmtInfo {
|
||||||
STimeWindow window; // the whole query time window
|
STimeWindow window; // the whole query time window
|
||||||
SInterval interval; // tumble time window
|
SInterval interval; // tumble time window
|
||||||
SSessionWindow sessionWindow; // session time window
|
SSessionWindow sessionWindow; // session time window
|
||||||
|
SStateWindow stateWindow; // state window query
|
||||||
SGroupbyExpr groupbyExpr; // groupby tags info
|
SGroupbyExpr groupbyExpr; // groupby tags info
|
||||||
SArray * colList; // SArray<SColumn*>
|
SArray * colList; // SArray<SColumn*>
|
||||||
SFieldInfo fieldsInfo;
|
SFieldInfo fieldsInfo;
|
||||||
SArray * exprList; // SArray<SExprInfo*>
|
SArray** exprList; // SArray<SExprInfo*>
|
||||||
SArray * exprList1; // final exprlist in case of arithmetic expression exists
|
|
||||||
SLimit limit;
|
SLimit limit;
|
||||||
SLimit slimit;
|
SLimit slimit;
|
||||||
STagCond tagCond;
|
STagCond tagCond;
|
||||||
|
@ -172,6 +112,7 @@ typedef struct SQueryStmtInfo {
|
||||||
struct SQueryStmtInfo *pDownstream;
|
struct SQueryStmtInfo *pDownstream;
|
||||||
int32_t havingFieldNum;
|
int32_t havingFieldNum;
|
||||||
SMultiFunctionsDesc info;
|
SMultiFunctionsDesc info;
|
||||||
|
int32_t exprListLevelIndex;
|
||||||
} SQueryStmtInfo;
|
} SQueryStmtInfo;
|
||||||
|
|
||||||
typedef struct SColumnIndex {
|
typedef struct SColumnIndex {
|
||||||
|
@ -225,14 +166,23 @@ void assignExprInfo(SExprInfo* dst, const SExprInfo* src);
|
||||||
void columnListCopy(SArray* dst, const SArray* src, uint64_t uid);
|
void columnListCopy(SArray* dst, const SArray* src, uint64_t uid);
|
||||||
void columnListDestroy(SArray* pColumnList);
|
void columnListDestroy(SArray* pColumnList);
|
||||||
|
|
||||||
void dropAllExprInfo(SArray* pExprInfo);
|
void dropAllExprInfo(SArray** pExprInfo, int32_t numOfLevel);
|
||||||
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, struct tExprNode* pParamExpr, SSchema* pResSchema, int16_t interSize);
|
|
||||||
|
typedef struct SSourceParam {
|
||||||
|
SArray *pExprNodeList; //Array<struct tExprNode*>
|
||||||
|
SArray *pColumnList; //Array<struct SColumn>
|
||||||
|
int32_t num;
|
||||||
|
} SSourceParam;
|
||||||
|
|
||||||
|
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, const char* funcName, SSourceParam* pSource, SSchema* pResSchema, int16_t interSize);
|
||||||
int32_t copyExprInfoList(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy);
|
int32_t copyExprInfoList(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy);
|
||||||
|
|
||||||
STableMetaInfo* getMetaInfo(SQueryStmtInfo* pQueryInfo, int32_t tableIndex);
|
STableMetaInfo* getMetaInfo(SQueryStmtInfo* pQueryInfo, int32_t tableIndex);
|
||||||
SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex);
|
SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex);
|
||||||
|
SSchema createSchema(uint8_t type, int16_t bytes, int16_t colId, const char* name);
|
||||||
|
|
||||||
int32_t getNewResColId();
|
int32_t getNewResColId();
|
||||||
|
void addIntoSourceParam(SSourceParam* pSourceParam, tExprNode* pNode, SColumn* pColumn);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,13 @@ extern "C" {
|
||||||
typedef int32_t SyncNodeId;
|
typedef int32_t SyncNodeId;
|
||||||
typedef int32_t SyncGroupId;
|
typedef int32_t SyncGroupId;
|
||||||
typedef int64_t SyncIndex;
|
typedef int64_t SyncIndex;
|
||||||
typedef uint64_t SSyncTerm;
|
typedef uint64_t SyncTerm;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TAOS_SYNC_ROLE_FOLLOWER = 0,
|
TAOS_SYNC_STATE_FOLLOWER = 0,
|
||||||
TAOS_SYNC_ROLE_CANDIDATE = 1,
|
TAOS_SYNC_STATE_CANDIDATE = 1,
|
||||||
TAOS_SYNC_ROLE_LEADER = 2,
|
TAOS_SYNC_STATE_LEADER = 2,
|
||||||
} ESyncRole;
|
} ESyncState;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void* data;
|
void* data;
|
||||||
|
@ -55,19 +55,19 @@ typedef struct {
|
||||||
int32_t selfIndex;
|
int32_t selfIndex;
|
||||||
int32_t replica;
|
int32_t replica;
|
||||||
SNodeInfo node[TSDB_MAX_REPLICA];
|
SNodeInfo node[TSDB_MAX_REPLICA];
|
||||||
ESyncRole role[TSDB_MAX_REPLICA];
|
ESyncState role[TSDB_MAX_REPLICA];
|
||||||
} SNodesRole;
|
} SNodesRole;
|
||||||
|
|
||||||
typedef struct SSyncFSM {
|
typedef struct SSyncFSM {
|
||||||
void* pData;
|
void* pData;
|
||||||
|
|
||||||
// apply committed log, bufs will be free by raft module
|
// apply committed log, bufs will be free by sync module
|
||||||
int32_t (*applyLog)(struct SSyncFSM* fsm, SyncIndex index, const SSyncBuffer* buf, void* pData);
|
int32_t (*applyLog)(struct SSyncFSM* fsm, SyncIndex index, const SSyncBuffer* buf, void* pData);
|
||||||
|
|
||||||
// cluster commit callback
|
// cluster commit callback
|
||||||
int32_t (*onClusterChanged)(struct SSyncFSM* fsm, const SSyncCluster* cluster, void* pData);
|
int32_t (*onClusterChanged)(struct SSyncFSM* fsm, const SSyncCluster* cluster, void* pData);
|
||||||
|
|
||||||
// fsm return snapshot in ppBuf, bufs will be free by raft module
|
// fsm return snapshot in ppBuf, bufs will be free by sync module
|
||||||
// TODO: getSnapshot SHOULD be async?
|
// TODO: getSnapshot SHOULD be async?
|
||||||
int32_t (*getSnapshot)(struct SSyncFSM* fsm, SSyncBuffer** ppBuf, int32_t* objId, bool* isLast);
|
int32_t (*getSnapshot)(struct SSyncFSM* fsm, SSyncBuffer** ppBuf, int32_t* objId, bool* isLast);
|
||||||
|
|
||||||
|
@ -89,19 +89,30 @@ typedef struct SSyncLogStore {
|
||||||
// write log with given index
|
// write log with given index
|
||||||
int32_t (*logWrite)(struct SSyncLogStore* logStore, SyncIndex index, SSyncBuffer* pBuf);
|
int32_t (*logWrite)(struct SSyncLogStore* logStore, SyncIndex index, SSyncBuffer* pBuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read log from given index(included) with limit, return the actual num in nBuf,
|
||||||
|
* pBuf will be free in sync module
|
||||||
|
**/
|
||||||
|
int32_t (*logRead)(struct SSyncLogStore* logStore, SyncIndex index, int limit,
|
||||||
|
SSyncBuffer* pBuf, int* nBuf);
|
||||||
|
|
||||||
// mark log with given index has been commtted
|
// mark log with given index has been commtted
|
||||||
int32_t (*logCommit)(struct SSyncLogStore* logStore, SyncIndex index);
|
int32_t (*logCommit)(struct SSyncLogStore* logStore, SyncIndex index);
|
||||||
|
|
||||||
// prune log before given index
|
// prune log before given index(not included)
|
||||||
int32_t (*logPrune)(struct SSyncLogStore* logStore, SyncIndex index);
|
int32_t (*logPrune)(struct SSyncLogStore* logStore, SyncIndex index);
|
||||||
|
|
||||||
// rollback log after given index
|
// rollback log after given index(included)
|
||||||
int32_t (*logRollback)(struct SSyncLogStore* logStore, SyncIndex index);
|
int32_t (*logRollback)(struct SSyncLogStore* logStore, SyncIndex index);
|
||||||
|
|
||||||
|
// return last index of log
|
||||||
|
SyncIndex (*logLastIndex)(struct SSyncLogStore* logStore);
|
||||||
} SSyncLogStore;
|
} SSyncLogStore;
|
||||||
|
|
||||||
typedef struct SSyncServerState {
|
typedef struct SSyncServerState {
|
||||||
SyncNodeId voteFor;
|
SyncNodeId voteFor;
|
||||||
SSyncTerm term;
|
SyncTerm term;
|
||||||
|
SyncIndex commitIndex;
|
||||||
} SSyncServerState;
|
} SSyncServerState;
|
||||||
|
|
||||||
typedef struct SSyncClusterConfig {
|
typedef struct SSyncClusterConfig {
|
||||||
|
@ -122,9 +133,9 @@ typedef struct SStateManager {
|
||||||
|
|
||||||
int32_t (*readServerState)(struct SStateManager* stateMng, SSyncServerState* state);
|
int32_t (*readServerState)(struct SStateManager* stateMng, SSyncServerState* state);
|
||||||
|
|
||||||
// void (*saveCluster)(struct SStateManager* stateMng, const SSyncClusterConfig* cluster);
|
void (*saveCluster)(struct SStateManager* stateMng, const SSyncClusterConfig* cluster);
|
||||||
|
|
||||||
// const SSyncClusterConfig* (*readCluster)(struct SStateManager* stateMng);
|
const SSyncClusterConfig* (*readCluster)(struct SStateManager* stateMng);
|
||||||
} SStateManager;
|
} SStateManager;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -146,13 +157,13 @@ SSyncNode* syncStart(const SSyncInfo*);
|
||||||
void syncReconfig(const SSyncNode*, const SSyncCluster*);
|
void syncReconfig(const SSyncNode*, const SSyncCluster*);
|
||||||
void syncStop(const SSyncNode*);
|
void syncStop(const SSyncNode*);
|
||||||
|
|
||||||
int32_t syncPropose(SSyncNode* syncNode, SSyncBuffer buffer, void* pData, bool isWeak);
|
int32_t syncPropose(SSyncNode* syncNode, const SSyncBuffer* pBuf, void* pData, bool isWeak);
|
||||||
|
|
||||||
// int32_t syncAddNode(SSyncNode syncNode, const SNodeInfo *pNode);
|
int32_t syncAddNode(SSyncNode syncNode, const SNodeInfo *pNode);
|
||||||
|
|
||||||
// int32_t syncRemoveNode(SSyncNode syncNode, const SNodeInfo *pNode);
|
int32_t syncRemoveNode(SSyncNode syncNode, const SNodeInfo *pNode);
|
||||||
|
|
||||||
extern int32_t syncDebugFlag;
|
extern int32_t sDebugFlag;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,8 @@ extern "C" {
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "osAtomic.h"
|
#include "osAtomic.h"
|
||||||
#include "osDef.h"
|
#include "osDef.h"
|
||||||
|
|
|
@ -22,7 +22,7 @@ extern "C" {
|
||||||
|
|
||||||
void taosRemoveDir(const char *dirname);
|
void taosRemoveDir(const char *dirname);
|
||||||
bool taosDirExist(char *dirname);
|
bool taosDirExist(char *dirname);
|
||||||
bool taosMkDir(char *dirname);
|
bool taosMkDir(const char *dirname);
|
||||||
void taosRemoveOldFiles(char *dirname, int32_t keepDays);
|
void taosRemoveOldFiles(char *dirname, int32_t keepDays);
|
||||||
bool taosExpandDir(char *dirname, char *outname, int32_t maxlen);
|
bool taosExpandDir(char *dirname, char *outname, int32_t maxlen);
|
||||||
bool taosRealPath(char *dirname, int32_t maxlen);
|
bool taosRealPath(char *dirname, int32_t maxlen);
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 _TD_AMALLOC_H_
|
|
||||||
#define _TD_AMALLOC_H_
|
|
||||||
|
|
||||||
#include "os.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define AMALLOC_APIS \
|
|
||||||
void *(*malloc)(void *, size_t size); \
|
|
||||||
void *(*calloc)(void *, size_t nmemb, size_t size); \
|
|
||||||
void *(*realloc)(void *, size_t size); \
|
|
||||||
void (*free)(void *ptr);
|
|
||||||
|
|
||||||
// Interfaces to implement
|
|
||||||
typedef struct {
|
|
||||||
AMALLOC_APIS
|
|
||||||
} SMemAllocatorIf;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void *impl;
|
|
||||||
AMALLOC_APIS
|
|
||||||
} SMemAllocator;
|
|
||||||
|
|
||||||
#define amalloc(allocator, size) ((allocator) ? (*((allocator)->malloc))((allocator)->impl, (size)) : malloc(size))
|
|
||||||
#define acalloc(allocator, nmemb, size) \
|
|
||||||
((allocator) ? (*((allocator)->calloc))((allocator)->impl, (nmemb), (size)) : calloc((nmemb), (size)))
|
|
||||||
#define arealloc(allocator, ptr, size) \
|
|
||||||
((allocator) ? (*((allocator)->realloc))((allocator)->impl, (ptr), (size)) : realloc((ptr), (size)))
|
|
||||||
#define afree(allocator, ptr, size) ((allocator) ? (*((allocator)->free))((allocator)->impl, (ptr), (size)) : free(ptr))
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*_TD_AMALLOC_H_*/
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_MALLOCATOR_H_
|
||||||
|
#define _TD_MALLOCATOR_H_
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct SMemAllocator SMemAllocator;
|
||||||
|
|
||||||
|
#define MALLOCATOR_APIS \
|
||||||
|
void *(*malloc)(SMemAllocator *, size_t size); \
|
||||||
|
void *(*calloc)(SMemAllocator *, size_t nmemb, size_t size); \
|
||||||
|
void *(*realloc)(SMemAllocator *, void *ptr, size_t size); \
|
||||||
|
void (*free)(SMemAllocator *, void *ptr); \
|
||||||
|
size_t (*usage)(SMemAllocator *);
|
||||||
|
|
||||||
|
// Interfaces to implement
|
||||||
|
typedef struct {
|
||||||
|
MALLOCATOR_APIS
|
||||||
|
} SMemAllocatorIf;
|
||||||
|
|
||||||
|
struct SMemAllocator {
|
||||||
|
void * impl;
|
||||||
|
size_t usize;
|
||||||
|
MALLOCATOR_APIS
|
||||||
|
};
|
||||||
|
|
||||||
|
// heap allocator
|
||||||
|
SMemAllocator *tdCreateHeapAllocator();
|
||||||
|
void tdDestroyHeapAllocator(SMemAllocator *pMemAllocator);
|
||||||
|
|
||||||
|
// arena allocator
|
||||||
|
SMemAllocator *tdCreateArenaAllocator(size_t size);
|
||||||
|
void tdDestroyArenaAllocator(SMemAllocator *);
|
||||||
|
|
||||||
|
#define mMalloc(pMemAllocator, size) (*(pMemAllocator->malloc))(pMemAllocator, size)
|
||||||
|
#define mCalloc(pMemAllocator, nmemb, size) (*(pMemAllocator->calloc))(pMemAllocator, nmemb, size)
|
||||||
|
#define mRealloc(pMemAllocator, ptr, size) (*(pMemAllocator->realloc))(pMemAllocator, ptr, size)
|
||||||
|
#define mFree(pMemAllocator, ptr) (*(pMemAllocator->free))(pMemAllocator, ptr)
|
||||||
|
#define mUsage(pMemAllocator) (*(pMemAllocator->usage))(pMemAllocator)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_MALLOCATOR_H_*/
|
|
@ -20,7 +20,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "tdef.h"
|
#include "taos.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
#define COMP_OVERFLOW_BYTES 2
|
#define COMP_OVERFLOW_BYTES 2
|
||||||
|
|
|
@ -134,6 +134,15 @@ do { \
|
||||||
#define TSDB_BINARY_OP_REMAINDER 4004
|
#define TSDB_BINARY_OP_REMAINDER 4004
|
||||||
#define TSDB_BINARY_OP_CONCAT 4005
|
#define TSDB_BINARY_OP_CONCAT 4005
|
||||||
|
|
||||||
|
#define FUNCTION_CEIL 4500
|
||||||
|
#define FUNCTION_FLOOR 4501
|
||||||
|
#define FUNCTION_ABS 4502
|
||||||
|
#define FUNCTION_ROUND 4503
|
||||||
|
|
||||||
|
#define FUNCTION_LENGTH 4800
|
||||||
|
#define FUNCTION_CONCAT 4801
|
||||||
|
#define FUNCTION_LTRIM 4802
|
||||||
|
#define FUNCTION_RTRIM 4803
|
||||||
|
|
||||||
#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN))
|
#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN))
|
||||||
#define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER))
|
#define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER))
|
||||||
|
@ -311,10 +320,6 @@ do { \
|
||||||
#define TSDB_QUERY_TYPE_NON_TYPE 0x00u // none type
|
#define TSDB_QUERY_TYPE_NON_TYPE 0x00u // none type
|
||||||
#define TSDB_QUERY_TYPE_FREE_RESOURCE 0x01u // free qhandle at vnode
|
#define TSDB_QUERY_TYPE_FREE_RESOURCE 0x01u // free qhandle at vnode
|
||||||
|
|
||||||
#define TSDB_UDF_TYPE_SCALAR 1
|
|
||||||
#define TSDB_UDF_TYPE_AGGREGATE 2
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1. ordinary sub query for select * from super_table
|
* 1. ordinary sub query for select * from super_table
|
||||||
* 2. all sqlobj generated by createSubqueryObj with this flag
|
* 2. all sqlobj generated by createSubqueryObj with this flag
|
||||||
|
@ -367,21 +372,6 @@ do { \
|
||||||
#define TSDB_MAX_DISKS_PER_TIER 16
|
#define TSDB_MAX_DISKS_PER_TIER 16
|
||||||
#define TSDB_MAX_DISKS (TSDB_MAX_TIERS * TSDB_MAX_DISKS_PER_TIER)
|
#define TSDB_MAX_DISKS (TSDB_MAX_TIERS * TSDB_MAX_DISKS_PER_TIER)
|
||||||
|
|
||||||
#define TSDB_DATA_TYPE_NULL 0 // 1 bytes
|
|
||||||
#define TSDB_DATA_TYPE_BOOL 1 // 1 bytes
|
|
||||||
#define TSDB_DATA_TYPE_TINYINT 2 // 1 byte
|
|
||||||
#define TSDB_DATA_TYPE_SMALLINT 3 // 2 bytes
|
|
||||||
#define TSDB_DATA_TYPE_INT 4 // 4 bytes
|
|
||||||
#define TSDB_DATA_TYPE_BIGINT 5 // 8 bytes
|
|
||||||
#define TSDB_DATA_TYPE_FLOAT 6 // 4 bytes
|
|
||||||
#define TSDB_DATA_TYPE_DOUBLE 7 // 8 bytes
|
|
||||||
#define TSDB_DATA_TYPE_BINARY 8 // string
|
|
||||||
#define TSDB_DATA_TYPE_TIMESTAMP 9 // 8 bytes
|
|
||||||
#define TSDB_DATA_TYPE_NCHAR 10 // unicode string
|
|
||||||
#define TSDB_DATA_TYPE_UTINYINT 11 // 1 byte
|
|
||||||
#define TSDB_DATA_TYPE_USMALLINT 12 // 2 bytes
|
|
||||||
#define TSDB_DATA_TYPE_UINT 13 // 4 bytes
|
|
||||||
#define TSDB_DATA_TYPE_UBIGINT 14 // 8 bytes
|
|
||||||
|
|
||||||
enum { TRANS_STAT_INIT = 0, TRANS_STAT_EXECUTING, TRANS_STAT_EXECUTED, TRANS_STAT_ROLLBACKING, TRANS_STAT_ROLLBACKED };
|
enum { TRANS_STAT_INIT = 0, TRANS_STAT_EXECUTING, TRANS_STAT_EXECUTED, TRANS_STAT_ROLLBACKING, TRANS_STAT_ROLLBACKED };
|
||||||
enum { TRANS_OPER_INIT = 0, TRANS_OPER_EXECUTE, TRANS_OPER_ROLLBACK };
|
enum { TRANS_OPER_INIT = 0, TRANS_OPER_EXECUTE, TRANS_OPER_ROLLBACK };
|
||||||
|
|
|
@ -21,7 +21,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
//#include "tdef.h"
|
#include "taos.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "tfunctional.h"
|
#include "tfunctional.h"
|
||||||
|
|
||||||
|
|
|
@ -376,7 +376,7 @@ static void *dnodeOpenVnodeFunc(void *param) {
|
||||||
|
|
||||||
char path[PATH_MAX + 20] = {0};
|
char path[PATH_MAX + 20] = {0};
|
||||||
snprintf(path, sizeof(path),"%s/vnode%d", tsVnodeDir, pVnode->vgId);
|
snprintf(path, sizeof(path),"%s/vnode%d", tsVnodeDir, pVnode->vgId);
|
||||||
SVnode *pImpl = vnodeOpen(pVnode->vgId, path);
|
SVnode *pImpl = vnodeOpen(path, NULL);
|
||||||
if (pImpl == NULL) {
|
if (pImpl == NULL) {
|
||||||
dError("vgId:%d, failed to open vnode by thread:%d", pVnode->vgId, pThread->threadIndex);
|
dError("vgId:%d, failed to open vnode by thread:%d", pVnode->vgId, pThread->threadIndex);
|
||||||
pThread->failed++;
|
pThread->failed++;
|
||||||
|
|
|
@ -7,6 +7,7 @@ target_include_directories(
|
||||||
)
|
)
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
vnode
|
vnode
|
||||||
|
PUBLIC os
|
||||||
PUBLIC transport
|
PUBLIC transport
|
||||||
PUBLIC meta
|
PUBLIC meta
|
||||||
PUBLIC tq
|
PUBLIC tq
|
||||||
|
|
|
@ -13,20 +13,27 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TD_COMMON_QARITHMETICOPERATOR_H_
|
#ifndef _TD_VNODE_ALLOCATOR_POOL_H_
|
||||||
#define _TD_COMMON_QARITHMETICOPERATOR_H_
|
#define _TD_VNODE_ALLOCATOR_POOL_H_
|
||||||
|
|
||||||
|
#include "vnode.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void (*_arithmetic_operator_fn_t)(void *left, int32_t numLeft, int32_t leftType, void *right, int32_t numRight,
|
typedef struct {
|
||||||
int32_t rightType, void *output, int32_t order);
|
int nexta;
|
||||||
|
int enda;
|
||||||
|
SMemAllocator *free[3];
|
||||||
|
SMemAllocator *used[3];
|
||||||
|
} SVAllocatorPool;
|
||||||
|
|
||||||
_arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr);
|
int vnodeOpenAllocatorPool(SVnode *pVnode);
|
||||||
|
void vnodeCloseAllocatorPool(SVnode *pVnode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /*_TD_COMMON_QARITHMETICOPERATOR_H_*/
|
#endif /*_TD_VNODE_ALLOCATOR_POOL_H_*/
|
|
@ -16,13 +16,14 @@
|
||||||
#ifndef _TD_VNODE_COMMIT_H_
|
#ifndef _TD_VNODE_COMMIT_H_
|
||||||
#define _TD_VNODE_COMMIT_H_
|
#define _TD_VNODE_COMMIT_H_
|
||||||
|
|
||||||
#include "vnodeInt.h"
|
#include "vnode.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int vnodeAsyncCommit(SVnode *pVnode);
|
bool vnodeShouldCommit(SVnode *pVnode);
|
||||||
|
int vnodeAsyncCommit(SVnode *pVnode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_VNODE_DEF_H_
|
||||||
|
#define _TD_VNODE_DEF_H_
|
||||||
|
|
||||||
|
#include "mallocator.h"
|
||||||
|
#include "sync.h"
|
||||||
|
#include "tlockfree.h"
|
||||||
|
|
||||||
|
#include "vnode.h"
|
||||||
|
#include "vnodeAllocatorPool.h"
|
||||||
|
#include "vnodeCommit.h"
|
||||||
|
#include "vnodeFileSystem.h"
|
||||||
|
#include "vnodeOptions.h"
|
||||||
|
#include "vnodeStateMgr.h"
|
||||||
|
#include "vnodeSync.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct SVnode {
|
||||||
|
char* path;
|
||||||
|
SVnodeOptions options;
|
||||||
|
SVState state;
|
||||||
|
SVAllocatorPool* pool;
|
||||||
|
SMemAllocator* inuse;
|
||||||
|
SMeta* pMeta;
|
||||||
|
STsdb* pTsdb;
|
||||||
|
STQ* pTq;
|
||||||
|
SVnodeSync* pSync;
|
||||||
|
SVnodeFS* pFs;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_VNODE_DEF_H_*/
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_VNODE_FILE_SYSTEM_H_
|
||||||
|
#define _TD_VNODE_FILE_SYSTEM_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
} SVnodeFS;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_VNODE_FILE_SYSTEM_H_*/
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#include "vnode.h"
|
#include "vnode.h"
|
||||||
|
|
||||||
#include "amalloc.h"
|
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "tlog.h"
|
#include "tlog.h"
|
||||||
|
@ -39,16 +38,6 @@ extern int32_t vDebugFlag;
|
||||||
#define vDebug(...) { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }}
|
#define vDebug(...) { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }}
|
||||||
#define vTrace(...) { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }}
|
#define vTrace(...) { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }}
|
||||||
|
|
||||||
typedef struct SVnode {
|
|
||||||
int32_t vgId;
|
|
||||||
SVnodeCfg cfg;
|
|
||||||
SMeta *pMeta;
|
|
||||||
STsdb *pTsdb;
|
|
||||||
STQ *pTQ;
|
|
||||||
SWal *pWal;
|
|
||||||
SSyncNode *pSync;
|
|
||||||
} SVnode;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,40 +16,12 @@
|
||||||
#ifndef _TD_VNODE_MEM_ALLOCATOR_H_
|
#ifndef _TD_VNODE_MEM_ALLOCATOR_H_
|
||||||
#define _TD_VNODE_MEM_ALLOCATOR_H_
|
#define _TD_VNODE_MEM_ALLOCATOR_H_
|
||||||
|
|
||||||
#include "vnodeInt.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct SVnodeMemAllocator SVnodeMemAllocator;
|
|
||||||
|
|
||||||
SVnodeMemAllocator *VMACreate(size_t size /* base size */, size_t ssize /* step size */,
|
|
||||||
size_t threshold /* threshold size when full*/);
|
|
||||||
void VMADestroy(SVnodeMemAllocator *pvma);
|
|
||||||
void VMAReset(SVnodeMemAllocator *pvma);
|
|
||||||
void * VMAMalloc(SVnodeMemAllocator *pvma, size_t size);
|
|
||||||
void VMAFree(SVnodeMemAllocator *pvma, void *ptr);
|
|
||||||
bool VMAIsFull(SVnodeMemAllocator *pvma);
|
|
||||||
|
|
||||||
// ------------------ FOR TEST ONLY ------------------
|
|
||||||
typedef struct SVMANode {
|
|
||||||
struct SVMANode *prev;
|
|
||||||
size_t tsize;
|
|
||||||
size_t used;
|
|
||||||
char data[];
|
|
||||||
} SVMANode;
|
|
||||||
|
|
||||||
struct SVnodeMemAllocator {
|
|
||||||
bool full; // if allocator is full
|
|
||||||
size_t threshold; // threshold;
|
|
||||||
size_t ssize; // step size to allocate
|
|
||||||
SVMANode *inuse; // inuse node to allocate
|
|
||||||
SVMANode node; // basic node to use
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /*_TD_VNODE_MEM_ALLOCATOR_H_*/
|
#endif /*_TD_VNODE_MEM_ALLOCATOR_H_*/
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_VNODE_OPTIONS_H_
|
||||||
|
#define _TD_VNODE_OPTIONS_H_
|
||||||
|
|
||||||
|
#include "vnode.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const SVnodeOptions defaultVnodeOptions;
|
||||||
|
|
||||||
|
int vnodeValidateOptions(const SVnodeOptions *);
|
||||||
|
void vnodeOptionsCopy(SVnodeOptions *pDest, const SVnodeOptions *pSrc);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_VNODE_OPTIONS_H_*/
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_VNODE_REQUEST_H_
|
||||||
|
#define _TD_VNODE_REQUEST_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_VNODE_REQUEST_H_*/
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_VNODE_STATE_MGR_H_
|
||||||
|
#define _TD_VNODE_STATE_MGR_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
} SVState;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_VNODE_STATE_MGR_H_*/
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_VNODE_SYNC_H_
|
||||||
|
#define _TD_VNODE_SYNC_H_
|
||||||
|
|
||||||
|
#include "sync.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* data */
|
||||||
|
} SVnodeSync;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_VNODE_SYNC_H_*/
|
|
@ -16,10 +16,11 @@
|
||||||
#ifndef _TD_VNODE_WRITE_H_
|
#ifndef _TD_VNODE_WRITE_H_
|
||||||
#define _TD_VNODE_WRITE_H_
|
#define _TD_VNODE_WRITE_H_
|
||||||
|
|
||||||
|
#include "vnode.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#include "vnodeInt.h"
|
|
||||||
|
|
||||||
void vnodeProcessWriteMsg(SVnode* pVnode, SVnodeMsg* pMsg);
|
void vnodeProcessWriteMsg(SVnode* pVnode, SVnodeMsg* pMsg);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vnodeDef.h"
|
||||||
|
|
||||||
|
int vnodeOpenAllocatorPool(SVnode *pVnode) {
|
||||||
|
// TODO
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vnodeCloseAllocatorPool(SVnode *pVnode) {
|
||||||
|
if (pVnode->pool) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------ STATIC METHODS ------------------------ */
|
||||||
|
static SVAllocatorPool *vapCreate() {
|
||||||
|
SVAllocatorPool *pPool = NULL;
|
||||||
|
/* TODO */
|
||||||
|
return pPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vapDestroy() {
|
||||||
|
// TODO
|
||||||
|
}
|
|
@ -13,13 +13,15 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "vnodeInt.h"
|
#include "vnodeDef.h"
|
||||||
|
|
||||||
static int vnodeStartCommit(SVnode *pVnode);
|
static int vnodeStartCommit(SVnode *pVnode);
|
||||||
static int vnodeEndCommit(SVnode *pVnode);
|
static int vnodeEndCommit(SVnode *pVnode);
|
||||||
|
|
||||||
|
bool vnodeShouldCommit(SVnode *pVnode) { return false; }
|
||||||
|
|
||||||
int vnodeAsyncCommit(SVnode *pVnode) {
|
int vnodeAsyncCommit(SVnode *pVnode) {
|
||||||
#if 0
|
#if 0
|
||||||
if (vnodeStartCommit(pVnode) < 0) {
|
if (vnodeStartCommit(pVnode) < 0) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vnodeDef.h"
|
|
@ -20,8 +20,6 @@
|
||||||
int32_t vnodeInit(SVnodePara para) { return 0; }
|
int32_t vnodeInit(SVnodePara para) { return 0; }
|
||||||
void vnodeCleanup() {}
|
void vnodeCleanup() {}
|
||||||
|
|
||||||
SVnode *vnodeOpen(int32_t vgId, const char *path) { return NULL; }
|
|
||||||
void vnodeClose(SVnode *pVnode) {}
|
|
||||||
int32_t vnodeAlter(SVnode *pVnode, const SVnodeCfg *pCfg) { return 0; }
|
int32_t vnodeAlter(SVnode *pVnode, const SVnodeCfg *pCfg) { return 0; }
|
||||||
SVnode *vnodeCreate(int32_t vgId, const char *path, const SVnodeCfg *pCfg) { return NULL; }
|
SVnode *vnodeCreate(int32_t vgId, const char *path, const SVnodeCfg *pCfg) { return NULL; }
|
||||||
void vnodeDrop(SVnode *pVnode) {}
|
void vnodeDrop(SVnode *pVnode) {}
|
||||||
|
@ -69,4 +67,4 @@ void vnodeProcessMsg(SVnode *pVnode, SVnodeMsg *pMsg, EVnMsgType msgType) {
|
||||||
case VN_MSG_TYPE_FETCH:
|
case VN_MSG_TYPE_FETCH:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vnodeDef.h"
|
||||||
|
|
||||||
|
static SVnode *vnodeNew(const char *path, const SVnodeOptions *pVnodeOptions);
|
||||||
|
static void vnodeFree(SVnode *pVnode);
|
||||||
|
static int vnodeOpenImpl(SVnode *pVnode);
|
||||||
|
static void vnodeCloseImpl(SVnode *pVnode);
|
||||||
|
|
||||||
|
SVnode *vnodeOpen(const char *path, const SVnodeOptions *pVnodeOptions) {
|
||||||
|
SVnode *pVnode = NULL;
|
||||||
|
|
||||||
|
// Set default options
|
||||||
|
if (pVnodeOptions == NULL) {
|
||||||
|
pVnodeOptions = &defaultVnodeOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate options
|
||||||
|
if (vnodeValidateOptions(pVnodeOptions) < 0) {
|
||||||
|
// TODO
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the handle
|
||||||
|
pVnode = vnodeNew(path, pVnodeOptions);
|
||||||
|
if (pVnode == NULL) {
|
||||||
|
// TODO: handle error
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosMkDir(path);
|
||||||
|
|
||||||
|
// Open the vnode
|
||||||
|
if (vnodeOpenImpl(pVnode) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pVnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vnodeClose(SVnode *pVnode) {
|
||||||
|
if (pVnode) {
|
||||||
|
vnodeCloseImpl(pVnode);
|
||||||
|
vnodeFree(pVnode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vnodeDestroy(const char *path) { taosRemoveDir(path); }
|
||||||
|
|
||||||
|
/* ------------------------ STATIC METHODS ------------------------ */
|
||||||
|
static SVnode *vnodeNew(const char *path, const SVnodeOptions *pVnodeOptions) {
|
||||||
|
SVnode *pVnode = NULL;
|
||||||
|
|
||||||
|
pVnode = (SVnode *)calloc(1, sizeof(*pVnode));
|
||||||
|
if (pVnode == NULL) {
|
||||||
|
// TODO
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pVnode->path = strdup(path);
|
||||||
|
vnodeOptionsCopy(&(pVnode->options), pVnodeOptions);
|
||||||
|
|
||||||
|
return pVnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vnodeFree(SVnode *pVnode) {
|
||||||
|
if (pVnode) {
|
||||||
|
tfree(pVnode->path);
|
||||||
|
free(pVnode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vnodeOpenImpl(SVnode *pVnode) {
|
||||||
|
char dir[TSDB_FILENAME_LEN];
|
||||||
|
|
||||||
|
// Open allocator pool
|
||||||
|
if (vnodeOpenAllocatorPool(pVnode) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open meta
|
||||||
|
sprintf(dir, "%s/meta", pVnode->path);
|
||||||
|
pVnode->pMeta = metaOpen(dir, &(pVnode->options.metaOptions));
|
||||||
|
if (pVnode->pMeta == NULL) {
|
||||||
|
// TODO: handle error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open tsdb
|
||||||
|
sprintf(dir, "%s/tsdb", pVnode->path);
|
||||||
|
pVnode->pTsdb = tsdbOpen(dir, &(pVnode->options.tsdbOptions));
|
||||||
|
if (pVnode->pTsdb == NULL) {
|
||||||
|
// TODO: handle error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Open TQ
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vnodeCloseImpl(SVnode *pVnode) {
|
||||||
|
if (pVnode) {
|
||||||
|
vnodeCloseAllocatorPool(pVnode);
|
||||||
|
// TODO: Close TQ
|
||||||
|
tsdbClose(pVnode->pTsdb);
|
||||||
|
metaClose(pVnode->pMeta);
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,112 +13,88 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "vnodeMemAllocator.h"
|
#include "vnodeDef.h"
|
||||||
|
|
||||||
#define VMA_IS_FULL(pvma) \
|
#define VNODE_HEAP_ALLOCATOR 0
|
||||||
(((pvma)->inuse != &((pvma)->node)) || ((pvma)->inuse->tsize - (pvma)->inuse->used < (pvma)->threshold))
|
#define VNODE_ARENA_ALLOCATOR 1
|
||||||
|
|
||||||
static SVMANode *VMANodeNew(size_t size);
|
typedef struct {
|
||||||
static void VMANodeFree(SVMANode *node);
|
uint64_t tsize;
|
||||||
|
uint64_t used;
|
||||||
|
} SVHeapAllocator;
|
||||||
|
|
||||||
SVnodeMemAllocator *VMACreate(size_t size, size_t ssize, size_t threshold) {
|
typedef struct SVArenaNode {
|
||||||
SVnodeMemAllocator *pvma = NULL;
|
struct SVArenaNode *prev;
|
||||||
|
void * nptr;
|
||||||
|
char data[];
|
||||||
|
} SVArenaNode;
|
||||||
|
|
||||||
if (size < threshold) {
|
typedef struct {
|
||||||
|
SVArenaNode *inuse;
|
||||||
|
SVArenaNode node;
|
||||||
|
} SVArenaAllocator;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int8_t type;
|
||||||
|
uint64_t tsize;
|
||||||
|
T_REF_DECLARE()
|
||||||
|
union {
|
||||||
|
SVHeapAllocator vha;
|
||||||
|
SVArenaAllocator vaa;
|
||||||
|
};
|
||||||
|
} SVMemAllocator;
|
||||||
|
|
||||||
|
SMemAllocator *vnodeCreateMemAllocator(int8_t type, uint64_t tsize, uint64_t ssize /* step size only for arena */) {
|
||||||
|
SMemAllocator * pma;
|
||||||
|
uint64_t msize;
|
||||||
|
SVMemAllocator *pva;
|
||||||
|
|
||||||
|
msize = sizeof(*pma) + sizeof(SVMemAllocator);
|
||||||
|
if (type == VNODE_ARENA_ALLOCATOR) {
|
||||||
|
msize += tsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pma = (SMemAllocator *)calloc(1, msize);
|
||||||
|
if (pma == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pvma = (SVnodeMemAllocator *)malloc(sizeof(*pvma) + size);
|
pma->impl = POINTER_SHIFT(pma, sizeof(*pma));
|
||||||
if (pvma) {
|
pva = (SVMemAllocator *)(pma->impl);
|
||||||
pvma->full = false;
|
pva->type = type;
|
||||||
pvma->threshold = threshold;
|
pva->tsize = tsize;
|
||||||
pvma->ssize = ssize;
|
|
||||||
pvma->inuse = &(pvma->node);
|
|
||||||
|
|
||||||
pvma->inuse->prev = NULL;
|
if (type == VNODE_HEAP_ALLOCATOR) {
|
||||||
pvma->inuse->tsize = size;
|
pma->malloc = NULL;
|
||||||
pvma->inuse->used = 0;
|
pma->calloc = NULL;
|
||||||
|
pma->realloc = NULL;
|
||||||
|
pma->free = NULL;
|
||||||
|
pma->usage = NULL;
|
||||||
|
} else if (type == VNODE_ARENA_ALLOCATOR) {
|
||||||
|
pma->malloc = NULL;
|
||||||
|
pma->calloc = NULL;
|
||||||
|
pma->realloc = NULL;
|
||||||
|
pma->free = NULL;
|
||||||
|
pma->usage = NULL;
|
||||||
|
} else {
|
||||||
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pvma;
|
return pma;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMADestroy(SVnodeMemAllocator *pvma) {
|
void vnodeDestroyMemAllocator(SMemAllocator *pma) {
|
||||||
if (pvma) {
|
// TODO
|
||||||
VMAReset(pvma);
|
|
||||||
free(pvma);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMAReset(SVnodeMemAllocator *pvma) {
|
void vnodeRefMemAllocator(SMemAllocator *pma) {
|
||||||
while (pvma->inuse != &(pvma->node)) {
|
// TODO
|
||||||
SVMANode *node = pvma->inuse;
|
|
||||||
pvma->inuse = node->prev;
|
|
||||||
VMANodeFree(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
pvma->inuse->used = 0;
|
|
||||||
pvma->full = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *VMAMalloc(SVnodeMemAllocator *pvma, size_t size) {
|
void vnodeUnrefMemAllocator(SMemAllocator *pma) {
|
||||||
void * ptr = NULL;
|
// TODO
|
||||||
size_t tsize = size + sizeof(size_t);
|
|
||||||
|
|
||||||
if (pvma->inuse->tsize - pvma->inuse->used < tsize) {
|
|
||||||
SVMANode *pNode = VMANodeNew(MAX(pvma->ssize, tsize));
|
|
||||||
if (pNode == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pNode->prev = pvma->inuse;
|
|
||||||
pvma->inuse = pNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = pvma->inuse->data + pvma->inuse->used;
|
|
||||||
pvma->inuse->used += tsize;
|
|
||||||
*(size_t *)ptr = size;
|
|
||||||
ptr = POINTER_SHIFT(ptr, sizeof(size_t));
|
|
||||||
|
|
||||||
pvma->full = VMA_IS_FULL(pvma);
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMAFree(SVnodeMemAllocator *pvma, void *ptr) {
|
/* ------------------------ Heap Allocator IMPL ------------------------ */
|
||||||
if (ptr) {
|
|
||||||
size_t size = *(size_t *)POINTER_SHIFT(ptr, -sizeof(size_t));
|
|
||||||
if (POINTER_SHIFT(ptr, size) == pvma->inuse->data + pvma->inuse->used) {
|
|
||||||
pvma->inuse->used -= (size + sizeof(size_t));
|
|
||||||
|
|
||||||
if ((pvma->inuse->used == 0) && (pvma->inuse != &(pvma->node))) {
|
/* ------------------------ Arena Allocator IMPL ------------------------ */
|
||||||
SVMANode *node = pvma->inuse;
|
|
||||||
pvma->inuse = node->prev;
|
|
||||||
VMANodeFree(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
pvma->full = VMA_IS_FULL(pvma);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VMAIsFull(SVnodeMemAllocator *pvma) { return pvma->full; }
|
|
||||||
|
|
||||||
static SVMANode *VMANodeNew(size_t size) {
|
|
||||||
SVMANode *node = NULL;
|
|
||||||
|
|
||||||
node = (SVMANode *)malloc(sizeof(*node) + size);
|
|
||||||
if (node) {
|
|
||||||
node->prev = NULL;
|
|
||||||
node->tsize = size;
|
|
||||||
node->used = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void VMANodeFree(SVMANode *node) {
|
|
||||||
if (node) {
|
|
||||||
free(node);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vnodeDef.h"
|
||||||
|
|
||||||
|
const SVnodeOptions defaultVnodeOptions = {0}; /* TODO */
|
||||||
|
|
||||||
|
void vnodeOptionsInit(SVnodeOptions *pVnodeOptions) { /* TODO */
|
||||||
|
vnodeOptionsCopy(pVnodeOptions, &defaultVnodeOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vnodeOptionsClear(SVnodeOptions *pVnodeOptions) { /* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
int vnodeValidateOptions(const SVnodeOptions *pVnodeOptions) {
|
||||||
|
// TODO
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vnodeOptionsCopy(SVnodeOptions *pDest, const SVnodeOptions *pSrc) {
|
||||||
|
memcpy((void *)pDest, (void *)pSrc, sizeof(SVnodeOptions));
|
||||||
|
}
|
|
@ -13,5 +13,4 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#include "vnodeDef.h"
|
||||||
#include "vnodeRead.h"
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
|
@ -13,5 +13,50 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#include "vnodeDef.h"
|
||||||
#include "vnodeWrite.h"
|
|
||||||
|
int vnodeProcessWriteReqs(SVnode *pVnode, SReqBatch *pReqBatch) {
|
||||||
|
/* TODO */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vnodeApplyWriteRequest(SVnode *pVnode, const SRequest *pRequest) {
|
||||||
|
int reqType; /* TODO */
|
||||||
|
size_t reqSize; /* TODO */
|
||||||
|
uint64_t reqVersion = 0; /* TODO */
|
||||||
|
int code = 0;
|
||||||
|
|
||||||
|
// Copy the request to vnode buffer
|
||||||
|
SRequest *pReq = mMalloc(pVnode->inuse, reqSize);
|
||||||
|
if (pReq == NULL) {
|
||||||
|
// TODO: handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pReq, pRequest, reqSize);
|
||||||
|
|
||||||
|
// Push the request to TQ so consumers can consume
|
||||||
|
tqPushMsg(pVnode->pTq, pReq, 0);
|
||||||
|
|
||||||
|
// Process the request
|
||||||
|
switch (reqType) {
|
||||||
|
case TSDB_MSG_TYPE_CREATE_TABLE:
|
||||||
|
code = metaCreateTable(pVnode->pMeta, NULL /* TODO */);
|
||||||
|
break;
|
||||||
|
case TSDB_MSG_TYPE_DROP_TABLE:
|
||||||
|
code = metaDropTable(pVnode->pMeta, 0 /* TODO */);
|
||||||
|
break;
|
||||||
|
/* TODO */
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vnodeShouldCommit(pVnode)) {
|
||||||
|
if (vnodeAsyncCommit(pVnode) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------ STATIC METHODS ------------------------ */
|
|
@ -1,9 +1,7 @@
|
||||||
# vnodeMemAllocatorTest
|
# Vnode API test
|
||||||
add_executable(VMATest "")
|
add_executable(vnodeApiTests "")
|
||||||
target_sources(VMATest
|
target_sources(vnodeApiTests
|
||||||
PRIVATE
|
PRIVATE
|
||||||
"../src/vnodeMemAllocator.c"
|
"vnodeApiTests.cpp"
|
||||||
"vnodeMemAllocatorTest.cpp"
|
|
||||||
)
|
)
|
||||||
target_include_directories(VMATest PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../inc")
|
target_link_libraries(vnodeApiTests vnode gtest gtest_main)
|
||||||
target_link_libraries(VMATest os gtest_main vnode)
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "vnode.h"
|
||||||
|
|
||||||
|
TEST(vnodeApiTest, vnodeOpen_vnodeClose_test) {
|
||||||
|
// Create and open a vnode
|
||||||
|
SVnode *pVnode = vnodeOpen("vnode1", NULL);
|
||||||
|
ASSERT_NE(pVnode, nullptr);
|
||||||
|
|
||||||
|
// Close the vnode
|
||||||
|
vnodeClose(pVnode);
|
||||||
|
}
|
|
@ -1,22 +0,0 @@
|
||||||
#include <gtest/gtest.h>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "vnodeMemAllocator.h"
|
|
||||||
|
|
||||||
TEST(VMATest, basic_create_and_destroy_test) {
|
|
||||||
SVnodeMemAllocator *vma = VMACreate(1024, 512, 64);
|
|
||||||
EXPECT_TRUE(vma != nullptr);
|
|
||||||
EXPECT_EQ(vma->full, false);
|
|
||||||
EXPECT_EQ(vma->ssize, 512);
|
|
||||||
EXPECT_EQ(vma->threshold, 64);
|
|
||||||
EXPECT_EQ(vma->inuse->tsize, 1024);
|
|
||||||
VMADestroy(vma);
|
|
||||||
|
|
||||||
vma = VMACreate(1024, 512, 1024);
|
|
||||||
EXPECT_TRUE(vma != nullptr);
|
|
||||||
VMADestroy(vma);
|
|
||||||
|
|
||||||
vma = VMACreate(1024, 512, 1025);
|
|
||||||
EXPECT_TRUE(vma == nullptr);
|
|
||||||
VMADestroy(vma);
|
|
||||||
}
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_META_CACHE_H_
|
||||||
|
#define _TD_META_CACHE_H_
|
||||||
|
|
||||||
|
#include "rocksdb/c.h"
|
||||||
|
|
||||||
|
#include "meta.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef rocksdb_cache_t meta_cache_t;
|
||||||
|
|
||||||
|
int metaOpenCache(SMeta *pMeta);
|
||||||
|
void metaCloseCache(SMeta *pMeta);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_META_CACHE_H_*/
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_META_DB_H_
|
||||||
|
#define _TD_META_DB_H_
|
||||||
|
|
||||||
|
#include "rocksdb/c.h"
|
||||||
|
|
||||||
|
#include "meta.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
rocksdb_t *tbDb; // uid -> tb obj
|
||||||
|
rocksdb_t *nameDb; // name -> uid
|
||||||
|
rocksdb_t *tagDb; // uid -> tag
|
||||||
|
rocksdb_t *schemaDb; // uid+version -> schema
|
||||||
|
rocksdb_t *mapDb; // suid -> uid_list
|
||||||
|
} meta_db_t;
|
||||||
|
|
||||||
|
int metaOpenDB(SMeta *pMeta);
|
||||||
|
void metaCloseDB(SMeta *pMeta);
|
||||||
|
int metaSaveTableToDB(SMeta *pMeta, const STbOptions *pTbOptions);
|
||||||
|
int metaRemoveTableFromDb(SMeta *pMeta, tb_uid_t uid);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_META_DB_H_*/
|
|
@ -16,22 +16,26 @@
|
||||||
#ifndef _TD_META_DEF_H_
|
#ifndef _TD_META_DEF_H_
|
||||||
#define _TD_META_DEF_H_
|
#define _TD_META_DEF_H_
|
||||||
|
|
||||||
#include "metaUid.h"
|
#include "meta.h"
|
||||||
#include "tkv.h"
|
#include "metaCache.h"
|
||||||
|
#include "metaDB.h"
|
||||||
|
#include "metaIdx.h"
|
||||||
|
#include "metaOptions.h"
|
||||||
|
#include "metaTbOptions.h"
|
||||||
|
#include "metaTbTag.h"
|
||||||
|
#include "metaTbUid.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct SMeta {
|
struct SMeta {
|
||||||
STableUidGenerator uidGenerator;
|
char* path; // path of current meta
|
||||||
|
SMetaOptions options; // meta option
|
||||||
STkvDb* tableDb; // uid->table obj
|
meta_db_t* pDB; // raw data db
|
||||||
STkvDb* tbnameDb; // tbname --> uid
|
meta_index_t* pIdx; // tag index
|
||||||
STkvDb* schemaDb; // uid+version --> schema
|
meta_cache_t* pCache; // LRU cache
|
||||||
STkvDb* tagDb; // uid --> tag
|
STbUidGenerator uidGnrt; // meta table UID generator
|
||||||
STkvDb* tagIdx; // TODO: need to integrate lucene or our own
|
|
||||||
// STkvCache* metaCache; // TODO: add a global cache here
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_META_IDX_H_
|
||||||
|
#define _TD_META_IDX_H_
|
||||||
|
|
||||||
|
#include "rocksdb/c.h"
|
||||||
|
|
||||||
|
#include "meta.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef rocksdb_t meta_index_t;
|
||||||
|
|
||||||
|
int metaOpenIdx(SMeta *pMeta);
|
||||||
|
void metaCloseIdx(SMeta *pMeta);
|
||||||
|
int metaSaveTableToIdx(SMeta *pMeta, const STbOptions *pTbOptions);
|
||||||
|
int metaRemoveTableFromIdx(SMeta *pMeta, tb_uid_t uid);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_META_IDX_H_*/
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_META_OPTIONS_H_
|
||||||
|
#define _TD_META_OPTIONS_H_
|
||||||
|
|
||||||
|
#include "meta.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const SMetaOptions defaultMetaOptions;
|
||||||
|
|
||||||
|
int metaValidateOptions(const SMetaOptions *);
|
||||||
|
void metaOptionsCopy(SMetaOptions *pDest, const SMetaOptions *pSrc);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_META_OPTIONS_H_*/
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_META_QUERY_H_
|
||||||
|
#define _TD_META_QUERY_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_META_QUERY_H_*/
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_META_TABLE_OPTIONS_H_
|
||||||
|
#define _TD_META_TABLE_OPTIONS_H_
|
||||||
|
|
||||||
|
#include "meta.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int metaValidateTbOptions(SMeta *pMeta, const STbOptions *);
|
||||||
|
size_t metaEncodeTbObjFromTbOptions(const STbOptions *, void *pBuf, size_t bsize);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_META_TABLE_OPTIONS_H_*/
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_META_TB_TAG_H_
|
||||||
|
#define _TD_META_TB_TAG_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_META_TB_TAG_H_*/
|
|
@ -23,20 +23,17 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ------------------------ APIS EXPOSED ------------------------ */
|
/* ------------------------ APIS EXPOSED ------------------------ */
|
||||||
typedef struct STableUidGenerator STableUidGenerator;
|
typedef struct STbUidGenerator {
|
||||||
|
tb_uid_t nextUid;
|
||||||
|
} STbUidGenerator;
|
||||||
|
|
||||||
|
// STableUidGenerator
|
||||||
|
int metaOpenUidGnrt(SMeta *pMeta);
|
||||||
|
void metaCloseUidGnrt(SMeta *pMeta);
|
||||||
|
|
||||||
// tb_uid_t
|
// tb_uid_t
|
||||||
#define IVLD_TB_UID 0
|
#define IVLD_TB_UID 0
|
||||||
tb_uid_t generateUid(STableUidGenerator *);
|
tb_uid_t metaGenerateUid(SMeta *pMeta);
|
||||||
|
|
||||||
// STableUidGenerator
|
|
||||||
void tableUidGeneratorInit(STableUidGenerator *, tb_uid_t suid);
|
|
||||||
#define tableUidGeneratorClear(ug)
|
|
||||||
|
|
||||||
/* ------------------------ FOR TEST AND COMPILE ONLY ------------------------ */
|
|
||||||
struct STableUidGenerator {
|
|
||||||
tb_uid_t nextUid;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "meta.h"
|
||||||
|
#include "metaDef.h"
|
||||||
|
|
||||||
|
int metaOpenCache(SMeta *pMeta) {
|
||||||
|
// TODO
|
||||||
|
if (pMeta->options.lruCacheSize) {
|
||||||
|
pMeta->pCache = rocksdb_cache_create_lru(pMeta->options.lruCacheSize);
|
||||||
|
if (pMeta->pCache == NULL) {
|
||||||
|
// TODO: handle error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void metaCloseCache(SMeta *pMeta) {
|
||||||
|
if (pMeta->pCache) {
|
||||||
|
rocksdb_cache_destroy(pMeta->pCache);
|
||||||
|
pMeta->pCache = NULL;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "meta.h"
|
||||||
|
|
||||||
|
int metaCommit(SMeta *pMeta) {
|
||||||
|
// TODO
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,199 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "metaDef.h"
|
||||||
|
|
||||||
|
static void metaSaveSchemaDB(SMeta *pMeta, tb_uid_t uid, STSchema *pSchema);
|
||||||
|
static void metaGetSchemaDBKey(char key[], tb_uid_t uid, int sversion);
|
||||||
|
static int metaSaveMapDB(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid);
|
||||||
|
|
||||||
|
#define SCHEMA_KEY_LEN (sizeof(tb_uid_t) + sizeof(int))
|
||||||
|
|
||||||
|
#define META_OPEN_DB_IMPL(pDB, options, dir, err) \
|
||||||
|
do { \
|
||||||
|
pDB = rocksdb_open(options, dir, &err); \
|
||||||
|
if (pDB == NULL) { \
|
||||||
|
metaCloseDB(pMeta); \
|
||||||
|
rocksdb_options_destroy(options); \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int metaOpenDB(SMeta *pMeta) {
|
||||||
|
char dir[128];
|
||||||
|
char * err = NULL;
|
||||||
|
rocksdb_options_t *options = rocksdb_options_create();
|
||||||
|
|
||||||
|
if (pMeta->pCache) {
|
||||||
|
rocksdb_options_set_row_cache(options, pMeta->pCache);
|
||||||
|
}
|
||||||
|
rocksdb_options_set_create_if_missing(options, 1);
|
||||||
|
|
||||||
|
pMeta->pDB = (meta_db_t *)calloc(1, sizeof(*(pMeta->pDB)));
|
||||||
|
if (pMeta->pDB == NULL) {
|
||||||
|
// TODO: handle error
|
||||||
|
rocksdb_options_destroy(options);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tbDb
|
||||||
|
sprintf(dir, "%s/tb_db", pMeta->path);
|
||||||
|
META_OPEN_DB_IMPL(pMeta->pDB->tbDb, options, dir, err);
|
||||||
|
|
||||||
|
// nameDb
|
||||||
|
sprintf(dir, "%s/name_db", pMeta->path);
|
||||||
|
META_OPEN_DB_IMPL(pMeta->pDB->nameDb, options, dir, err);
|
||||||
|
|
||||||
|
// tagDb
|
||||||
|
sprintf(dir, "%s/tag_db", pMeta->path);
|
||||||
|
META_OPEN_DB_IMPL(pMeta->pDB->tagDb, options, dir, err);
|
||||||
|
|
||||||
|
// schemaDb
|
||||||
|
sprintf(dir, "%s/schema_db", pMeta->path);
|
||||||
|
META_OPEN_DB_IMPL(pMeta->pDB->schemaDb, options, dir, err);
|
||||||
|
|
||||||
|
// mapDb
|
||||||
|
sprintf(dir, "%s/map_db", pMeta->path);
|
||||||
|
META_OPEN_DB_IMPL(pMeta->pDB->mapDb, options, dir, err);
|
||||||
|
|
||||||
|
rocksdb_options_destroy(options);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define META_CLOSE_DB_IMPL(pDB) \
|
||||||
|
do { \
|
||||||
|
if (pDB) { \
|
||||||
|
rocksdb_close(pDB); \
|
||||||
|
pDB = NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
void metaCloseDB(SMeta *pMeta) {
|
||||||
|
if (pMeta->pDB) {
|
||||||
|
META_CLOSE_DB_IMPL(pMeta->pDB->mapDb);
|
||||||
|
META_CLOSE_DB_IMPL(pMeta->pDB->schemaDb);
|
||||||
|
META_CLOSE_DB_IMPL(pMeta->pDB->tagDb);
|
||||||
|
META_CLOSE_DB_IMPL(pMeta->pDB->nameDb);
|
||||||
|
META_CLOSE_DB_IMPL(pMeta->pDB->tbDb);
|
||||||
|
free(pMeta->pDB);
|
||||||
|
pMeta->pDB = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int metaSaveTableToDB(SMeta *pMeta, const STbOptions *pTbOptions) {
|
||||||
|
tb_uid_t uid;
|
||||||
|
char * err = NULL;
|
||||||
|
size_t size;
|
||||||
|
char pBuf[1024]; // TODO
|
||||||
|
|
||||||
|
rocksdb_writeoptions_t *wopt = rocksdb_writeoptions_create();
|
||||||
|
|
||||||
|
// Generate a uid for child and normal table
|
||||||
|
if (pTbOptions->type == META_SUPER_TABLE) {
|
||||||
|
uid = pTbOptions->stbOptions.uid;
|
||||||
|
} else {
|
||||||
|
uid = metaGenerateUid(pMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save tbname -> uid to tbnameDB
|
||||||
|
rocksdb_put(pMeta->pDB->nameDb, wopt, pTbOptions->name, strlen(pTbOptions->name), (char *)(&uid), sizeof(uid), &err);
|
||||||
|
|
||||||
|
// Save uid -> tb_obj to tbDB
|
||||||
|
size = metaEncodeTbObjFromTbOptions(pTbOptions, pBuf, 1024);
|
||||||
|
rocksdb_put(pMeta->pDB->tbDb, wopt, (char *)(&uid), sizeof(uid), pBuf, size, &err);
|
||||||
|
|
||||||
|
switch (pTbOptions->type) {
|
||||||
|
case META_NORMAL_TABLE:
|
||||||
|
// save schemaDB
|
||||||
|
metaSaveSchemaDB(pMeta, uid, pTbOptions->ntbOptions.pSchame);
|
||||||
|
break;
|
||||||
|
case META_SUPER_TABLE:
|
||||||
|
// save schemaDB
|
||||||
|
metaSaveSchemaDB(pMeta, uid, pTbOptions->stbOptions.pSchema);
|
||||||
|
|
||||||
|
// save mapDB (really need?)
|
||||||
|
rocksdb_put(pMeta->pDB->mapDb, wopt, (char *)(&uid), sizeof(uid), "", 0, &err);
|
||||||
|
break;
|
||||||
|
case META_CHILD_TABLE:
|
||||||
|
// save tagDB
|
||||||
|
rocksdb_put(pMeta->pDB->tagDb, wopt, (char *)(&uid), sizeof(uid), pTbOptions->ctbOptions.tags,
|
||||||
|
kvRowLen(pTbOptions->ctbOptions.tags), &err);
|
||||||
|
|
||||||
|
// save mapDB
|
||||||
|
metaSaveMapDB(pMeta, pTbOptions->ctbOptions.suid, uid);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
rocksdb_writeoptions_destroy(wopt);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int metaRemoveTableFromDb(SMeta *pMeta, tb_uid_t uid) {
|
||||||
|
/* TODO */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------ STATIC METHODS ------------------------ */
|
||||||
|
static void metaSaveSchemaDB(SMeta *pMeta, tb_uid_t uid, STSchema *pSchema) {
|
||||||
|
char key[64];
|
||||||
|
char pBuf[1024];
|
||||||
|
char * ppBuf = pBuf;
|
||||||
|
size_t vsize;
|
||||||
|
char * err = NULL;
|
||||||
|
|
||||||
|
rocksdb_writeoptions_t *wopt = rocksdb_writeoptions_create();
|
||||||
|
|
||||||
|
metaGetSchemaDBKey(key, uid, schemaVersion(pSchema));
|
||||||
|
vsize = tdEncodeSchema((void **)(&ppBuf), pSchema);
|
||||||
|
rocksdb_put(pMeta->pDB->schemaDb, wopt, key, SCHEMA_KEY_LEN, pBuf, vsize, &err);
|
||||||
|
|
||||||
|
rocksdb_writeoptions_destroy(wopt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void metaGetSchemaDBKey(char *key, tb_uid_t uid, int sversion) {
|
||||||
|
*(tb_uid_t *)key = uid;
|
||||||
|
*(int *)POINTER_SHIFT(key, sizeof(tb_uid_t)) = sversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int metaSaveMapDB(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid) {
|
||||||
|
size_t vlen;
|
||||||
|
char * val;
|
||||||
|
char * err = NULL;
|
||||||
|
|
||||||
|
rocksdb_readoptions_t *ropt = rocksdb_readoptions_create();
|
||||||
|
val = rocksdb_get(pMeta->pDB->mapDb, ropt, (char *)(&suid), sizeof(suid), &vlen, &err);
|
||||||
|
rocksdb_readoptions_destroy(ropt);
|
||||||
|
|
||||||
|
void *nval = malloc(vlen + sizeof(uid));
|
||||||
|
if (nval == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vlen) {
|
||||||
|
memcpy(nval, val, vlen);
|
||||||
|
}
|
||||||
|
memcpy(POINTER_SHIFT(nval, vlen), (void *)(&uid), sizeof(uid));
|
||||||
|
|
||||||
|
rocksdb_writeoptions_t *wopt = rocksdb_writeoptions_create();
|
||||||
|
|
||||||
|
rocksdb_put(pMeta->pDB->mapDb, wopt, (char *)(&suid), sizeof(suid), nval, vlen + sizeof(uid), &err);
|
||||||
|
|
||||||
|
rocksdb_writeoptions_destroy(wopt);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "metaDef.h"
|
||||||
|
|
||||||
|
int metaOpenIdx(SMeta *pMeta) {
|
||||||
|
char idxDir[128]; // TODO
|
||||||
|
char * err = NULL;
|
||||||
|
rocksdb_options_t *options = rocksdb_options_create();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
sprintf(idxDir, "%s/index", pMeta->path);
|
||||||
|
|
||||||
|
if (pMeta->pCache) {
|
||||||
|
rocksdb_options_set_row_cache(options, pMeta->pCache);
|
||||||
|
}
|
||||||
|
rocksdb_options_set_create_if_missing(options, 1);
|
||||||
|
|
||||||
|
pMeta->pIdx = rocksdb_open(options, idxDir, &err);
|
||||||
|
if (pMeta->pIdx == NULL) {
|
||||||
|
// TODO: handle error
|
||||||
|
rocksdb_options_destroy(options);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rocksdb_options_destroy(options);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void metaCloseIdx(SMeta *pMeta) { /* TODO */
|
||||||
|
if (pMeta->pIdx) {
|
||||||
|
rocksdb_close(pMeta->pIdx);
|
||||||
|
pMeta->pIdx = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int metaSaveTableToIdx(SMeta *pMeta, const STbOptions *pTbOptions) {
|
||||||
|
// TODO
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -13,75 +13,134 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "meta.h"
|
|
||||||
#include "metaDef.h"
|
|
||||||
#include "tcoding.h"
|
#include "tcoding.h"
|
||||||
|
|
||||||
static int metaCreateSuperTable(SMeta *pMeta, const char *tbname, const SSuperTableOpts *pSuperTableOpts);
|
#include "meta.h"
|
||||||
static int metaCreateChildTable(SMeta *pMeta, const char *tbname, const SChildTableOpts *pChildTableOpts);
|
#include "metaDB.h"
|
||||||
static int metaCreateNormalTable(SMeta *pMeta, const char *tbname, const SNormalTableOpts *pNormalTableOpts);
|
#include "metaDef.h"
|
||||||
|
#include "metaOptions.h"
|
||||||
|
|
||||||
SMeta *metaOpen(SMetaOpts *pMetaOpts) {
|
static SMeta *metaNew(const char *path, const SMetaOptions *pMetaOptions);
|
||||||
|
static void metaFree(SMeta *pMeta);
|
||||||
|
static int metaOpenImpl(SMeta *pMeta);
|
||||||
|
static void metaCloseImpl(SMeta *pMeta);
|
||||||
|
|
||||||
|
SMeta *metaOpen(const char *path, const SMetaOptions *pMetaOptions) {
|
||||||
SMeta *pMeta = NULL;
|
SMeta *pMeta = NULL;
|
||||||
|
|
||||||
|
// Set default options
|
||||||
|
if (pMetaOptions == NULL) {
|
||||||
|
pMetaOptions = &defaultMetaOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the options
|
||||||
|
if (metaValidateOptions(pMetaOptions) < 0) {
|
||||||
|
// TODO: deal with error
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate handle
|
||||||
|
pMeta = metaNew(path, pMetaOptions);
|
||||||
|
if (pMeta == NULL) {
|
||||||
|
// TODO: handle error
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create META path (TODO)
|
||||||
|
taosMkDir(path);
|
||||||
|
|
||||||
|
// Open meta
|
||||||
|
if (metaOpenImpl(pMeta) < 0) {
|
||||||
|
metaFree(pMeta);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
void metaClose(SMeta *pMeta) {
|
||||||
|
if (pMeta) {
|
||||||
|
metaCloseImpl(pMeta);
|
||||||
|
metaFree(pMeta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void metaRemove(const char *path) { taosRemoveDir(path); }
|
||||||
|
|
||||||
|
/* ------------------------ STATIC METHODS ------------------------ */
|
||||||
|
static SMeta *metaNew(const char *path, const SMetaOptions *pMetaOptions) {
|
||||||
|
SMeta *pMeta;
|
||||||
|
size_t psize = strlen(path);
|
||||||
|
|
||||||
pMeta = (SMeta *)calloc(1, sizeof(*pMeta));
|
pMeta = (SMeta *)calloc(1, sizeof(*pMeta));
|
||||||
if (pMeta == NULL) {
|
if (pMeta == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check if file exists and handle the error
|
pMeta->path = strdup(path);
|
||||||
taosMkDir("meta");
|
if (pMeta->path == NULL) {
|
||||||
|
metaFree(pMeta);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Open tableDb
|
metaOptionsCopy(&(pMeta->options), pMetaOptions);
|
||||||
STkvOpts *tableDbOpts = tkvOptsCreate();
|
|
||||||
tkvOptsSetCreateIfMissing(tableDbOpts, 1);
|
|
||||||
pMeta->tableDb = tkvOpen(tableDbOpts, "meta/table_db");
|
|
||||||
tkvOptsDestroy(tableDbOpts);
|
|
||||||
|
|
||||||
// Open tbnameDb
|
|
||||||
STkvOpts *tbnameDbOpts = tkvOptsCreate();
|
|
||||||
tkvOptsSetCreateIfMissing(tbnameDbOpts, 1);
|
|
||||||
pMeta->tbnameDb = tkvOpen(tbnameDbOpts, "meta/tbname_db");
|
|
||||||
tkvOptsDestroy(tbnameDbOpts);
|
|
||||||
|
|
||||||
// Open schemaDb
|
|
||||||
STkvOpts *schemaDbOpts = tkvOptsCreate();
|
|
||||||
tkvOptsSetCreateIfMissing(schemaDbOpts, 1);
|
|
||||||
pMeta->schemaDb = tkvOpen(schemaDbOpts, "meta/schema_db");
|
|
||||||
tkvOptsDestroy(schemaDbOpts);
|
|
||||||
|
|
||||||
// Open tagDb
|
|
||||||
STkvOpts *tagDbOpts = tkvOptsCreate();
|
|
||||||
tkvOptsSetCreateIfMissing(tagDbOpts, 1);
|
|
||||||
pMeta->tagDb = tkvOpen(tagDbOpts, "meta/tag_db");
|
|
||||||
tkvOptsDestroy(tagDbOpts);
|
|
||||||
|
|
||||||
// Open tagIdx
|
|
||||||
STkvOpts *tagIdxDbOpts = tkvOptsCreate();
|
|
||||||
tkvOptsSetCreateIfMissing(tagIdxDbOpts, 1);
|
|
||||||
pMeta->tagIdx = tkvOpen(tagIdxDbOpts, "meta/tag_idx_db");
|
|
||||||
tkvOptsDestroy(tagIdxDbOpts);
|
|
||||||
|
|
||||||
// TODO: need to figure out how to persist the START UID
|
|
||||||
tableUidGeneratorInit(&(pMeta->uidGenerator), IVLD_TB_UID);
|
|
||||||
return pMeta;
|
return pMeta;
|
||||||
}
|
};
|
||||||
|
|
||||||
void metaClose(SMeta *pMeta) {
|
static void metaFree(SMeta *pMeta) {
|
||||||
if (pMeta) {
|
if (pMeta) {
|
||||||
tableUidGeneratorClear(&pMeta->uidGenerator);
|
tfree(pMeta->path);
|
||||||
|
|
||||||
tkvClose(pMeta->tagIdx);
|
|
||||||
tkvClose(pMeta->tagDb);
|
|
||||||
tkvClose(pMeta->schemaDb);
|
|
||||||
tkvClose(pMeta->tbnameDb);
|
|
||||||
tkvClose(pMeta->tableDb);
|
|
||||||
|
|
||||||
free(pMeta);
|
free(pMeta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int metaCreateTable(SMeta *pMeta, const STableOpts *pTableOpts) {
|
static int metaOpenImpl(SMeta *pMeta) {
|
||||||
|
// Open meta cache
|
||||||
|
if (metaOpenCache(pMeta) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
metaCloseImpl(pMeta);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open meta db
|
||||||
|
if (metaOpenDB(pMeta) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
metaCloseImpl(pMeta);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open meta index
|
||||||
|
if (metaOpenIdx(pMeta) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
metaCloseImpl(pMeta);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open meta table uid generator
|
||||||
|
if (metaOpenUidGnrt(pMeta) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
metaCloseImpl(pMeta);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void metaCloseImpl(SMeta *pMeta) {
|
||||||
|
metaCloseUidGnrt(pMeta);
|
||||||
|
metaCloseIdx(pMeta);
|
||||||
|
metaCloseDB(pMeta);
|
||||||
|
metaCloseCache(pMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// OLD -------------------------------------------------------------------
|
||||||
|
#if 0
|
||||||
|
static int metaCreateSuperTable(SMeta *pMeta, const char *tbname, const SSuperTableOpts *pSuperTableOpts);
|
||||||
|
static int metaCreateChildTable(SMeta *pMeta, const char *tbname, const SChildTableOpts *pChildTableOpts);
|
||||||
|
static int metaCreateNormalTable(SMeta *pMeta, const char *tbname, const SNormalTableOpts *pNormalTableOpts);
|
||||||
|
|
||||||
|
int metaCreateTable(SMeta *pMeta, const STableOptions *pTableOpts) {
|
||||||
size_t vallen;
|
size_t vallen;
|
||||||
char * pUid;
|
char * pUid;
|
||||||
|
|
||||||
|
@ -107,7 +166,6 @@ int metaCreateTable(SMeta *pMeta, const STableOpts *pTableOpts) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------ STATIC METHODS ------------------------ */
|
|
||||||
static int metaCreateSuperTable(SMeta *pMeta, const char *tbname, const SSuperTableOpts *pSuperTableOpts) {
|
static int metaCreateSuperTable(SMeta *pMeta, const char *tbname, const SSuperTableOpts *pSuperTableOpts) {
|
||||||
size_t vallen;
|
size_t vallen;
|
||||||
size_t keylen;
|
size_t keylen;
|
||||||
|
@ -213,13 +271,13 @@ static int metaCreateNormalTable(SMeta *pMeta, const char *tbname, const SNormal
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void metaNormalTableOptsInit(STableOpts *pTableOpts, const char *name, const STSchema *pSchema) {
|
void metaNormalTableOptsInit(STableOptions *pTableOpts, const char *name, const STSchema *pSchema) {
|
||||||
pTableOpts->type = META_NORMAL_TABLE;
|
pTableOpts->type = META_NORMAL_TABLE;
|
||||||
pTableOpts->name = strdup(name);
|
pTableOpts->name = strdup(name);
|
||||||
pTableOpts->normalOpts.pSchema = tdDupSchema(pSchema);
|
pTableOpts->normalOpts.pSchema = tdDupSchema(pSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
void metaSuperTableOptsInit(STableOpts *pTableOpts, const char *name, tb_uid_t uid, const STSchema *pSchema,
|
void metaSuperTableOptsInit(STableOptions *pTableOpts, const char *name, tb_uid_t uid, const STSchema *pSchema,
|
||||||
const STSchema *pTagSchema) {
|
const STSchema *pTagSchema) {
|
||||||
pTableOpts->type = META_SUPER_TABLE;
|
pTableOpts->type = META_SUPER_TABLE;
|
||||||
pTableOpts->name = strdup(name);
|
pTableOpts->name = strdup(name);
|
||||||
|
@ -228,14 +286,14 @@ void metaSuperTableOptsInit(STableOpts *pTableOpts, const char *name, tb_uid_t u
|
||||||
pTableOpts->superOpts.pTagSchema = tdDupSchema(pTagSchema);
|
pTableOpts->superOpts.pTagSchema = tdDupSchema(pTagSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
void metaChildTableOptsInit(STableOpts *pTableOpts, const char *name, tb_uid_t suid, const SKVRow tags) {
|
void metaChildTableOptsInit(STableOptions *pTableOpts, const char *name, tb_uid_t suid, const SKVRow tags) {
|
||||||
pTableOpts->type = META_CHILD_TABLE;
|
pTableOpts->type = META_CHILD_TABLE;
|
||||||
pTableOpts->name = strdup(name);
|
pTableOpts->name = strdup(name);
|
||||||
pTableOpts->childOpts.suid = suid;
|
pTableOpts->childOpts.suid = suid;
|
||||||
pTableOpts->childOpts.tags = tdKVRowDup(tags);
|
pTableOpts->childOpts.tags = tdKVRowDup(tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void metaTableOptsClear(STableOpts *pTableOpts) {
|
void metaTableOptsClear(STableOptions *pTableOpts) {
|
||||||
switch (pTableOpts->type) {
|
switch (pTableOpts->type) {
|
||||||
case META_NORMAL_TABLE:
|
case META_NORMAL_TABLE:
|
||||||
tfree(pTableOpts->name);
|
tfree(pTableOpts->name);
|
||||||
|
@ -258,3 +316,5 @@ void metaTableOptsClear(STableOpts *pTableOpts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void metaDestroy(const char *path) { taosRemoveDir(path); }
|
void metaDestroy(const char *path) { taosRemoveDir(path); }
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "metaDef.h"
|
||||||
|
|
||||||
|
const SMetaOptions defaultMetaOptions = {.lruCacheSize = 0};
|
||||||
|
|
||||||
|
/* ------------------------ EXPOSED METHODS ------------------------ */
|
||||||
|
void metaOptionsInit(SMetaOptions *pMetaOptions) { metaOptionsCopy(pMetaOptions, &defaultMetaOptions); }
|
||||||
|
|
||||||
|
void metaOptionsClear(SMetaOptions *pMetaOptions) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int metaValidateOptions(const SMetaOptions *pMetaOptions) {
|
||||||
|
// TODO
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void metaOptionsCopy(SMetaOptions *pDest, const SMetaOptions *pSrc) { memcpy(pDest, pSrc, sizeof(*pSrc)); }
|
||||||
|
|
||||||
|
/* ------------------------ STATIC METHODS ------------------------ */
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "metaDef.h"
|
||||||
|
|
||||||
|
int metaCreateTable(SMeta *pMeta, const STbOptions *pTbOptions) {
|
||||||
|
// Validate the tbOptions
|
||||||
|
if (metaValidateTbOptions(pMeta, pTbOptions) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: add atomicity
|
||||||
|
|
||||||
|
if (metaSaveTableToDB(pMeta, pTbOptions) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metaSaveTableToIdx(pMeta, pTbOptions) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int metaDropTable(SMeta *pMeta, tb_uid_t uid) {
|
||||||
|
if (metaRemoveTableFromIdx(pMeta, uid) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metaRemoveTableFromIdx(pMeta, uid) < 0) {
|
||||||
|
// TODO
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "metaDef.h"
|
||||||
|
#include "tcoding.h"
|
||||||
|
|
||||||
|
int metaValidateTbOptions(SMeta *pMeta, const STbOptions *pTbOptions) {
|
||||||
|
// TODO
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t metaEncodeTbObjFromTbOptions(const STbOptions *pTbOptions, void *pBuf, size_t bsize) {
|
||||||
|
void **ppBuf = &pBuf;
|
||||||
|
int tlen = 0;
|
||||||
|
|
||||||
|
tlen += taosEncodeFixedU8(ppBuf, pTbOptions->type);
|
||||||
|
tlen += taosEncodeString(ppBuf, pTbOptions->name);
|
||||||
|
tlen += taosEncodeFixedU32(ppBuf, pTbOptions->ttl);
|
||||||
|
|
||||||
|
switch (pTbOptions->type) {
|
||||||
|
case META_SUPER_TABLE:
|
||||||
|
tlen += taosEncodeFixedU64(ppBuf, pTbOptions->stbOptions.uid);
|
||||||
|
tlen += tdEncodeSchema(ppBuf, pTbOptions->stbOptions.pTagSchema);
|
||||||
|
// TODO: encode schema version array
|
||||||
|
break;
|
||||||
|
case META_CHILD_TABLE:
|
||||||
|
tlen += taosEncodeFixedU64(ppBuf, pTbOptions->ctbOptions.suid);
|
||||||
|
break;
|
||||||
|
case META_NORMAL_TABLE:
|
||||||
|
// TODO: encode schema version array
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tlen;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
|
@ -13,14 +13,18 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "metaUid.h"
|
#include "meta.h"
|
||||||
|
#include "metaDef.h"
|
||||||
|
|
||||||
tb_uid_t generateUid(STableUidGenerator *pGen) {
|
int metaOpenUidGnrt(SMeta *pMeta) {
|
||||||
// Generate a new table UID
|
// Init a generator
|
||||||
return ++(pGen->nextUid);
|
pMeta->uidGnrt.nextUid = IVLD_TB_UID;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tableUidGeneratorInit(STableUidGenerator *pGen, tb_uid_t suid) {
|
void metaCloseUidGnrt(SMeta *pMeta) { /* TODO */ }
|
||||||
// Init a generator
|
|
||||||
pGen->nextUid = suid;
|
tb_uid_t metaGenerateUid(SMeta *pMeta) {
|
||||||
|
// Generate a new table UID
|
||||||
|
return ++(pMeta->uidGnrt.nextUid);
|
||||||
}
|
}
|
|
@ -1,24 +1,24 @@
|
||||||
add_executable(metaTest "")
|
# add_executable(metaTest "")
|
||||||
target_sources(metaTest
|
# target_sources(metaTest
|
||||||
PRIVATE
|
# PRIVATE
|
||||||
"../src/metaMain.c"
|
# "../src/metaMain.c"
|
||||||
"../src/metaUid.c"
|
# "../src/metaUid.c"
|
||||||
"metaTests.cpp"
|
# "metaTests.cpp"
|
||||||
)
|
# )
|
||||||
target_include_directories(metaTest
|
# target_include_directories(metaTest
|
||||||
PUBLIC
|
# PUBLIC
|
||||||
"${CMAKE_SOURCE_DIR}/include/dnode/vnode/meta"
|
# "${CMAKE_SOURCE_DIR}/include/server/vnode/meta"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
# "${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||||
)
|
# )
|
||||||
target_link_libraries(metaTest
|
# target_link_libraries(metaTest
|
||||||
os
|
# os
|
||||||
util
|
# util
|
||||||
common
|
# common
|
||||||
gtest_main
|
# gtest_main
|
||||||
tkv
|
# tkv
|
||||||
)
|
# )
|
||||||
enable_testing()
|
# enable_testing()
|
||||||
add_test(
|
# add_test(
|
||||||
NAME meta_test
|
# NAME meta_test
|
||||||
COMMAND metaTest
|
# COMMAND metaTest
|
||||||
)
|
# )
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#if 0
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -38,7 +39,7 @@ static SKVRow metaGetSimpleTags() {
|
||||||
|
|
||||||
TEST(MetaTest, DISABLED_meta_create_1m_normal_tables_test) {
|
TEST(MetaTest, DISABLED_meta_create_1m_normal_tables_test) {
|
||||||
// Open Meta
|
// Open Meta
|
||||||
SMeta *meta = metaOpen(NULL);
|
SMeta *meta = metaOpen(NULL, NULL);
|
||||||
std::cout << "Meta is opened!" << std::endl;
|
std::cout << "Meta is opened!" << std::endl;
|
||||||
|
|
||||||
// Create 1000000 normal tables
|
// Create 1000000 normal tables
|
||||||
|
@ -100,4 +101,5 @@ TEST(MetaTest, meta_create_1m_child_tables_test) {
|
||||||
// Destroy Meta
|
// Destroy Meta
|
||||||
metaDestroy("meta");
|
metaDestroy("meta");
|
||||||
std::cout << "Meta is destroyed!" << std::endl;
|
std::cout << "Meta is destroyed!" << std::endl;
|
||||||
}
|
}
|
||||||
|
#endif
|
|
@ -12,3 +12,7 @@ target_link_libraries(
|
||||||
PUBLIC os
|
PUBLIC os
|
||||||
PUBLIC util
|
PUBLIC util
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(${BUILD_TEST})
|
||||||
|
add_subdirectory(test)
|
||||||
|
endif(${BUILD_TEST})
|
||||||
|
|
|
@ -19,23 +19,42 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tq.h"
|
#include "tq.h"
|
||||||
|
|
||||||
#define TQ_BUCKET_SIZE 0xFF
|
|
||||||
#define TQ_PAGE_SIZE 4096
|
|
||||||
//key + offset + size
|
|
||||||
#define TQ_IDX_ENTRY_SIZE 24
|
|
||||||
|
|
||||||
inline static int TqMaxEntryOnePage() { //170
|
|
||||||
return TQ_PAGE_SIZE / TQ_IDX_ENTRY_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static int TqEmptyTail() { //16
|
|
||||||
return TQ_PAGE_SIZE - TqMaxEntryOnePage();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TQ_BUCKET_MASK 0xFF
|
||||||
|
#define TQ_BUCKET_SIZE 256
|
||||||
|
|
||||||
|
#define TQ_PAGE_SIZE 4096
|
||||||
|
//key + offset + size
|
||||||
|
#define TQ_IDX_SIZE 24
|
||||||
|
//4096 / 24
|
||||||
|
#define TQ_MAX_IDX_ONE_PAGE 170
|
||||||
|
//24 * 170
|
||||||
|
#define TQ_IDX_PAGE_BODY_SIZE 4080
|
||||||
|
//4096 - 4080
|
||||||
|
#define TQ_IDX_PAGE_HEAD_SIZE 16
|
||||||
|
|
||||||
|
#define TQ_ACTION_CONST 0
|
||||||
|
#define TQ_ACTION_INUSE 1
|
||||||
|
#define TQ_ACTION_INUSE_CONT 2
|
||||||
|
#define TQ_ACTION_INTXN 3
|
||||||
|
|
||||||
|
#define TQ_SVER 0
|
||||||
|
|
||||||
|
static const int8_t TQ_CONST_DELETE = TQ_ACTION_CONST;
|
||||||
|
#define TQ_DELETE_TOKEN (void*)&TQ_CONST_DELETE
|
||||||
|
|
||||||
|
typedef struct TqSerializedHead {
|
||||||
|
int16_t ver;
|
||||||
|
int16_t action;
|
||||||
|
int32_t checksum;
|
||||||
|
int64_t ssize;
|
||||||
|
char content[];
|
||||||
|
} TqSerializedHead;
|
||||||
|
|
||||||
typedef struct TqMetaHandle {
|
typedef struct TqMetaHandle {
|
||||||
int64_t key;
|
int64_t key;
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
|
@ -59,30 +78,31 @@ typedef struct TqMetaStore {
|
||||||
TqMetaList* unpersistHead;
|
TqMetaList* unpersistHead;
|
||||||
int fileFd; //TODO:temporaral use, to be replaced by unified tfile
|
int fileFd; //TODO:temporaral use, to be replaced by unified tfile
|
||||||
int idxFd; //TODO:temporaral use, to be replaced by unified tfile
|
int idxFd; //TODO:temporaral use, to be replaced by unified tfile
|
||||||
int (*serializer)(TqGroupHandle*, void**);
|
char* dirPath;
|
||||||
const void* (*deserializer)(const void*, TqGroupHandle*);
|
int (*serializer)(const void* pObj, TqSerializedHead** ppHead);
|
||||||
|
const void* (*deserializer)(const TqSerializedHead* pHead, void** ppObj);
|
||||||
void (*deleter)(void*);
|
void (*deleter)(void*);
|
||||||
} TqMetaStore;
|
} TqMetaStore;
|
||||||
|
|
||||||
TqMetaStore* tqStoreOpen(const char* path,
|
TqMetaStore* tqStoreOpen(const char* path,
|
||||||
int serializer(TqGroupHandle*, void**),
|
int serializer(const void* pObj, TqSerializedHead** ppHead),
|
||||||
const void* deserializer(const void*, TqGroupHandle*),
|
const void* deserializer(const TqSerializedHead* pHead, void** ppObj),
|
||||||
void deleter(void*));
|
void deleter(void* pObj));
|
||||||
int32_t tqStoreClose(TqMetaStore*);
|
int32_t tqStoreClose(TqMetaStore*);
|
||||||
//int32_t tqStoreDelete(TqMetaStore*);
|
//int32_t tqStoreDelete(TqMetaStore*);
|
||||||
//int32_t TqStoreCommitAll(TqMetaStore*);
|
//int32_t TqStoreCommitAll(TqMetaStore*);
|
||||||
int32_t tqStorePersist(TqMetaStore*);
|
int32_t tqStorePersist(TqMetaStore*);
|
||||||
|
//clean deleted idx and data from persistent file
|
||||||
|
int32_t tqStoreCompact(TqMetaStore*);
|
||||||
|
|
||||||
TqMetaHandle* tqHandleGet(TqMetaStore*, int64_t key);
|
void* tqHandleGet(TqMetaStore*, int64_t key);
|
||||||
int32_t tqHandlePut(TqMetaStore*, int64_t key, void* value);
|
int32_t tqHandleMovePut(TqMetaStore*, int64_t key, void* value);
|
||||||
//do commit
|
int32_t tqHandleCopyPut(TqMetaStore*, int64_t key, void* value, size_t vsize);
|
||||||
int32_t tqHandleCommit(TqMetaStore*, int64_t key);
|
//delete committed kv pair
|
||||||
//delete uncommitted
|
//notice that a delete action still needs to be committed
|
||||||
int32_t tqHandleAbort(TqMetaStore*, int64_t key);
|
int32_t tqHandleDel(TqMetaStore*, int64_t key);
|
||||||
//delete committed
|
int32_t tqHandleCommit(TqMetaStore*, int64_t key);
|
||||||
int32_t tqHandleDel(TqMetaStore*, int64_t key);
|
int32_t tqHandleAbort(TqMetaStore*, int64_t key);
|
||||||
//delete both committed and uncommitted
|
|
||||||
int32_t tqHandleClear(TqMetaStore*, int64_t key);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
//
|
//
|
||||||
//handle management message
|
//handle management message
|
||||||
//
|
//
|
||||||
|
|
||||||
|
int tqGetgHandleSSize(const TqGroupHandle *gHandle);
|
||||||
|
|
||||||
static int tqProtoCheck(TmqMsgHead *pMsg) {
|
static int tqProtoCheck(TmqMsgHead *pMsg) {
|
||||||
return pMsg->protoVer == 0;
|
return pMsg->protoVer == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
*/
|
*/
|
||||||
#include "tqMetaStore.h"
|
#include "tqMetaStore.h"
|
||||||
//TODO:replace by an abstract file layer
|
//TODO:replace by an abstract file layer
|
||||||
|
#include "osDir.h"
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -22,32 +23,80 @@
|
||||||
#define TQ_IDX_NAME "tq.idx"
|
#define TQ_IDX_NAME "tq.idx"
|
||||||
|
|
||||||
|
|
||||||
static int32_t tqHandlePutCommitted(TqMetaStore*, int64_t key, void* value);
|
static int32_t tqHandlePutCommitted(TqMetaStore*, int64_t key, void* value);
|
||||||
static TqMetaHandle* tqHandleGetUncommitted(TqMetaStore*, int64_t key);
|
static void* tqHandleGetUncommitted(TqMetaStore*, int64_t key);
|
||||||
|
|
||||||
typedef struct TqMetaPageBuf {
|
static inline void tqLinkUnpersist(TqMetaStore *pMeta, TqMetaList* pNode) {
|
||||||
int16_t offset;
|
if(pNode->unpersistNext == NULL) {
|
||||||
char buffer[TQ_PAGE_SIZE];
|
pNode->unpersistNext = pMeta->unpersistHead->unpersistNext;
|
||||||
} TqMetaPageBuf;
|
pNode->unpersistPrev = pMeta->unpersistHead;
|
||||||
|
pMeta->unpersistHead->unpersistNext->unpersistPrev = pNode;
|
||||||
|
pMeta->unpersistHead->unpersistNext = pNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int tqSeekLastPage(int fd) {
|
||||||
|
int offset = lseek(fd, 0, SEEK_END);
|
||||||
|
int pageNo = offset / TQ_PAGE_SIZE;
|
||||||
|
int curPageOffset = pageNo * TQ_PAGE_SIZE;
|
||||||
|
return lseek(fd, curPageOffset, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: the struct is tightly coupled with index entry
|
||||||
|
typedef struct TqIdxPageHead {
|
||||||
|
int16_t writeOffset;
|
||||||
|
int8_t unused[14];
|
||||||
|
} TqIdxPageHead;
|
||||||
|
|
||||||
|
typedef struct TqIdxPageBuf {
|
||||||
|
TqIdxPageHead head;
|
||||||
|
char buffer[TQ_IDX_PAGE_BODY_SIZE];
|
||||||
|
} TqIdxPageBuf;
|
||||||
|
|
||||||
|
static inline int tqReadLastPage(int fd, TqIdxPageBuf* pBuf) {
|
||||||
|
int offset = tqSeekLastPage(fd);
|
||||||
|
int nBytes;
|
||||||
|
if((nBytes = read(fd, pBuf, TQ_PAGE_SIZE)) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(nBytes == 0) {
|
||||||
|
memset(pBuf, 0, TQ_PAGE_SIZE);
|
||||||
|
pBuf->head.writeOffset = TQ_IDX_PAGE_HEAD_SIZE;
|
||||||
|
}
|
||||||
|
ASSERT(nBytes == 0 || nBytes == pBuf->head.writeOffset);
|
||||||
|
|
||||||
|
return lseek(fd, offset, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
TqMetaStore* tqStoreOpen(const char* path,
|
TqMetaStore* tqStoreOpen(const char* path,
|
||||||
int serializer(TqGroupHandle*, void**),
|
int serializer(const void* pObj, TqSerializedHead** ppHead),
|
||||||
const void* deserializer(const void*, TqGroupHandle*),
|
const void* deserializer(const TqSerializedHead* pHead, void** ppObj),
|
||||||
void deleter(void*)) {
|
void deleter(void* pObj)) {
|
||||||
TqMetaStore* pMeta = malloc(sizeof(TqMetaStore));
|
TqMetaStore* pMeta = malloc(sizeof(TqMetaStore));
|
||||||
if(pMeta == NULL) {
|
if(pMeta == NULL) {
|
||||||
//close
|
//close
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
memset(pMeta, 0, sizeof(TqMetaStore));
|
||||||
|
|
||||||
//concat data file name and index file name
|
//concat data file name and index file name
|
||||||
size_t pathLen = strlen(path);
|
size_t pathLen = strlen(path);
|
||||||
|
pMeta->dirPath = malloc(pathLen+1);
|
||||||
|
if(pMeta->dirPath != NULL) {
|
||||||
|
//TODO: memory insufficient
|
||||||
|
}
|
||||||
|
strcpy(pMeta->dirPath, path);
|
||||||
|
|
||||||
char name[pathLen+10];
|
char name[pathLen+10];
|
||||||
|
|
||||||
strcpy(name, path);
|
strcpy(name, path);
|
||||||
|
if(!taosDirExist(name) && !taosMkDir(name)) {
|
||||||
|
ASSERT(false);
|
||||||
|
}
|
||||||
strcat(name, "/" TQ_IDX_NAME);
|
strcat(name, "/" TQ_IDX_NAME);
|
||||||
int idxFd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0755);
|
int idxFd = open(name, O_RDWR | O_CREAT, 0755);
|
||||||
if(idxFd < 0) {
|
if(idxFd < 0) {
|
||||||
|
ASSERT(false);
|
||||||
//close file
|
//close file
|
||||||
//free memory
|
//free memory
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -56,17 +105,24 @@ TqMetaStore* tqStoreOpen(const char* path,
|
||||||
pMeta->idxFd = idxFd;
|
pMeta->idxFd = idxFd;
|
||||||
pMeta->unpersistHead = malloc(sizeof(TqMetaList));
|
pMeta->unpersistHead = malloc(sizeof(TqMetaList));
|
||||||
if(pMeta->unpersistHead == NULL) {
|
if(pMeta->unpersistHead == NULL) {
|
||||||
|
ASSERT(false);
|
||||||
//close file
|
//close file
|
||||||
//free memory
|
//free memory
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
memset(pMeta->unpersistHead, 0, sizeof(TqMetaList));
|
||||||
|
pMeta->unpersistHead->unpersistNext
|
||||||
|
= pMeta->unpersistHead->unpersistPrev
|
||||||
|
= pMeta->unpersistHead;
|
||||||
|
|
||||||
strcpy(name, path);
|
strcpy(name, path);
|
||||||
strcat(name, "/" TQ_META_NAME);
|
strcat(name, "/" TQ_META_NAME);
|
||||||
int fileFd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0755);
|
int fileFd = open(name, O_RDWR | O_CREAT, 0755);
|
||||||
if(fileFd < 0) return NULL;
|
if(fileFd < 0){
|
||||||
|
ASSERT(false);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
memset(pMeta, 0, sizeof(TqMetaStore));
|
|
||||||
pMeta->fileFd = fileFd;
|
pMeta->fileFd = fileFd;
|
||||||
|
|
||||||
pMeta->serializer = serializer;
|
pMeta->serializer = serializer;
|
||||||
|
@ -74,23 +130,109 @@ TqMetaStore* tqStoreOpen(const char* path,
|
||||||
pMeta->deleter = deleter;
|
pMeta->deleter = deleter;
|
||||||
|
|
||||||
//read idx file and load into memory
|
//read idx file and load into memory
|
||||||
char readBuf[TQ_PAGE_SIZE];
|
TqIdxPageBuf idxBuf;
|
||||||
int readSize;
|
TqSerializedHead* serializedObj = malloc(TQ_PAGE_SIZE);
|
||||||
while((readSize = read(idxFd, readBuf, TQ_PAGE_SIZE)) != -1) {
|
if(serializedObj == NULL) {
|
||||||
|
//TODO:memory insufficient
|
||||||
|
}
|
||||||
|
int idxRead;
|
||||||
|
int allocated = TQ_PAGE_SIZE;
|
||||||
|
bool readEnd = false;
|
||||||
|
while((idxRead = read(idxFd, &idxBuf, TQ_PAGE_SIZE))) {
|
||||||
|
if(idxRead == -1) {
|
||||||
|
//TODO: handle error
|
||||||
|
ASSERT(false);
|
||||||
|
}
|
||||||
|
ASSERT(idxBuf.head.writeOffset == idxRead);
|
||||||
//loop read every entry
|
//loop read every entry
|
||||||
for(int i = 0; i < readSize; i += TQ_IDX_ENTRY_SIZE) {
|
for(int i = 0; i < idxBuf.head.writeOffset - TQ_IDX_PAGE_HEAD_SIZE; i += TQ_IDX_SIZE) {
|
||||||
TqMetaList *pNode = malloc(sizeof(TqMetaHandle));
|
TqMetaList *pNode = malloc(sizeof(TqMetaList));
|
||||||
memset(pNode, 0, sizeof(TqMetaList));
|
|
||||||
if(pNode == NULL) {
|
if(pNode == NULL) {
|
||||||
//TODO: free memory and return error
|
//TODO: free memory and return error
|
||||||
}
|
}
|
||||||
memcpy(&pNode->handle, &readBuf[i], TQ_IDX_ENTRY_SIZE);
|
memset(pNode, 0, sizeof(TqMetaList));
|
||||||
int bucketKey = pNode->handle.key & TQ_BUCKET_SIZE;
|
memcpy(&pNode->handle, &idxBuf.buffer[i], TQ_IDX_SIZE);
|
||||||
pNode->next = pMeta->bucket[bucketKey];
|
|
||||||
pMeta->bucket[bucketKey] = pNode;
|
lseek(fileFd, pNode->handle.offset, SEEK_SET);
|
||||||
|
if(allocated < pNode->handle.serializedSize) {
|
||||||
|
void *ptr = realloc(serializedObj, pNode->handle.serializedSize);
|
||||||
|
if(ptr == NULL) {
|
||||||
|
//TODO: memory insufficient
|
||||||
|
}
|
||||||
|
serializedObj = ptr;
|
||||||
|
allocated = pNode->handle.serializedSize;
|
||||||
|
}
|
||||||
|
serializedObj->ssize = pNode->handle.serializedSize;
|
||||||
|
if(read(fileFd, serializedObj, pNode->handle.serializedSize) != pNode->handle.serializedSize) {
|
||||||
|
//TODO: read error
|
||||||
|
}
|
||||||
|
if(serializedObj->action == TQ_ACTION_INUSE) {
|
||||||
|
if(serializedObj->ssize != sizeof(TqSerializedHead)) {
|
||||||
|
pMeta->deserializer(serializedObj, &pNode->handle.valueInUse);
|
||||||
|
} else {
|
||||||
|
pNode->handle.valueInUse = TQ_DELETE_TOKEN;
|
||||||
|
}
|
||||||
|
} else if(serializedObj->action == TQ_ACTION_INTXN) {
|
||||||
|
if(serializedObj->ssize != sizeof(TqSerializedHead)) {
|
||||||
|
pMeta->deserializer(serializedObj, &pNode->handle.valueInTxn);
|
||||||
|
} else {
|
||||||
|
pNode->handle.valueInTxn = TQ_DELETE_TOKEN;
|
||||||
|
}
|
||||||
|
} else if(serializedObj->action == TQ_ACTION_INUSE_CONT) {
|
||||||
|
if(serializedObj->ssize != sizeof(TqSerializedHead)) {
|
||||||
|
pMeta->deserializer(serializedObj, &pNode->handle.valueInUse);
|
||||||
|
} else {
|
||||||
|
pNode->handle.valueInUse = TQ_DELETE_TOKEN;
|
||||||
|
}
|
||||||
|
TqSerializedHead* ptr = POINTER_SHIFT(serializedObj, serializedObj->ssize);
|
||||||
|
if(ptr->ssize != sizeof(TqSerializedHead)) {
|
||||||
|
pMeta->deserializer(ptr, &pNode->handle.valueInTxn);
|
||||||
|
} else {
|
||||||
|
pNode->handle.valueInTxn = TQ_DELETE_TOKEN;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//put into list
|
||||||
|
int bucketKey = pNode->handle.key & TQ_BUCKET_MASK;
|
||||||
|
TqMetaList* pBucketNode = pMeta->bucket[bucketKey];
|
||||||
|
if(pBucketNode == NULL) {
|
||||||
|
pMeta->bucket[bucketKey] = pNode;
|
||||||
|
} else if(pBucketNode->handle.key == pNode->handle.key) {
|
||||||
|
pNode->next = pBucketNode->next;
|
||||||
|
pMeta->bucket[bucketKey] = pNode;
|
||||||
|
} else {
|
||||||
|
while(pBucketNode->next &&
|
||||||
|
pBucketNode->next->handle.key != pNode->handle.key) {
|
||||||
|
pBucketNode = pBucketNode->next;
|
||||||
|
}
|
||||||
|
if(pBucketNode->next) {
|
||||||
|
ASSERT(pBucketNode->next->handle.key == pNode->handle.key);
|
||||||
|
TqMetaList *pNodeFound = pBucketNode->next;
|
||||||
|
pNode->next = pNodeFound->next;
|
||||||
|
pBucketNode->next = pNode;
|
||||||
|
pBucketNode = pNodeFound;
|
||||||
|
} else {
|
||||||
|
pNode->next = pMeta->bucket[bucketKey];
|
||||||
|
pMeta->bucket[bucketKey] = pNode;
|
||||||
|
pBucketNode = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(pBucketNode) {
|
||||||
|
if(pBucketNode->handle.valueInUse
|
||||||
|
&& pBucketNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||||
|
pMeta->deleter(pBucketNode->handle.valueInUse);
|
||||||
|
}
|
||||||
|
if(pBucketNode->handle.valueInTxn
|
||||||
|
&& pBucketNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||||
|
pMeta->deleter(pBucketNode->handle.valueInTxn);
|
||||||
|
}
|
||||||
|
free(pBucketNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(serializedObj);
|
||||||
return pMeta;
|
return pMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,107 +244,167 @@ int32_t tqStoreClose(TqMetaStore* pMeta) {
|
||||||
close(pMeta->idxFd);
|
close(pMeta->idxFd);
|
||||||
//free memory
|
//free memory
|
||||||
for(int i = 0; i < TQ_BUCKET_SIZE; i++) {
|
for(int i = 0; i < TQ_BUCKET_SIZE; i++) {
|
||||||
TqMetaList* node = pMeta->bucket[i];
|
TqMetaList* pNode = pMeta->bucket[i];
|
||||||
pMeta->bucket[i] = NULL;
|
while(pNode) {
|
||||||
while(node) {
|
ASSERT(pNode->unpersistNext == NULL);
|
||||||
ASSERT(node->unpersistNext == NULL);
|
ASSERT(pNode->unpersistPrev == NULL);
|
||||||
ASSERT(node->unpersistPrev == NULL);
|
if(pNode->handle.valueInTxn
|
||||||
if(node->handle.valueInTxn) {
|
&& pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||||
pMeta->deleter(node->handle.valueInTxn);
|
pMeta->deleter(pNode->handle.valueInTxn);
|
||||||
}
|
}
|
||||||
if(node->handle.valueInUse) {
|
if(pNode->handle.valueInUse
|
||||||
pMeta->deleter(node->handle.valueInUse);
|
&& pNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||||
|
pMeta->deleter(pNode->handle.valueInUse);
|
||||||
}
|
}
|
||||||
TqMetaList* next = node->next;
|
TqMetaList* next = pNode->next;
|
||||||
free(node);
|
free(pNode);
|
||||||
node = next;
|
pNode = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(pMeta->dirPath);
|
||||||
|
free(pMeta->unpersistHead);
|
||||||
free(pMeta);
|
free(pMeta);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqStoreDelete(TqMetaStore* pMeta) {
|
int32_t tqStoreDelete(TqMetaStore* pMeta) {
|
||||||
//close file
|
close(pMeta->fileFd);
|
||||||
//delete file
|
close(pMeta->idxFd);
|
||||||
//free memory
|
//free memory
|
||||||
|
for(int i = 0; i < TQ_BUCKET_SIZE; i++) {
|
||||||
|
TqMetaList* pNode = pMeta->bucket[i];
|
||||||
|
pMeta->bucket[i] = NULL;
|
||||||
|
while(pNode) {
|
||||||
|
if(pNode->handle.valueInTxn
|
||||||
|
&& pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||||
|
pMeta->deleter(pNode->handle.valueInTxn);
|
||||||
|
}
|
||||||
|
if(pNode->handle.valueInUse
|
||||||
|
&& pNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||||
|
pMeta->deleter(pNode->handle.valueInUse);
|
||||||
|
}
|
||||||
|
TqMetaList* next = pNode->next;
|
||||||
|
free(pNode);
|
||||||
|
pNode = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(pMeta->unpersistHead);
|
||||||
|
taosRemoveDir(pMeta->dirPath);
|
||||||
|
free(pMeta->dirPath);
|
||||||
|
free(pMeta);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: wrap in tfile
|
//TODO: wrap in tfile
|
||||||
int32_t tqStorePersist(TqMetaStore* pMeta) {
|
int32_t tqStorePersist(TqMetaStore* pMeta) {
|
||||||
char writeBuf[TQ_PAGE_SIZE];
|
TqIdxPageBuf idxBuf;
|
||||||
int64_t* bufPtr = (int64_t*)writeBuf;
|
int64_t* bufPtr = (int64_t*)idxBuf.buffer;
|
||||||
TqMetaList *pHead = pMeta->unpersistHead;
|
TqMetaList *pHead = pMeta->unpersistHead;
|
||||||
TqMetaList *pNode = pHead->unpersistNext;
|
TqMetaList *pNode = pHead->unpersistNext;
|
||||||
while(pHead != pNode) {
|
TqSerializedHead *pSHead = malloc(sizeof(TqSerializedHead));
|
||||||
if(pNode->handle.valueInUse == NULL) {
|
if(pSHead == NULL) {
|
||||||
//put delete token in data file
|
//TODO: memory error
|
||||||
uint32_t delete = TQ_ACTION_DELETE;
|
return -1;
|
||||||
int nBytes = write(pMeta->fileFd, &delete, sizeof(uint32_t));
|
}
|
||||||
ASSERT(nBytes == sizeof(uint32_t));
|
pSHead->ver = TQ_SVER;
|
||||||
|
pSHead->checksum = 0;
|
||||||
|
pSHead->ssize = sizeof(TqSerializedHead);
|
||||||
|
int allocatedSize = sizeof(TqSerializedHead);
|
||||||
|
int offset = lseek(pMeta->fileFd, 0, SEEK_CUR);
|
||||||
|
|
||||||
//remove from list
|
tqReadLastPage(pMeta->idxFd, &idxBuf);
|
||||||
int bucketKey = pNode->handle.key & TQ_BUCKET_SIZE;
|
|
||||||
|
if(idxBuf.head.writeOffset == TQ_PAGE_SIZE) {
|
||||||
|
lseek(pMeta->idxFd, 0, SEEK_END);
|
||||||
|
memset(&idxBuf, 0, TQ_PAGE_SIZE);
|
||||||
|
idxBuf.head.writeOffset = TQ_IDX_PAGE_HEAD_SIZE;
|
||||||
|
} else {
|
||||||
|
bufPtr = POINTER_SHIFT(&idxBuf, idxBuf.head.writeOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(pHead != pNode) {
|
||||||
|
int nBytes = 0;
|
||||||
|
|
||||||
|
if(pNode->handle.valueInUse) {
|
||||||
|
if(pNode->handle.valueInTxn) {
|
||||||
|
pSHead->action = TQ_ACTION_INUSE_CONT;
|
||||||
|
} else {
|
||||||
|
pSHead->action = TQ_ACTION_INUSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pNode->handle.valueInUse == TQ_DELETE_TOKEN) {
|
||||||
|
pSHead->ssize = sizeof(TqSerializedHead);
|
||||||
|
} else {
|
||||||
|
pMeta->serializer(pNode->handle.valueInUse, &pSHead);
|
||||||
|
}
|
||||||
|
nBytes = write(pMeta->fileFd, pSHead, pSHead->ssize);
|
||||||
|
ASSERT(nBytes == pSHead->ssize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pNode->handle.valueInTxn) {
|
||||||
|
pSHead->action = TQ_ACTION_INTXN;
|
||||||
|
if(pNode->handle.valueInTxn == TQ_DELETE_TOKEN) {
|
||||||
|
pSHead->ssize = sizeof(TqSerializedHead);
|
||||||
|
} else {
|
||||||
|
pMeta->serializer(pNode->handle.valueInTxn, &pSHead);
|
||||||
|
}
|
||||||
|
int nBytesTxn = write(pMeta->fileFd, pSHead, pSHead->ssize);
|
||||||
|
ASSERT(nBytesTxn == pSHead->ssize);
|
||||||
|
nBytes += nBytesTxn;
|
||||||
|
}
|
||||||
|
pNode->handle.offset = offset;
|
||||||
|
offset += nBytes;
|
||||||
|
|
||||||
|
//write idx file
|
||||||
|
//TODO: endian check and convert
|
||||||
|
*(bufPtr++) = pNode->handle.key;
|
||||||
|
*(bufPtr++) = pNode->handle.offset;
|
||||||
|
*(bufPtr++) = (int64_t)nBytes;
|
||||||
|
idxBuf.head.writeOffset += TQ_IDX_SIZE;
|
||||||
|
|
||||||
|
if(idxBuf.head.writeOffset >= TQ_PAGE_SIZE) {
|
||||||
|
nBytes = write(pMeta->idxFd, &idxBuf, TQ_PAGE_SIZE);
|
||||||
|
//TODO: handle error with tfile
|
||||||
|
ASSERT(nBytes == TQ_PAGE_SIZE);
|
||||||
|
memset(&idxBuf, 0, TQ_PAGE_SIZE);
|
||||||
|
idxBuf.head.writeOffset = TQ_IDX_PAGE_HEAD_SIZE;
|
||||||
|
bufPtr = (int64_t*)&idxBuf.buffer;
|
||||||
|
}
|
||||||
|
//remove from unpersist list
|
||||||
|
pHead->unpersistNext = pNode->unpersistNext;
|
||||||
|
pHead->unpersistNext->unpersistPrev = pHead;
|
||||||
|
pNode->unpersistPrev = pNode->unpersistNext = NULL;
|
||||||
|
pNode = pHead->unpersistNext;
|
||||||
|
|
||||||
|
//remove from bucket
|
||||||
|
if(pNode->handle.valueInUse == TQ_DELETE_TOKEN &&
|
||||||
|
pNode->handle.valueInTxn == NULL
|
||||||
|
) {
|
||||||
|
int bucketKey = pNode->handle.key & TQ_BUCKET_MASK;
|
||||||
TqMetaList* pBucketHead = pMeta->bucket[bucketKey];
|
TqMetaList* pBucketHead = pMeta->bucket[bucketKey];
|
||||||
if(pBucketHead == pNode) {
|
if(pBucketHead == pNode) {
|
||||||
pMeta->bucket[bucketKey] = pBucketHead->next;
|
pMeta->bucket[bucketKey] = pNode->next;
|
||||||
} else {
|
} else {
|
||||||
TqMetaList* pBucketNode = pBucketHead;
|
TqMetaList* pBucketNode = pBucketHead;
|
||||||
while(pBucketNode->next != NULL
|
while(pBucketNode->next != NULL
|
||||||
&& pBucketNode->next != pNode) {
|
&& pBucketNode->next != pNode) {
|
||||||
pBucketNode = pBucketNode->next;
|
pBucketNode = pBucketNode->next;
|
||||||
}
|
}
|
||||||
if(pBucketNode->next != NULL) {
|
//impossible for pBucket->next == NULL
|
||||||
ASSERT(pBucketNode->next == pNode);
|
ASSERT(pBucketNode->next == pNode);
|
||||||
pBucketNode->next = pNode->next;
|
pBucketNode->next = pNode->next;
|
||||||
if(pNode->handle.valueInUse) {
|
|
||||||
pMeta->deleter(pNode->handle.valueInUse);
|
|
||||||
}
|
|
||||||
free(pNode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
free(pNode);
|
||||||
}
|
}
|
||||||
//serialize
|
|
||||||
void* pBytes = NULL;
|
|
||||||
int sz = pMeta->serializer(pNode->handle.valueInUse, &pBytes);
|
|
||||||
ASSERT(pBytes != NULL);
|
|
||||||
//get current offset
|
|
||||||
//append data
|
|
||||||
int64_t offset = lseek(pMeta->fileFd, 0, SEEK_CUR);
|
|
||||||
int nBytes = write(pMeta->fileFd, pBytes, sz);
|
|
||||||
//TODO: handle error in tfile
|
|
||||||
ASSERT(nBytes == sz);
|
|
||||||
|
|
||||||
pNode->handle.offset = offset;
|
|
||||||
pNode->handle.serializedSize = sz;
|
|
||||||
|
|
||||||
//write idx
|
|
||||||
//TODO: endian check and convert
|
|
||||||
*(bufPtr++) = pNode->handle.key;
|
|
||||||
*(bufPtr++) = pNode->handle.offset;
|
|
||||||
*(bufPtr++) = (int64_t)sz;
|
|
||||||
if((char*)(bufPtr + 3) > writeBuf + TQ_PAGE_SIZE) {
|
|
||||||
nBytes = write(pMeta->idxFd, writeBuf, sizeof(writeBuf));
|
|
||||||
//TODO: handle error in tfile
|
|
||||||
ASSERT(nBytes == sizeof(writeBuf));
|
|
||||||
memset(writeBuf, 0, TQ_PAGE_SIZE);
|
|
||||||
bufPtr = (int64_t*)writeBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove from unpersist list
|
|
||||||
pHead->unpersistNext = pNode->unpersistNext;
|
|
||||||
pHead->unpersistNext->unpersistPrev = pHead;
|
|
||||||
|
|
||||||
pNode->unpersistPrev = pNode->unpersistNext = NULL;
|
|
||||||
pNode = pHead->unpersistNext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//write left bytes
|
//write left bytes
|
||||||
if((char*)bufPtr != writeBuf) {
|
free(pSHead);
|
||||||
int used = (char*)bufPtr - writeBuf;
|
//TODO: write new version in tfile
|
||||||
int nBytes = write(pMeta->idxFd, writeBuf, used);
|
if((char*)bufPtr != idxBuf.buffer) {
|
||||||
|
int nBytes = write(pMeta->idxFd, &idxBuf, idxBuf.head.writeOffset);
|
||||||
//TODO: handle error in tfile
|
//TODO: handle error in tfile
|
||||||
ASSERT(nBytes == used);
|
ASSERT(nBytes == idxBuf.head.writeOffset);
|
||||||
}
|
}
|
||||||
//TODO: using fsync in tfile
|
//TODO: using fsync in tfile
|
||||||
fsync(pMeta->idxFd);
|
fsync(pMeta->idxFd);
|
||||||
|
@ -211,12 +413,15 @@ int32_t tqStorePersist(TqMetaStore* pMeta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tqHandlePutCommitted(TqMetaStore* pMeta, int64_t key, void* value) {
|
static int32_t tqHandlePutCommitted(TqMetaStore* pMeta, int64_t key, void* value) {
|
||||||
int64_t bucketKey = key & TQ_BUCKET_SIZE;
|
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||||
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||||
while(pNode) {
|
while(pNode) {
|
||||||
if(pNode->handle.key == key) {
|
if(pNode->handle.key == key) {
|
||||||
//TODO: think about thread safety
|
//TODO: think about thread safety
|
||||||
pMeta->deleter(pNode->handle.valueInUse);
|
if(pNode->handle.valueInUse
|
||||||
|
&& pNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||||
|
pMeta->deleter(pNode->handle.valueInUse);
|
||||||
|
}
|
||||||
//change pointer ownership
|
//change pointer ownership
|
||||||
pNode->handle.valueInUse = value;
|
pNode->handle.valueInUse = value;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -240,13 +445,14 @@ static int32_t tqHandlePutCommitted(TqMetaStore* pMeta, int64_t key, void* value
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TqMetaHandle* tqHandleGet(TqMetaStore* pMeta, int64_t key) {
|
void* tqHandleGet(TqMetaStore* pMeta, int64_t key) {
|
||||||
int64_t bucketKey = key & TQ_BUCKET_SIZE;
|
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||||
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||||
while(pNode) {
|
while(pNode) {
|
||||||
if(pNode->handle.key == key) {
|
if(pNode->handle.key == key) {
|
||||||
if(pNode->handle.valueInUse != NULL) {
|
if(pNode->handle.valueInUse != NULL
|
||||||
return &pNode->handle;
|
&& pNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||||
|
return pNode->handle.valueInUse;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -257,15 +463,19 @@ TqMetaHandle* tqHandleGet(TqMetaStore* pMeta, int64_t key) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqHandlePut(TqMetaStore* pMeta, int64_t key, void* value) {
|
int32_t tqHandleMovePut(TqMetaStore* pMeta, int64_t key, void* value) {
|
||||||
int64_t bucketKey = key & TQ_BUCKET_SIZE;
|
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||||
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||||
while(pNode) {
|
while(pNode) {
|
||||||
if(pNode->handle.key == key) {
|
if(pNode->handle.key == key) {
|
||||||
//TODO: think about thread safety
|
//TODO: think about thread safety
|
||||||
pMeta->deleter(pNode->handle.valueInTxn);
|
if(pNode->handle.valueInTxn
|
||||||
|
&& pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||||
|
pMeta->deleter(pNode->handle.valueInTxn);
|
||||||
|
}
|
||||||
//change pointer ownership
|
//change pointer ownership
|
||||||
pNode->handle.valueInTxn = value;
|
pNode->handle.valueInTxn = value;
|
||||||
|
tqLinkUnpersist(pMeta, pNode);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
pNode = pNode->next;
|
pNode = pNode->next;
|
||||||
|
@ -279,16 +489,58 @@ int32_t tqHandlePut(TqMetaStore* pMeta, int64_t key, void* value) {
|
||||||
memset(pNewNode, 0, sizeof(TqMetaList));
|
memset(pNewNode, 0, sizeof(TqMetaList));
|
||||||
pNewNode->handle.key = key;
|
pNewNode->handle.key = key;
|
||||||
pNewNode->handle.valueInTxn = value;
|
pNewNode->handle.valueInTxn = value;
|
||||||
|
pNewNode->next = pMeta->bucket[bucketKey];
|
||||||
|
pMeta->bucket[bucketKey] = pNewNode;
|
||||||
|
tqLinkUnpersist(pMeta, pNewNode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TqMetaHandle* tqHandleGetUncommitted(TqMetaStore* pMeta, int64_t key) {
|
int32_t tqHandleCopyPut(TqMetaStore* pMeta, int64_t key, void* value, size_t vsize) {
|
||||||
int64_t bucketKey = key & TQ_BUCKET_SIZE;
|
void *vmem = malloc(vsize);
|
||||||
|
if(vmem == NULL) {
|
||||||
|
//TODO: memory error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(vmem, value, vsize);
|
||||||
|
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||||
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||||
while(pNode) {
|
while(pNode) {
|
||||||
if(pNode->handle.key == key) {
|
if(pNode->handle.key == key) {
|
||||||
if(pNode->handle.valueInTxn != NULL) {
|
//TODO: think about thread safety
|
||||||
return &pNode->handle;
|
if(pNode->handle.valueInTxn
|
||||||
|
&& pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||||
|
pMeta->deleter(pNode->handle.valueInTxn);
|
||||||
|
}
|
||||||
|
//change pointer ownership
|
||||||
|
pNode->handle.valueInTxn = vmem;
|
||||||
|
tqLinkUnpersist(pMeta, pNode);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
pNode = pNode->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TqMetaList *pNewNode = malloc(sizeof(TqMetaList));
|
||||||
|
if(pNewNode == NULL) {
|
||||||
|
//TODO: memory error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(pNewNode, 0, sizeof(TqMetaList));
|
||||||
|
pNewNode->handle.key = key;
|
||||||
|
pNewNode->handle.valueInTxn = vmem;
|
||||||
|
pNewNode->next = pMeta->bucket[bucketKey];
|
||||||
|
pMeta->bucket[bucketKey] = pNewNode;
|
||||||
|
tqLinkUnpersist(pMeta, pNewNode);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* tqHandleGetUncommitted(TqMetaStore* pMeta, int64_t key) {
|
||||||
|
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||||
|
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||||
|
while(pNode) {
|
||||||
|
if(pNode->handle.key == key) {
|
||||||
|
if(pNode->handle.valueInTxn != NULL
|
||||||
|
&& pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||||
|
return pNode->handle.valueInTxn;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -300,36 +552,39 @@ static TqMetaHandle* tqHandleGetUncommitted(TqMetaStore* pMeta, int64_t key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqHandleCommit(TqMetaStore* pMeta, int64_t key) {
|
int32_t tqHandleCommit(TqMetaStore* pMeta, int64_t key) {
|
||||||
int64_t bucketKey = key & TQ_BUCKET_SIZE;
|
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||||
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||||
while(pNode) {
|
while(pNode) {
|
||||||
if(pNode->handle.key == key) {
|
if(pNode->handle.key == key) {
|
||||||
if(pNode->handle.valueInUse != NULL) {
|
if(pNode->handle.valueInTxn == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(pNode->handle.valueInUse
|
||||||
|
&& pNode->handle.valueInUse != TQ_DELETE_TOKEN) {
|
||||||
pMeta->deleter(pNode->handle.valueInUse);
|
pMeta->deleter(pNode->handle.valueInUse);
|
||||||
}
|
}
|
||||||
pNode->handle.valueInUse = pNode->handle.valueInTxn;
|
pNode->handle.valueInUse = pNode->handle.valueInTxn;
|
||||||
if(pNode->unpersistNext == NULL) {
|
pNode->handle.valueInTxn = NULL;
|
||||||
pNode->unpersistNext = pMeta->unpersistHead->unpersistNext;
|
tqLinkUnpersist(pMeta, pNode);
|
||||||
pNode->unpersistPrev = pMeta->unpersistHead;
|
|
||||||
pMeta->unpersistHead->unpersistNext->unpersistPrev = pNode;
|
|
||||||
pMeta->unpersistHead->unpersistNext = pNode;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
pNode = pNode->next;
|
pNode = pNode->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqHandleAbort(TqMetaStore* pMeta, int64_t key) {
|
int32_t tqHandleAbort(TqMetaStore* pMeta, int64_t key) {
|
||||||
int64_t bucketKey = key & TQ_BUCKET_SIZE;
|
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||||
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||||
while(pNode) {
|
while(pNode) {
|
||||||
if(pNode->handle.key == key) {
|
if(pNode->handle.key == key) {
|
||||||
if(pNode->handle.valueInTxn != NULL) {
|
if(pNode->handle.valueInTxn) {
|
||||||
pMeta->deleter(pNode->handle.valueInTxn);
|
if(pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||||
|
pMeta->deleter(pNode->handle.valueInTxn);
|
||||||
|
}
|
||||||
pNode->handle.valueInTxn = NULL;
|
pNode->handle.valueInTxn = NULL;
|
||||||
|
tqLinkUnpersist(pMeta, pNode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -341,12 +596,15 @@ int32_t tqHandleAbort(TqMetaStore* pMeta, int64_t key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqHandleDel(TqMetaStore* pMeta, int64_t key) {
|
int32_t tqHandleDel(TqMetaStore* pMeta, int64_t key) {
|
||||||
int64_t bucketKey = key & TQ_BUCKET_SIZE;
|
int64_t bucketKey = key & TQ_BUCKET_MASK;
|
||||||
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
||||||
while(pNode) {
|
while(pNode) {
|
||||||
if(pNode->handle.key == key) {
|
if(pNode->handle.valueInTxn != TQ_DELETE_TOKEN) {
|
||||||
pMeta->deleter(pNode->handle.valueInTxn);
|
if(pNode->handle.valueInTxn) {
|
||||||
pNode->handle.valueInTxn = NULL;
|
pMeta->deleter(pNode->handle.valueInTxn);
|
||||||
|
}
|
||||||
|
pNode->handle.valueInTxn = TQ_DELETE_TOKEN;
|
||||||
|
tqLinkUnpersist(pMeta, pNode);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
pNode = pNode->next;
|
pNode = pNode->next;
|
||||||
|
@ -356,35 +614,7 @@ int32_t tqHandleDel(TqMetaStore* pMeta, int64_t key) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqHandleClear(TqMetaStore* pMeta, int64_t key) {
|
//TODO: clean deleted idx and data from persistent file
|
||||||
int64_t bucketKey = key & TQ_BUCKET_SIZE;
|
int32_t tqStoreCompact(TqMetaStore *pMeta) {
|
||||||
TqMetaList* pNode = pMeta->bucket[bucketKey];
|
return 0;
|
||||||
bool exist = false;
|
|
||||||
while(pNode) {
|
|
||||||
if(pNode->handle.key == key) {
|
|
||||||
if(pNode->handle.valueInUse != NULL) {
|
|
||||||
exist = true;
|
|
||||||
pMeta->deleter(pNode->handle.valueInUse);
|
|
||||||
pNode->handle.valueInUse = NULL;
|
|
||||||
}
|
|
||||||
if(pNode->handle.valueInTxn != NULL) {
|
|
||||||
exist = true;
|
|
||||||
pMeta->deleter(pNode->handle.valueInTxn);
|
|
||||||
pNode->handle.valueInTxn = NULL;
|
|
||||||
}
|
|
||||||
if(exist) {
|
|
||||||
if(pNode->unpersistNext == NULL) {
|
|
||||||
pNode->unpersistNext = pMeta->unpersistHead->unpersistNext;
|
|
||||||
pNode->unpersistPrev = pMeta->unpersistHead;
|
|
||||||
pMeta->unpersistHead->unpersistNext->unpersistPrev = pNode;
|
|
||||||
pMeta->unpersistHead->unpersistNext = pNode;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
pNode = pNode->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -2;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
add_executable(tqTest "")
|
||||||
|
target_sources(tqTest
|
||||||
|
PRIVATE
|
||||||
|
"tqMetaTest.cpp"
|
||||||
|
)
|
||||||
|
target_include_directories(tqTest
|
||||||
|
PUBLIC
|
||||||
|
"${CMAKE_SOURCE_DIR}/include/server/vnode/tq"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(tqTest
|
||||||
|
tq
|
||||||
|
gtest_main
|
||||||
|
)
|
||||||
|
enable_testing()
|
||||||
|
add_test(
|
||||||
|
NAME tq_test
|
||||||
|
COMMAND tqTest
|
||||||
|
)
|
|
@ -0,0 +1,294 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#include "tqMetaStore.h"
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
int32_t a;
|
||||||
|
};
|
||||||
|
|
||||||
|
int FooSerializer(const void* pObj, TqSerializedHead** ppHead) {
|
||||||
|
Foo* foo = (Foo*) pObj;
|
||||||
|
if((*ppHead) == NULL || (*ppHead)->ssize < sizeof(TqSerializedHead) + sizeof(int32_t)) {
|
||||||
|
*ppHead = (TqSerializedHead*)realloc(*ppHead, sizeof(TqSerializedHead) + sizeof(int32_t));
|
||||||
|
(*ppHead)->ssize = sizeof(TqSerializedHead) + sizeof(int32_t);
|
||||||
|
}
|
||||||
|
*(int32_t*)(*ppHead)->content = foo->a;
|
||||||
|
return (*ppHead)->ssize;
|
||||||
|
}
|
||||||
|
|
||||||
|
const void* FooDeserializer(const TqSerializedHead* pHead, void** ppObj) {
|
||||||
|
if(*ppObj == NULL) {
|
||||||
|
*ppObj = realloc(*ppObj, sizeof(int32_t));
|
||||||
|
}
|
||||||
|
Foo* pFoo = *(Foo**)ppObj;
|
||||||
|
pFoo->a = *(int32_t*)pHead->content;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FooDeleter(void* pObj) {
|
||||||
|
free(pObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TqMetaTest : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void SetUp() override {
|
||||||
|
taosRemoveDir(pathName);
|
||||||
|
pMeta = tqStoreOpen(pathName,
|
||||||
|
FooSerializer, FooDeserializer, FooDeleter);
|
||||||
|
ASSERT(pMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown() override {
|
||||||
|
tqStoreClose(pMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
TqMetaStore* pMeta;
|
||||||
|
const char* pathName = "/tmp/tq_test";
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(TqMetaTest, copyPutTest) {
|
||||||
|
Foo foo;
|
||||||
|
foo.a = 3;
|
||||||
|
tqHandleCopyPut(pMeta, 1, &foo, sizeof(Foo));
|
||||||
|
|
||||||
|
Foo* pFoo = (Foo*) tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo == NULL, true);
|
||||||
|
|
||||||
|
tqHandleCommit(pMeta, 1);
|
||||||
|
pFoo = (Foo*) tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo->a, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TqMetaTest, persistTest) {
|
||||||
|
Foo* pFoo = (Foo*)malloc(sizeof(Foo));
|
||||||
|
pFoo->a = 2;
|
||||||
|
tqHandleMovePut(pMeta, 1, pFoo);
|
||||||
|
Foo* pBar = (Foo*)tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pBar == NULL, true);
|
||||||
|
tqHandleCommit(pMeta, 1);
|
||||||
|
pBar = (Foo*)tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pBar->a, pFoo->a);
|
||||||
|
pBar = (Foo*)tqHandleGet(pMeta, 2);
|
||||||
|
EXPECT_EQ(pBar == NULL, true);
|
||||||
|
|
||||||
|
tqStoreClose(pMeta);
|
||||||
|
pMeta = tqStoreOpen(pathName,
|
||||||
|
FooSerializer, FooDeserializer, FooDeleter);
|
||||||
|
ASSERT(pMeta);
|
||||||
|
|
||||||
|
pBar = (Foo*)tqHandleGet(pMeta, 1);
|
||||||
|
ASSERT_EQ(pBar != NULL, true);
|
||||||
|
EXPECT_EQ(pBar->a, 2);
|
||||||
|
|
||||||
|
pBar = (Foo*)tqHandleGet(pMeta, 2);
|
||||||
|
EXPECT_EQ(pBar == NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TqMetaTest, uncommittedTest) {
|
||||||
|
Foo* pFoo = (Foo*)malloc(sizeof(Foo));
|
||||||
|
pFoo->a = 3;
|
||||||
|
tqHandleMovePut(pMeta, 1, pFoo);
|
||||||
|
|
||||||
|
pFoo = (Foo*) tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo == NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TqMetaTest, abortTest) {
|
||||||
|
Foo* pFoo = (Foo*)malloc(sizeof(Foo));
|
||||||
|
pFoo->a = 3;
|
||||||
|
tqHandleMovePut(pMeta, 1, pFoo);
|
||||||
|
|
||||||
|
pFoo = (Foo*) tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo == NULL, true);
|
||||||
|
|
||||||
|
tqHandleAbort(pMeta, 1);
|
||||||
|
pFoo = (Foo*) tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo == NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TqMetaTest, deleteTest) {
|
||||||
|
Foo* pFoo = (Foo*)malloc(sizeof(Foo));
|
||||||
|
pFoo->a = 3;
|
||||||
|
tqHandleMovePut(pMeta, 1, pFoo);
|
||||||
|
|
||||||
|
pFoo = (Foo*) tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo == NULL, true);
|
||||||
|
|
||||||
|
tqHandleCommit(pMeta, 1);
|
||||||
|
|
||||||
|
pFoo = (Foo*) tqHandleGet(pMeta, 1);
|
||||||
|
ASSERT_EQ(pFoo != NULL, true);
|
||||||
|
EXPECT_EQ(pFoo->a, 3);
|
||||||
|
|
||||||
|
tqHandleDel(pMeta, 1);
|
||||||
|
pFoo = (Foo*) tqHandleGet(pMeta, 1);
|
||||||
|
ASSERT_EQ(pFoo != NULL, true);
|
||||||
|
EXPECT_EQ(pFoo->a, 3);
|
||||||
|
|
||||||
|
tqHandleCommit(pMeta, 1);
|
||||||
|
pFoo = (Foo*) tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo == NULL, true);
|
||||||
|
|
||||||
|
tqStoreClose(pMeta);
|
||||||
|
pMeta = tqStoreOpen(pathName,
|
||||||
|
FooSerializer, FooDeserializer, FooDeleter);
|
||||||
|
ASSERT(pMeta);
|
||||||
|
|
||||||
|
pFoo = (Foo*) tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo == NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TqMetaTest, intxnPersist) {
|
||||||
|
Foo* pFoo = (Foo*)malloc(sizeof(Foo));
|
||||||
|
pFoo->a = 3;
|
||||||
|
tqHandleMovePut(pMeta, 1, pFoo);
|
||||||
|
tqHandleCommit(pMeta, 1);
|
||||||
|
|
||||||
|
Foo* pBar = (Foo*)malloc(sizeof(Foo));
|
||||||
|
pBar->a = 4;
|
||||||
|
tqHandleMovePut(pMeta, 1, pBar);
|
||||||
|
|
||||||
|
Foo* pFoo1 = (Foo*)tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo1->a, 3);
|
||||||
|
|
||||||
|
tqStoreClose(pMeta);
|
||||||
|
pMeta = tqStoreOpen(pathName,
|
||||||
|
FooSerializer, FooDeserializer, FooDeleter);
|
||||||
|
ASSERT(pMeta);
|
||||||
|
|
||||||
|
pFoo1 = (Foo*)tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo1->a, 3);
|
||||||
|
|
||||||
|
tqHandleCommit(pMeta, 1);
|
||||||
|
|
||||||
|
pFoo1 = (Foo*)tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo1->a, 4);
|
||||||
|
|
||||||
|
tqStoreClose(pMeta);
|
||||||
|
pMeta = tqStoreOpen(pathName,
|
||||||
|
FooSerializer, FooDeserializer, FooDeleter);
|
||||||
|
ASSERT(pMeta);
|
||||||
|
|
||||||
|
pFoo1 = (Foo*)tqHandleGet(pMeta, 1);
|
||||||
|
EXPECT_EQ(pFoo1->a, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TqMetaTest, multiplePage) {
|
||||||
|
srand(0);
|
||||||
|
std::vector<int> v;
|
||||||
|
for(int i = 0; i < 1000; i++) {
|
||||||
|
v.push_back(rand());
|
||||||
|
Foo foo;
|
||||||
|
foo.a = v[i];
|
||||||
|
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 500; i++) {
|
||||||
|
tqHandleCommit(pMeta, i);
|
||||||
|
Foo* pFoo = (Foo*)tqHandleGet(pMeta, i);
|
||||||
|
ASSERT_EQ(pFoo != NULL, true) << " at idx " << i << "\n";
|
||||||
|
EXPECT_EQ(pFoo->a, v[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
tqStoreClose(pMeta);
|
||||||
|
pMeta = tqStoreOpen(pathName,
|
||||||
|
FooSerializer, FooDeserializer, FooDeleter);
|
||||||
|
ASSERT(pMeta);
|
||||||
|
|
||||||
|
for(int i = 500; i < 1000; i++) {
|
||||||
|
tqHandleCommit(pMeta, i);
|
||||||
|
Foo* pFoo = (Foo*)tqHandleGet(pMeta, i);
|
||||||
|
ASSERT_EQ(pFoo != NULL, true) << " at idx " << i << "\n";
|
||||||
|
EXPECT_EQ(pFoo->a, v[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 1000; i++) {
|
||||||
|
Foo* pFoo = (Foo*)tqHandleGet(pMeta, i);
|
||||||
|
ASSERT_EQ(pFoo != NULL, true) << " at idx " << i << "\n";
|
||||||
|
EXPECT_EQ(pFoo->a, v[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TqMetaTest, multipleRewrite) {
|
||||||
|
srand(0);
|
||||||
|
std::vector<int> v;
|
||||||
|
for(int i = 0; i < 1000; i++) {
|
||||||
|
v.push_back(rand());
|
||||||
|
Foo foo;
|
||||||
|
foo.a = v[i];
|
||||||
|
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 500; i++) {
|
||||||
|
tqHandleCommit(pMeta, i);
|
||||||
|
v[i] = rand();
|
||||||
|
Foo foo;
|
||||||
|
foo.a = v[i];
|
||||||
|
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 500; i < 1000; i++) {
|
||||||
|
v[i] = rand();
|
||||||
|
Foo foo;
|
||||||
|
foo.a = v[i];
|
||||||
|
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 1000; i++) {
|
||||||
|
tqHandleCommit(pMeta, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
tqStoreClose(pMeta);
|
||||||
|
pMeta = tqStoreOpen(pathName,
|
||||||
|
FooSerializer, FooDeserializer, FooDeleter);
|
||||||
|
ASSERT(pMeta);
|
||||||
|
|
||||||
|
for(int i = 500; i < 1000; i++) {
|
||||||
|
v[i] = rand();
|
||||||
|
Foo foo;
|
||||||
|
foo.a = v[i];
|
||||||
|
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||||
|
tqHandleCommit(pMeta, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 1000; i++) {
|
||||||
|
Foo* pFoo = (Foo*)tqHandleGet(pMeta, i);
|
||||||
|
ASSERT_EQ(pFoo != NULL, true) << " at idx " << i << "\n";
|
||||||
|
EXPECT_EQ(pFoo->a, v[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TqMetaTest, dupCommit) {
|
||||||
|
srand(0);
|
||||||
|
std::vector<int> v;
|
||||||
|
for(int i = 0; i < 1000; i++) {
|
||||||
|
v.push_back(rand());
|
||||||
|
Foo foo;
|
||||||
|
foo.a = v[i];
|
||||||
|
tqHandleCopyPut(pMeta, i, &foo, sizeof(Foo));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 1000; i++) {
|
||||||
|
int ret = tqHandleCommit(pMeta, i);
|
||||||
|
EXPECT_EQ(ret, 0);
|
||||||
|
ret = tqHandleCommit(pMeta, i);
|
||||||
|
EXPECT_EQ(ret, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 1000; i++) {
|
||||||
|
int ret = tqHandleCommit(pMeta, i);
|
||||||
|
EXPECT_EQ(ret, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 1000; i++) {
|
||||||
|
Foo* pFoo = (Foo*)tqHandleGet(pMeta, i);
|
||||||
|
ASSERT_EQ(pFoo != NULL, true) << " at idx " << i << "\n";
|
||||||
|
EXPECT_EQ(pFoo->a, v[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -13,8 +13,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TD_RAFT_INT_H_
|
#ifndef _TD_TSDB_IDX_H_
|
||||||
#define _TD_RAFT_INT_H_
|
#define _TD_TSDB_IDX_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -24,4 +24,4 @@ extern "C" {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /*_TD_RAFT_INT_H_*/
|
#endif /*_TD_TSDB_IDX_H_*/
|
|
@ -20,6 +20,11 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern const STsdbOptions defautlTsdbOptions;
|
||||||
|
|
||||||
|
int tsdbValidateOptions(const STsdbOptions *);
|
||||||
|
void tsdbOptionsCopy(STsdbOptions *pDest, const STsdbOptions *pSrc);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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 _TD_TSDB_SMA_H_
|
||||||
|
#define _TD_TSDB_SMA_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_TSDB_SMA_H_*/
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
|
@ -13,4 +13,82 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tsdbDef.h"
|
#include "tsdbDef.h"
|
||||||
|
|
||||||
|
static STsdb *tsdbNew(const char *path, const STsdbOptions *pTsdbOptions);
|
||||||
|
static void tsdbFree(STsdb *pTsdb);
|
||||||
|
static int tsdbOpenImpl(STsdb *pTsdb);
|
||||||
|
static void tsdbCloseImpl(STsdb *pTsdb);
|
||||||
|
|
||||||
|
STsdb *tsdbOpen(const char *path, const STsdbOptions *pTsdbOptions) {
|
||||||
|
STsdb *pTsdb = NULL;
|
||||||
|
|
||||||
|
// Set default TSDB Options
|
||||||
|
if (pTsdbOptions == NULL) {
|
||||||
|
pTsdbOptions = &defautlTsdbOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the options
|
||||||
|
if (tsdbValidateOptions(pTsdbOptions) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the handle
|
||||||
|
pTsdb = tsdbNew(path, pTsdbOptions);
|
||||||
|
if (pTsdb == NULL) {
|
||||||
|
// TODO: handle error
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosMkDir(path);
|
||||||
|
|
||||||
|
// Open the TSDB
|
||||||
|
if (tsdbOpenImpl(pTsdb) < 0) {
|
||||||
|
// TODO: handle error
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pTsdb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tsdbClose(STsdb *pTsdb) {
|
||||||
|
if (pTsdb) {
|
||||||
|
tsdbCloseImpl(pTsdb);
|
||||||
|
tsdbFree(pTsdb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tsdbRemove(const char *path) { taosRemoveDir(path); }
|
||||||
|
|
||||||
|
/* ------------------------ STATIC METHODS ------------------------ */
|
||||||
|
static STsdb *tsdbNew(const char *path, const STsdbOptions *pTsdbOptions) {
|
||||||
|
STsdb *pTsdb = NULL;
|
||||||
|
|
||||||
|
pTsdb = (STsdb *)calloc(1, sizeof(STsdb));
|
||||||
|
if (pTsdb == NULL) {
|
||||||
|
// TODO: handle error
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTsdb->path = strdup(path);
|
||||||
|
tsdbOptionsCopy(&(pTsdb->options), pTsdbOptions);
|
||||||
|
|
||||||
|
return pTsdb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tsdbFree(STsdb *pTsdb) {
|
||||||
|
if (pTsdb) {
|
||||||
|
tfree(pTsdb->path);
|
||||||
|
free(pTsdb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsdbOpenImpl(STsdb *pTsdb) {
|
||||||
|
// TODO
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tsdbCloseImpl(STsdb *pTsdb) {
|
||||||
|
// TODO
|
||||||
|
}
|
|
@ -11,4 +11,24 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "tsdbDef.h"
|
||||||
|
|
||||||
|
const STsdbOptions defautlTsdbOptions = {.lruCacheSize = 0};
|
||||||
|
|
||||||
|
int tsdbOptionsInit(STsdbOptions *pTsdbOptions) {
|
||||||
|
// TODO
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tsdbOptionsClear(STsdbOptions *pTsdbOptions) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int tsdbValidateOptions(const STsdbOptions *pTsdbOptions) {
|
||||||
|
// TODO
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tsdbOptionsCopy(STsdbOptions *pDest, const STsdbOptions *pSrc) { memcpy(pDest, pSrc, sizeof(STsdbOptions)); }
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
|
@ -8,5 +8,5 @@ target_include_directories(
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
executor
|
executor
|
||||||
PRIVATE os util common
|
PRIVATE os util common function parser
|
||||||
)
|
)
|
|
@ -15,6 +15,8 @@
|
||||||
#ifndef TDENGINE_QUERYUTIL_H
|
#ifndef TDENGINE_QUERYUTIL_H
|
||||||
#define TDENGINE_QUERYUTIL_H
|
#define TDENGINE_QUERYUTIL_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "tpagedfile.h"
|
||||||
#include "tbuffer.h"
|
#include "tbuffer.h"
|
||||||
|
|
||||||
#define SET_RES_WINDOW_KEY(_k, _ori, _len, _uid) \
|
#define SET_RES_WINDOW_KEY(_k, _ori, _len, _uid) \
|
||||||
|
@ -40,42 +42,92 @@
|
||||||
|
|
||||||
#define curTimeWindowIndex(_winres) ((_winres)->curIndex)
|
#define curTimeWindowIndex(_winres) ((_winres)->curIndex)
|
||||||
|
|
||||||
int32_t getOutputInterResultBufSize(SQueryAttr* pQueryAttr);
|
struct SColumnFilterElem;
|
||||||
|
|
||||||
size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv);
|
typedef bool (*__filter_func_t)(struct SColumnFilterElem* pFilter, const char* val1, const char* val2, int16_t type);
|
||||||
|
|
||||||
|
typedef struct SGroupResInfo {
|
||||||
|
int32_t totalGroup;
|
||||||
|
int32_t currentGroup;
|
||||||
|
int32_t index;
|
||||||
|
SArray* pRows; // SArray<SResultRow*>
|
||||||
|
bool ordered;
|
||||||
|
int32_t position;
|
||||||
|
} SGroupResInfo;
|
||||||
|
|
||||||
|
typedef struct SResultRow {
|
||||||
|
int32_t pageId; // pageId & rowId is the position of current result in disk-based output buffer
|
||||||
|
int32_t offset:29; // row index in buffer page
|
||||||
|
bool startInterp; // the time window start timestamp has done the interpolation already.
|
||||||
|
bool endInterp; // the time window end timestamp has done the interpolation already.
|
||||||
|
bool closed; // this result status: closed or opened
|
||||||
|
uint32_t numOfRows; // number of rows of current time window
|
||||||
|
struct SResultRowEntryInfo* pEntryInfo; // For each result column, there is a resultInfo
|
||||||
|
STimeWindow win;
|
||||||
|
char *key; // start key of current result row
|
||||||
|
} SResultRow;
|
||||||
|
|
||||||
|
typedef struct SResultRowInfo {
|
||||||
|
SResultRow** pResult; // result list
|
||||||
|
int16_t type:8; // data type for hash key
|
||||||
|
int32_t size:24; // number of result set
|
||||||
|
int32_t capacity; // max capacity
|
||||||
|
int32_t curPos; // current active result row index of pResult list
|
||||||
|
} SResultRowInfo;
|
||||||
|
|
||||||
|
typedef struct SResultRowPool {
|
||||||
|
int32_t elemSize;
|
||||||
|
int32_t blockSize;
|
||||||
|
int32_t numOfElemPerBlock;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int32_t blockIndex;
|
||||||
|
int32_t pos;
|
||||||
|
} position;
|
||||||
|
|
||||||
|
SArray* pData; // SArray<void*>
|
||||||
|
} SResultRowPool;
|
||||||
|
|
||||||
|
struct SQueryAttr;
|
||||||
|
struct SQueryRuntimeEnv;
|
||||||
|
struct SUdfInfo;
|
||||||
|
|
||||||
|
int32_t getOutputInterResultBufSize(struct SQueryAttr* pQueryAttr);
|
||||||
|
|
||||||
|
size_t getResultRowSize(struct SQueryRuntimeEnv* pRuntimeEnv);
|
||||||
int32_t initResultRowInfo(SResultRowInfo* pResultRowInfo, int32_t size, int16_t type);
|
int32_t initResultRowInfo(SResultRowInfo* pResultRowInfo, int32_t size, int16_t type);
|
||||||
void cleanupResultRowInfo(SResultRowInfo* pResultRowInfo);
|
void cleanupResultRowInfo(SResultRowInfo* pResultRowInfo);
|
||||||
|
|
||||||
void resetResultRowInfo(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo);
|
void resetResultRowInfo(struct SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo);
|
||||||
int32_t numOfClosedResultRows(SResultRowInfo* pResultRowInfo);
|
int32_t numOfClosedResultRows(SResultRowInfo* pResultRowInfo);
|
||||||
void closeAllResultRows(SResultRowInfo* pResultRowInfo);
|
void closeAllResultRows(SResultRowInfo* pResultRowInfo);
|
||||||
|
|
||||||
int32_t initResultRow(SResultRow *pResultRow);
|
int32_t initResultRow(SResultRow *pResultRow);
|
||||||
void closeResultRow(SResultRowInfo* pResultRowInfo, int32_t slot);
|
void closeResultRow(SResultRowInfo* pResultRowInfo, int32_t slot);
|
||||||
bool isResultRowClosed(SResultRowInfo *pResultRowInfo, int32_t slot);
|
bool isResultRowClosed(SResultRowInfo *pResultRowInfo, int32_t slot);
|
||||||
void clearResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResultRow, int16_t type);
|
void clearResultRow(struct SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResultRow, int16_t type);
|
||||||
|
|
||||||
SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset);
|
struct SResultRowEntryInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset);
|
||||||
|
|
||||||
void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr);
|
void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr);
|
||||||
void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols);
|
void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols);
|
||||||
int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable);
|
int32_t getRowNumForMultioutput(struct SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable);
|
||||||
|
|
||||||
static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) {
|
static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) {
|
||||||
assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size);
|
assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size);
|
||||||
return pResultRowInfo->pResult[slot];
|
return pResultRowInfo->pResult[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE char* getPosInResultPage(SQueryAttr* pQueryAttr, tFilePage* page, int32_t rowOffset,
|
static FORCE_INLINE char* getPosInResultPage(struct SQueryAttr* pQueryAttr, SFilePage* page, int32_t rowOffset,
|
||||||
int32_t offset) {
|
int32_t offset) {
|
||||||
assert(rowOffset >= 0 && pQueryAttr != NULL);
|
assert(rowOffset >= 0 && pQueryAttr != NULL);
|
||||||
|
|
||||||
int32_t numOfRows = (int32_t)getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery);
|
// int32_t numOfRows = (int32_t)getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery);
|
||||||
return ((char *)page->data) + rowOffset + offset * numOfRows;
|
// return ((char *)page->data) + rowOffset + offset * numOfRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
|
//bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
|
||||||
bool notNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
|
//bool notNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
|
||||||
|
|
||||||
__filter_func_t getFilterOperator(int32_t lowerOptr, int32_t upperOptr);
|
__filter_func_t getFilterOperator(int32_t lowerOptr, int32_t upperOptr);
|
||||||
|
|
||||||
|
@ -103,8 +155,8 @@ bool hasRemainData(SGroupResInfo* pGroupResInfo);
|
||||||
bool incNextGroup(SGroupResInfo* pGroupResInfo);
|
bool incNextGroup(SGroupResInfo* pGroupResInfo);
|
||||||
int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo);
|
int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo);
|
||||||
|
|
||||||
int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv *pRuntimeEnv, int32_t* offset);
|
int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, struct SQueryRuntimeEnv *pRuntimeEnv, int32_t* offset);
|
||||||
|
|
||||||
int32_t initUdfInfo(SUdfInfo* pUdfInfo);
|
int32_t initUdfInfo(struct SUdfInfo* pUdfInfo);
|
||||||
|
|
||||||
#endif // TDENGINE_QUERYUTIL_H
|
#endif // TDENGINE_QUERYUTIL_H
|
|
@ -0,0 +1,645 @@
|
||||||
|
/*
|
||||||
|
* 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_EXECUTORIMPL_H
|
||||||
|
#define TDENGINE_EXECUTORIMPL_H
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "ttszip.h"
|
||||||
|
#include "tvariant.h"
|
||||||
|
|
||||||
|
#include "thash.h"
|
||||||
|
//#include "parser.h"
|
||||||
|
#include "executil.h"
|
||||||
|
#include "taosdef.h"
|
||||||
|
#include "tarray.h"
|
||||||
|
#include "tfilter.h"
|
||||||
|
#include "tlockfree.h"
|
||||||
|
#include "tpagedfile.h"
|
||||||
|
|
||||||
|
struct SColumnFilterElem;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t numOfTables;
|
||||||
|
SArray *pGroupList;
|
||||||
|
SHashObj *map; // speedup acquire the tableQueryInfo by table uid
|
||||||
|
} STableGroupInfo;
|
||||||
|
|
||||||
|
typedef int32_t (*__block_search_fn_t)(char* data, int32_t num, int64_t key, int32_t order);
|
||||||
|
|
||||||
|
#define IS_QUERY_KILLED(_q) ((_q)->code == TSDB_CODE_TSC_QUERY_CANCELLED)
|
||||||
|
#define Q_STATUS_EQUAL(p, s) (((p) & (s)) != 0u)
|
||||||
|
#define QUERY_IS_ASC_QUERY(q) (GET_FORWARD_DIRECTION_FACTOR((q)->order.order) == QUERY_ASC_FORWARD_STEP)
|
||||||
|
|
||||||
|
#define GET_TABLEGROUP(q, _index) ((SArray*) taosArrayGetP((q)->tableqinfoGroupInfo.pGroupList, (_index)))
|
||||||
|
|
||||||
|
#define GET_NUM_OF_RESULTS(_r) (((_r)->outputBuf) == NULL? 0:((_r)->outputBuf)->info.rows)
|
||||||
|
|
||||||
|
#define NEEDTO_COMPRESS_QUERY(size) ((size) > tsCompressColData? 1 : 0)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// when query starts to execute, this status will set
|
||||||
|
QUERY_NOT_COMPLETED = 0x1u,
|
||||||
|
|
||||||
|
/* query is over
|
||||||
|
* 1. this status is used in one row result query process, e.g., count/sum/first/last/ avg...etc.
|
||||||
|
* 2. when all data within queried time window, it is also denoted as query_completed
|
||||||
|
*/
|
||||||
|
QUERY_COMPLETED = 0x2u,
|
||||||
|
|
||||||
|
/* when the result is not completed return to client, this status will be
|
||||||
|
* usually used in case of interval query with interpolation option
|
||||||
|
*/
|
||||||
|
QUERY_OVER = 0x4u,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct SResultRowCell {
|
||||||
|
uint64_t groupId;
|
||||||
|
SResultRow *pRow;
|
||||||
|
} SResultRowCell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the number of generated results is greater than this value,
|
||||||
|
* query query will be halt and return results to client immediate.
|
||||||
|
*/
|
||||||
|
typedef struct SRspResultInfo {
|
||||||
|
int64_t total; // total generated result size in rows
|
||||||
|
int32_t capacity; // capacity of current result output buffer
|
||||||
|
int32_t threshold; // result size threshold in rows.
|
||||||
|
} SRspResultInfo;
|
||||||
|
|
||||||
|
typedef struct SColumnFilterElem {
|
||||||
|
int16_t bytes; // column length
|
||||||
|
__filter_func_t fp;
|
||||||
|
SColumnFilterInfo filterInfo;
|
||||||
|
void *q;
|
||||||
|
} SColumnFilterElem;
|
||||||
|
|
||||||
|
typedef struct SSingleColumnFilterInfo {
|
||||||
|
void* pData;
|
||||||
|
void* pData2; //used for nchar column
|
||||||
|
int32_t numOfFilters;
|
||||||
|
SColumnInfo info;
|
||||||
|
SColumnFilterElem* pFilters;
|
||||||
|
} SSingleColumnFilterInfo;
|
||||||
|
|
||||||
|
typedef struct STableQueryInfo {
|
||||||
|
TSKEY lastKey;
|
||||||
|
int32_t groupIndex; // group id in table list
|
||||||
|
SVariant tag;
|
||||||
|
STimeWindow win;
|
||||||
|
STSCursor cur;
|
||||||
|
void* pTable; // for retrieve the page id list
|
||||||
|
SResultRowInfo resInfo;
|
||||||
|
} STableQueryInfo;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
QUERY_PROF_BEFORE_OPERATOR_EXEC = 0,
|
||||||
|
QUERY_PROF_AFTER_OPERATOR_EXEC,
|
||||||
|
QUERY_PROF_QUERY_ABORT
|
||||||
|
} EQueryProfEventType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EQueryProfEventType eventType;
|
||||||
|
int64_t eventTime;
|
||||||
|
|
||||||
|
union {
|
||||||
|
uint8_t operatorType; //for operator event
|
||||||
|
int32_t abortCode; //for query abort event
|
||||||
|
};
|
||||||
|
} SQueryProfEvent;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t operatorType;
|
||||||
|
int64_t sumSelfTime;
|
||||||
|
int64_t sumRunTimes;
|
||||||
|
} SOperatorProfResult;
|
||||||
|
|
||||||
|
typedef struct SQueryCostInfo {
|
||||||
|
uint64_t loadStatisTime;
|
||||||
|
uint64_t loadFileBlockTime;
|
||||||
|
uint64_t loadDataInCacheTime;
|
||||||
|
uint64_t loadStatisSize;
|
||||||
|
uint64_t loadFileBlockSize;
|
||||||
|
uint64_t loadDataInCacheSize;
|
||||||
|
|
||||||
|
uint64_t loadDataTime;
|
||||||
|
uint64_t totalRows;
|
||||||
|
uint64_t totalCheckedRows;
|
||||||
|
uint32_t totalBlocks;
|
||||||
|
uint32_t loadBlocks;
|
||||||
|
uint32_t loadBlockStatis;
|
||||||
|
uint32_t discardBlocks;
|
||||||
|
uint64_t elapsedTime;
|
||||||
|
uint64_t firstStageMergeTime;
|
||||||
|
uint64_t winInfoSize;
|
||||||
|
uint64_t tableInfoSize;
|
||||||
|
uint64_t hashSize;
|
||||||
|
uint64_t numOfTimeWindows;
|
||||||
|
|
||||||
|
SArray* queryProfEvents; //SArray<SQueryProfEvent>
|
||||||
|
SHashObj* operatorProfResults; //map<operator_type, SQueryProfEvent>
|
||||||
|
} SQueryCostInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int64_t vgroupLimit;
|
||||||
|
int64_t ts;
|
||||||
|
} SOrderedPrjQueryInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* tags;
|
||||||
|
SArray* pResult; // SArray<SStddevInterResult>
|
||||||
|
} SInterResult;
|
||||||
|
|
||||||
|
// The basic query information extracted from the SQueryInfo tree to support the
|
||||||
|
// execution of query in a data node.
|
||||||
|
typedef struct SQueryAttr {
|
||||||
|
SLimit limit;
|
||||||
|
SLimit slimit;
|
||||||
|
|
||||||
|
// todo comment it
|
||||||
|
bool stableQuery; // super table query or not
|
||||||
|
bool topBotQuery; // TODO used bitwise flag
|
||||||
|
bool groupbyColumn; // denote if this is a groupby normal column query
|
||||||
|
bool hasTagResults; // if there are tag values in final result or not
|
||||||
|
bool timeWindowInterpo;// if the time window start/end required interpolation
|
||||||
|
bool queryBlockDist; // if query data block distribution
|
||||||
|
bool stabledev; // super table stddev query
|
||||||
|
bool tsCompQuery; // is tscomp query
|
||||||
|
bool diffQuery; // is diff query
|
||||||
|
bool simpleAgg;
|
||||||
|
bool pointInterpQuery; // point interpolation query
|
||||||
|
bool needReverseScan; // need reverse scan
|
||||||
|
bool distinct; // distinct query or not
|
||||||
|
bool stateWindow; // window State on sub/normal table
|
||||||
|
bool createFilterOperator; // if filter operator is needed
|
||||||
|
bool multigroupResult; // multigroup result can exist in one SSDataBlock
|
||||||
|
int32_t interBufSize; // intermediate buffer sizse
|
||||||
|
|
||||||
|
int32_t havingNum; // having expr number
|
||||||
|
|
||||||
|
SOrder order;
|
||||||
|
int16_t numOfCols;
|
||||||
|
int16_t numOfTags;
|
||||||
|
|
||||||
|
STimeWindow window;
|
||||||
|
SInterval interval;
|
||||||
|
SSessionWindow sw;
|
||||||
|
int16_t precision;
|
||||||
|
int16_t numOfOutput;
|
||||||
|
int16_t fillType;
|
||||||
|
|
||||||
|
int32_t srcRowSize; // todo extract struct
|
||||||
|
int32_t resultRowSize;
|
||||||
|
int32_t intermediateResultRowSize; // intermediate result row size, in case of top-k query.
|
||||||
|
int32_t maxTableColumnWidth;
|
||||||
|
int32_t tagLen; // tag value length of current query
|
||||||
|
SGroupbyExpr *pGroupbyExpr;
|
||||||
|
|
||||||
|
SExprInfo* pExpr1;
|
||||||
|
SExprInfo* pExpr2;
|
||||||
|
int32_t numOfExpr2;
|
||||||
|
SExprInfo* pExpr3;
|
||||||
|
int32_t numOfExpr3;
|
||||||
|
|
||||||
|
SColumnInfo* tableCols;
|
||||||
|
SColumnInfo* tagColList;
|
||||||
|
int32_t numOfFilterCols;
|
||||||
|
int64_t* fillVal;
|
||||||
|
SOrderedPrjQueryInfo prjInfo; // limit value for each vgroup, only available in global order projection query.
|
||||||
|
|
||||||
|
SSingleColumnFilterInfo* pFilterInfo;
|
||||||
|
// SFilterInfo *pFilters;
|
||||||
|
|
||||||
|
void* tsdb;
|
||||||
|
// SMemRef memRef;
|
||||||
|
STableGroupInfo tableGroupInfo; // table <tid, last_key> list SArray<STableKeyInfo>
|
||||||
|
int32_t vgId;
|
||||||
|
SArray *pUdfInfo; // no need to free
|
||||||
|
} SQueryAttr;
|
||||||
|
|
||||||
|
typedef SSDataBlock* (*__operator_fn_t)(void* param, bool* newgroup);
|
||||||
|
typedef void (*__optr_cleanup_fn_t)(void* param, int32_t num);
|
||||||
|
|
||||||
|
struct SOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SQueryRuntimeEnv {
|
||||||
|
jmp_buf env;
|
||||||
|
SQueryAttr* pQueryAttr;
|
||||||
|
uint32_t status; // query status
|
||||||
|
void* qinfo;
|
||||||
|
uint8_t scanFlag; // denotes reversed scan of data or not
|
||||||
|
void* pQueryHandle;
|
||||||
|
|
||||||
|
int32_t prevGroupId; // previous executed group id
|
||||||
|
bool enableGroupData;
|
||||||
|
SDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file
|
||||||
|
SHashObj* pResultRowHashTable; // quick locate the window object for each result
|
||||||
|
SHashObj* pResultRowListSet; // used to check if current ResultRowInfo has ResultRow object or not
|
||||||
|
SArray* pResultRowArrayList; // The array list that contains the Result rows
|
||||||
|
char* keyBuf; // window key buffer
|
||||||
|
SResultRowPool* pool; // The window result objects pool, all the resultRow Objects are allocated and managed by this object.
|
||||||
|
char** prevRow;
|
||||||
|
|
||||||
|
SArray* prevResult; // intermediate result, SArray<SInterResult>
|
||||||
|
STSBuf* pTsBuf; // timestamp filter list
|
||||||
|
STSCursor cur;
|
||||||
|
|
||||||
|
char* tagVal; // tag value of current data block
|
||||||
|
struct SScalarFunctionSupport * scalarSup;
|
||||||
|
|
||||||
|
SSDataBlock *outputBuf;
|
||||||
|
STableGroupInfo tableqinfoGroupInfo; // this is a group array list, including SArray<STableQueryInfo*> structure
|
||||||
|
struct SOperatorInfo *proot;
|
||||||
|
SGroupResInfo groupResInfo;
|
||||||
|
int64_t currentOffset; // dynamic offset value
|
||||||
|
|
||||||
|
STableQueryInfo *current;
|
||||||
|
SRspResultInfo resultInfo;
|
||||||
|
SHashObj *pTableRetrieveTsMap;
|
||||||
|
struct SUdfInfo *pUdfInfo;
|
||||||
|
} SQueryRuntimeEnv;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
OP_IN_EXECUTING = 1,
|
||||||
|
OP_RES_TO_RETURN = 2,
|
||||||
|
OP_EXEC_DONE = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OPERATOR_TYPE_E {
|
||||||
|
OP_TableScan = 1,
|
||||||
|
OP_DataBlocksOptScan = 2,
|
||||||
|
OP_TableSeqScan = 3,
|
||||||
|
OP_TagScan = 4,
|
||||||
|
OP_TableBlockInfoScan= 5,
|
||||||
|
OP_Aggregate = 6,
|
||||||
|
OP_Project = 7,
|
||||||
|
OP_Groupby = 8,
|
||||||
|
OP_Limit = 9,
|
||||||
|
OP_SLimit = 10,
|
||||||
|
OP_TimeWindow = 11,
|
||||||
|
OP_SessionWindow = 12,
|
||||||
|
OP_Fill = 13,
|
||||||
|
OP_MultiTableAggregate = 14,
|
||||||
|
OP_MultiTableTimeInterval = 15,
|
||||||
|
OP_DummyInput = 16, //TODO remove it after fully refactor.
|
||||||
|
OP_MultiwayMergeSort = 17, // multi-way data merge into one input stream.
|
||||||
|
OP_GlobalAggregate = 18, // global merge for the multi-way data sources.
|
||||||
|
OP_Filter = 19,
|
||||||
|
OP_Distinct = 20,
|
||||||
|
OP_Join = 21,
|
||||||
|
OP_StateWindow = 22,
|
||||||
|
OP_AllTimeWindow = 23,
|
||||||
|
OP_AllMultiTableTimeInterval = 24,
|
||||||
|
OP_Order = 25,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct SOperatorInfo {
|
||||||
|
uint8_t operatorType;
|
||||||
|
bool blockingOptr; // block operator or not
|
||||||
|
uint8_t status; // denote if current operator is completed
|
||||||
|
int32_t numOfOutput; // number of columns of the current operator results
|
||||||
|
char *name; // name, used to show the query execution plan
|
||||||
|
void *info; // extension attribution
|
||||||
|
SExprInfo *pExpr;
|
||||||
|
SQueryRuntimeEnv *pRuntimeEnv;
|
||||||
|
|
||||||
|
struct SOperatorInfo **upstream; // upstream pointer list
|
||||||
|
int32_t numOfUpstream; // number of upstream. The value is always ONE expect for join operator
|
||||||
|
__operator_fn_t exec;
|
||||||
|
__optr_cleanup_fn_t cleanup;
|
||||||
|
} SOperatorInfo;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
QUERY_RESULT_NOT_READY = 1,
|
||||||
|
QUERY_RESULT_READY = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t numOfTags;
|
||||||
|
int32_t numOfCols;
|
||||||
|
SColumnInfo *colList;
|
||||||
|
} SQueriedTableInfo;
|
||||||
|
|
||||||
|
typedef struct SQInfo {
|
||||||
|
void* signature;
|
||||||
|
uint64_t qId;
|
||||||
|
int32_t code; // error code to returned to client
|
||||||
|
int64_t owner; // if it is in execution
|
||||||
|
|
||||||
|
SQueryRuntimeEnv runtimeEnv;
|
||||||
|
SQueryAttr query;
|
||||||
|
void* pBuf; // allocated buffer for STableQueryInfo, sizeof(STableQueryInfo)*numOfTables;
|
||||||
|
|
||||||
|
pthread_mutex_t lock; // used to synchronize the rsp/query threads
|
||||||
|
tsem_t ready;
|
||||||
|
int32_t dataReady; // denote if query result is ready or not
|
||||||
|
void* rspContext; // response context
|
||||||
|
int64_t startExecTs; // start to exec timestamp
|
||||||
|
char* sql; // query sql string
|
||||||
|
SQueryCostInfo summary;
|
||||||
|
} SQInfo;
|
||||||
|
|
||||||
|
typedef struct SQueryParam {
|
||||||
|
char *sql;
|
||||||
|
char *tagCond;
|
||||||
|
char *colCond;
|
||||||
|
char *tbnameCond;
|
||||||
|
char *prevResult;
|
||||||
|
SArray *pTableIdList;
|
||||||
|
SSqlExpr **pExpr;
|
||||||
|
SSqlExpr **pSecExpr;
|
||||||
|
SExprInfo *pExprs;
|
||||||
|
SExprInfo *pSecExprs;
|
||||||
|
|
||||||
|
SFilterInfo *pFilters;
|
||||||
|
|
||||||
|
SColIndex *pGroupColIndex;
|
||||||
|
SColumnInfo *pTagColumnInfo;
|
||||||
|
SGroupbyExpr *pGroupbyExpr;
|
||||||
|
int32_t tableScanOperator;
|
||||||
|
SArray *pOperator;
|
||||||
|
struct SUdfInfo *pUdfInfo;
|
||||||
|
} SQueryParam;
|
||||||
|
|
||||||
|
typedef struct STableScanInfo {
|
||||||
|
void *pQueryHandle;
|
||||||
|
int32_t numOfBlocks;
|
||||||
|
int32_t numOfSkipped;
|
||||||
|
int32_t numOfBlockStatis;
|
||||||
|
int64_t numOfRows;
|
||||||
|
|
||||||
|
int32_t order; // scan order
|
||||||
|
int32_t times; // repeat counts
|
||||||
|
int32_t current;
|
||||||
|
int32_t reverseTimes; // 0 by default
|
||||||
|
|
||||||
|
SQLFunctionCtx *pCtx; // next operator query context
|
||||||
|
SResultRowInfo *pResultRowInfo;
|
||||||
|
int32_t *rowCellInfoOffset;
|
||||||
|
SExprInfo *pExpr;
|
||||||
|
SSDataBlock block;
|
||||||
|
int32_t numOfOutput;
|
||||||
|
int64_t elapsedTime;
|
||||||
|
|
||||||
|
int32_t tableIndex;
|
||||||
|
int32_t prevGroupId; // previous table group id
|
||||||
|
} STableScanInfo;
|
||||||
|
|
||||||
|
typedef struct STagScanInfo {
|
||||||
|
SColumnInfo* pCols;
|
||||||
|
SSDataBlock* pRes;
|
||||||
|
int32_t totalTables;
|
||||||
|
int32_t curPos;
|
||||||
|
} STagScanInfo;
|
||||||
|
|
||||||
|
typedef struct SOptrBasicInfo {
|
||||||
|
SResultRowInfo resultRowInfo;
|
||||||
|
int32_t *rowCellInfoOffset; // offset value for each row result cell info
|
||||||
|
SQLFunctionCtx *pCtx;
|
||||||
|
SSDataBlock *pRes;
|
||||||
|
} SOptrBasicInfo;
|
||||||
|
|
||||||
|
typedef struct SOptrBasicInfo STableIntervalOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SAggOperatorInfo {
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
|
uint32_t seed;
|
||||||
|
} SAggOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SProjectOperatorInfo {
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
|
int32_t bufCapacity;
|
||||||
|
uint32_t seed;
|
||||||
|
|
||||||
|
SSDataBlock *existDataBlock;
|
||||||
|
} SProjectOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SLimitOperatorInfo {
|
||||||
|
int64_t limit;
|
||||||
|
int64_t total;
|
||||||
|
} SLimitOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SSLimitOperatorInfo {
|
||||||
|
int64_t groupTotal;
|
||||||
|
int64_t currentGroupOffset;
|
||||||
|
|
||||||
|
int64_t rowsTotal;
|
||||||
|
int64_t currentOffset;
|
||||||
|
SLimit limit;
|
||||||
|
SLimit slimit;
|
||||||
|
|
||||||
|
char **prevRow;
|
||||||
|
SArray *orderColumnList;
|
||||||
|
bool hasPrev;
|
||||||
|
bool ignoreCurrentGroup;
|
||||||
|
bool multigroupResult;
|
||||||
|
SSDataBlock *pRes; // result buffer
|
||||||
|
SSDataBlock *pPrevBlock;
|
||||||
|
int64_t capacity;
|
||||||
|
int64_t threshold;
|
||||||
|
} SSLimitOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SFilterOperatorInfo {
|
||||||
|
SSingleColumnFilterInfo *pFilterInfo;
|
||||||
|
int32_t numOfFilterCols;
|
||||||
|
} SFilterOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SFillOperatorInfo {
|
||||||
|
struct SFillInfo *pFillInfo;
|
||||||
|
SSDataBlock *pRes;
|
||||||
|
int64_t totalInputRows;
|
||||||
|
void **p;
|
||||||
|
SSDataBlock *existNewGroupBlock;
|
||||||
|
bool multigroupResult;
|
||||||
|
} SFillOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SGroupbyOperatorInfo {
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
|
int32_t colIndex;
|
||||||
|
char *prevData; // previous group by value
|
||||||
|
} SGroupbyOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SSWindowOperatorInfo {
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
|
STimeWindow curWindow; // current time window
|
||||||
|
TSKEY prevTs; // previous timestamp
|
||||||
|
int32_t numOfRows; // number of rows
|
||||||
|
int32_t start; // start row index
|
||||||
|
bool reptScan; // next round scan
|
||||||
|
} SSWindowOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SStateWindowOperatorInfo {
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
|
STimeWindow curWindow; // current time window
|
||||||
|
int32_t numOfRows; // number of rows
|
||||||
|
int32_t colIndex; // start row index
|
||||||
|
int32_t start;
|
||||||
|
char* prevData; // previous data
|
||||||
|
bool reptScan;
|
||||||
|
} SStateWindowOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SDistinctDataInfo {
|
||||||
|
int32_t index;
|
||||||
|
int32_t type;
|
||||||
|
int32_t bytes;
|
||||||
|
} SDistinctDataInfo;
|
||||||
|
|
||||||
|
typedef struct SDistinctOperatorInfo {
|
||||||
|
SHashObj *pSet;
|
||||||
|
SSDataBlock *pRes;
|
||||||
|
bool recordNullVal; //has already record the null value, no need to try again
|
||||||
|
int64_t threshold;
|
||||||
|
int64_t outputCapacity;
|
||||||
|
int32_t totalBytes;
|
||||||
|
char* buf;
|
||||||
|
SArray* pDistinctDataInfo;
|
||||||
|
} SDistinctOperatorInfo;
|
||||||
|
|
||||||
|
struct SGlobalMerger;
|
||||||
|
|
||||||
|
typedef struct SMultiwayMergeInfo {
|
||||||
|
struct SGlobalMerger *pMerge;
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
|
int32_t bufCapacity;
|
||||||
|
int64_t seed;
|
||||||
|
char **prevRow;
|
||||||
|
SArray *orderColumnList;
|
||||||
|
int32_t resultRowFactor;
|
||||||
|
|
||||||
|
bool hasGroupColData;
|
||||||
|
char **currentGroupColData;
|
||||||
|
SArray *groupColumnList;
|
||||||
|
bool hasDataBlockForNewGroup;
|
||||||
|
SSDataBlock *pExistBlock;
|
||||||
|
|
||||||
|
SArray *udfInfo;
|
||||||
|
bool hasPrev;
|
||||||
|
bool multiGroupResults;
|
||||||
|
} SMultiwayMergeInfo;
|
||||||
|
|
||||||
|
// todo support the disk-based sort
|
||||||
|
typedef struct SOrderOperatorInfo {
|
||||||
|
int32_t colIndex;
|
||||||
|
int32_t order;
|
||||||
|
SSDataBlock *pDataBlock;
|
||||||
|
} SOrderOperatorInfo;
|
||||||
|
|
||||||
|
void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream);
|
||||||
|
|
||||||
|
SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime);
|
||||||
|
SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime);
|
||||||
|
SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||||
|
|
||||||
|
SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createProjectOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream);
|
||||||
|
SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createAllTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, bool multigroupResult);
|
||||||
|
SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||||
|
SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput,
|
||||||
|
int32_t numOfRows, void* merger);
|
||||||
|
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param, SArray* pUdfInfo, bool groupResultMixedUp);
|
||||||
|
SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger, bool multigroupResult);
|
||||||
|
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
||||||
|
int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter);
|
||||||
|
|
||||||
|
SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUpstream, SSchema* pSchema, int32_t numOfOutput);
|
||||||
|
SOperatorInfo* createOrderOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, SOrder* pOrderVal);
|
||||||
|
|
||||||
|
SSDataBlock* doGlobalAggregate(void* param, bool* newgroup);
|
||||||
|
SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup);
|
||||||
|
SSDataBlock* doSLimit(void* param, bool* newgroup);
|
||||||
|
|
||||||
|
int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo, uint64_t qId);
|
||||||
|
void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock);
|
||||||
|
bool doFilterDataBlock(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, int32_t numOfRows, int8_t* p);
|
||||||
|
void doCompactSDataBlock(SSDataBlock* pBlock, int32_t numOfRows, int8_t* p);
|
||||||
|
|
||||||
|
SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows);
|
||||||
|
|
||||||
|
void* destroyOutputBuf(SSDataBlock* pBlock);
|
||||||
|
void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols);
|
||||||
|
|
||||||
|
void setInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order);
|
||||||
|
void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset);
|
||||||
|
void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOfInputRows);
|
||||||
|
void clearOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity);
|
||||||
|
void copyTsColoum(SSDataBlock* pRes, SQLFunctionCtx* pCtx, int32_t numOfOutput);
|
||||||
|
|
||||||
|
void freeParam(SQueryParam *param);
|
||||||
|
int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param);
|
||||||
|
int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo,
|
||||||
|
SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg, struct SUdfInfo* pUdfInfo);
|
||||||
|
|
||||||
|
int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo,
|
||||||
|
SSqlExpr **pExpr, SExprInfo *prevExpr, struct SUdfInfo *pUdfInfo);
|
||||||
|
|
||||||
|
int32_t createQueryFilter(char *data, uint16_t len, SFilterInfo** pFilters);
|
||||||
|
|
||||||
|
SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code);
|
||||||
|
SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
||||||
|
SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, SFilterInfo* pFilters, int32_t vgId, char* sql, uint64_t qId, struct SUdfInfo* pUdfInfo);
|
||||||
|
|
||||||
|
int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start,
|
||||||
|
int32_t prevResultLen, void* merger);
|
||||||
|
|
||||||
|
int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId);
|
||||||
|
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters);
|
||||||
|
|
||||||
|
STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf);
|
||||||
|
STableQueryInfo* createTmpTableQueryInfo(STimeWindow win);
|
||||||
|
|
||||||
|
int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, void *pQueryMsg);
|
||||||
|
|
||||||
|
bool isQueryKilled(SQInfo *pQInfo);
|
||||||
|
int32_t checkForQueryBuf(size_t numOfTables);
|
||||||
|
bool checkNeedToCompressQueryCol(SQInfo *pQInfo);
|
||||||
|
bool doBuildResCheck(SQInfo* pQInfo);
|
||||||
|
void setQueryStatus(SQueryRuntimeEnv *pRuntimeEnv, int8_t status);
|
||||||
|
|
||||||
|
bool onlyQueryTags(SQueryAttr* pQueryAttr);
|
||||||
|
void destroyUdfInfo(struct SUdfInfo* pUdfInfo);
|
||||||
|
|
||||||
|
bool isValidQInfo(void *param);
|
||||||
|
|
||||||
|
int32_t doDumpQueryResult(SQInfo *pQInfo, char *data, int8_t compressed, int32_t *compLen);
|
||||||
|
|
||||||
|
size_t getResultSize(SQInfo *pQInfo, int64_t *numOfRows);
|
||||||
|
void setQueryKilled(SQInfo *pQInfo);
|
||||||
|
|
||||||
|
void publishOperatorProfEvent(SOperatorInfo* operatorInfo, EQueryProfEventType eventType);
|
||||||
|
void publishQueryAbortEvent(SQInfo* pQInfo, int32_t code);
|
||||||
|
void calculateOperatorProfResults(SQInfo* pQInfo);
|
||||||
|
void queryCostStatis(SQInfo *pQInfo);
|
||||||
|
|
||||||
|
void freeQInfo(SQInfo *pQInfo);
|
||||||
|
void freeQueryAttr(SQueryAttr *pQuery);
|
||||||
|
|
||||||
|
int32_t getMaximumIdleDurationSec();
|
||||||
|
|
||||||
|
void doInvokeUdf(struct SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t type);
|
||||||
|
|
||||||
|
#endif // TDENGINE_EXECUTORIMPL_H
|
|
@ -20,9 +20,9 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "texpr.h"
|
#include "thash.h"
|
||||||
#include "hash.h"
|
|
||||||
#include "tname.h"
|
#include "tname.h"
|
||||||
|
#include "function.h"
|
||||||
|
|
||||||
#define FILTER_DEFAULT_GROUP_SIZE 4
|
#define FILTER_DEFAULT_GROUP_SIZE 4
|
||||||
#define FILTER_DEFAULT_UNIT_SIZE 4
|
#define FILTER_DEFAULT_UNIT_SIZE 4
|
||||||
|
@ -105,7 +105,7 @@ typedef struct SFilterColRange {
|
||||||
|
|
||||||
typedef bool (*rangeCompFunc) (const void *, const void *, const void *, const void *, __compar_fn_t);
|
typedef bool (*rangeCompFunc) (const void *, const void *, const void *, const void *, __compar_fn_t);
|
||||||
typedef int32_t(*filter_desc_compare_func)(const void *, const void *);
|
typedef int32_t(*filter_desc_compare_func)(const void *, const void *);
|
||||||
typedef bool(*filter_exec_func)(void *, int32_t, int8_t**, SDataStatis *, int16_t);
|
typedef bool(*filter_exec_func)(void *, int32_t, int8_t**, SColumnDataAgg *, int16_t);
|
||||||
|
|
||||||
typedef struct SFilterRangeCompare {
|
typedef struct SFilterRangeCompare {
|
||||||
int64_t s;
|
int64_t s;
|
||||||
|
@ -324,13 +324,13 @@ typedef struct SFilterInfo {
|
||||||
|
|
||||||
|
|
||||||
extern int32_t filterInitFromTree(tExprNode* tree, SFilterInfo **pinfo, uint32_t options);
|
extern int32_t filterInitFromTree(tExprNode* tree, SFilterInfo **pinfo, uint32_t options);
|
||||||
extern bool filterExecute(SFilterInfo *info, int32_t numOfRows, int8_t** p, SDataStatis *statis, int16_t numOfCols);
|
extern bool filterExecute(SFilterInfo *info, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols);
|
||||||
extern int32_t filterSetColFieldData(SFilterInfo *info, int32_t numOfCols, SArray* pDataBlock);
|
extern int32_t filterSetColFieldData(SFilterInfo *info, int32_t numOfCols, SArray* pDataBlock);
|
||||||
extern int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win);
|
extern int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win);
|
||||||
extern int32_t filterConverNcharColumns(SFilterInfo* pFilterInfo, int32_t rows, bool *gotNchar);
|
extern int32_t filterConverNcharColumns(SFilterInfo* pFilterInfo, int32_t rows, bool *gotNchar);
|
||||||
extern int32_t filterFreeNcharColumns(SFilterInfo* pFilterInfo);
|
extern int32_t filterFreeNcharColumns(SFilterInfo* pFilterInfo);
|
||||||
extern void filterFreeInfo(SFilterInfo *info);
|
extern void filterFreeInfo(SFilterInfo *info);
|
||||||
extern bool filterRangeExecute(SFilterInfo *info, SDataStatis *pDataStatis, int32_t numOfCols, int32_t numOfRows);
|
extern bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg *pDataStatis, int32_t numOfCols, int32_t numOfRows);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
|
@ -15,11 +15,11 @@
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
#include "hash.h"
|
#include "thash.h"
|
||||||
|
|
||||||
#include "qExecutor.h"
|
#include "executil.h"
|
||||||
#include "qUtil.h"
|
#include "executorimpl.h"
|
||||||
#include "queryLog.h"
|
//#include "queryLog.h"
|
||||||
#include "tbuffer.h"
|
#include "tbuffer.h"
|
||||||
#include "tcompression.h"
|
#include "tcompression.h"
|
||||||
#include "tlosertree.h"
|
#include "tlosertree.h"
|
||||||
|
@ -33,9 +33,9 @@ typedef struct SCompSupporter {
|
||||||
int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable) {
|
int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable) {
|
||||||
if (pQueryAttr && (!stable)) {
|
if (pQueryAttr && (!stable)) {
|
||||||
for (int16_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
|
for (int16_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
|
||||||
if (pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_TOP || pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_BOTTOM) {
|
// if (pQueryAttr->pExpr1[i].base. == FUNCTION_TOP || pQueryAttr->pExpr1[i].base.functionId == FUNCTION_BOTTOM) {
|
||||||
return (int32_t)pQueryAttr->pExpr1[i].base.param[0].i64;
|
// return (int32_t)pQueryAttr->pExpr1[i].base.param[0].i;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,18 +143,18 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16
|
||||||
|
|
||||||
// the result does not put into the SDiskbasedResultBuf, ignore it.
|
// the result does not put into the SDiskbasedResultBuf, ignore it.
|
||||||
if (pResultRow->pageId >= 0) {
|
if (pResultRow->pageId >= 0) {
|
||||||
tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pResultRow->pageId);
|
SFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pResultRow->pageId);
|
||||||
|
|
||||||
int16_t offset = 0;
|
int16_t offset = 0;
|
||||||
for (int32_t i = 0; i < pRuntimeEnv->pQueryAttr->numOfOutput; ++i) {
|
for (int32_t i = 0; i < pRuntimeEnv->pQueryAttr->numOfOutput; ++i) {
|
||||||
SResultRowCellInfo *pResultInfo = &pResultRow->pCellInfo[i];
|
struct SResultRowEntryInfo *pEntryInfo = NULL;//pResultRow->pEntryInfo[i];
|
||||||
|
|
||||||
int16_t size = pRuntimeEnv->pQueryAttr->pExpr1[i].base.resType;
|
int16_t size = pRuntimeEnv->pQueryAttr->pExpr1[i].base.resSchema.bytes;
|
||||||
char * s = getPosInResultPage(pRuntimeEnv->pQueryAttr, page, pResultRow->offset, offset);
|
char * s = getPosInResultPage(pRuntimeEnv->pQueryAttr, page, pResultRow->offset, offset);
|
||||||
memset(s, 0, size);
|
memset(s, 0, size);
|
||||||
|
|
||||||
offset += size;
|
offset += size;
|
||||||
RESET_RESULT_INFO(pResultInfo);
|
cleanupResultRowEntry(pEntryInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,14 +168,16 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO refactor: use macro
|
// TODO refactor: use macro
|
||||||
SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset) {
|
struct SResultRowEntryInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset) {
|
||||||
assert(index >= 0 && offset != NULL);
|
assert(index >= 0 && offset != NULL);
|
||||||
return (SResultRowCellInfo*)((char*) pRow->pCellInfo + offset[index]);
|
// return (SResultRowEntryInfo*)((char*) pRow->pCellInfo + offset[index]);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv) {
|
size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv) {
|
||||||
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||||
return (pQueryAttr->numOfOutput * sizeof(SResultRowCellInfo)) + pQueryAttr->interBufSize + sizeof(SResultRow);
|
return 0;
|
||||||
|
// return (pQueryAttr->numOfOutput * sizeof(SResultRowEntryInfo)) + pQueryAttr->interBufSize + sizeof(SResultRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
SResultRowPool* initResultRowPool(size_t size) {
|
SResultRowPool* initResultRowPool(size_t size) {
|
||||||
|
@ -271,9 +273,9 @@ void interResToBinary(SBufferWriter* bw, SArray* pRes, int32_t tagLen) {
|
||||||
tbufWriteUint32(bw, numOfRows);
|
tbufWriteUint32(bw, numOfRows);
|
||||||
|
|
||||||
for(int32_t k = 0; k < numOfRows; ++k) {
|
for(int32_t k = 0; k < numOfRows; ++k) {
|
||||||
SResPair v = *(SResPair*) taosArrayGet(p->pResult, k);
|
// SResPair v = *(SResPair*) taosArrayGet(p->pResult, k);
|
||||||
tbufWriteDouble(bw, v.avg);
|
// tbufWriteDouble(bw, v.avg);
|
||||||
tbufWriteInt64(bw, v.key);
|
// tbufWriteInt64(bw, v.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,19 +303,19 @@ SArray* interResFromBinary(const char* data, int32_t len) {
|
||||||
|
|
||||||
SArray* p = taosArrayInit(numOfCols, sizeof(SStddevInterResult));
|
SArray* p = taosArrayInit(numOfCols, sizeof(SStddevInterResult));
|
||||||
for(int32_t j = 0; j < numOfCols; ++j) {
|
for(int32_t j = 0; j < numOfCols; ++j) {
|
||||||
int16_t colId = tbufReadUint16(&br);
|
// int16_t colId = tbufReadUint16(&br);
|
||||||
int32_t numOfRows = tbufReadUint32(&br);
|
int32_t numOfRows = tbufReadUint32(&br);
|
||||||
|
|
||||||
SStddevInterResult interRes = {.colId = colId, .pResult = taosArrayInit(4, sizeof(struct SResPair)),};
|
// SStddevInterResult interRes = {.colId = colId, .pResult = taosArrayInit(4, sizeof(struct SResPair)),};
|
||||||
for(int32_t k = 0; k < numOfRows; ++k) {
|
for(int32_t k = 0; k < numOfRows; ++k) {
|
||||||
SResPair px = {0};
|
// SResPair px = {0};
|
||||||
px.avg = tbufReadDouble(&br);
|
// px.avg = tbufReadDouble(&br);
|
||||||
px.key = tbufReadInt64(&br);
|
// px.key = tbufReadInt64(&br);
|
||||||
|
//
|
||||||
taosArrayPush(interRes.pResult, &px);
|
// taosArrayPush(interRes.pResult, &px);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosArrayPush(p, &interRes);
|
// taosArrayPush(p, &interRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* p1 = NULL;
|
char* p1 = NULL;
|
||||||
|
@ -395,22 +397,22 @@ static int64_t getNumOfResultWindowRes(SQueryRuntimeEnv* pRuntimeEnv, SResultRow
|
||||||
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||||
|
|
||||||
for (int32_t j = 0; j < pQueryAttr->numOfOutput; ++j) {
|
for (int32_t j = 0; j < pQueryAttr->numOfOutput; ++j) {
|
||||||
int32_t functionId = pQueryAttr->pExpr1[j].base.functionId;
|
int32_t functionId = 0;//pQueryAttr->pExpr1[j].base.functionId;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ts, tag, tagprj function can not decide the output number of current query
|
* ts, tag, tagprj function can not decide the output number of current query
|
||||||
* the number of output result is decided by main output
|
* the number of output result is decided by main output
|
||||||
*/
|
*/
|
||||||
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAGPRJ) {
|
if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG || functionId == FUNCTION_TAGPRJ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SResultRowCellInfo *pResultInfo = getResultCell(pResultRow, j, rowCellInfoOffset);
|
// SResultRowEntryInfo *pResultInfo = getResultCell(pResultRow, j, rowCellInfoOffset);
|
||||||
assert(pResultInfo != NULL);
|
// assert(pResultInfo != NULL);
|
||||||
|
//
|
||||||
if (pResultInfo->numOfRes > 0) {
|
// if (pResultInfo->numOfRes > 0) {
|
||||||
return pResultInfo->numOfRes;
|
// return pResultInfo->numOfRes;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -545,7 +547,7 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEn
|
||||||
pTableQueryInfoList = malloc(POINTER_BYTES * size);
|
pTableQueryInfoList = malloc(POINTER_BYTES * size);
|
||||||
|
|
||||||
if (pTableQueryInfoList == NULL || posList == NULL || pGroupResInfo->pRows == NULL || pGroupResInfo->pRows == NULL) {
|
if (pTableQueryInfoList == NULL || posList == NULL || pGroupResInfo->pRows == NULL || pGroupResInfo->pRows == NULL) {
|
||||||
qError("QInfo:%"PRIu64" failed alloc memory", GET_QID(pRuntimeEnv));
|
// qError("QInfo:%"PRIu64" failed alloc memory", GET_QID(pRuntimeEnv));
|
||||||
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
|
@ -617,8 +619,8 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEn
|
||||||
|
|
||||||
int64_t endt = taosGetTimestampMs();
|
int64_t endt = taosGetTimestampMs();
|
||||||
|
|
||||||
qDebug("QInfo:%"PRIx64" result merge completed for group:%d, elapsed time:%" PRId64 " ms", GET_QID(pRuntimeEnv),
|
// qDebug("QInfo:%"PRIx64" result merge completed for group:%d, elapsed time:%" PRId64 " ms", GET_QID(pRuntimeEnv),
|
||||||
pGroupResInfo->currentGroup, endt - startt);
|
// pGroupResInfo->currentGroup, endt - startt);
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
tfree(pTableQueryInfoList);
|
tfree(pTableQueryInfoList);
|
||||||
|
@ -639,90 +641,90 @@ int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv* pRu
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("QInfo:%"PRIu64" no result in group %d, continue", GET_QID(pRuntimeEnv), pGroupResInfo->currentGroup);
|
// qDebug("QInfo:%"PRIu64" no result in group %d, continue", GET_QID(pRuntimeEnv), pGroupResInfo->currentGroup);
|
||||||
cleanupGroupResInfo(pGroupResInfo);
|
cleanupGroupResInfo(pGroupResInfo);
|
||||||
incNextGroup(pGroupResInfo);
|
incNextGroup(pGroupResInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t elapsedTime = taosGetTimestampUs() - st;
|
// int64_t elapsedTime = taosGetTimestampUs() - st;
|
||||||
qDebug("QInfo:%"PRIu64" merge res data into group, index:%d, total group:%d, elapsed time:%" PRId64 "us", GET_QID(pRuntimeEnv),
|
// qDebug("QInfo:%"PRIu64" merge res data into group, index:%d, total group:%d, elapsed time:%" PRId64 "us", GET_QID(pRuntimeEnv),
|
||||||
pGroupResInfo->currentGroup, pGroupResInfo->totalGroup, elapsedTime);
|
// pGroupResInfo->currentGroup, pGroupResInfo->totalGroup, elapsedTime);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void blockDistInfoToBinary(STableBlockDist* pDist, struct SBufferWriter* bw) {
|
//void blockDistInfoToBinary(STableBlockDist* pDist, struct SBufferWriter* bw) {
|
||||||
tbufWriteUint32(bw, pDist->numOfTables);
|
// tbufWriteUint32(bw, pDist->numOfTables);
|
||||||
tbufWriteUint16(bw, pDist->numOfFiles);
|
// tbufWriteUint16(bw, pDist->numOfFiles);
|
||||||
tbufWriteUint64(bw, pDist->totalSize);
|
// tbufWriteUint64(bw, pDist->totalSize);
|
||||||
tbufWriteUint64(bw, pDist->totalRows);
|
// tbufWriteUint64(bw, pDist->totalRows);
|
||||||
tbufWriteInt32(bw, pDist->maxRows);
|
// tbufWriteInt32(bw, pDist->maxRows);
|
||||||
tbufWriteInt32(bw, pDist->minRows);
|
// tbufWriteInt32(bw, pDist->minRows);
|
||||||
tbufWriteUint32(bw, pDist->numOfRowsInMemTable);
|
// tbufWriteUint32(bw, pDist->numOfRowsInMemTable);
|
||||||
tbufWriteUint32(bw, pDist->numOfSmallBlocks);
|
// tbufWriteUint32(bw, pDist->numOfSmallBlocks);
|
||||||
tbufWriteUint64(bw, taosArrayGetSize(pDist->dataBlockInfos));
|
// tbufWriteUint64(bw, taosArrayGetSize(pDist->dataBlockInfos));
|
||||||
|
//
|
||||||
|
// // compress the binary string
|
||||||
|
// char* p = TARRAY_GET_START(pDist->dataBlockInfos);
|
||||||
|
//
|
||||||
|
// // compress extra bytes
|
||||||
|
// size_t x = taosArrayGetSize(pDist->dataBlockInfos) * pDist->dataBlockInfos->elemSize;
|
||||||
|
// char* tmp = malloc(x + 2);
|
||||||
|
//
|
||||||
|
// bool comp = false;
|
||||||
|
// int32_t len = tsCompressString(p, (int32_t)x, 1, tmp, (int32_t)x, ONE_STAGE_COMP, NULL, 0);
|
||||||
|
// if (len == -1 || len >= x) { // compress failed, do not compress this binary data
|
||||||
|
// comp = false;
|
||||||
|
// len = (int32_t)x;
|
||||||
|
// } else {
|
||||||
|
// comp = true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// tbufWriteUint8(bw, comp);
|
||||||
|
// tbufWriteUint32(bw, len);
|
||||||
|
// if (comp) {
|
||||||
|
// tbufWriteBinary(bw, tmp, len);
|
||||||
|
// } else {
|
||||||
|
// tbufWriteBinary(bw, p, len);
|
||||||
|
// }
|
||||||
|
// tfree(tmp);
|
||||||
|
//}
|
||||||
|
|
||||||
// compress the binary string
|
//void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDist) {
|
||||||
char* p = TARRAY_GET_START(pDist->dataBlockInfos);
|
// SBufferReader br = tbufInitReader(data, len, false);
|
||||||
|
//
|
||||||
// compress extra bytes
|
// pDist->numOfTables = tbufReadUint32(&br);
|
||||||
size_t x = taosArrayGetSize(pDist->dataBlockInfos) * pDist->dataBlockInfos->elemSize;
|
// pDist->numOfFiles = tbufReadUint16(&br);
|
||||||
char* tmp = malloc(x + 2);
|
// pDist->totalSize = tbufReadUint64(&br);
|
||||||
|
// pDist->totalRows = tbufReadUint64(&br);
|
||||||
bool comp = false;
|
// pDist->maxRows = tbufReadInt32(&br);
|
||||||
int32_t len = tsCompressString(p, (int32_t)x, 1, tmp, (int32_t)x, ONE_STAGE_COMP, NULL, 0);
|
// pDist->minRows = tbufReadInt32(&br);
|
||||||
if (len == -1 || len >= x) { // compress failed, do not compress this binary data
|
// pDist->numOfRowsInMemTable = tbufReadUint32(&br);
|
||||||
comp = false;
|
// pDist->numOfSmallBlocks = tbufReadUint32(&br);
|
||||||
len = (int32_t)x;
|
// int64_t numSteps = tbufReadUint64(&br);
|
||||||
} else {
|
//
|
||||||
comp = true;
|
// bool comp = tbufReadUint8(&br);
|
||||||
}
|
// uint32_t compLen = tbufReadUint32(&br);
|
||||||
|
//
|
||||||
tbufWriteUint8(bw, comp);
|
// size_t originalLen = (size_t) (numSteps *sizeof(SFileBlockInfo));
|
||||||
tbufWriteUint32(bw, len);
|
//
|
||||||
if (comp) {
|
// char* outputBuf = NULL;
|
||||||
tbufWriteBinary(bw, tmp, len);
|
// if (comp) {
|
||||||
} else {
|
// outputBuf = malloc(originalLen);
|
||||||
tbufWriteBinary(bw, p, len);
|
//
|
||||||
}
|
// size_t actualLen = compLen;
|
||||||
tfree(tmp);
|
// const char* compStr = tbufReadBinary(&br, &actualLen);
|
||||||
}
|
//
|
||||||
|
// int32_t orignalLen = tsDecompressString(compStr, compLen, 1, outputBuf,
|
||||||
void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDist) {
|
// (int32_t)originalLen , ONE_STAGE_COMP, NULL, 0);
|
||||||
SBufferReader br = tbufInitReader(data, len, false);
|
// assert(orignalLen == numSteps *sizeof(SFileBlockInfo));
|
||||||
|
// } else {
|
||||||
pDist->numOfTables = tbufReadUint32(&br);
|
// outputBuf = (char*) tbufReadBinary(&br, &originalLen);
|
||||||
pDist->numOfFiles = tbufReadUint16(&br);
|
// }
|
||||||
pDist->totalSize = tbufReadUint64(&br);
|
//
|
||||||
pDist->totalRows = tbufReadUint64(&br);
|
// pDist->dataBlockInfos = taosArrayFromList(outputBuf, (uint32_t)numSteps, sizeof(SFileBlockInfo));
|
||||||
pDist->maxRows = tbufReadInt32(&br);
|
// if (comp) {
|
||||||
pDist->minRows = tbufReadInt32(&br);
|
// tfree(outputBuf);
|
||||||
pDist->numOfRowsInMemTable = tbufReadUint32(&br);
|
// }
|
||||||
pDist->numOfSmallBlocks = tbufReadUint32(&br);
|
//}
|
||||||
int64_t numSteps = tbufReadUint64(&br);
|
|
||||||
|
|
||||||
bool comp = tbufReadUint8(&br);
|
|
||||||
uint32_t compLen = tbufReadUint32(&br);
|
|
||||||
|
|
||||||
size_t originalLen = (size_t) (numSteps *sizeof(SFileBlockInfo));
|
|
||||||
|
|
||||||
char* outputBuf = NULL;
|
|
||||||
if (comp) {
|
|
||||||
outputBuf = malloc(originalLen);
|
|
||||||
|
|
||||||
size_t actualLen = compLen;
|
|
||||||
const char* compStr = tbufReadBinary(&br, &actualLen);
|
|
||||||
|
|
||||||
int32_t orignalLen = tsDecompressString(compStr, compLen, 1, outputBuf,
|
|
||||||
(int32_t)originalLen , ONE_STAGE_COMP, NULL, 0);
|
|
||||||
assert(orignalLen == numSteps *sizeof(SFileBlockInfo));
|
|
||||||
} else {
|
|
||||||
outputBuf = (char*) tbufReadBinary(&br, &originalLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
pDist->dataBlockInfos = taosArrayFromList(outputBuf, (uint32_t)numSteps, sizeof(SFileBlockInfo));
|
|
||||||
if (comp) {
|
|
||||||
tfree(outputBuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,411 +0,0 @@
|
||||||
/*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "os.h"
|
|
||||||
|
|
||||||
#include "ttypes.h"
|
|
||||||
#include "tarithoperator.h"
|
|
||||||
#include "tcompare.h"
|
|
||||||
|
|
||||||
//GET_TYPED_DATA(v, double, _right_type, (char *)&((right)[i]));
|
|
||||||
|
|
||||||
void calc_i32_i32_add(void *left, void *right, int32_t numLeft, int32_t numRight, void *output, int32_t order) {
|
|
||||||
int32_t *pLeft = (int32_t *)left;
|
|
||||||
int32_t *pRight = (int32_t *)right;
|
|
||||||
double * pOutput = (double *)output;
|
|
||||||
|
|
||||||
int32_t i = (order == TSDB_ORDER_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
|
||||||
int32_t step = (order == TSDB_ORDER_ASC) ? 1 : -1;
|
|
||||||
|
|
||||||
if (numLeft == numRight) {
|
|
||||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
|
||||||
if (isNull((char *)&(pLeft[i]), TSDB_DATA_TYPE_INT) || isNull((char *)&(pRight[i]), TSDB_DATA_TYPE_INT)) {
|
|
||||||
SET_DOUBLE_NULL(pOutput);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pOutput = (double)pLeft[i] + pRight[i];
|
|
||||||
}
|
|
||||||
} else if (numLeft == 1) {
|
|
||||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
|
||||||
if (isNull((char *)(pLeft), TSDB_DATA_TYPE_INT) || isNull((char *)&(pRight[i]), TSDB_DATA_TYPE_INT)) {
|
|
||||||
SET_DOUBLE_NULL(pOutput);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pOutput = (double)pLeft[0] + pRight[i];
|
|
||||||
}
|
|
||||||
} else if (numRight == 1) {
|
|
||||||
for (; i >= 0 && i < numLeft; i += step, pOutput += 1) {
|
|
||||||
if (isNull((char *)&(pLeft[i]), TSDB_DATA_TYPE_INT) || isNull((char *)(pRight), TSDB_DATA_TYPE_INT)) {
|
|
||||||
SET_DOUBLE_NULL(pOutput);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*pOutput = (double)pLeft[i] + pRight[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef double (*_arithmetic_getVectorDoubleValue_fn_t)(void *src, int32_t index);
|
|
||||||
|
|
||||||
double getVectorDoubleValue_TINYINT(void *src, int32_t index) {
|
|
||||||
return (double)*((int8_t *)src + index);
|
|
||||||
}
|
|
||||||
double getVectorDoubleValue_UTINYINT(void *src, int32_t index) {
|
|
||||||
return (double)*((uint8_t *)src + index);
|
|
||||||
}
|
|
||||||
double getVectorDoubleValue_SMALLINT(void *src, int32_t index) {
|
|
||||||
return (double)*((int16_t *)src + index);
|
|
||||||
}
|
|
||||||
double getVectorDoubleValue_USMALLINT(void *src, int32_t index) {
|
|
||||||
return (double)*((uint16_t *)src + index);
|
|
||||||
}
|
|
||||||
double getVectorDoubleValue_INT(void *src, int32_t index) {
|
|
||||||
return (double)*((int32_t *)src + index);
|
|
||||||
}
|
|
||||||
double getVectorDoubleValue_UINT(void *src, int32_t index) {
|
|
||||||
return (double)*((uint32_t *)src + index);
|
|
||||||
}
|
|
||||||
double getVectorDoubleValue_BIGINT(void *src, int32_t index) {
|
|
||||||
return (double)*((int64_t *)src + index);
|
|
||||||
}
|
|
||||||
double getVectorDoubleValue_UBIGINT(void *src, int32_t index) {
|
|
||||||
return (double)*((uint64_t *)src + index);
|
|
||||||
}
|
|
||||||
double getVectorDoubleValue_FLOAT(void *src, int32_t index) {
|
|
||||||
return (double)*((float *)src + index);
|
|
||||||
}
|
|
||||||
double getVectorDoubleValue_DOUBLE(void *src, int32_t index) {
|
|
||||||
return (double)*((double *)src + index);
|
|
||||||
}
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) {
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t p = NULL;
|
|
||||||
if(srcType==TSDB_DATA_TYPE_TINYINT) {
|
|
||||||
p = getVectorDoubleValue_TINYINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_UTINYINT) {
|
|
||||||
p = getVectorDoubleValue_UTINYINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_SMALLINT) {
|
|
||||||
p = getVectorDoubleValue_SMALLINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_USMALLINT) {
|
|
||||||
p = getVectorDoubleValue_USMALLINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_INT) {
|
|
||||||
p = getVectorDoubleValue_INT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_UINT) {
|
|
||||||
p = getVectorDoubleValue_UINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_BIGINT) {
|
|
||||||
p = getVectorDoubleValue_BIGINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_UBIGINT) {
|
|
||||||
p = getVectorDoubleValue_UBIGINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_FLOAT) {
|
|
||||||
p = getVectorDoubleValue_FLOAT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_DOUBLE) {
|
|
||||||
p = getVectorDoubleValue_DOUBLE;
|
|
||||||
}else {
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
typedef void* (*_arithmetic_getVectorValueAddr_fn_t)(void *src, int32_t index);
|
|
||||||
|
|
||||||
void* getVectorValueAddr_TINYINT(void *src, int32_t index) {
|
|
||||||
return (void*)((int8_t *)src + index);
|
|
||||||
}
|
|
||||||
void* getVectorValueAddr_UTINYINT(void *src, int32_t index) {
|
|
||||||
return (void*)((uint8_t *)src + index);
|
|
||||||
}
|
|
||||||
void* getVectorValueAddr_SMALLINT(void *src, int32_t index) {
|
|
||||||
return (void*)((int16_t *)src + index);
|
|
||||||
}
|
|
||||||
void* getVectorValueAddr_USMALLINT(void *src, int32_t index) {
|
|
||||||
return (void*)((uint16_t *)src + index);
|
|
||||||
}
|
|
||||||
void* getVectorValueAddr_INT(void *src, int32_t index) {
|
|
||||||
return (void*)((int32_t *)src + index);
|
|
||||||
}
|
|
||||||
void* getVectorValueAddr_UINT(void *src, int32_t index) {
|
|
||||||
return (void*)((uint32_t *)src + index);
|
|
||||||
}
|
|
||||||
void* getVectorValueAddr_BIGINT(void *src, int32_t index) {
|
|
||||||
return (void*)((int64_t *)src + index);
|
|
||||||
}
|
|
||||||
void* getVectorValueAddr_UBIGINT(void *src, int32_t index) {
|
|
||||||
return (void*)((uint64_t *)src + index);
|
|
||||||
}
|
|
||||||
void* getVectorValueAddr_FLOAT(void *src, int32_t index) {
|
|
||||||
return (void*)((float *)src + index);
|
|
||||||
}
|
|
||||||
void* getVectorValueAddr_DOUBLE(void *src, int32_t index) {
|
|
||||||
return (void*)((double *)src + index);
|
|
||||||
}
|
|
||||||
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) {
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t p = NULL;
|
|
||||||
if(srcType==TSDB_DATA_TYPE_TINYINT) {
|
|
||||||
p = getVectorValueAddr_TINYINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_UTINYINT) {
|
|
||||||
p = getVectorValueAddr_UTINYINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_SMALLINT) {
|
|
||||||
p = getVectorValueAddr_SMALLINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_USMALLINT) {
|
|
||||||
p = getVectorValueAddr_USMALLINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_INT) {
|
|
||||||
p = getVectorValueAddr_INT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_UINT) {
|
|
||||||
p = getVectorValueAddr_UINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_BIGINT) {
|
|
||||||
p = getVectorValueAddr_BIGINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_UBIGINT) {
|
|
||||||
p = getVectorValueAddr_UBIGINT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_FLOAT) {
|
|
||||||
p = getVectorValueAddr_FLOAT;
|
|
||||||
}else if(srcType==TSDB_DATA_TYPE_DOUBLE) {
|
|
||||||
p = getVectorValueAddr_DOUBLE;
|
|
||||||
}else {
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vectorAdd(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
|
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
|
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
|
||||||
double *output=(double*)out;
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
|
|
||||||
|
|
||||||
if ((len1) == (len2)) {
|
|
||||||
for (; i < (len2) && i >= 0; i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) + getVectorDoubleValueFnRight(right,i));
|
|
||||||
}
|
|
||||||
} else if ((len1) == 1) {
|
|
||||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) + getVectorDoubleValueFnRight(right,i));
|
|
||||||
}
|
|
||||||
} else if ((len2) == 1) {
|
|
||||||
for (; i >= 0 && i < (len1); i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) + getVectorDoubleValueFnRight(right,0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void vectorSub(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
|
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
|
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
|
||||||
double *output=(double*)out;
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
|
|
||||||
|
|
||||||
if ((len1) == (len2)) {
|
|
||||||
for (; i < (len2) && i >= 0; i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - getVectorDoubleValueFnRight(right,i));
|
|
||||||
}
|
|
||||||
} else if ((len1) == 1) {
|
|
||||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) - getVectorDoubleValueFnRight(right,i));
|
|
||||||
}
|
|
||||||
} else if ((len2) == 1) {
|
|
||||||
for (; i >= 0 && i < (len1); i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - getVectorDoubleValueFnRight(right,0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void vectorMultiply(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
|
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
|
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
|
||||||
double *output=(double*)out;
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
|
|
||||||
|
|
||||||
if ((len1) == (len2)) {
|
|
||||||
for (; i < (len2) && i >= 0; i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) * getVectorDoubleValueFnRight(right,i));
|
|
||||||
}
|
|
||||||
} else if ((len1) == 1) {
|
|
||||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) * getVectorDoubleValueFnRight(right,i));
|
|
||||||
}
|
|
||||||
} else if ((len2) == 1) {
|
|
||||||
for (; i >= 0 && i < (len1); i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) * getVectorDoubleValueFnRight(right,0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void vectorDivide(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
|
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
|
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
|
||||||
double *output=(double*)out;
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
|
|
||||||
|
|
||||||
if ((len1) == (len2)) {
|
|
||||||
for (; i < (len2) && i >= 0; i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double v, u = 0.0;
|
|
||||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,i));
|
|
||||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) /getVectorDoubleValueFnRight(right,i));
|
|
||||||
}
|
|
||||||
} else if ((len1) == 1) {
|
|
||||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double v, u = 0.0;
|
|
||||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,i));
|
|
||||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) /getVectorDoubleValueFnRight(right,i));
|
|
||||||
}
|
|
||||||
} else if ((len2) == 1) {
|
|
||||||
for (; i >= 0 && i < (len1); i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double v, u = 0.0;
|
|
||||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,0));
|
|
||||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) /getVectorDoubleValueFnRight(right,0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void vectorRemainder(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
|
|
||||||
int32_t i = (_ord == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
|
|
||||||
int32_t step = (_ord == TSDB_ORDER_ASC) ? 1 : -1;
|
|
||||||
double *output=(double*)out;
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
|
|
||||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
|
|
||||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
|
|
||||||
|
|
||||||
if (len1 == (len2)) {
|
|
||||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double v, u = 0.0;
|
|
||||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,i));
|
|
||||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - ((int64_t)(getVectorDoubleValueFnLeft(left,i) / getVectorDoubleValueFnRight(right,i))) * getVectorDoubleValueFnRight(right,i));
|
|
||||||
}
|
|
||||||
} else if (len1 == 1) {
|
|
||||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double v, u = 0.0;
|
|
||||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,i));
|
|
||||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) - ((int64_t)(getVectorDoubleValueFnLeft(left,0) / getVectorDoubleValueFnRight(right,i))) * getVectorDoubleValueFnRight(right,i));
|
|
||||||
}
|
|
||||||
} else if ((len2) == 1) {
|
|
||||||
for (; i >= 0 && i < len1; i += step, output += 1) {
|
|
||||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double v, u = 0.0;
|
|
||||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,0));
|
|
||||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
|
||||||
SET_DOUBLE_NULL(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - ((int64_t)(getVectorDoubleValueFnLeft(left,i) / getVectorDoubleValueFnRight(right,0))) * getVectorDoubleValueFnRight(right,0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr) {
|
|
||||||
switch (arithmeticOptr) {
|
|
||||||
case TSDB_BINARY_OP_ADD:
|
|
||||||
return vectorAdd;
|
|
||||||
case TSDB_BINARY_OP_SUBTRACT:
|
|
||||||
return vectorSub;
|
|
||||||
case TSDB_BINARY_OP_MULTIPLY:
|
|
||||||
return vectorMultiply;
|
|
||||||
case TSDB_BINARY_OP_DIVIDE:
|
|
||||||
return vectorDivide;
|
|
||||||
case TSDB_BINARY_OP_REMAINDER:
|
|
||||||
return vectorRemainder;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue