Merge remote-tracking branch 'origin/3.0' into feature/shm
This commit is contained in:
commit
db970c79a8
|
@ -127,6 +127,11 @@ target_include_directories(
|
|||
# zlib
|
||||
set(CMAKE_PROJECT_INCLUDE_BEFORE "${CMAKE_SUPPORT_DIR}/EnableCMP0048.txt.in")
|
||||
add_subdirectory(zlib)
|
||||
target_include_directories(
|
||||
zlibstatic
|
||||
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/zlib
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/zlib
|
||||
)
|
||||
target_include_directories(
|
||||
zlib
|
||||
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/zlib
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef enum {
|
|||
TSDB_SUPER_TABLE = 1, // super table
|
||||
TSDB_CHILD_TABLE = 2, // table created from super table
|
||||
TSDB_NORMAL_TABLE = 3, // ordinary table
|
||||
TSDB_STREAM_TABLE = 4, // table created from stream computing
|
||||
TSDB_STREAM_TABLE = 4, // table created by stream processing
|
||||
TSDB_TEMP_TABLE = 5, // temp table created by nest query
|
||||
TSDB_TABLE_MAX = 6
|
||||
} ETableType;
|
||||
|
@ -50,7 +50,12 @@ typedef enum {
|
|||
TSDB_CHECK_ITEM_MAX
|
||||
} ECheckItemType;
|
||||
|
||||
typedef enum { TD_ROW_DISCARD_UPDATE = 0, TD_ROW_OVERWRITE_UPDATE = 1, TD_ROW_PARTIAL_UPDATE = 2 } TDUpdateConfig;
|
||||
typedef enum {
|
||||
TD_ROW_DISCARD_UPDATE = 0,
|
||||
TD_ROW_OVERWRITE_UPDATE = 1,
|
||||
TD_ROW_PARTIAL_UPDATE = 2,
|
||||
} TDUpdateConfig;
|
||||
|
||||
typedef enum {
|
||||
TSDB_STATIS_OK = 0, // statis part exist and load successfully
|
||||
TSDB_STATIS_NONE = 1, // statis part not exist
|
||||
|
@ -61,6 +66,12 @@ typedef enum {
|
|||
TSDB_SMA_STAT_EXPIRED = 1, // not ready or expired
|
||||
} ETsdbSmaStat;
|
||||
|
||||
typedef enum {
|
||||
TSDB_SMA_TYPE_BLOCK = 0, // Block-wise SMA
|
||||
TSDB_SMA_TYPE_TIME_RANGE = 1, // Time-range-wise SMA
|
||||
TSDB_SMA_TYPE_ROLLUP = 2, // Rollup SMA
|
||||
} ETsdbSmaType;
|
||||
|
||||
extern char *qtypeStr[];
|
||||
|
||||
#define TSDB_PORT_HTTP 11
|
||||
|
|
|
@ -57,7 +57,8 @@ typedef struct SDataBlockInfo {
|
|||
STimeWindow window;
|
||||
int32_t rows;
|
||||
int32_t rowSize;
|
||||
int32_t numOfCols;
|
||||
int16_t numOfCols;
|
||||
int16_t hasVarCol;
|
||||
union {int64_t uid; int64_t blockId;};
|
||||
} SDataBlockInfo;
|
||||
|
||||
|
@ -96,13 +97,15 @@ typedef struct SColumnInfoData {
|
|||
|
||||
static FORCE_INLINE int32_t tEncodeDataBlock(void** buf, const SSDataBlock* pBlock) {
|
||||
int64_t tbUid = pBlock->info.uid;
|
||||
int32_t numOfCols = pBlock->info.numOfCols;
|
||||
int16_t numOfCols = pBlock->info.numOfCols;
|
||||
int16_t hasVarCol = pBlock->info.hasVarCol;
|
||||
int32_t rows = pBlock->info.rows;
|
||||
int32_t sz = taosArrayGetSize(pBlock->pDataBlock);
|
||||
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedI64(buf, tbUid);
|
||||
tlen += taosEncodeFixedI32(buf, numOfCols);
|
||||
tlen += taosEncodeFixedI16(buf, numOfCols);
|
||||
tlen += taosEncodeFixedI16(buf, hasVarCol);
|
||||
tlen += taosEncodeFixedI32(buf, rows);
|
||||
tlen += taosEncodeFixedI32(buf, sz);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
|
@ -120,7 +123,8 @@ static FORCE_INLINE void* tDecodeDataBlock(const void* buf, SSDataBlock* pBlock)
|
|||
int32_t sz;
|
||||
|
||||
buf = taosDecodeFixedI64(buf, &pBlock->info.uid);
|
||||
buf = taosDecodeFixedI32(buf, &pBlock->info.numOfCols);
|
||||
buf = taosDecodeFixedI16(buf, &pBlock->info.numOfCols);
|
||||
buf = taosDecodeFixedI16(buf, &pBlock->info.hasVarCol);
|
||||
buf = taosDecodeFixedI32(buf, &pBlock->info.rows);
|
||||
buf = taosDecodeFixedI32(buf, &sz);
|
||||
pBlock->pDataBlock = taosArrayInit(sz, sizeof(SColumnInfoData));
|
||||
|
@ -136,6 +140,23 @@ static FORCE_INLINE void* tDecodeDataBlock(const void* buf, SSDataBlock* pBlock)
|
|||
return (void*)buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tDeleteSSDataBlock(SSDataBlock* pBlock) {
|
||||
if (pBlock == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// int32_t numOfOutput = pBlock->info.numOfCols;
|
||||
int32_t sz = taosArrayGetSize(pBlock->pDataBlock);
|
||||
for (int32_t i = 0; i < sz; ++i) {
|
||||
SColumnInfoData* pColInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i);
|
||||
tfree(pColInfoData->pData);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pBlock->pDataBlock);
|
||||
tfree(pBlock->pBlockAgg);
|
||||
// tfree(pBlock);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSMqPollRsp(void** buf, const SMqPollRsp* pRsp) {
|
||||
int32_t tlen = 0;
|
||||
int32_t sz = 0;
|
||||
|
@ -178,23 +199,6 @@ static FORCE_INLINE void* tDecodeSMqPollRsp(void* buf, SMqPollRsp* pRsp) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tDeleteSSDataBlock(SSDataBlock* pBlock) {
|
||||
if (pBlock == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// int32_t numOfOutput = pBlock->info.numOfCols;
|
||||
int32_t sz = taosArrayGetSize(pBlock->pDataBlock);
|
||||
for (int32_t i = 0; i < sz; ++i) {
|
||||
SColumnInfoData* pColInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i);
|
||||
tfree(pColInfoData->pData);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pBlock->pDataBlock);
|
||||
tfree(pBlock->pBlockAgg);
|
||||
// tfree(pBlock);
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tDeleteSMqConsumeRsp(SMqPollRsp* pRsp) {
|
||||
if (pRsp->schemas) {
|
||||
if (pRsp->schemas->nCols) {
|
||||
|
@ -204,10 +208,6 @@ static FORCE_INLINE void tDeleteSMqConsumeRsp(SMqPollRsp* pRsp) {
|
|||
}
|
||||
taosArrayDestroyEx(pRsp->pBlockData, (void (*)(void*))tDeleteSSDataBlock);
|
||||
pRsp->pBlockData = NULL;
|
||||
// for (int32_t i = 0; i < taosArrayGetSize(pRsp->pBlockData); i++) {
|
||||
// SSDataBlock* pDataBlock = (SSDataBlock*)taosArrayGet(pRsp->pBlockData, i);
|
||||
// tDeleteSSDataBlock(pDataBlock);
|
||||
//}
|
||||
}
|
||||
|
||||
//======================================================================================================================
|
||||
|
|
|
@ -117,7 +117,7 @@ int32_t blockDataSort_rv(SSDataBlock* pDataBlock, SArray* pOrderInfo, bool nullF
|
|||
|
||||
int32_t blockDataEnsureColumnCapacity(SColumnInfoData* pColumn, uint32_t numOfRows);
|
||||
int32_t blockDataEnsureCapacity(SSDataBlock* pDataBlock, uint32_t numOfRows);
|
||||
void blockDataClearup(SSDataBlock* pDataBlock, bool hasVarCol);
|
||||
void blockDataClearup(SSDataBlock* pDataBlock);
|
||||
SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock);
|
||||
size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize);
|
||||
void* blockDataDestroy(SSDataBlock* pBlock);
|
||||
|
|
|
@ -190,7 +190,10 @@ typedef struct SEp {
|
|||
|
||||
typedef struct {
|
||||
int32_t contLen;
|
||||
union {
|
||||
int32_t vgId;
|
||||
int32_t streamTaskId;
|
||||
};
|
||||
} SMsgHead;
|
||||
|
||||
// Submit message for one table
|
||||
|
@ -1139,6 +1142,17 @@ int32_t tSerializeSCMCreateStreamReq(void* buf, int32_t bufLen, const SCMCreateS
|
|||
int32_t tDeserializeSCMCreateStreamReq(void* buf, int32_t bufLen, SCMCreateStreamReq* pReq);
|
||||
void tFreeSCMCreateStreamReq(SCMCreateStreamReq* pReq);
|
||||
|
||||
typedef struct {
|
||||
char name[TSDB_TOPIC_FNAME_LEN];
|
||||
int64_t streamId;
|
||||
char* sql;
|
||||
char* executorMsg;
|
||||
} SMVCreateStreamReq, SMSCreateStreamReq;
|
||||
|
||||
typedef struct {
|
||||
int64_t streamId;
|
||||
} SMVCreateStreamRsp, SMSCreateStreamRsp;
|
||||
|
||||
typedef struct {
|
||||
char name[TSDB_TOPIC_FNAME_LEN];
|
||||
int8_t igExists;
|
||||
|
@ -1903,11 +1917,12 @@ typedef struct {
|
|||
int8_t slidingUnit;
|
||||
char indexName[TSDB_INDEX_NAME_LEN];
|
||||
char timezone[TD_TIMEZONE_LEN]; // sma data is invalid if timezone change.
|
||||
uint16_t exprLen;
|
||||
uint16_t tagsFilterLen;
|
||||
int32_t exprLen;
|
||||
int32_t tagsFilterLen;
|
||||
int64_t indexUid;
|
||||
tb_uid_t tableUid; // super/child/common table uid
|
||||
int64_t interval;
|
||||
int64_t offset;
|
||||
int64_t sliding;
|
||||
char* expr; // sma expression
|
||||
char* tagsFilter;
|
||||
|
@ -2009,11 +2024,12 @@ static FORCE_INLINE int32_t tEncodeTSma(void** buf, const STSma* pSma) {
|
|||
tlen += taosEncodeFixedI8(buf, pSma->slidingUnit);
|
||||
tlen += taosEncodeString(buf, pSma->indexName);
|
||||
tlen += taosEncodeString(buf, pSma->timezone);
|
||||
tlen += taosEncodeFixedU16(buf, pSma->exprLen);
|
||||
tlen += taosEncodeFixedU16(buf, pSma->tagsFilterLen);
|
||||
tlen += taosEncodeFixedI32(buf, pSma->exprLen);
|
||||
tlen += taosEncodeFixedI32(buf, pSma->tagsFilterLen);
|
||||
tlen += taosEncodeFixedI64(buf, pSma->indexUid);
|
||||
tlen += taosEncodeFixedI64(buf, pSma->tableUid);
|
||||
tlen += taosEncodeFixedI64(buf, pSma->interval);
|
||||
tlen += taosEncodeFixedI64(buf, pSma->offset);
|
||||
tlen += taosEncodeFixedI64(buf, pSma->sliding);
|
||||
|
||||
if (pSma->exprLen > 0) {
|
||||
|
@ -2043,14 +2059,14 @@ static FORCE_INLINE void* tDecodeTSma(void* buf, STSma* pSma) {
|
|||
buf = taosDecodeFixedI8(buf, &pSma->slidingUnit);
|
||||
buf = taosDecodeStringTo(buf, pSma->indexName);
|
||||
buf = taosDecodeStringTo(buf, pSma->timezone);
|
||||
buf = taosDecodeFixedU16(buf, &pSma->exprLen);
|
||||
buf = taosDecodeFixedU16(buf, &pSma->tagsFilterLen);
|
||||
buf = taosDecodeFixedI32(buf, &pSma->exprLen);
|
||||
buf = taosDecodeFixedI32(buf, &pSma->tagsFilterLen);
|
||||
buf = taosDecodeFixedI64(buf, &pSma->indexUid);
|
||||
buf = taosDecodeFixedI64(buf, &pSma->tableUid);
|
||||
buf = taosDecodeFixedI64(buf, &pSma->interval);
|
||||
buf = taosDecodeFixedI64(buf, &pSma->offset);
|
||||
buf = taosDecodeFixedI64(buf, &pSma->sliding);
|
||||
|
||||
|
||||
if (pSma->exprLen > 0) {
|
||||
pSma->expr = (char*)calloc(pSma->exprLen, 1);
|
||||
if (pSma->expr != NULL) {
|
||||
|
|
|
@ -25,6 +25,17 @@ extern "C" {
|
|||
|
||||
#define TIME_IS_VAR_DURATION(_t) ((_t) == 'n' || (_t) == 'y' || (_t) == 'N' || (_t) == 'Y')
|
||||
|
||||
#define TIME_UNIT_NANOSECOND 'b'
|
||||
#define TIME_UNIT_MICROSECOND 'u'
|
||||
#define TIME_UNIT_MILLISECOND 'a'
|
||||
#define TIME_UNIT_SECOND 's'
|
||||
#define TIME_UNIT_MINUTE 'm'
|
||||
#define TIME_UNIT_HOUR 'h'
|
||||
#define TIME_UNIT_DAY 'd'
|
||||
#define TIME_UNIT_WEEK 'w'
|
||||
#define TIME_UNIT_MONTH 'n'
|
||||
#define TIME_UNIT_YEAR 'y'
|
||||
|
||||
/*
|
||||
* @return timestamp decided by global conf variable, tsTimePrecision
|
||||
* if precision == TSDB_TIME_PRECISION_MICRO, it returns timestamp in microsecond.
|
||||
|
|
|
@ -48,108 +48,113 @@
|
|||
#define TK_DNODES 30
|
||||
#define TK_NK_ID 31
|
||||
#define TK_NK_IPTOKEN 32
|
||||
#define TK_DATABASE 33
|
||||
#define TK_DATABASES 34
|
||||
#define TK_USE 35
|
||||
#define TK_IF 36
|
||||
#define TK_NOT 37
|
||||
#define TK_EXISTS 38
|
||||
#define TK_BLOCKS 39
|
||||
#define TK_CACHE 40
|
||||
#define TK_CACHELAST 41
|
||||
#define TK_COMP 42
|
||||
#define TK_DAYS 43
|
||||
#define TK_FSYNC 44
|
||||
#define TK_MAXROWS 45
|
||||
#define TK_MINROWS 46
|
||||
#define TK_KEEP 47
|
||||
#define TK_PRECISION 48
|
||||
#define TK_QUORUM 49
|
||||
#define TK_REPLICA 50
|
||||
#define TK_TTL 51
|
||||
#define TK_WAL 52
|
||||
#define TK_VGROUPS 53
|
||||
#define TK_SINGLE_STABLE 54
|
||||
#define TK_STREAM_MODE 55
|
||||
#define TK_TABLE 56
|
||||
#define TK_NK_LP 57
|
||||
#define TK_NK_RP 58
|
||||
#define TK_STABLE 59
|
||||
#define TK_TABLES 60
|
||||
#define TK_STABLES 61
|
||||
#define TK_USING 62
|
||||
#define TK_TAGS 63
|
||||
#define TK_NK_DOT 64
|
||||
#define TK_NK_COMMA 65
|
||||
#define TK_COMMENT 66
|
||||
#define TK_BOOL 67
|
||||
#define TK_TINYINT 68
|
||||
#define TK_SMALLINT 69
|
||||
#define TK_INT 70
|
||||
#define TK_INTEGER 71
|
||||
#define TK_BIGINT 72
|
||||
#define TK_FLOAT 73
|
||||
#define TK_DOUBLE 74
|
||||
#define TK_BINARY 75
|
||||
#define TK_TIMESTAMP 76
|
||||
#define TK_NCHAR 77
|
||||
#define TK_UNSIGNED 78
|
||||
#define TK_JSON 79
|
||||
#define TK_VARCHAR 80
|
||||
#define TK_MEDIUMBLOB 81
|
||||
#define TK_BLOB 82
|
||||
#define TK_VARBINARY 83
|
||||
#define TK_DECIMAL 84
|
||||
#define TK_SMA 85
|
||||
#define TK_MNODES 86
|
||||
#define TK_NK_FLOAT 87
|
||||
#define TK_NK_BOOL 88
|
||||
#define TK_NK_VARIABLE 89
|
||||
#define TK_BETWEEN 90
|
||||
#define TK_IS 91
|
||||
#define TK_NULL 92
|
||||
#define TK_NK_LT 93
|
||||
#define TK_NK_GT 94
|
||||
#define TK_NK_LE 95
|
||||
#define TK_NK_GE 96
|
||||
#define TK_NK_NE 97
|
||||
#define TK_NK_EQ 98
|
||||
#define TK_LIKE 99
|
||||
#define TK_MATCH 100
|
||||
#define TK_NMATCH 101
|
||||
#define TK_IN 102
|
||||
#define TK_FROM 103
|
||||
#define TK_AS 104
|
||||
#define TK_JOIN 105
|
||||
#define TK_ON 106
|
||||
#define TK_INNER 107
|
||||
#define TK_SELECT 108
|
||||
#define TK_DISTINCT 109
|
||||
#define TK_WHERE 110
|
||||
#define TK_PARTITION 111
|
||||
#define TK_BY 112
|
||||
#define TK_SESSION 113
|
||||
#define TK_STATE_WINDOW 114
|
||||
#define TK_INTERVAL 115
|
||||
#define TK_SLIDING 116
|
||||
#define TK_FILL 117
|
||||
#define TK_VALUE 118
|
||||
#define TK_NONE 119
|
||||
#define TK_PREV 120
|
||||
#define TK_LINEAR 121
|
||||
#define TK_NEXT 122
|
||||
#define TK_GROUP 123
|
||||
#define TK_HAVING 124
|
||||
#define TK_ORDER 125
|
||||
#define TK_SLIMIT 126
|
||||
#define TK_SOFFSET 127
|
||||
#define TK_LIMIT 128
|
||||
#define TK_OFFSET 129
|
||||
#define TK_ASC 130
|
||||
#define TK_DESC 131
|
||||
#define TK_NULLS 132
|
||||
#define TK_FIRST 133
|
||||
#define TK_LAST 134
|
||||
#define TK_QNODE 33
|
||||
#define TK_ON 34
|
||||
#define TK_QNODES 35
|
||||
#define TK_DATABASE 36
|
||||
#define TK_DATABASES 37
|
||||
#define TK_USE 38
|
||||
#define TK_IF 39
|
||||
#define TK_NOT 40
|
||||
#define TK_EXISTS 41
|
||||
#define TK_BLOCKS 42
|
||||
#define TK_CACHE 43
|
||||
#define TK_CACHELAST 44
|
||||
#define TK_COMP 45
|
||||
#define TK_DAYS 46
|
||||
#define TK_FSYNC 47
|
||||
#define TK_MAXROWS 48
|
||||
#define TK_MINROWS 49
|
||||
#define TK_KEEP 50
|
||||
#define TK_PRECISION 51
|
||||
#define TK_QUORUM 52
|
||||
#define TK_REPLICA 53
|
||||
#define TK_TTL 54
|
||||
#define TK_WAL 55
|
||||
#define TK_VGROUPS 56
|
||||
#define TK_SINGLE_STABLE 57
|
||||
#define TK_STREAM_MODE 58
|
||||
#define TK_TABLE 59
|
||||
#define TK_NK_LP 60
|
||||
#define TK_NK_RP 61
|
||||
#define TK_STABLE 62
|
||||
#define TK_TABLES 63
|
||||
#define TK_STABLES 64
|
||||
#define TK_USING 65
|
||||
#define TK_TAGS 66
|
||||
#define TK_NK_DOT 67
|
||||
#define TK_NK_COMMA 68
|
||||
#define TK_COMMENT 69
|
||||
#define TK_BOOL 70
|
||||
#define TK_TINYINT 71
|
||||
#define TK_SMALLINT 72
|
||||
#define TK_INT 73
|
||||
#define TK_INTEGER 74
|
||||
#define TK_BIGINT 75
|
||||
#define TK_FLOAT 76
|
||||
#define TK_DOUBLE 77
|
||||
#define TK_BINARY 78
|
||||
#define TK_TIMESTAMP 79
|
||||
#define TK_NCHAR 80
|
||||
#define TK_UNSIGNED 81
|
||||
#define TK_JSON 82
|
||||
#define TK_VARCHAR 83
|
||||
#define TK_MEDIUMBLOB 84
|
||||
#define TK_BLOB 85
|
||||
#define TK_VARBINARY 86
|
||||
#define TK_DECIMAL 87
|
||||
#define TK_SMA 88
|
||||
#define TK_INDEX 89
|
||||
#define TK_FULLTEXT 90
|
||||
#define TK_FUNCTION 91
|
||||
#define TK_INTERVAL 92
|
||||
#define TK_MNODES 93
|
||||
#define TK_NK_FLOAT 94
|
||||
#define TK_NK_BOOL 95
|
||||
#define TK_NK_VARIABLE 96
|
||||
#define TK_BETWEEN 97
|
||||
#define TK_IS 98
|
||||
#define TK_NULL 99
|
||||
#define TK_NK_LT 100
|
||||
#define TK_NK_GT 101
|
||||
#define TK_NK_LE 102
|
||||
#define TK_NK_GE 103
|
||||
#define TK_NK_NE 104
|
||||
#define TK_NK_EQ 105
|
||||
#define TK_LIKE 106
|
||||
#define TK_MATCH 107
|
||||
#define TK_NMATCH 108
|
||||
#define TK_IN 109
|
||||
#define TK_FROM 110
|
||||
#define TK_AS 111
|
||||
#define TK_JOIN 112
|
||||
#define TK_INNER 113
|
||||
#define TK_SELECT 114
|
||||
#define TK_DISTINCT 115
|
||||
#define TK_WHERE 116
|
||||
#define TK_PARTITION 117
|
||||
#define TK_BY 118
|
||||
#define TK_SESSION 119
|
||||
#define TK_STATE_WINDOW 120
|
||||
#define TK_SLIDING 121
|
||||
#define TK_FILL 122
|
||||
#define TK_VALUE 123
|
||||
#define TK_NONE 124
|
||||
#define TK_PREV 125
|
||||
#define TK_LINEAR 126
|
||||
#define TK_NEXT 127
|
||||
#define TK_GROUP 128
|
||||
#define TK_HAVING 129
|
||||
#define TK_ORDER 130
|
||||
#define TK_SLIMIT 131
|
||||
#define TK_SOFFSET 132
|
||||
#define TK_LIMIT 133
|
||||
#define TK_OFFSET 134
|
||||
#define TK_ASC 135
|
||||
#define TK_DESC 136
|
||||
#define TK_NULLS 137
|
||||
#define TK_FIRST 138
|
||||
#define TK_LAST 139
|
||||
|
||||
#define TK_NK_SPACE 300
|
||||
#define TK_NK_COMMENT 301
|
||||
|
|
|
@ -80,6 +80,10 @@ int32_t sndGetLoad(SSnode *pSnode, SSnodeLoad *pLoad);
|
|||
*/
|
||||
int32_t sndProcessMsg(SSnode *pSnode, SRpcMsg *pMsg, SRpcMsg **pRsp);
|
||||
|
||||
int32_t sndProcessUMsg(SSnode *pSnode, SRpcMsg *pMsg);
|
||||
|
||||
int32_t sndProcessSMsg(SSnode *pSnode, SRpcMsg *pMsg);
|
||||
|
||||
/**
|
||||
* @brief Drop a snode.
|
||||
*
|
||||
|
|
|
@ -295,19 +295,8 @@ typedef struct SMultiFunctionsDesc {
|
|||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength,
|
||||
bool isSuperTable);
|
||||
|
||||
/**
|
||||
* If the given name is a valid built-in sql function, the value of true will be returned.
|
||||
* @param name
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
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 qIsAggregateFunction(const char* functionName);
|
||||
bool qIsSelectivityFunction(const char* functionName);
|
||||
|
||||
tExprNode* exprTreeFromBinary(const void* data, size_t size);
|
||||
|
||||
void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc);
|
||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include "querynodes.h"
|
||||
|
||||
typedef struct SDatabaseOptions {
|
||||
ENodeType type;
|
||||
int32_t numOfBlocks;
|
||||
int32_t cacheBlockSize;
|
||||
int8_t cachelast;
|
||||
|
@ -46,7 +47,7 @@ typedef struct SCreateDatabaseStmt {
|
|||
ENodeType type;
|
||||
char dbName[TSDB_DB_NAME_LEN];
|
||||
bool ignoreExists;
|
||||
SDatabaseOptions options;
|
||||
SDatabaseOptions* pOptions;
|
||||
} SCreateDatabaseStmt;
|
||||
|
||||
typedef struct SUseDatabaseStmt {
|
||||
|
@ -61,6 +62,7 @@ typedef struct SDropDatabaseStmt {
|
|||
} SDropDatabaseStmt;
|
||||
|
||||
typedef struct STableOptions {
|
||||
ENodeType type;
|
||||
int32_t keep;
|
||||
int32_t ttl;
|
||||
char comments[TSDB_STB_COMMENT_LEN];
|
||||
|
@ -81,7 +83,7 @@ typedef struct SCreateTableStmt {
|
|||
bool ignoreExists;
|
||||
SNodeList* pCols;
|
||||
SNodeList* pTags;
|
||||
STableOptions options;
|
||||
STableOptions* pOptions;
|
||||
} SCreateTableStmt;
|
||||
|
||||
typedef struct SCreateSubTableClause {
|
||||
|
@ -155,6 +157,33 @@ typedef struct SShowStmt {
|
|||
char dbName[TSDB_DB_NAME_LEN];
|
||||
} SShowStmt;
|
||||
|
||||
typedef enum EIndexType {
|
||||
INDEX_TYPE_SMA = 1,
|
||||
INDEX_TYPE_FULLTEXT
|
||||
} EIndexType;
|
||||
|
||||
typedef struct SIndexOptions {
|
||||
ENodeType type;
|
||||
SNodeList* pFuncs;
|
||||
SNode* pInterval;
|
||||
SNode* pOffset;
|
||||
SNode* pSliding;
|
||||
} SIndexOptions;
|
||||
|
||||
typedef struct SCreateIndexStmt {
|
||||
ENodeType type;
|
||||
EIndexType indexType;
|
||||
char indexName[TSDB_INDEX_NAME_LEN];
|
||||
char tableName[TSDB_TABLE_NAME_LEN];
|
||||
SNodeList* pCols;
|
||||
SIndexOptions* pOptions;
|
||||
} SCreateIndexStmt;
|
||||
|
||||
typedef struct SCreateQnodeStmt {
|
||||
ENodeType type;
|
||||
int32_t dnodeId;
|
||||
} SCreateQnodeStmt;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -67,6 +67,9 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_SLOT_DESC,
|
||||
QUERY_NODE_COLUMN_DEF,
|
||||
QUERY_NODE_DOWNSTREAM_SOURCE,
|
||||
QUERY_NODE_DATABASE_OPTIONS,
|
||||
QUERY_NODE_TABLE_OPTIONS,
|
||||
QUERY_NODE_INDEX_OPTIONS,
|
||||
|
||||
// Statement nodes are used in parser and planner module.
|
||||
QUERY_NODE_SET_OPERATOR,
|
||||
|
@ -93,6 +96,9 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_SHOW_DNODES_STMT,
|
||||
QUERY_NODE_SHOW_VGROUPS_STMT,
|
||||
QUERY_NODE_SHOW_MNODES_STMT,
|
||||
QUERY_NODE_SHOW_QNODES_STMT,
|
||||
QUERY_NODE_CREATE_INDEX_STMT,
|
||||
QUERY_NODE_CREATE_QNODE_STMT,
|
||||
|
||||
// logic plan node
|
||||
QUERY_NODE_LOGIC_PLAN_SCAN,
|
||||
|
@ -101,6 +107,7 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_LOGIC_PLAN_PROJECT,
|
||||
QUERY_NODE_LOGIC_PLAN_VNODE_MODIF,
|
||||
QUERY_NODE_LOGIC_PLAN_EXCHANGE,
|
||||
QUERY_NODE_LOGIC_PLAN_WINDOW,
|
||||
QUERY_NODE_LOGIC_SUBPLAN,
|
||||
QUERY_NODE_LOGIC_PLAN,
|
||||
|
||||
|
@ -115,6 +122,7 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_PHYSICAL_PLAN_AGG,
|
||||
QUERY_NODE_PHYSICAL_PLAN_EXCHANGE,
|
||||
QUERY_NODE_PHYSICAL_PLAN_SORT,
|
||||
QUERY_NODE_PHYSICAL_PLAN_INTERVAL,
|
||||
QUERY_NODE_PHYSICAL_PLAN_DISPATCH,
|
||||
QUERY_NODE_PHYSICAL_PLAN_INSERT,
|
||||
QUERY_NODE_PHYSICAL_SUBPLAN,
|
||||
|
@ -183,6 +191,9 @@ const char* nodesNodeName(ENodeType type);
|
|||
int32_t nodesNodeToString(const SNodeptr pNode, bool format, char** pStr, int32_t* pLen);
|
||||
int32_t nodesStringToNode(const char* pStr, SNode** pNode);
|
||||
|
||||
int32_t nodesListToString(const SNodeList* pList, bool format, char** pStr, int32_t* pLen);
|
||||
int32_t nodesStringToList(const char* pStr, SNodeList** pList);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -80,6 +80,24 @@ typedef struct SExchangeLogicNode {
|
|||
int32_t srcGroupId;
|
||||
} SExchangeLogicNode;
|
||||
|
||||
typedef enum EWindowType {
|
||||
WINDOW_TYPE_INTERVAL = 1,
|
||||
WINDOW_TYPE_SESSION,
|
||||
WINDOW_TYPE_STATE
|
||||
} EWindowType;
|
||||
|
||||
typedef struct SWindowLogicNode {
|
||||
SLogicNode node;
|
||||
EWindowType winType;
|
||||
SNodeList* pFuncs;
|
||||
int64_t interval;
|
||||
int64_t offset;
|
||||
int64_t sliding;
|
||||
int8_t intervalUnit;
|
||||
int8_t slidingUnit;
|
||||
SFillNode* pFill;
|
||||
} SWindowLogicNode;
|
||||
|
||||
typedef enum ESubplanType {
|
||||
SUBPLAN_TYPE_MERGE = 1,
|
||||
SUBPLAN_TYPE_PARTIAL,
|
||||
|
@ -191,6 +209,18 @@ typedef struct SExchangePhysiNode {
|
|||
SNodeList* pSrcEndPoints; // element is SDownstreamSource, scheduler fill by calling qSetSuplanExecutionNode
|
||||
} SExchangePhysiNode;
|
||||
|
||||
typedef struct SIntervalPhysiNode {
|
||||
SPhysiNode node;
|
||||
SNodeList* pExprs; // these are expression list of parameter expression of function
|
||||
SNodeList* pFuncs;
|
||||
int64_t interval;
|
||||
int64_t offset;
|
||||
int64_t sliding;
|
||||
int8_t intervalUnit;
|
||||
int8_t slidingUnit;
|
||||
SFillNode* pFill;
|
||||
} SIntervalPhysiNode;
|
||||
|
||||
typedef struct SDataSinkNode {
|
||||
ENodeType type;
|
||||
SDataBlockDescNode* pInputDataBlockDesc;
|
||||
|
|
|
@ -82,6 +82,7 @@ typedef struct SValueNode {
|
|||
double d;
|
||||
char* p;
|
||||
} datum;
|
||||
char unit;
|
||||
} SValueNode;
|
||||
|
||||
typedef struct SOperatorNode {
|
||||
|
|
|
@ -51,6 +51,7 @@ typedef struct SQuery {
|
|||
SSchema* pResSchema;
|
||||
SCmdMsgInfo* pCmdMsg;
|
||||
int32_t msgType;
|
||||
bool streamQuery;
|
||||
} SQuery;
|
||||
|
||||
int32_t qParseQuerySql(SParseContext* pCxt, SQuery** pQuery);
|
||||
|
|
|
@ -26,6 +26,7 @@ typedef struct SPlanContext {
|
|||
uint64_t queryId;
|
||||
int32_t acctId;
|
||||
SNode* pAstRoot;
|
||||
bool streamQuery;
|
||||
} SPlanContext;
|
||||
|
||||
// Create the physical plan for the query, according to the AST.
|
||||
|
|
|
@ -78,6 +78,10 @@ typedef struct SRpcInit {
|
|||
// call back to keep conn or not
|
||||
bool (*pfp)(void *parent, tmsg_t msgType);
|
||||
|
||||
// to support Send messages multiple times on a link
|
||||
//
|
||||
void* (*mfp)(void *parent, tmsg_t msgType);
|
||||
|
||||
void *parent;
|
||||
} SRpcInit;
|
||||
|
||||
|
@ -96,6 +100,9 @@ void rpcSendRecv(void *shandle, SEpSet *pEpSet, SRpcMsg *pReq, SRpcMsg *pRsp)
|
|||
int rpcReportProgress(void *pConn, char *pCont, int contLen);
|
||||
void rpcCancelRequest(int64_t rid);
|
||||
|
||||
// just release client conn to rpc instance, no close sock
|
||||
void rpcReleaseHandle(void *handle);
|
||||
|
||||
void rpcRefHandle(void *handle, int8_t type);
|
||||
void rpcUnrefHandle(void *handle, int8_t type);
|
||||
|
||||
|
|
|
@ -17,12 +17,16 @@
|
|||
#define _TD_OS_LOCALE_H_
|
||||
|
||||
#include "os.h"
|
||||
#include "osString.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// If the error is in a third-party library, place this header file under the third-party library header file.
|
||||
#ifndef ALLOW_FORBID_FUNC
|
||||
#define setlocale SETLOCALE_FUNC_TAOS_FORBID
|
||||
#endif
|
||||
|
||||
char *taosCharsetReplace(char *charsetstr);
|
||||
void taosGetSystemLocale(char *outLocale, char *outCharset);
|
||||
void taosSetSystemLocale(const char *inLocale, const char *inCharSet);
|
||||
|
|
|
@ -354,6 +354,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_TDB_MESSED_MSG TAOS_DEF_ERROR_CODE(0, 0x0614)
|
||||
#define TSDB_CODE_TDB_IVLD_TAG_VAL TAOS_DEF_ERROR_CODE(0, 0x0615)
|
||||
#define TSDB_CODE_TDB_NO_CACHE_LAST_ROW TAOS_DEF_ERROR_CODE(0, 0x0616)
|
||||
#define TSDB_CODE_TDB_NO_SMA_INDEX_IN_META TAOS_DEF_ERROR_CODE(0, 0x0617)
|
||||
|
||||
// query
|
||||
#define TSDB_CODE_QRY_INVALID_QHANDLE TAOS_DEF_ERROR_CODE(0, 0x0700)
|
||||
|
|
|
@ -445,6 +445,9 @@ typedef struct {
|
|||
|
||||
#define TMQ_SEPARATOR ':'
|
||||
|
||||
#define SND_UNIQUE_THREAD_NUM 2
|
||||
#define SND_SHARED_THREAD_NUM 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,7 @@ extern "C" {
|
|||
typedef void SJson;
|
||||
|
||||
SJson* tjsonCreateObject();
|
||||
SJson* tjsonCreateArray();
|
||||
void tjsonDelete(SJson* pJson);
|
||||
|
||||
SJson* tjsonAddArrayToObject(SJson* pJson, const char* pName);
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 "taoserror.h"
|
||||
#include "thash.h"
|
||||
|
||||
/**
|
||||
* Generate an non-negative signed 32bit id
|
||||
*+------------+-----+-----------+---------------+
|
||||
*| uid|localIp| PId | timestamp | serial number |
|
||||
*+------------+-----+-----------+---------------+
|
||||
*| 6bit |6bit | 12bit | 8bit |
|
||||
*+------------+-----+-----------+---------------+
|
||||
* @return
|
||||
*/
|
||||
int32_t tGenIdPI32(void);
|
||||
|
||||
/**
|
||||
* Generate an non-negative signed 64bit id
|
||||
*+------------+-----+-----------+---------------+
|
||||
*| uid|localIp| PId | timestamp | serial number |
|
||||
*+------------+-----+-----------+---------------+
|
||||
*| 12bit |12bit|24bit |16bit |
|
||||
*+------------+-----+-----------+---------------+
|
||||
* @return
|
||||
*/
|
||||
int64_t tGenIdPI64(void);
|
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "parser.h"
|
||||
#include "planner.h"
|
||||
#include "query.h"
|
||||
#include "taos.h"
|
||||
#include "tcommon.h"
|
||||
|
@ -229,6 +230,7 @@ void setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32_t
|
|||
int32_t buildRequest(STscObj* pTscObj, const char* sql, int sqlLen, SRequestObj** pRequest);
|
||||
|
||||
int32_t parseSql(SRequestObj* pRequest, SQuery** pQuery);
|
||||
int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArray* pNodeList);
|
||||
|
||||
// --- heartbeat
|
||||
// global, called by mgmt
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
#include "clientInt.h"
|
||||
#include "clientLog.h"
|
||||
#include "parser.h"
|
||||
#include "planner.h"
|
||||
#include "scheduler.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tdef.h"
|
||||
|
@ -195,11 +193,7 @@ int32_t execDdlQuery(SRequestObj* pRequest, SQuery* pQuery) {
|
|||
int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArray* pNodeList) {
|
||||
pRequest->type = pQuery->msgType;
|
||||
SPlanContext cxt = { .queryId = pRequest->requestId, .pAstRoot = pQuery->pRoot, .acctId = pRequest->pTscObj->acctId };
|
||||
int32_t code = qCreateQueryPlan(&cxt, pPlan, pNodeList);
|
||||
if (code != 0) {
|
||||
return code;
|
||||
}
|
||||
return code;
|
||||
return qCreateQueryPlan(&cxt, pPlan, pNodeList);
|
||||
}
|
||||
|
||||
void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t numOfCols) {
|
||||
|
@ -215,7 +209,6 @@ void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) {
|
||||
void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter;
|
||||
|
||||
|
|
|
@ -482,21 +482,19 @@ TAOS_RES* tmq_create_topic(TAOS* taos, const char* topicName, const char* sql, i
|
|||
}
|
||||
|
||||
tscDebug("start to create topic, %s", topicName);
|
||||
#if 0
|
||||
|
||||
CHECK_CODE_GOTO(buildRequest(pTscObj, sql, sqlLen, &pRequest), _return);
|
||||
CHECK_CODE_GOTO(parseSql(pRequest, &pQueryNode), _return);
|
||||
|
||||
SQueryStmtInfo* pQueryStmtInfo = (SQueryStmtInfo*)pQueryNode;
|
||||
pQueryStmtInfo->info.continueQuery = true;
|
||||
pQueryNode->streamQuery = true;
|
||||
|
||||
// todo check for invalid sql statement and return with error code
|
||||
|
||||
SSchema* schema = NULL;
|
||||
int32_t numOfCols = 0;
|
||||
CHECK_CODE_GOTO(qCreateQueryDag(pQueryNode, &pRequest->body.pDag, &schema, &numOfCols, NULL, pRequest->requestId),
|
||||
_return);
|
||||
CHECK_CODE_GOTO(getPlan(pRequest, pQueryNode, &pRequest->body.pDag, NULL), _return);
|
||||
|
||||
pStr = qDagToString(pRequest->body.pDag);
|
||||
pStr = qQueryPlanToString(pRequest->body.pDag);
|
||||
if (pStr == NULL) {
|
||||
goto _return;
|
||||
}
|
||||
|
@ -506,7 +504,7 @@ TAOS_RES* tmq_create_topic(TAOS* taos, const char* topicName, const char* sql, i
|
|||
// The topic should be related to a database that the queried table is belonged to.
|
||||
SName name = {0};
|
||||
char dbName[TSDB_DB_FNAME_LEN] = {0};
|
||||
tNameGetFullDbName(&((SQueryStmtInfo*)pQueryNode)->pTableMetaInfo[0]->name, dbName);
|
||||
// tNameGetFullDbName(&((SQueryStmtInfo*)pQueryNode)->pTableMetaInfo[0]->name, dbName);
|
||||
|
||||
tNameFromString(&name, dbName, T_NAME_ACCT | T_NAME_DB);
|
||||
tNameFromString(&name, topicName, T_NAME_TABLE);
|
||||
|
@ -538,7 +536,7 @@ TAOS_RES* tmq_create_topic(TAOS* taos, const char* topicName, const char* sql, i
|
|||
asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &epSet, &transporterId, sendInfo);
|
||||
|
||||
tsem_wait(&pRequest->body.rspSem);
|
||||
#endif
|
||||
|
||||
_return:
|
||||
qDestroyQuery(pQueryNode);
|
||||
/*if (sendInfo != NULL) {*/
|
||||
|
|
|
@ -1059,10 +1059,10 @@ int32_t blockDataSort_rv(SSDataBlock* pDataBlock, SArray* pOrderInfo, bool nullF
|
|||
// destroyTupleIndex(index);
|
||||
}
|
||||
|
||||
void blockDataClearup(SSDataBlock* pDataBlock, bool hasVarCol) {
|
||||
void blockDataClearup(SSDataBlock* pDataBlock) {
|
||||
pDataBlock->info.rows = 0;
|
||||
|
||||
if (hasVarCol) {
|
||||
if (pDataBlock->info.hasVarCol) {
|
||||
for (int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) {
|
||||
SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, i);
|
||||
|
||||
|
@ -1148,7 +1148,9 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock) {
|
|||
|
||||
SSDataBlock* pBlock = calloc(1, sizeof(SSDataBlock));
|
||||
pBlock->pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData));
|
||||
|
||||
pBlock->info.numOfCols = numOfCols;
|
||||
pBlock->info.hasVarCol = pDataBlock->info.hasVarCol;
|
||||
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData colInfo = {0};
|
||||
|
|
|
@ -2666,7 +2666,6 @@ int32_t tSerializeSCMCreateStreamReq(void *buf, int32_t bufLen, const SCMCreateS
|
|||
if (tEncodeCStr(&encoder, pReq->sql) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->physicalPlan) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->logicalPlan) < 0) return -1;
|
||||
|
||||
tEndEncode(&encoder);
|
||||
|
||||
int32_t tlen = encoder.pos;
|
||||
|
|
|
@ -26,11 +26,11 @@ typedef struct SSnodeMgmt {
|
|||
int32_t refCount;
|
||||
int8_t deployed;
|
||||
int8_t dropped;
|
||||
int8_t uniqueWorkerInUse;
|
||||
SSnode *pSnode;
|
||||
SRWLatch latch;
|
||||
SDnodeWorker writeWorker;
|
||||
SProcObj *pProcess;
|
||||
bool singleProc;
|
||||
SArray *uniqueWorkers; // SArray<SDnodeWorker*>
|
||||
SDnodeWorker sharedWorker;
|
||||
} SSnodeMgmt;
|
||||
|
||||
void smGetMgmtFp(SMgmtWrapper *pMgmt);
|
||||
|
|
|
@ -20,7 +20,21 @@
|
|||
// #include "dndWorker.h"
|
||||
|
||||
#if 0
|
||||
static void dndProcessSnodeQueue(SDnode *pDnode, SRpcMsg *pMsg);
|
||||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
int32_t refCount;
|
||||
int32_t snVersion;
|
||||
int8_t dropped;
|
||||
char *path;
|
||||
SSnode *pImpl;
|
||||
STaosQueue *pSharedQ;
|
||||
STaosQueue *pUniqueQ;
|
||||
} SSnodeObj;
|
||||
|
||||
static void dndProcessSnodeSharedQueue(SDnode *pDnode, SRpcMsg *pMsg);
|
||||
|
||||
static void dndProcessSnodeUniqueQueue(SDnode *pDnode, STaosQall *qall, int32_t numOfMsgs);
|
||||
|
||||
static SSnode *dndAcquireSnode(SDnode *pDnode) {
|
||||
SSnodeMgmt *pMgmt = &pDnode->smgmt;
|
||||
|
@ -153,8 +167,21 @@ static int32_t dndWriteSnodeFile(SDnode *pDnode) {
|
|||
|
||||
static int32_t dndStartSnodeWorker(SDnode *pDnode) {
|
||||
SSnodeMgmt *pMgmt = &pDnode->smgmt;
|
||||
if (dndInitWorker(pDnode, &pMgmt->writeWorker, DND_WORKER_SINGLE, "snode-write", 0, 1, dndProcessSnodeQueue) != 0) {
|
||||
dError("failed to start snode write worker since %s", terrstr());
|
||||
pMgmt->uniqueWorkers = taosArrayInit(0, sizeof(void *));
|
||||
for (int32_t i = 0; i < SND_UNIQUE_THREAD_NUM; i++) {
|
||||
SDnodeWorker *pUniqueWorker = malloc(sizeof(SDnodeWorker));
|
||||
if (pUniqueWorker == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (dndInitWorker(pDnode, pUniqueWorker, DND_WORKER_MULTI, "snode-unique", 1, 1, dndProcessSnodeSharedQueue) != 0) {
|
||||
dError("failed to start snode unique worker since %s", terrstr());
|
||||
return -1;
|
||||
}
|
||||
taosArrayPush(pMgmt->uniqueWorkers, &pUniqueWorker);
|
||||
}
|
||||
if (dndInitWorker(pDnode, &pMgmt->sharedWorker, DND_WORKER_SINGLE, "snode-shared", SND_SHARED_THREAD_NUM,
|
||||
SND_SHARED_THREAD_NUM, dndProcessSnodeSharedQueue)) {
|
||||
dError("failed to start snode shared worker since %s", terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -172,7 +199,11 @@ static void dndStopSnodeWorker(SDnode *pDnode) {
|
|||
taosMsleep(10);
|
||||
}
|
||||
|
||||
dndCleanupWorker(&pMgmt->writeWorker);
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pMgmt->uniqueWorkers); i++) {
|
||||
SDnodeWorker *worker = taosArrayGetP(pMgmt->uniqueWorkers, i);
|
||||
dndCleanupWorker(worker);
|
||||
}
|
||||
taosArrayDestroy(pMgmt->uniqueWorkers);
|
||||
}
|
||||
|
||||
static void dndBuildSnodeOption(SDnode *pDnode, SSnodeOpt *pOption) {
|
||||
|
@ -293,17 +324,36 @@ int32_t smProcessDropReq(SDnode *pDnode, SRpcMsg *pReq) {
|
|||
}
|
||||
}
|
||||
|
||||
static void dndProcessSnodeQueue(SDnode *pDnode, SRpcMsg *pMsg) {
|
||||
static void dndProcessSnodeUniqueQueue(SDnode *pDnode, STaosQall *qall, int32_t numOfMsgs) {
|
||||
SSnodeMgmt *pMgmt = &pDnode->smgmt;
|
||||
SRpcMsg *pRsp = NULL;
|
||||
int32_t code = TSDB_CODE_DND_SNODE_NOT_DEPLOYED;
|
||||
|
||||
SSnode *pSnode = dndAcquireSnode(pDnode);
|
||||
if (pSnode != NULL) {
|
||||
code = sndProcessMsg(pSnode, pMsg, &pRsp);
|
||||
for (int32_t i = 0; i < numOfMsgs; i++) {
|
||||
SRpcMsg *pMsg = NULL;
|
||||
taosGetQitem(qall, (void **)&pMsg);
|
||||
|
||||
sndProcessUMsg(pSnode, pMsg);
|
||||
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
taosFreeQitem(pMsg);
|
||||
}
|
||||
}
|
||||
dndReleaseSnode(pDnode, pSnode);
|
||||
}
|
||||
|
||||
static void dndProcessSnodeSharedQueue(SDnode *pDnode, SRpcMsg *pMsg) {
|
||||
SSnodeMgmt *pMgmt = &pDnode->smgmt;
|
||||
int32_t code = TSDB_CODE_DND_SNODE_NOT_DEPLOYED;
|
||||
|
||||
SSnode *pSnode = dndAcquireSnode(pDnode);
|
||||
if (pSnode != NULL) {
|
||||
code = sndProcessSMsg(pSnode, pMsg);
|
||||
}
|
||||
dndReleaseSnode(pDnode, pSnode);
|
||||
|
||||
#if 0
|
||||
if (pMsg->msgType & 1u) {
|
||||
if (pRsp != NULL) {
|
||||
pRsp->ahandle = pMsg->ahandle;
|
||||
|
@ -315,11 +365,58 @@ static void dndProcessSnodeQueue(SDnode *pDnode, SRpcMsg *pMsg) {
|
|||
rpcSendResponse(&rpcRsp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
taosFreeQitem(pMsg);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t dndGetSWIdFromMsg(SRpcMsg *pMsg) {
|
||||
SMsgHead *pHead = pMsg->pCont;
|
||||
pHead->streamTaskId = htonl(pHead->streamTaskId);
|
||||
return pHead->streamTaskId % SND_UNIQUE_THREAD_NUM;
|
||||
}
|
||||
|
||||
static void dndWriteSnodeMsgToWorkerByMsg(SDnode *pDnode, SRpcMsg *pMsg) {
|
||||
int32_t code = TSDB_CODE_DND_SNODE_NOT_DEPLOYED;
|
||||
|
||||
SSnode *pSnode = dndAcquireSnode(pDnode);
|
||||
if (pSnode != NULL) {
|
||||
int32_t index = dndGetSWIdFromMsg(pMsg);
|
||||
SDnodeWorker *pWorker = taosArrayGetP(pDnode->smgmt.uniqueWorkers, index);
|
||||
code = dndWriteMsgToWorker(pWorker, pMsg, sizeof(SRpcMsg));
|
||||
}
|
||||
|
||||
dndReleaseSnode(pDnode, pSnode);
|
||||
|
||||
if (code != 0) {
|
||||
if (pMsg->msgType & 1u) {
|
||||
SRpcMsg rsp = {.handle = pMsg->handle, .ahandle = pMsg->ahandle, .code = code};
|
||||
rpcSendResponse(&rsp);
|
||||
}
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
}
|
||||
}
|
||||
|
||||
static void dndWriteSnodeMsgToMgmtWorker(SDnode *pDnode, SRpcMsg *pMsg) {
|
||||
int32_t code = TSDB_CODE_DND_SNODE_NOT_DEPLOYED;
|
||||
|
||||
SSnode *pSnode = dndAcquireSnode(pDnode);
|
||||
if (pSnode != NULL) {
|
||||
SDnodeWorker *pWorker = taosArrayGet(pDnode->smgmt.uniqueWorkers, 0);
|
||||
code = dndWriteMsgToWorker(pWorker, pMsg, sizeof(SRpcMsg));
|
||||
}
|
||||
dndReleaseSnode(pDnode, pSnode);
|
||||
|
||||
if (code != 0) {
|
||||
if (pMsg->msgType & 1u) {
|
||||
SRpcMsg rsp = {.handle = pMsg->handle, .ahandle = pMsg->ahandle, .code = code};
|
||||
rpcSendResponse(&rsp);
|
||||
}
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
}
|
||||
}
|
||||
|
||||
static void dndWriteSnodeMsgToWorker(SDnode *pDnode, SDnodeWorker *pWorker, SRpcMsg *pMsg) {
|
||||
int32_t code = TSDB_CODE_DND_SNODE_NOT_DEPLOYED;
|
||||
|
||||
|
@ -338,8 +435,16 @@ static void dndWriteSnodeMsgToWorker(SDnode *pDnode, SDnodeWorker *pWorker, SRpc
|
|||
}
|
||||
}
|
||||
|
||||
void dndProcessSnodeWriteMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||
dndWriteSnodeMsgToWorker(pDnode, &pDnode->smgmt.writeWorker, pMsg);
|
||||
void dndProcessSnodeMgmtMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||
dndWriteSnodeMsgToMgmtWorker(pDnode, pMsg);
|
||||
}
|
||||
|
||||
void dndProcessSnodeUniqueMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||
dndWriteSnodeMsgToWorkerByMsg(pDnode, pMsg);
|
||||
}
|
||||
|
||||
void dndProcessSnodeSharedMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||
dndWriteSnodeMsgToWorker(pDnode, &pDnode->smgmt.sharedWorker, pMsg);
|
||||
}
|
||||
|
||||
int32_t dndInitSnode(SDnode *pDnode) {
|
||||
|
|
|
@ -679,6 +679,12 @@ static FORCE_INLINE void* tDecodeSMqConsumerObj(void* buf, SMqConsumerObj* pCons
|
|||
return buf;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int32_t taskId;
|
||||
int32_t level;
|
||||
SSubplan* plan;
|
||||
} SStreamTaskMeta;
|
||||
|
||||
typedef struct {
|
||||
char name[TSDB_TOPIC_FNAME_LEN];
|
||||
char db[TSDB_DB_FNAME_LEN];
|
||||
|
@ -687,12 +693,14 @@ typedef struct {
|
|||
int64_t uid;
|
||||
int64_t dbUid;
|
||||
int32_t version;
|
||||
int32_t vgNum;
|
||||
SRWLatch lock;
|
||||
int8_t status;
|
||||
// int32_t sqlLen;
|
||||
char* sql;
|
||||
char* logicalPlan;
|
||||
char* physicalPlan;
|
||||
SArray* tasks; // SArray<SArray<SStreamTaskMeta>>
|
||||
} SStreamObj;
|
||||
|
||||
int32_t tEncodeSStreamObj(SCoder* pEncoder, const SStreamObj* pObj);
|
||||
|
|
|
@ -1292,11 +1292,11 @@ static int32_t mndGetDbMeta(SMndMsg *pReq, SShowObj *pShow, STableMetaRsp *pMeta
|
|||
pSchema[cols].bytes = pShow->bytes[cols];
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 1;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_TINYINT;
|
||||
strcpy(pSchema[cols].name, "update");
|
||||
pSchema[cols].bytes = pShow->bytes[cols];
|
||||
cols++;
|
||||
// pShow->bytes[cols] = 1;
|
||||
// pSchema[cols].type = TSDB_DATA_TYPE_TINYINT;
|
||||
// strcpy(pSchema[cols].name, "update");
|
||||
// pSchema[cols].bytes = pShow->bytes[cols];
|
||||
// cols++;
|
||||
|
||||
pMeta->numOfColumns = cols;
|
||||
pShow->numOfColumns = cols;
|
||||
|
@ -1432,9 +1432,9 @@ static int32_t mndRetrieveDbs(SMndMsg *pReq, SShowObj *pShow, char *data, int32_
|
|||
STR_WITH_SIZE_TO_VARSTR(pWrite, prec, 2);
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int8_t *)pWrite = pDb->cfg.update;
|
||||
cols++;
|
||||
// pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
// *(int8_t *)pWrite = pDb->cfg.update;
|
||||
// cols++;
|
||||
|
||||
numOfRows++;
|
||||
sdbRelease(pSdb, pDb);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "mndOffset.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndStb.h"
|
||||
#include "mndStream.h"
|
||||
#include "mndSubscribe.h"
|
||||
#include "mndTopic.h"
|
||||
#include "mndTrans.h"
|
||||
|
@ -28,6 +29,80 @@
|
|||
#include "mndVgroup.h"
|
||||
#include "tcompare.h"
|
||||
#include "tname.h"
|
||||
#include "tuuid.h"
|
||||
|
||||
int32_t mndScheduleStream(SMnode* pMnode, SStreamObj* pStream) {
|
||||
SSdb* pSdb = pMnode->pSdb;
|
||||
SVgObj* pVgroup = NULL;
|
||||
SQueryPlan* pPlan = qStringToQueryPlan(pStream->physicalPlan);
|
||||
if (pPlan == NULL) {
|
||||
terrno = TSDB_CODE_QRY_INVALID_INPUT;
|
||||
return -1;
|
||||
}
|
||||
ASSERT(pStream->vgNum == 0);
|
||||
|
||||
int32_t levelNum = LIST_LENGTH(pPlan->pSubplans);
|
||||
pStream->tasks = taosArrayInit(levelNum, sizeof(SArray));
|
||||
|
||||
for (int32_t i = 0; i < levelNum; i++) {
|
||||
SArray* taskOneLevel = taosArrayInit(0, sizeof(SStreamTaskMeta));
|
||||
SNodeListNode* inner = nodesListGetNode(pPlan->pSubplans, i);
|
||||
int32_t opNum = LIST_LENGTH(inner->pNodeList);
|
||||
ASSERT(opNum == 1);
|
||||
|
||||
SSubplan* plan = nodesListGetNode(inner->pNodeList, 0);
|
||||
if (i == 0) {
|
||||
ASSERT(plan->type == SUBPLAN_TYPE_SCAN);
|
||||
void* pIter = NULL;
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void**)&pVgroup);
|
||||
if (pIter == NULL) break;
|
||||
if (pVgroup->dbUid != pStream->dbUid) {
|
||||
sdbRelease(pSdb, pVgroup);
|
||||
continue;
|
||||
}
|
||||
|
||||
pStream->vgNum++;
|
||||
plan->execNode.nodeId = pVgroup->vgId;
|
||||
plan->execNode.epSet = mndGetVgroupEpset(pMnode, pVgroup);
|
||||
SStreamTaskMeta task = {
|
||||
.taskId = tGenIdPI32(),
|
||||
.level = i,
|
||||
.plan = plan,
|
||||
};
|
||||
// send to vnode
|
||||
taosArrayPush(taskOneLevel, &task);
|
||||
}
|
||||
} else if (plan->subplanType == SUBPLAN_TYPE_SCAN) {
|
||||
// duplicatable
|
||||
|
||||
int32_t parallel = 0;
|
||||
// if no snode, parallel set to fetch thread num in vnode
|
||||
|
||||
// if has snode, set to shared thread num in snode
|
||||
parallel = SND_SHARED_THREAD_NUM;
|
||||
|
||||
for (int32_t j = 0; j < parallel; j++) {
|
||||
SStreamTaskMeta task = {
|
||||
.taskId = tGenIdPI32(),
|
||||
.level = i,
|
||||
.plan = plan,
|
||||
};
|
||||
taosArrayPush(taskOneLevel, &task);
|
||||
}
|
||||
} else {
|
||||
// not duplicatable
|
||||
SStreamTaskMeta task = {
|
||||
.taskId = tGenIdPI32(),
|
||||
.level = i,
|
||||
.plan = plan,
|
||||
};
|
||||
taosArrayPush(taskOneLevel, &task);
|
||||
}
|
||||
taosArrayPush(pStream->tasks, taskOneLevel);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscribeObj* pSub) {
|
||||
SSdb* pSdb = pMnode->pSdb;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "mndShow.h"
|
||||
#include "mndSnode.h"
|
||||
#include "mndStb.h"
|
||||
#include "mndStream.h"
|
||||
#include "mndSubscribe.h"
|
||||
#include "mndSync.h"
|
||||
#include "mndTelem.h"
|
||||
|
@ -214,6 +215,7 @@ static int32_t mndInitSteps(SMnode *pMnode) {
|
|||
if (mndAllocStep(pMnode, "mnode-user", mndInitUser, mndCleanupUser) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-auth", mndInitAuth, mndCleanupAuth) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-acct", mndInitAcct, mndCleanupAcct) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-stream", mndInitStream, mndCleanupStream) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-topic", mndInitTopic, mndCleanupTopic) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-consumer", mndInitConsumer, mndCleanupConsumer) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-subscribe", mndInitSubscribe, mndCleanupSubscribe) != 0) return -1;
|
||||
|
|
|
@ -27,7 +27,7 @@ Testbase MndTestDb::test;
|
|||
|
||||
TEST_F(MndTestDb, 01_ShowDb) {
|
||||
test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, "");
|
||||
CHECK_META("show databases", 18);
|
||||
CHECK_META("show databases", 17);
|
||||
CHECK_SCHEMA(0, TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN - 1 + VARSTR_HEADER_SIZE, "name");
|
||||
CHECK_SCHEMA(1, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time");
|
||||
CHECK_SCHEMA(2, TSDB_DATA_TYPE_SMALLINT, 2, "vgroups");
|
||||
|
@ -45,7 +45,7 @@ TEST_F(MndTestDb, 01_ShowDb) {
|
|||
CHECK_SCHEMA(14, TSDB_DATA_TYPE_TINYINT, 1, "comp");
|
||||
CHECK_SCHEMA(15, TSDB_DATA_TYPE_TINYINT, 1, "cachelast");
|
||||
CHECK_SCHEMA(16, TSDB_DATA_TYPE_BINARY, 3 + VARSTR_HEADER_SIZE, "precision");
|
||||
CHECK_SCHEMA(17, TSDB_DATA_TYPE_TINYINT, 1, "update");
|
||||
// CHECK_SCHEMA(17, TSDB_DATA_TYPE_TINYINT, 1, "update");
|
||||
|
||||
test.SendShowRetrieveReq();
|
||||
EXPECT_EQ(test.GetShowRows(), 0);
|
||||
|
@ -85,7 +85,7 @@ TEST_F(MndTestDb, 02_Create_Alter_Drop_Db) {
|
|||
}
|
||||
|
||||
test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, "");
|
||||
CHECK_META("show databases", 18);
|
||||
CHECK_META("show databases", 17);
|
||||
|
||||
test.SendShowRetrieveReq();
|
||||
EXPECT_EQ(test.GetShowRows(), 1);
|
||||
|
@ -173,7 +173,7 @@ TEST_F(MndTestDb, 02_Create_Alter_Drop_Db) {
|
|||
test.Restart();
|
||||
|
||||
test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, "");
|
||||
CHECK_META("show databases", 18);
|
||||
CHECK_META("show databases", 17);
|
||||
|
||||
test.SendShowRetrieveReq();
|
||||
EXPECT_EQ(test.GetShowRows(), 1);
|
||||
|
@ -215,7 +215,7 @@ TEST_F(MndTestDb, 02_Create_Alter_Drop_Db) {
|
|||
}
|
||||
|
||||
test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, "");
|
||||
CHECK_META("show databases", 18);
|
||||
CHECK_META("show databases", 17);
|
||||
|
||||
test.SendShowRetrieveReq();
|
||||
EXPECT_EQ(test.GetShowRows(), 0);
|
||||
|
@ -255,7 +255,7 @@ TEST_F(MndTestDb, 03_Create_Use_Restart_Use_Db) {
|
|||
}
|
||||
|
||||
test.SendShowMetaReq(TSDB_MGMT_TABLE_DB, "");
|
||||
CHECK_META("show databases", 18);
|
||||
CHECK_META("show databases", 17);
|
||||
|
||||
test.SendShowRetrieveReq();
|
||||
EXPECT_EQ(test.GetShowRows(), 1);
|
||||
|
|
|
@ -30,47 +30,48 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
enum {
|
||||
STREAM_STATUS__READY = 1,
|
||||
STREAM_STATUS__RUNNING = 1,
|
||||
STREAM_STATUS__STOPPED,
|
||||
STREAM_STATUS__CREATING,
|
||||
STREAM_STATUS__STOPING,
|
||||
STREAM_STATUS__RESUMING,
|
||||
STREAM_STATUS__RESTORING,
|
||||
STREAM_STATUS__DELETING,
|
||||
};
|
||||
|
||||
enum {
|
||||
STREAM_RUNNER__RUNNING = 1,
|
||||
STREAM_RUNNER__STOP,
|
||||
STREAM_TASK_STATUS__RUNNING = 1,
|
||||
STREAM_TASK_STATUS__STOP,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
SHashObj* pHash; // taskId -> streamTask
|
||||
} SStreamMeta;
|
||||
|
||||
typedef struct SSnode {
|
||||
SStreamMeta* pMeta;
|
||||
SSnodeOpt cfg;
|
||||
} SSnode;
|
||||
|
||||
typedef struct {
|
||||
int64_t streamId;
|
||||
int32_t taskId;
|
||||
int32_t IdxInLevel;
|
||||
int32_t level;
|
||||
} SStreamInfo;
|
||||
} SStreamTaskInfo;
|
||||
|
||||
typedef struct {
|
||||
SStreamInfo meta;
|
||||
SStreamTaskInfo meta;
|
||||
int8_t status;
|
||||
void* executor;
|
||||
STaosQueue* queue;
|
||||
void* stateStore;
|
||||
// storage handle
|
||||
} SStreamRunner;
|
||||
} SStreamTask;
|
||||
|
||||
typedef struct {
|
||||
SHashObj* pHash;
|
||||
} SStreamMeta;
|
||||
int32_t sndCreateTask();
|
||||
int32_t sndDropTaskOfStream(int64_t streamId);
|
||||
|
||||
int32_t sndCreateStream();
|
||||
int32_t sndDropStream();
|
||||
|
||||
int32_t sndStopStream();
|
||||
int32_t sndResumeStream();
|
||||
int32_t sndStopTaskOfStream(int64_t streamId);
|
||||
int32_t sndResumeTaskOfStream(int64_t streamId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
#include "sndInt.h"
|
||||
#include "tuuid.h"
|
||||
|
||||
SSnode *sndOpen(const char *path, const SSnodeOpt *pOption) {
|
||||
SSnode *pSnode = calloc(1, sizeof(SSnode));
|
||||
|
@ -31,3 +32,25 @@ int32_t sndProcessMsg(SSnode *pSnode, SRpcMsg *pMsg, SRpcMsg **pRsp) {
|
|||
}
|
||||
|
||||
void sndDestroy(const char *path) {}
|
||||
|
||||
static int32_t sndDeployTask(SSnode *pSnode, SRpcMsg *pMsg) {
|
||||
SStreamTask *task = malloc(sizeof(SStreamTask));
|
||||
if (task == NULL) {
|
||||
return -1;
|
||||
}
|
||||
task->meta.taskId = tGenIdPI32();
|
||||
taosHashPut(pSnode->pMeta->pHash, &task->meta.taskId, sizeof(int32_t), &task, sizeof(void *));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t sndProcessUMsg(SSnode *pSnode, SRpcMsg *pMsg) {
|
||||
// stream deployment
|
||||
// stream stop/resume
|
||||
// operator exec
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t sndProcessSMsg(SSnode *pSnode, SRpcMsg *pMsg) {
|
||||
// operator exec
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@ int tsdbCommit(STsdb *pTsdb);
|
|||
* @return int32_t
|
||||
*/
|
||||
int32_t tsdbInsertTSmaData(STsdb *pTsdb, char *msg);
|
||||
int32_t tsdbUpdateSmaWindow(STsdb *pTsdb, int8_t smaType, char *msg);
|
||||
|
||||
/**
|
||||
* @brief Insert RSma(Time-range-wise Rollup SMA) data.
|
||||
|
@ -105,6 +106,12 @@ int32_t tsdbInsertTSmaData(STsdb *pTsdb, char *msg);
|
|||
*/
|
||||
int32_t tsdbInsertRSmaData(STsdb *pTsdb, char *msg);
|
||||
|
||||
// TODO: This is the basic params, and should wrap the params to a queryHandle.
|
||||
int32_t tsdbGetTSmaData(STsdb *pTsdb, STSmaDataWrapper *pData, int64_t indexUid, int64_t interval,
|
||||
int8_t intervalUnit, tb_uid_t tableUid, col_id_t colId, TSKEY querySkey,
|
||||
int32_t nMaxResult);
|
||||
|
||||
|
||||
// STsdbCfg
|
||||
int tsdbOptionsInit(STsdbCfg *);
|
||||
void tsdbOptionsClear(STsdbCfg *);
|
||||
|
|
|
@ -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_TSDB_DB_DEF_H_
|
||||
#define _TD_TSDB_DB_DEF_H_
|
||||
|
||||
#include "db.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SDBFile SDBFile;
|
||||
typedef DB_ENV* TDBEnv;
|
||||
|
||||
struct SDBFile {
|
||||
DB* pDB;
|
||||
char* path;
|
||||
};
|
||||
|
||||
int32_t tsdbOpenDBF(TDBEnv pEnv, SDBFile* pDBF);
|
||||
void tsdbCloseDBF(SDBFile* pDBF);
|
||||
int32_t tsdbOpenBDBEnv(DB_ENV** ppEnv, const char* path);
|
||||
void tsdbCloseBDBEnv(DB_ENV* pEnv);
|
||||
int32_t tsdbSaveSmaToDB(SDBFile* pDBF, void* key, uint32_t keySize, void* data, uint32_t dataSize);
|
||||
void* tsdbGetSmaDataByKey(SDBFile* pDBF, void* key, uint32_t keySize, uint32_t* valueSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_TSDB_DB_DEF_H_*/
|
|
@ -27,6 +27,7 @@
|
|||
#include "ttime.h"
|
||||
|
||||
#include "tsdb.h"
|
||||
#include "tsdbDBDef.h"
|
||||
#include "tsdbCommit.h"
|
||||
#include "tsdbFS.h"
|
||||
#include "tsdbFile.h"
|
||||
|
@ -37,12 +38,15 @@
|
|||
#include "tsdbReadImpl.h"
|
||||
#include "tsdbSma.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct STsdb {
|
||||
int32_t vgId;
|
||||
bool repoLocked;
|
||||
pthread_mutex_t mutex;
|
||||
char * path;
|
||||
STsdbCfg config;
|
||||
STsdbMemTable * mem;
|
||||
|
@ -52,12 +56,17 @@ struct STsdb {
|
|||
STsdbFS * fs;
|
||||
SMeta * pMeta;
|
||||
STfs * pTfs;
|
||||
SSmaStat * pSmaStat;
|
||||
SSmaEnv * pTSmaEnv;
|
||||
SSmaEnv * pRSmaEnv;
|
||||
};
|
||||
|
||||
#define REPO_ID(r) ((r)->vgId)
|
||||
#define REPO_CFG(r) (&(r)->config)
|
||||
#define REPO_FS(r) (r)->fs
|
||||
#define IS_REPO_LOCKED(r) (r)->repoLocked
|
||||
|
||||
int tsdbLockRepo(STsdb *pTsdb);
|
||||
int tsdbUnlockRepo(STsdb *pTsdb);
|
||||
|
||||
static FORCE_INLINE STSchema *tsdbGetTableSchemaImpl(STable *pTable, bool lock, bool copy, int32_t version) {
|
||||
return pTable->pSchema;
|
||||
|
|
|
@ -339,11 +339,13 @@ typedef struct {
|
|||
int fid;
|
||||
int8_t state;
|
||||
uint8_t ver;
|
||||
uint16_t reserve;
|
||||
#if 0
|
||||
SDFInfo info;
|
||||
#endif
|
||||
STfsFile f;
|
||||
TdFilePtr pFile;
|
||||
|
||||
} SSFile; // files split by days with fid
|
||||
|
||||
#define TSDB_LATEST_FSET_VER 0
|
||||
|
|
|
@ -17,27 +17,29 @@
|
|||
#define _TD_TSDB_SMA_H_
|
||||
|
||||
typedef struct SSmaStat SSmaStat;
|
||||
typedef struct SSmaEnv SSmaEnv;
|
||||
|
||||
// insert/update interface
|
||||
int32_t tsdbInsertTSmaDataImpl(STsdb *pTsdb, char *msg);
|
||||
int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg);
|
||||
struct SSmaEnv {
|
||||
pthread_rwlock_t lock;
|
||||
TDBEnv dbEnv;
|
||||
char * path;
|
||||
SSmaStat * pStat;
|
||||
};
|
||||
|
||||
#define SMA_ENV_LOCK(env) ((env)->lock)
|
||||
#define SMA_ENV_ENV(env) ((env)->dbEnv)
|
||||
#define SMA_ENV_PATH(env) ((env)->path)
|
||||
#define SMA_ENV_STAT(env) ((env)->pStat)
|
||||
#define SMA_ENV_STAT_ITEMS(env) ((env)->pStat->smaStatItems)
|
||||
|
||||
// query interface
|
||||
// TODO: This is the basic params, and should wrap the params to a queryHandle.
|
||||
int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, STSmaDataWrapper *pData, STimeWindow *queryWin, int32_t nMaxResult);
|
||||
|
||||
// management interface
|
||||
int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, char *msg);
|
||||
int32_t tsdbDestroySmaState(SSmaStat *pSmaStat);
|
||||
void tsdbDestroySmaEnv(SSmaEnv *pSmaEnv);
|
||||
void *tsdbFreeSmaEnv(SSmaEnv *pSmaEnv);
|
||||
#if 0
|
||||
int32_t tsdbGetTSmaStatus(STsdb *pTsdb, STSma *param, void *result);
|
||||
int32_t tsdbRemoveTSmaData(STsdb *pTsdb, STSma *param, STimeWindow *pWin);
|
||||
#endif
|
||||
|
||||
// internal func
|
||||
|
||||
|
||||
static FORCE_INLINE int32_t tsdbEncodeTSmaKey(tb_uid_t tableUid, col_id_t colId, TSKEY tsKey, void **pData) {
|
||||
int32_t len = 0;
|
||||
len += taosEncodeFixedI64(pData, tableUid);
|
||||
|
@ -46,4 +48,31 @@ static FORCE_INLINE int32_t tsdbEncodeTSmaKey(tb_uid_t tableUid, col_id_t colId,
|
|||
return len;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int tsdbRLockSma(SSmaEnv *pEnv) {
|
||||
int code = pthread_rwlock_rdlock(&(pEnv->lock));
|
||||
if (code != 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(code);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int tsdbWLockSma(SSmaEnv *pEnv) {
|
||||
int code = pthread_rwlock_wrlock(&(pEnv->lock));
|
||||
if (code != 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(code);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int tsdbUnLockSma(SSmaEnv *pEnv) {
|
||||
int code = pthread_rwlock_unlock(&(pEnv->lock));
|
||||
if (code != 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(code);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _TD_TSDB_SMA_H_ */
|
|
@ -231,7 +231,6 @@ int metaSaveSmaToDB(SMeta *pMeta, STSma *pSmaCfg) {
|
|||
void *pBuf = NULL, *qBuf = NULL;
|
||||
DBT key1 = {0}, value1 = {0};
|
||||
|
||||
{
|
||||
// save sma info
|
||||
int32_t len = tEncodeTSma(NULL, pSmaCfg);
|
||||
pBuf = calloc(len, 1);
|
||||
|
@ -249,12 +248,14 @@ int metaSaveSmaToDB(SMeta *pMeta, STSma *pSmaCfg) {
|
|||
value1.data = pBuf;
|
||||
value1.size = POINTER_DISTANCE(qBuf, pBuf);
|
||||
value1.app_data = pSmaCfg;
|
||||
}
|
||||
|
||||
metaDBWLock(pMeta->pDB);
|
||||
pMeta->pDB->pSmaDB->put(pMeta->pDB->pSmaDB, NULL, &key1, &value1, 0);
|
||||
metaDBULock(pMeta->pDB);
|
||||
|
||||
// release
|
||||
tfree(pBuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,8 +83,8 @@ bool tqNextDataBlock(STqReadHandle* pHandle) {
|
|||
}
|
||||
|
||||
int tqRetrieveDataBlockInfo(STqReadHandle* pHandle, SDataBlockInfo* pBlockInfo) {
|
||||
/*int32_t sversion = pHandle->pBlock->sversion;*/
|
||||
/*SSchemaWrapper* pSchema = metaGetTableSchema(pHandle->pMeta, pHandle->pBlock->uid, sversion, false);*/
|
||||
// currently only rows are used
|
||||
|
||||
pBlockInfo->numOfCols = taosArrayGetSize(pHandle->pColIdList);
|
||||
pBlockInfo->rows = pHandle->pBlock->numOfRows;
|
||||
pBlockInfo->uid = pHandle->pBlock->uid;
|
||||
|
|
|
@ -12,3 +12,162 @@
|
|||
* 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/>.
|
||||
*/
|
||||
|
||||
#define ALLOW_FORBID_FUNC
|
||||
#include "db.h"
|
||||
|
||||
#include "taoserror.h"
|
||||
#include "tcoding.h"
|
||||
#include "thash.h"
|
||||
#include "tsdbDBDef.h"
|
||||
#include "tsdbLog.h"
|
||||
|
||||
#define IMPL_WITH_LOCK 1
|
||||
|
||||
static int tsdbOpenBDBDb(DB **ppDB, DB_ENV *pEnv, const char *pFName, bool isDup);
|
||||
static void tsdbCloseBDBDb(DB *pDB);
|
||||
|
||||
#define BDB_PERR(info, code) fprintf(stderr, "%s:%d " info " reason: %s\n", __FILE__, __LINE__, db_strerror(code))
|
||||
|
||||
int32_t tsdbOpenDBF(TDBEnv pEnv, SDBFile *pDBF) {
|
||||
// TDBEnv is shared by a group of SDBFile
|
||||
if (!pEnv) {
|
||||
terrno = TSDB_CODE_INVALID_PTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Open DBF
|
||||
if (tsdbOpenBDBDb(&(pDBF->pDB), pEnv, pDBF->path, false) < 0) {
|
||||
terrno = TSDB_CODE_TDB_INIT_FAILED;
|
||||
tsdbCloseBDBDb(pDBF->pDB);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tsdbCloseDBF(SDBFile *pDBF) {
|
||||
if (pDBF->pDB) {
|
||||
tsdbCloseBDBDb(pDBF->pDB);
|
||||
pDBF->pDB = NULL;
|
||||
}
|
||||
tfree(pDBF->path);
|
||||
}
|
||||
|
||||
int32_t tsdbOpenBDBEnv(DB_ENV **ppEnv, const char *path) {
|
||||
int ret = 0;
|
||||
DB_ENV *pEnv = NULL;
|
||||
|
||||
if (path == NULL) return 0;
|
||||
|
||||
ret = db_env_create(&pEnv, 0);
|
||||
if (ret != 0) {
|
||||
BDB_PERR("Failed to create tsdb env", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = pEnv->open(pEnv, path, DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL, 0);
|
||||
if (ret != 0) {
|
||||
// BDB_PERR("Failed to open tsdb env", ret);
|
||||
tsdbWarn("Failed to open tsdb env for path %s since %d", path ? path : "NULL", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ppEnv = pEnv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tsdbCloseBDBEnv(DB_ENV *pEnv) {
|
||||
if (pEnv) {
|
||||
pEnv->close(pEnv, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int tsdbOpenBDBDb(DB **ppDB, DB_ENV *pEnv, const char *pFName, bool isDup) {
|
||||
int ret;
|
||||
DB *pDB;
|
||||
|
||||
ret = db_create(&(pDB), pEnv, 0);
|
||||
if (ret != 0) {
|
||||
BDB_PERR("Failed to create DBP", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (isDup) {
|
||||
ret = pDB->set_flags(pDB, DB_DUPSORT);
|
||||
if (ret != 0) {
|
||||
BDB_PERR("Failed to set DB flags", ret);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = pDB->open(pDB, NULL, pFName, NULL, DB_BTREE, DB_CREATE, 0);
|
||||
if (ret) {
|
||||
BDB_PERR("Failed to open DBF", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ppDB = pDB;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tsdbCloseBDBDb(DB *pDB) {
|
||||
if (pDB) {
|
||||
pDB->close(pDB, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tsdbSaveSmaToDB(SDBFile *pDBF, void *key, uint32_t keySize, void *data, uint32_t dataSize) {
|
||||
int ret;
|
||||
DBT key1 = {0}, value1 = {0};
|
||||
|
||||
key1.data = key;
|
||||
key1.size = keySize;
|
||||
|
||||
value1.data = data;
|
||||
value1.size = dataSize;
|
||||
|
||||
// TODO: lock
|
||||
ret = pDBF->pDB->put(pDBF->pDB, NULL, &key1, &value1, 0);
|
||||
if (ret) {
|
||||
BDB_PERR("Failed to put data to DBF", ret);
|
||||
// TODO: unlock
|
||||
return -1;
|
||||
}
|
||||
// TODO: unlock
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *tsdbGetSmaDataByKey(SDBFile *pDBF, void* key, uint32_t keySize, uint32_t *valueSize) {
|
||||
void *result = NULL;
|
||||
DBT key1 = {0};
|
||||
DBT value1 = {0};
|
||||
int ret;
|
||||
|
||||
// Set key/value
|
||||
key1.data = key;
|
||||
key1.size = keySize;
|
||||
|
||||
// Query
|
||||
// TODO: lock
|
||||
ret = pDBF->pDB->get(pDBF->pDB, NULL, &key1, &value1, 0);
|
||||
// TODO: unlock
|
||||
if (ret != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = calloc(1, value1.size);
|
||||
|
||||
if (result == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*valueSize = value1.size;
|
||||
memcpy(result, value1.data, value1.size);
|
||||
|
||||
return result;
|
||||
}
|
|
@ -80,6 +80,8 @@ static STsdb *tsdbNew(const char *path, int32_t vgId, const STsdbCfg *pTsdbCfg,
|
|||
pTsdb->pmaf = pMAF;
|
||||
pTsdb->pMeta = pMeta;
|
||||
pTsdb->pTfs = pTfs;
|
||||
pTsdb->pTSmaEnv = NULL;
|
||||
pTsdb->pRSmaEnv = NULL;
|
||||
|
||||
pTsdb->fs = tsdbNewFS(pTsdbCfg);
|
||||
|
||||
|
@ -88,8 +90,9 @@ static STsdb *tsdbNew(const char *path, int32_t vgId, const STsdbCfg *pTsdbCfg,
|
|||
|
||||
static void tsdbFree(STsdb *pTsdb) {
|
||||
if (pTsdb) {
|
||||
tsdbFreeSmaEnv(pTsdb->pRSmaEnv);
|
||||
tsdbFreeSmaEnv(pTsdb->pTSmaEnv);
|
||||
tsdbFreeFS(pTsdb->fs);
|
||||
tsdbDestroySmaState(pTsdb->pSmaStat);
|
||||
tfree(pTsdb->path);
|
||||
free(pTsdb);
|
||||
}
|
||||
|
@ -105,6 +108,30 @@ static void tsdbCloseImpl(STsdb *pTsdb) {
|
|||
tsdbCloseFS(pTsdb);
|
||||
// TODO
|
||||
}
|
||||
|
||||
int tsdbLockRepo(STsdb *pTsdb) {
|
||||
int code = pthread_mutex_lock(&pTsdb->mutex);
|
||||
if (code != 0) {
|
||||
tsdbError("vgId:%d failed to lock tsdb since %s", REPO_ID(pTsdb), strerror(errno));
|
||||
terrno = TAOS_SYSTEM_ERROR(code);
|
||||
return -1;
|
||||
}
|
||||
pTsdb->repoLocked = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsdbUnlockRepo(STsdb *pTsdb) {
|
||||
ASSERT(IS_REPO_LOCKED(pTsdb));
|
||||
pTsdb->repoLocked = false;
|
||||
int code = pthread_mutex_unlock(&pTsdb->mutex);
|
||||
if (code != 0) {
|
||||
tsdbError("vgId:%d failed to unlock tsdb since %s", REPO_ID(pTsdb), strerror(errno));
|
||||
terrno = TAOS_SYSTEM_ERROR(code);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
|
||||
#include "tsdbDef.h"
|
||||
|
||||
#undef SMA_PRINT_DEBUG_LOG
|
||||
#define SMA_STORAGE_TSDB_DAYS 30
|
||||
#define SMA_STORAGE_TSDB_TIMES 30
|
||||
#define SMA_STORAGE_SPLIT_HOURS 24
|
||||
#define SMA_KEY_LEN 18 // tableUid_colId_TSKEY 8+2+8
|
||||
|
||||
|
@ -23,7 +25,7 @@
|
|||
#define SMA_STATE_ITEM_HASH_SLOT 32
|
||||
|
||||
#define SMA_TEST_INDEX_NAME "smaTestIndexName" // TODO: just for test
|
||||
#define SMA_TEST_INDEX_UID 123456 // TODO: just for test
|
||||
#define SMA_TEST_INDEX_UID 2000000001 // TODO: just for test
|
||||
typedef enum {
|
||||
SMA_STORAGE_LEVEL_TSDB = 0, // use days of self-defined e.g. vnode${N}/tsdb/tsma/sma_index_uid/v2t200.dat
|
||||
SMA_STORAGE_LEVEL_DFILESET = 1 // use days of TS data e.g. vnode${N}/tsdb/rsma/sma_index_uid/v2r200.dat
|
||||
|
@ -31,23 +33,22 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
STsdb * pTsdb;
|
||||
char * pDFile; // TODO: use the real DFile type, not char*
|
||||
SDBFile dFile;
|
||||
int32_t interval; // interval with the precision of DB
|
||||
// TODO
|
||||
} STSmaWriteH;
|
||||
|
||||
typedef struct {
|
||||
int32_t iter;
|
||||
int32_t fid;
|
||||
} SmaFsIter;
|
||||
typedef struct {
|
||||
STsdb * pTsdb;
|
||||
char * pDFile; // TODO: use the real DFile type, not char*
|
||||
SDBFile dFile;
|
||||
int32_t interval; // interval with the precision of DB
|
||||
int32_t blockSize; // size of SMA block item
|
||||
int8_t storageLevel;
|
||||
int8_t days;
|
||||
SmaFsIter smaFsIter;
|
||||
// TODO
|
||||
} STSmaReadH;
|
||||
|
||||
typedef struct {
|
||||
|
@ -68,18 +69,117 @@ struct SSmaStat {
|
|||
};
|
||||
|
||||
// declaration of static functions
|
||||
static int32_t tsdbInsertTSmaDataImpl(STsdb *pTsdb, char *msg);
|
||||
static int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg);
|
||||
// TODO: This is the basic params, and should wrap the params to a queryHandle.
|
||||
static int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, STSmaDataWrapper *pData, int64_t indexUid, int64_t interval,
|
||||
int8_t intervalUnit, tb_uid_t tableUid, col_id_t colId, TSKEY querySkey,
|
||||
int32_t nMaxResult);
|
||||
static int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, int8_t smaType, char *msg);
|
||||
|
||||
static int32_t tsdbInitSmaStat(SSmaStat **pSmaStat);
|
||||
static int32_t tsdbDestroySmaState(SSmaStat *pSmaStat);
|
||||
static SSmaEnv *tsdbNewSmaEnv(const STsdb *pTsdb, const char *path);
|
||||
static int32_t tsdbInitSmaEnv(STsdb *pTsdb, const char *path, SSmaEnv **pEnv);
|
||||
static int32_t tsdbInitTSmaWriteH(STSmaWriteH *pSmaH, STsdb *pTsdb, STSmaDataWrapper *pData);
|
||||
static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, STSmaDataWrapper *pData);
|
||||
static int32_t tsdbJudgeStorageLevel(int64_t interval, int8_t intervalUnit);
|
||||
static void tsdbDestroyTSmaWriteH(STSmaWriteH *pSmaH);
|
||||
static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, int64_t interval, int8_t intervalUnit);
|
||||
static int32_t tsdbGetSmaStorageLevel(int64_t interval, int8_t intervalUnit);
|
||||
static int32_t tsdbInsertTSmaDataSection(STSmaWriteH *pSmaH, STSmaDataWrapper *pData);
|
||||
static int32_t tsdbInsertTSmaBlocks(void *bTree, const char *smaKey, const char *pData, int32_t dataLen);
|
||||
static int32_t tsdbInsertTSmaBlocks(STSmaWriteH *pSmaH, void *smaKey, uint32_t keyLen, void *pData, uint32_t dataLen);
|
||||
|
||||
static int64_t tsdbGetIntervalByPrecision(int64_t interval, uint8_t intervalUnit, int8_t precision);
|
||||
static int32_t tsdbGetTSmaDays(STsdb *pTsdb, int64_t interval, int32_t storageLevel);
|
||||
static int32_t tsdbSetTSmaDataFile(STSmaWriteH *pSmaH, STSmaDataWrapper *pData, int32_t storageLevel, int32_t fid);
|
||||
static int32_t tsdbInitTSmaFile(STSmaReadH *pSmaH, TSKEY skey);
|
||||
static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, TSKEY *queryKey);
|
||||
|
||||
static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, STSmaDataWrapper *pData);
|
||||
static int32_t tsdbInitTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin);
|
||||
static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin);
|
||||
static SSmaEnv *tsdbNewSmaEnv(const STsdb *pTsdb, const char *path) {
|
||||
SSmaEnv *pEnv = NULL;
|
||||
|
||||
pEnv = (SSmaEnv *)calloc(1, sizeof(SSmaEnv));
|
||||
if (pEnv == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int code = pthread_rwlock_init(&(pEnv->lock), NULL);
|
||||
if (code) {
|
||||
terrno = TAOS_SYSTEM_ERROR(code);
|
||||
free(pEnv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ASSERT(path && (strlen(path) > 0));
|
||||
pEnv->path = strdup(path);
|
||||
if (pEnv->path == NULL) {
|
||||
tsdbFreeSmaEnv(pEnv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tsdbInitSmaStat(&pEnv->pStat) != TSDB_CODE_SUCCESS) {
|
||||
tsdbFreeSmaEnv(pEnv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tsdbOpenBDBEnv(&pEnv->dbEnv, pEnv->path) != TSDB_CODE_SUCCESS) {
|
||||
tsdbFreeSmaEnv(pEnv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pEnv;
|
||||
}
|
||||
|
||||
static int32_t tsdbInitSmaEnv(STsdb *pTsdb, const char *path, SSmaEnv **pEnv) {
|
||||
if (!pEnv) {
|
||||
terrno = TSDB_CODE_INVALID_PTR;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
if (pEnv && *pEnv) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (tsdbLockRepo(pTsdb) != 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
if (*pEnv == NULL) {
|
||||
if ((*pEnv = tsdbNewSmaEnv(pTsdb, path)) == NULL) {
|
||||
tsdbUnlockRepo(pTsdb);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (tsdbUnlockRepo(pTsdb) != 0) {
|
||||
tsdbFreeSmaEnv(*pEnv);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release resources allocated for its member fields, not including itself.
|
||||
*
|
||||
* @param pSmaEnv
|
||||
* @return int32_t
|
||||
*/
|
||||
void tsdbDestroySmaEnv(SSmaEnv *pSmaEnv) {
|
||||
if (pSmaEnv) {
|
||||
tsdbDestroySmaState(pSmaEnv->pStat);
|
||||
tfree(pSmaEnv->pStat);
|
||||
tfree(pSmaEnv->path);
|
||||
pthread_rwlock_destroy(&(pSmaEnv->lock));
|
||||
tsdbCloseBDBEnv(pSmaEnv->dbEnv);
|
||||
}
|
||||
}
|
||||
|
||||
void *tsdbFreeSmaEnv(SSmaEnv *pSmaEnv) {
|
||||
tsdbDestroySmaEnv(pSmaEnv);
|
||||
tfree(pSmaEnv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int32_t tsdbInitSmaStat(SSmaStat **pSmaStat) {
|
||||
ASSERT(pSmaStat != NULL);
|
||||
|
@ -125,6 +225,12 @@ static SSmaStatItem *tsdbNewSmaStatItem(int8_t state) {
|
|||
return pItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release resources allocated for its member fields, not including itself.
|
||||
*
|
||||
* @param pSmaStat
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tsdbDestroySmaState(SSmaStat *pSmaStat) {
|
||||
if (pSmaStat) {
|
||||
// TODO: use taosHashSetFreeFp when taosHashSetFreeFp is ready.
|
||||
|
@ -135,7 +241,6 @@ int32_t tsdbDestroySmaState(SSmaStat *pSmaStat) {
|
|||
item = taosHashIterate(pSmaStat->smaStatItems, item);
|
||||
}
|
||||
taosHashCleanup(pSmaStat->smaStatItems);
|
||||
free(pSmaStat);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,22 +248,35 @@ int32_t tsdbDestroySmaState(SSmaStat *pSmaStat) {
|
|||
* @brief Update expired window according to msg from stream computing module.
|
||||
*
|
||||
* @param pTsdb
|
||||
* @param smaType ETsdbSmaType
|
||||
* @param msg
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, char *msg) {
|
||||
if (msg == NULL) {
|
||||
int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, int8_t smaType, char *msg) {
|
||||
STsdbCfg *pCfg = REPO_CFG(pTsdb);
|
||||
SSmaEnv * pEnv = NULL;
|
||||
|
||||
if (!msg || !pTsdb->pMeta) {
|
||||
terrno = TSDB_CODE_INVALID_PTR;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
// lazy mode
|
||||
if (tsdbInitSmaStat(&pTsdb->pSmaStat) != TSDB_CODE_SUCCESS) {
|
||||
char smaPath[TSDB_FILENAME_LEN] = "/proj/.sma/";
|
||||
if (tsdbInitSmaEnv(pTsdb, smaPath, &pEnv) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
if (smaType == TSDB_SMA_TYPE_TIME_RANGE) {
|
||||
pTsdb->pTSmaEnv = pEnv;
|
||||
} else if (smaType == TSDB_SMA_TYPE_ROLLUP) {
|
||||
pTsdb->pRSmaEnv = pEnv;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
// TODO: decode the msg => start
|
||||
int64_t indexUid = SMA_TEST_INDEX_UID;
|
||||
const char * indexName = SMA_TEST_INDEX_NAME;
|
||||
// const char * indexName = SMA_TEST_INDEX_NAME;
|
||||
const int32_t SMA_TEST_EXPIRED_WINDOW_SIZE = 10;
|
||||
TSKEY expiredWindows[SMA_TEST_EXPIRED_WINDOW_SIZE];
|
||||
int64_t now = taosGetTimestampMs();
|
||||
|
@ -167,9 +285,9 @@ int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, char *msg) {
|
|||
}
|
||||
|
||||
// TODO: decode the msg <= end
|
||||
SHashObj *pItemsHash = pTsdb->pSmaStat->smaStatItems;
|
||||
SHashObj *pItemsHash = SMA_ENV_STAT_ITEMS(pEnv);
|
||||
|
||||
SSmaStatItem *pItem = (SSmaStatItem *)taosHashGet(pItemsHash, indexName, strlen(indexName));
|
||||
SSmaStatItem *pItem = (SSmaStatItem *)taosHashGet(pItemsHash, &indexUid, sizeof(indexUid));
|
||||
if (pItem == NULL) {
|
||||
pItem = tsdbNewSmaStatItem(TSDB_SMA_STAT_EXPIRED); // TODO use the real state
|
||||
if (pItem == NULL) {
|
||||
|
@ -181,20 +299,28 @@ int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, char *msg) {
|
|||
// cache smaMeta
|
||||
STSma *pSma = metaGetSmaInfoByIndex(pTsdb->pMeta, indexUid);
|
||||
if (pSma == NULL) {
|
||||
terrno = TSDB_CODE_TDB_NO_SMA_INDEX_IN_META;
|
||||
taosHashCleanup(pItem->expiredWindows);
|
||||
free(pItem);
|
||||
tsdbWarn("vgId:%d update expired window failed for smaIndex %" PRIi64 " since %s", REPO_ID(pTsdb), indexUid,
|
||||
tstrerror(terrno));
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
pItem->pSma = pSma;
|
||||
|
||||
// TODO: change indexName to indexUid
|
||||
if (taosHashPut(pItemsHash, indexName, strnlen(indexName, TSDB_INDEX_NAME_LEN), &pItem, sizeof(pItem)) != 0) {
|
||||
if (taosHashPut(pItemsHash, &indexUid, sizeof(indexUid), &pItem, sizeof(pItem)) != 0) {
|
||||
// If error occurs during put smaStatItem, free the resources of pItem
|
||||
taosHashCleanup(pItem->expiredWindows);
|
||||
free(pItem);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
SSmaStatItem *pItem1 = (SSmaStatItem *)taosHashGet(pItemsHash, &indexUid, sizeof(indexUid));
|
||||
int size1 = taosHashGetSize(pItem1->expiredWindows);
|
||||
tsdbWarn("vgId:%d smaIndex %" PRIi64 " size is %d before hashPut", REPO_ID(pTsdb), indexUid, size1);
|
||||
#endif
|
||||
|
||||
int8_t state = TSDB_SMA_STAT_EXPIRED;
|
||||
for (int32_t i = 0; i < SMA_TEST_EXPIRED_WINDOW_SIZE; ++i) {
|
||||
|
@ -207,21 +333,28 @@ int32_t tsdbUpdateExpiredWindow(STsdb *pTsdb, char *msg) {
|
|||
// windows failed to put into hash table.
|
||||
taosHashCleanup(pItem->expiredWindows);
|
||||
tfree(pItem->pSma);
|
||||
taosHashRemove(pItemsHash, indexName, sizeof(indexName));
|
||||
taosHashRemove(pItemsHash, &indexUid, sizeof(indexUid));
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
SSmaStatItem *pItem2 = (SSmaStatItem *)taosHashGet(pItemsHash, &indexUid, sizeof(indexUid));
|
||||
int size2 = taosHashGetSize(pItem1->expiredWindows);
|
||||
tsdbWarn("vgId:%d smaIndex %" PRIi64 " size is %d after hashPut", REPO_ID(pTsdb), indexUid, size2);
|
||||
#endif
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t tsdbResetExpiredWindow(STsdb *pTsdb, int64_t indexUid, TSKEY skey) {
|
||||
static int32_t tsdbResetExpiredWindow(SSmaStat *pStat, int64_t indexUid, TSKEY skey) {
|
||||
SSmaStatItem *pItem = NULL;
|
||||
|
||||
if (pTsdb->pSmaStat && pTsdb->pSmaStat->smaStatItems) {
|
||||
pItem = (SSmaStatItem *)taosHashGet(pTsdb->pSmaStat->smaStatItems, &indexUid, sizeof(indexUid));
|
||||
// TODO: If HASH_ENTRY_LOCK used, whether rwlock needed to handle cases of removing hashNode?
|
||||
if (pStat && pStat->smaStatItems) {
|
||||
pItem = (SSmaStatItem *)taosHashGet(pStat->smaStatItems, &indexUid, sizeof(indexUid));
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (pItem != NULL) {
|
||||
// TODO: reset time window for the sma data blocks
|
||||
if (taosHashRemove(pItem->expiredWindows, &skey, sizeof(TSKEY)) != 0) {
|
||||
|
@ -231,6 +364,7 @@ static int32_t tsdbResetExpiredWindow(STsdb *pTsdb, int64_t indexUid, TSKEY skey
|
|||
} else {
|
||||
// error handling
|
||||
}
|
||||
#endif
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -241,7 +375,7 @@ static int32_t tsdbResetExpiredWindow(STsdb *pTsdb, int64_t indexUid, TSKEY skey
|
|||
* @param intervalUnit
|
||||
* @return int32_t
|
||||
*/
|
||||
static int32_t tsdbJudgeStorageLevel(int64_t interval, int8_t intervalUnit) {
|
||||
static int32_t tsdbGetSmaStorageLevel(int64_t interval, int8_t intervalUnit) {
|
||||
// TODO: configurable for SMA_STORAGE_SPLIT_HOURS?
|
||||
switch (intervalUnit) {
|
||||
case TD_TIME_UNIT_HOUR:
|
||||
|
@ -281,18 +415,35 @@ static int32_t tsdbJudgeStorageLevel(int64_t interval, int8_t intervalUnit) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Insert TSma data blocks to B+Tree
|
||||
* @brief Insert TSma data blocks to DB File build by B+Tree
|
||||
*
|
||||
* @param bTree
|
||||
* @param pSmaH
|
||||
* @param smaKey
|
||||
* @param keyLen
|
||||
* @param pData
|
||||
* @param dataLen
|
||||
* @return int32_t
|
||||
*/
|
||||
static int32_t tsdbInsertTSmaBlocks(void *bTree, const char *smaKey, const char *pData, int32_t dataLen) {
|
||||
static int32_t tsdbInsertTSmaBlocks(STSmaWriteH *pSmaH, void *smaKey, uint32_t keyLen, void *pData, uint32_t dataLen) {
|
||||
SDBFile *pDBFile = &pSmaH->dFile;
|
||||
|
||||
// TODO: insert sma data blocks into B+Tree
|
||||
tsdbDebug("insert sma data blocks into B+Tree: smaKey %" PRIx64 "-%" PRIu16 "-%" PRIx64 ", dataLen %d",
|
||||
*(uint64_t *)smaKey, *(uint16_t *)POINTER_SHIFT(smaKey, 8), *(int64_t *)POINTER_SHIFT(smaKey, 10), dataLen);
|
||||
tsdbDebug("vgId:%d insert sma data blocks into %s: smaKey %" PRIx64 "-%" PRIu16 "-%" PRIx64 ", dataLen %d",
|
||||
REPO_ID(pSmaH->pTsdb), pDBFile->path, *(tb_uid_t *)smaKey, *(uint16_t *)POINTER_SHIFT(smaKey, 8),
|
||||
*(int64_t *)POINTER_SHIFT(smaKey, 10), dataLen);
|
||||
|
||||
if (tsdbSaveSmaToDB(pDBFile, smaKey, keyLen, pData, dataLen) != 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
#ifdef SMA_PRINT_DEBUG_LOG
|
||||
uint32_t valueSize = 0;
|
||||
void * data = tsdbGetSmaDataByKey(pDBFile, smaKey, keyLen, &valueSize);
|
||||
ASSERT(data != NULL);
|
||||
for (uint32_t v = 0; v < valueSize; v += 8) {
|
||||
tsdbWarn("vgId:%d sma data - val[%d] is %" PRIi64, REPO_ID(pSmaH->pTsdb), v, *(int64_t *)POINTER_SHIFT(data, v));
|
||||
}
|
||||
#endif
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -324,41 +475,41 @@ static int64_t tsdbGetIntervalByPrecision(int64_t interval, uint8_t intervalUnit
|
|||
}
|
||||
}
|
||||
|
||||
switch (intervalUnit) {
|
||||
case TD_TIME_UNIT_MILLISEC:
|
||||
if (TSDB_TIME_PRECISION_MILLI == precision) {
|
||||
return interval;
|
||||
} else if (TSDB_TIME_PRECISION_MICRO == precision) {
|
||||
return interval * 1e3;
|
||||
} else { // nano second
|
||||
return interval * 1e6;
|
||||
}
|
||||
break;
|
||||
case TD_TIME_UNIT_MICROSEC:
|
||||
if (TSDB_TIME_PRECISION_MILLI == precision) {
|
||||
switch (precision) {
|
||||
case TSDB_TIME_PRECISION_MILLI:
|
||||
if (TD_TIME_UNIT_MICROSEC == intervalUnit) { // us
|
||||
return interval / 1e3;
|
||||
} else if (TSDB_TIME_PRECISION_MICRO == precision) {
|
||||
return interval;
|
||||
} else { // nano second
|
||||
return interval * 1e3;
|
||||
}
|
||||
break;
|
||||
case TD_TIME_UNIT_NANOSEC:
|
||||
if (TSDB_TIME_PRECISION_MILLI == precision) {
|
||||
} else if (TD_TIME_UNIT_NANOSEC == intervalUnit) { // nano second
|
||||
return interval / 1e6;
|
||||
} else if (TSDB_TIME_PRECISION_MICRO == precision) {
|
||||
return interval / 1e3;
|
||||
} else { // nano second
|
||||
} else {
|
||||
return interval;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (TSDB_TIME_PRECISION_MILLI == precision) {
|
||||
case TSDB_TIME_PRECISION_MICRO:
|
||||
if (TD_TIME_UNIT_MICROSEC == intervalUnit) { // us
|
||||
return interval;
|
||||
} else if (TD_TIME_UNIT_NANOSEC == intervalUnit) { // nano second
|
||||
return interval / 1e3;
|
||||
} else {
|
||||
return interval * 1e3;
|
||||
} else if (TSDB_TIME_PRECISION_MICRO == precision) {
|
||||
}
|
||||
break;
|
||||
case TSDB_TIME_PRECISION_NANO:
|
||||
if (TD_TIME_UNIT_MICROSEC == intervalUnit) {
|
||||
return interval * 1e3;
|
||||
} else if (TD_TIME_UNIT_NANOSEC == intervalUnit) { // nano second
|
||||
return interval;
|
||||
} else {
|
||||
return interval * 1e6;
|
||||
} else { // nano second
|
||||
return interval * 1e9;
|
||||
}
|
||||
break;
|
||||
default: // ms
|
||||
if (TD_TIME_UNIT_MICROSEC == intervalUnit) { // us
|
||||
return interval / 1e3;
|
||||
} else if (TD_TIME_UNIT_NANOSEC == intervalUnit) { // nano second
|
||||
return interval / 1e6;
|
||||
} else {
|
||||
return interval;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -381,8 +532,6 @@ static int32_t tsdbInsertTSmaDataSection(STSmaWriteH *pSmaH, STSmaDataWrapper *p
|
|||
|
||||
// TODO: check the data integrity
|
||||
|
||||
void *bTree = pSmaH->pDFile;
|
||||
|
||||
int32_t len = 0;
|
||||
while (true) {
|
||||
if (len >= pData->dataLen) {
|
||||
|
@ -405,7 +554,7 @@ static int32_t tsdbInsertTSmaDataSection(STSmaWriteH *pSmaH, STSmaDataWrapper *p
|
|||
pData->indexUid, pData->skey, pTbData->tableUid, pColData->colId);
|
||||
#endif
|
||||
tsdbEncodeTSmaKey(pTbData->tableUid, pColData->colId, pData->skey, (void **)&pSmaKey);
|
||||
if (tsdbInsertTSmaBlocks(bTree, smaKey, pColData->data, pColData->blockSize) < 0) {
|
||||
if (tsdbInsertTSmaBlocks(pSmaH, smaKey, SMA_KEY_LEN, pColData->data, pColData->blockSize) < 0) {
|
||||
tsdbWarn("vgId:%d insert tSma blocks failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
|
||||
}
|
||||
tbLen += (sizeof(STSmaColData) + pColData->blockSize);
|
||||
|
@ -419,15 +568,43 @@ static int32_t tsdbInsertTSmaDataSection(STSmaWriteH *pSmaH, STSmaDataWrapper *p
|
|||
static int32_t tsdbInitTSmaWriteH(STSmaWriteH *pSmaH, STsdb *pTsdb, STSmaDataWrapper *pData) {
|
||||
pSmaH->pTsdb = pTsdb;
|
||||
pSmaH->interval = tsdbGetIntervalByPrecision(pData->interval, pData->intervalUnit, REPO_CFG(pTsdb)->precision);
|
||||
}
|
||||
|
||||
static int32_t tsdbSetTSmaDataFile(STSmaWriteH *pSmaH, STSmaDataWrapper *pData, int32_t storageLevel, int32_t fid) {
|
||||
// TODO
|
||||
pSmaH->pDFile = "tSma_interval_file_name";
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void tsdbDestroyTSmaWriteH(STSmaWriteH *pSmaH) {
|
||||
if (pSmaH) {
|
||||
tsdbCloseDBF(&pSmaH->dFile);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t tsdbSetTSmaDataFile(STSmaWriteH *pSmaH, STSmaDataWrapper *pData, int32_t storageLevel, int32_t fid) {
|
||||
STsdb *pTsdb = pSmaH->pTsdb;
|
||||
ASSERT(pSmaH->dFile.path == NULL && pSmaH->dFile.pDB == NULL);
|
||||
char tSmaFile[TSDB_FILENAME_LEN] = {0};
|
||||
snprintf(tSmaFile, TSDB_FILENAME_LEN, "v%df%d.tsma", REPO_ID(pTsdb), fid);
|
||||
pSmaH->dFile.path = strdup(tSmaFile);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param pTsdb
|
||||
* @param interval Interval calculated by DB's precision
|
||||
* @param storageLevel
|
||||
* @return int32_t
|
||||
*/
|
||||
static int32_t tsdbGetTSmaDays(STsdb *pTsdb, int64_t interval, int32_t storageLevel) {
|
||||
STsdbCfg *pCfg = REPO_CFG(pTsdb);
|
||||
int32_t daysPerFile = pCfg->daysPerFile;
|
||||
|
||||
if (storageLevel == SMA_STORAGE_LEVEL_TSDB) {
|
||||
int32_t days = SMA_STORAGE_TSDB_TIMES * (interval / tsTickPerDay[pCfg->precision]);
|
||||
daysPerFile = days > SMA_STORAGE_TSDB_DAYS ? days : SMA_STORAGE_TSDB_DAYS;
|
||||
}
|
||||
|
||||
return daysPerFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert/Update Time-range-wise SMA data.
|
||||
|
@ -441,48 +618,69 @@ static int32_t tsdbSetTSmaDataFile(STSmaWriteH *pSmaH, STSmaDataWrapper *pData,
|
|||
* @param msg
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tsdbInsertTSmaDataImpl(STsdb *pTsdb, char *msg) {
|
||||
static int32_t tsdbInsertTSmaDataImpl(STsdb *pTsdb, char *msg) {
|
||||
STsdbCfg * pCfg = REPO_CFG(pTsdb);
|
||||
STSmaDataWrapper *pData = (STSmaDataWrapper *)msg;
|
||||
STSmaWriteH tSmaH = {0};
|
||||
|
||||
tsdbInitTSmaWriteH(&tSmaH, pTsdb, pData);
|
||||
if (!pTsdb->pTSmaEnv) {
|
||||
terrno = TSDB_CODE_INVALID_PTR;
|
||||
tsdbWarn("vgId:%d insert tSma data failed since pTSmaEnv is NULL", REPO_ID(pTsdb));
|
||||
return terrno;
|
||||
}
|
||||
|
||||
if (pData->dataLen <= 0) {
|
||||
TASSERT(0);
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
return terrno;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
// Step 1: Judge the storage level
|
||||
int32_t storageLevel = tsdbJudgeStorageLevel(pData->interval, pData->intervalUnit);
|
||||
int32_t daysPerFile = storageLevel == SMA_STORAGE_LEVEL_TSDB ? SMA_STORAGE_TSDB_DAYS : pCfg->daysPerFile;
|
||||
STSmaWriteH tSmaH = {0};
|
||||
|
||||
if (tsdbInitTSmaWriteH(&tSmaH, pTsdb, pData) != 0) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
// Step 1: Judge the storage level and days
|
||||
int32_t storageLevel = tsdbGetSmaStorageLevel(pData->interval, pData->intervalUnit);
|
||||
int32_t daysPerFile = tsdbGetTSmaDays(pTsdb, tSmaH.interval, storageLevel);
|
||||
int32_t fid = (int32_t)(TSDB_KEY_FID(pData->skey, daysPerFile, pCfg->precision));
|
||||
|
||||
// Step 2: Set the DFile for storage of SMA index, and iterate/split the TSma data and store to B+Tree index file
|
||||
// - Set and open the DFile or the B+Tree file
|
||||
|
||||
int32_t fid = (int32_t)(TSDB_KEY_FID(pData->skey, daysPerFile, pCfg->precision));
|
||||
|
||||
// Save all the TSma data to one file
|
||||
// TODO: tsdbStartTSmaCommit();
|
||||
tsdbSetTSmaDataFile(&tSmaH, pData, storageLevel, fid);
|
||||
tsdbInsertTSmaDataSection(&tSmaH, pData);
|
||||
if (tsdbOpenDBF(pTsdb->pTSmaEnv->dbEnv, &tSmaH.dFile) != 0) {
|
||||
tsdbWarn("vgId:%d open DB file %s failed since %s", REPO_ID(pTsdb),
|
||||
tSmaH.dFile.path ? tSmaH.dFile.path : "path is NULL", tstrerror(terrno));
|
||||
tsdbDestroyTSmaWriteH(&tSmaH);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
if (tsdbInsertTSmaDataSection(&tSmaH, pData) != 0) {
|
||||
tsdbWarn("vgId:%d insert tSma data section failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
|
||||
tsdbDestroyTSmaWriteH(&tSmaH);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
// TODO:tsdbEndTSmaCommit();
|
||||
|
||||
// reset the SSmaStat
|
||||
tsdbResetExpiredWindow(pTsdb, pData->indexUid, pData->skey);
|
||||
// Step 3: reset the SSmaStat
|
||||
tsdbResetExpiredWindow(SMA_ENV_STAT(pTsdb->pTSmaEnv), pData->indexUid, pData->skey);
|
||||
|
||||
tsdbDestroyTSmaWriteH(&tSmaH);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t tsdbSetRSmaDataFile(STSmaWriteH *pSmaH, STSmaDataWrapper *pData, int32_t fid) {
|
||||
// TODO
|
||||
pSmaH->pDFile = "rSma_interval_file_name";
|
||||
STsdb *pTsdb = pSmaH->pTsdb;
|
||||
|
||||
char tSmaFile[TSDB_FILENAME_LEN] = {0};
|
||||
snprintf(tSmaFile, TSDB_FILENAME_LEN, "v%df%d.rsma", REPO_ID(pTsdb), fid);
|
||||
pSmaH->dFile.path = strdup(tSmaFile);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg) {
|
||||
static int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg) {
|
||||
STsdbCfg * pCfg = REPO_CFG(pTsdb);
|
||||
STSmaDataWrapper *pData = (STSmaDataWrapper *)msg;
|
||||
STSmaWriteH tSmaH = {0};
|
||||
|
@ -496,7 +694,7 @@ int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg) {
|
|||
}
|
||||
|
||||
// Step 1: Judge the storage level
|
||||
int32_t storageLevel = tsdbJudgeStorageLevel(pData->interval, pData->intervalUnit);
|
||||
int32_t storageLevel = tsdbGetSmaStorageLevel(pData->interval, pData->intervalUnit);
|
||||
int32_t daysPerFile = storageLevel == SMA_STORAGE_LEVEL_TSDB ? SMA_STORAGE_TSDB_DAYS : pCfg->daysPerFile;
|
||||
|
||||
// Step 2: Set the DFile for storage of SMA index, and iterate/split the TSma data and store to B+Tree index file
|
||||
|
@ -507,45 +705,46 @@ int32_t tsdbInsertRSmaDataImpl(STsdb *pTsdb, char *msg) {
|
|||
// Save all the TSma data to one file
|
||||
// TODO: tsdbStartTSmaCommit();
|
||||
tsdbSetTSmaDataFile(&tSmaH, pData, storageLevel, fid);
|
||||
|
||||
tsdbInsertTSmaDataSection(&tSmaH, pData);
|
||||
// TODO:tsdbEndTSmaCommit();
|
||||
|
||||
// reset the SSmaStat
|
||||
tsdbResetExpiredWindow(pTsdb, pData->indexUid, pData->skey);
|
||||
tsdbResetExpiredWindow(SMA_ENV_STAT(pTsdb->pRSmaEnv), pData->indexUid, pData->skey);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init of tSma ReadH
|
||||
* @brief
|
||||
*
|
||||
* @param pSmaH
|
||||
* @param pTsdb
|
||||
* @param param
|
||||
* @param pData
|
||||
* @param interval
|
||||
* @param intervalUnit
|
||||
* @return int32_t
|
||||
*/
|
||||
static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, STSmaDataWrapper *pData) {
|
||||
static int32_t tsdbInitTSmaReadH(STSmaReadH *pSmaH, STsdb *pTsdb, int64_t interval, int8_t intervalUnit) {
|
||||
pSmaH->pTsdb = pTsdb;
|
||||
pSmaH->interval = tsdbGetIntervalByPrecision(pData->interval, pData->intervalUnit, REPO_CFG(pTsdb)->precision);
|
||||
// pSmaH->blockSize = param->numOfFuncIds * sizeof(int64_t);
|
||||
pSmaH->interval = tsdbGetIntervalByPrecision(interval, intervalUnit, REPO_CFG(pTsdb)->precision);
|
||||
pSmaH->storageLevel = tsdbGetSmaStorageLevel(interval, intervalUnit);
|
||||
pSmaH->days = tsdbGetTSmaDays(pTsdb, pSmaH->interval, pSmaH->storageLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init of tSma FS
|
||||
*
|
||||
* @param pReadH
|
||||
* @param param
|
||||
* @param queryWin
|
||||
* @param skey
|
||||
* @return int32_t
|
||||
*/
|
||||
static int32_t tsdbInitTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin) {
|
||||
int32_t storageLevel = 0; //tsdbJudgeStorageLevel(param->interval, param->intervalUnit);
|
||||
int32_t daysPerFile =
|
||||
storageLevel == SMA_STORAGE_LEVEL_TSDB ? SMA_STORAGE_TSDB_DAYS : REPO_CFG(pReadH->pTsdb)->daysPerFile;
|
||||
pReadH->storageLevel = storageLevel;
|
||||
pReadH->days = daysPerFile;
|
||||
pReadH->smaFsIter.iter = 0;
|
||||
static int32_t tsdbInitTSmaFile(STSmaReadH *pSmaH, TSKEY skey) {
|
||||
int32_t fid = (int32_t)(TSDB_KEY_FID(skey, pSmaH->days, REPO_CFG(pSmaH->pTsdb)->precision));
|
||||
char tSmaFile[TSDB_FILENAME_LEN] = {0};
|
||||
snprintf(tSmaFile, TSDB_FILENAME_LEN, "v%df%d.tsma", REPO_ID(pSmaH->pTsdb), fid);
|
||||
pSmaH->dFile.path = strdup(tSmaFile);
|
||||
pSmaH->smaFsIter.iter = 0;
|
||||
pSmaH->smaFsIter.fid = fid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -557,17 +756,18 @@ static int32_t tsdbInitTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin) {
|
|||
* @return true
|
||||
* @return false
|
||||
*/
|
||||
static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin) {
|
||||
static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, TSKEY *queryKey) {
|
||||
SArray *smaFs = pReadH->pTsdb->fs->cstatus->sf;
|
||||
int32_t nSmaFs = taosArrayGetSize(smaFs);
|
||||
|
||||
pReadH->pDFile = NULL;
|
||||
tsdbCloseDBF(&pReadH->dFile);
|
||||
|
||||
#if 0
|
||||
while (pReadH->smaFsIter.iter < nSmaFs) {
|
||||
void *pSmaFile = taosArrayGet(smaFs, pReadH->smaFsIter.iter);
|
||||
if (pSmaFile) { // match(indexName, queryWindow)
|
||||
// TODO: select the file by index_name ...
|
||||
pReadH->pDFile = pSmaFile;
|
||||
pReadH->dFile = pSmaFile;
|
||||
++pReadH->smaFsIter.iter;
|
||||
break;
|
||||
}
|
||||
|
@ -578,41 +778,83 @@ static bool tsdbSetAndOpenTSmaFile(STSmaReadH *pReadH, STimeWindow *queryWin) {
|
|||
tsdbDebug("vg%d: smaFile %s matched", REPO_ID(pReadH->pTsdb), "[pSmaFile dir]");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the data between queryWin and fill the pData.
|
||||
* @brief
|
||||
*
|
||||
* @param pTsdb
|
||||
* @param param
|
||||
* @param pTsdb Return the data between queryWin and fill the pData.
|
||||
* @param pData
|
||||
* @param queryWin
|
||||
* @param indexUid
|
||||
* @param interval
|
||||
* @param intervalUnit
|
||||
* @param tableUid
|
||||
* @param colId
|
||||
* @param pQuerySKey
|
||||
* @param nMaxResult The query invoker should control the nMaxResult need to return to avoid OOM.
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, STSmaDataWrapper *pData, STimeWindow *queryWin, int32_t nMaxResult) {
|
||||
SSmaStatItem *pItem =
|
||||
(SSmaStatItem *)taosHashGet(pTsdb->pSmaStat->smaStatItems, &pData->indexUid, sizeof(pData->indexUid));
|
||||
static int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, STSmaDataWrapper *pData, int64_t indexUid, int64_t interval,
|
||||
int8_t intervalUnit, tb_uid_t tableUid, col_id_t colId, TSKEY querySkey,
|
||||
int32_t nMaxResult) {
|
||||
SSmaStatItem *pItem = (SSmaStatItem *)taosHashGet(SMA_ENV_STAT_ITEMS(pTsdb->pTSmaEnv), &indexUid, sizeof(indexUid));
|
||||
if (pItem == NULL) {
|
||||
// mark all window as expired and notify query module to query raw TS data.
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t nQueryWin = 0;
|
||||
#if 0
|
||||
int32_t nQueryWin = taosArrayGetSize(pQuerySKey);
|
||||
for (int32_t n = 0; n < nQueryWin; ++n) {
|
||||
TSKEY thisWindow = n;
|
||||
if (taosHashGet(pItem->expiredWindows, &thisWindow, sizeof(thisWindow)) != NULL) {
|
||||
TSKEY skey = taosArrayGet(pQuerySKey, n);
|
||||
if (taosHashGet(pItem->expiredWindows, &skey, sizeof(TSKEY)) != NULL) {
|
||||
// TODO: mark this window as expired.
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#if 0
|
||||
if (taosHashGet(pItem->expiredWindows, &querySkey, sizeof(TSKEY)) != NULL) {
|
||||
// TODO: mark this window as expired.
|
||||
}
|
||||
#endif
|
||||
STSmaReadH tReadH = {0};
|
||||
tsdbInitTSmaReadH(&tReadH, pTsdb, pData);
|
||||
tsdbInitTSmaReadH(&tReadH, pTsdb, interval, intervalUnit);
|
||||
tsdbCloseDBF(&tReadH.dFile);
|
||||
|
||||
tsdbInitTSmaFile(&tReadH, queryWin);
|
||||
tsdbInitTSmaFile(&tReadH, querySkey);
|
||||
if (tsdbOpenDBF(SMA_ENV_ENV(pTsdb->pTSmaEnv), &tReadH.dFile) != 0) {
|
||||
tsdbWarn("vgId:%d open DBF %s failed since %s", REPO_ID(pTsdb), tReadH.dFile.path, tstrerror(terrno));
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
char smaKey[SMA_KEY_LEN] = {0};
|
||||
void *pSmaKey = &smaKey;
|
||||
tsdbEncodeTSmaKey(tableUid, colId, querySkey, (void **)&pSmaKey);
|
||||
|
||||
tsdbDebug("vgId:%d get sma data from %s: smaKey %" PRIx64 "-%" PRIu16 "-%" PRIx64 ", keyLen %d", REPO_ID(pTsdb),
|
||||
tReadH.dFile.path, *(tb_uid_t *)smaKey, *(uint16_t *)POINTER_SHIFT(smaKey, 8),
|
||||
*(int64_t *)POINTER_SHIFT(smaKey, 10), SMA_KEY_LEN);
|
||||
|
||||
void * result = NULL;
|
||||
uint32_t valueSize = 0;
|
||||
if ((result = tsdbGetSmaDataByKey(&tReadH.dFile, smaKey, SMA_KEY_LEN, &valueSize)) == NULL) {
|
||||
tsdbWarn("vgId:%d get sma data failed from smaIndex %" PRIi64 ", smaKey %" PRIx64 "-%" PRIu16 "-%" PRIx64
|
||||
" since %s",
|
||||
REPO_ID(pTsdb), indexUid, *(tb_uid_t *)smaKey, *(uint16_t *)POINTER_SHIFT(smaKey, 8),
|
||||
*(int64_t *)POINTER_SHIFT(smaKey, 10), tstrerror(terrno));
|
||||
tsdbCloseDBF(&tReadH.dFile);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
tfree(result);
|
||||
#ifdef SMA_PRINT_DEBUG_LOG
|
||||
for (uint32_t v = 0; v < valueSize; v += 8) {
|
||||
tsdbWarn("vgId:%d v[%d]=%" PRIi64, REPO_ID(pTsdb), v, *(int64_t *)POINTER_SHIFT(result, v));
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
int32_t nResult = 0;
|
||||
int64_t lastKey = 0;
|
||||
|
||||
|
@ -634,8 +876,9 @@ int32_t tsdbGetTSmaDataImpl(STsdb *pTsdb, STSmaDataWrapper *pData, STimeWindow *
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
// read data from file and fill the result
|
||||
tsdbCloseDBF(&tReadH.dFile);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -674,3 +917,54 @@ int32_t tsdbRemoveTSmaData(STsdb *pTsdb, void *smaIndex, STimeWindow *pWin) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Insert/Update tSma(Time-range-wise SMA) data from stream computing engine
|
||||
*
|
||||
* @param pTsdb
|
||||
* @param param
|
||||
* @param msg
|
||||
* @return int32_t
|
||||
* TODO: Who is responsible for resource allocate and release?
|
||||
*/
|
||||
int32_t tsdbInsertTSmaData(STsdb *pTsdb, char *msg) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if ((code = tsdbInsertTSmaDataImpl(pTsdb, msg)) < 0) {
|
||||
tsdbWarn("vgId:%d insert tSma data failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbUpdateSmaWindow(STsdb *pTsdb, int8_t smaType, char *msg) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if ((code = tsdbUpdateExpiredWindow(pTsdb, smaType, msg)) < 0) {
|
||||
tsdbWarn("vgId:%d update expired sma window failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert Time-range-wise Rollup Sma(RSma) data
|
||||
*
|
||||
* @param pTsdb
|
||||
* @param param
|
||||
* @param msg
|
||||
* @return int32_t
|
||||
*/
|
||||
int32_t tsdbInsertRSmaData(STsdb *pTsdb, char *msg) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if ((code = tsdbInsertRSmaDataImpl(pTsdb, msg)) < 0) {
|
||||
tsdbWarn("vgId:%d insert rSma data failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbGetTSmaData(STsdb *pTsdb, STSmaDataWrapper *pData, int64_t indexUid, int64_t interval, int8_t intervalUnit,
|
||||
tb_uid_t tableUid, col_id_t colId, TSKEY querySkey, int32_t nMaxResult) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if ((code = tsdbGetTSmaDataImpl(pTsdb, pData, indexUid, interval, intervalUnit, tableUid, colId, querySkey,
|
||||
nMaxResult)) < 0) {
|
||||
tsdbWarn("vgId:%d get tSma data failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
|
||||
}
|
||||
return code;
|
||||
}
|
|
@ -34,6 +34,7 @@ int tsdbInsertData(STsdb *pTsdb, SSubmitReq *pMsg, SSubmitRsp *pRsp) {
|
|||
return tsdbMemTableInsert(pTsdb, pTsdb->mem, pMsg, NULL);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* @brief Insert/Update tSma(Time-range-wise SMA) data from stream computing engine
|
||||
*
|
||||
|
@ -51,6 +52,14 @@ int32_t tsdbInsertTSmaData(STsdb *pTsdb, char *msg) {
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbUpdateSmaWindow(STsdb *pTsdb, int8_t smaType, char *msg) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if ((code = tsdbUpdateExpiredWindow(pTsdb, smaType, msg)) < 0) {
|
||||
tsdbWarn("vgId:%d update expired sma window failed since %s", REPO_ID(pTsdb), tstrerror(terrno));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert Time-range-wise Rollup Sma(RSma) data
|
||||
*
|
||||
|
@ -66,3 +75,5 @@ int32_t tsdbInsertRSmaData(STsdb *pTsdb, char *msg) {
|
|||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -33,7 +33,7 @@ int main(int argc, char **argv) {
|
|||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
TEST(testCase, tSmaEncodeDecodeTest) {
|
||||
TEST(testCase, tSma_Meta_Encode_Decode_Test) {
|
||||
// encode
|
||||
STSma tSma = {0};
|
||||
tSma.version = 0;
|
||||
|
@ -87,8 +87,9 @@ TEST(testCase, tSmaEncodeDecodeTest) {
|
|||
tdDestroyTSma(&tSma);
|
||||
tdDestroyTSmaWrapper(&dstTSmaWrapper);
|
||||
}
|
||||
|
||||
#if 1
|
||||
TEST(testCase, tSma_DB_Put_Get_Del_Test) {
|
||||
TEST(testCase, tSma_metaDB_Put_Get_Del_Test) {
|
||||
const char * smaIndexName1 = "sma_index_test_1";
|
||||
const char * smaIndexName2 = "sma_index_test_2";
|
||||
const char * timezone = "Asia/Shanghai";
|
||||
|
@ -220,13 +221,84 @@ TEST(testCase, tSma_DB_Put_Get_Del_Test) {
|
|||
#endif
|
||||
|
||||
#if 1
|
||||
TEST(testCase, tSmaInsertTest) {
|
||||
const int64_t indexUid = 2000000002;
|
||||
TEST(testCase, tSma_Data_Insert_Query_Test) {
|
||||
// step 1: prepare meta
|
||||
const char * smaIndexName1 = "sma_index_test_1";
|
||||
const char * timezone = "Asia/Shanghai";
|
||||
const char * expr = "select count(a,b, top 20), from table interval 1d, sliding 1h;";
|
||||
const char * tagsFilter = "where tags.location='Beijing' and tags.district='ChaoYang'";
|
||||
const char * smaTestDir = "./smaTest";
|
||||
const tb_uid_t tbUid = 1234567890;
|
||||
const int64_t indexUid1 = 2000000001;
|
||||
const int64_t interval1 = 1;
|
||||
const int8_t intervalUnit1 = TD_TIME_UNIT_DAY;
|
||||
const uint32_t nCntTSma = 2;
|
||||
TSKEY skey1 = 1646987196;
|
||||
const int64_t testSmaData1 = 100;
|
||||
const int64_t testSmaData2 = 200;
|
||||
// encode
|
||||
STSma tSma = {0};
|
||||
tSma.version = 0;
|
||||
tSma.intervalUnit = TD_TIME_UNIT_DAY;
|
||||
tSma.interval = 1;
|
||||
tSma.slidingUnit = TD_TIME_UNIT_HOUR;
|
||||
tSma.sliding = 0;
|
||||
tSma.indexUid = indexUid1;
|
||||
tstrncpy(tSma.indexName, smaIndexName1, TSDB_INDEX_NAME_LEN);
|
||||
tstrncpy(tSma.timezone, timezone, TD_TIMEZONE_LEN);
|
||||
tSma.tableUid = tbUid;
|
||||
|
||||
tSma.exprLen = strlen(expr);
|
||||
tSma.expr = (char *)calloc(tSma.exprLen + 1, 1);
|
||||
tstrncpy(tSma.expr, expr, tSma.exprLen + 1);
|
||||
|
||||
tSma.tagsFilterLen = strlen(tagsFilter);
|
||||
tSma.tagsFilter = (char *)calloc(tSma.tagsFilterLen + 1, 1);
|
||||
tstrncpy(tSma.tagsFilter, tagsFilter, tSma.tagsFilterLen + 1);
|
||||
|
||||
SMeta * pMeta = NULL;
|
||||
STSma * pSmaCfg = &tSma;
|
||||
const SMetaCfg *pMetaCfg = &defaultMetaOptions;
|
||||
|
||||
taosRemoveDir(smaTestDir);
|
||||
|
||||
pMeta = metaOpen(smaTestDir, pMetaCfg, NULL);
|
||||
assert(pMeta != NULL);
|
||||
// save index 1
|
||||
EXPECT_EQ(metaSaveSmaToDB(pMeta, pSmaCfg), 0);
|
||||
|
||||
// step 2: insert data
|
||||
STSmaDataWrapper *pSmaData = NULL;
|
||||
STsdb tsdb = {0};
|
||||
STsdbCfg * pCfg = &tsdb.config;
|
||||
|
||||
pCfg->daysPerFile = 1;
|
||||
tsdb.pMeta = pMeta;
|
||||
tsdb.vgId = 2;
|
||||
tsdb.config.daysPerFile = 10; // default days is 10
|
||||
tsdb.config.keep1 = 30;
|
||||
tsdb.config.keep2 = 90;
|
||||
tsdb.config.keep = 365;
|
||||
tsdb.config.precision = TSDB_TIME_PRECISION_MILLI;
|
||||
tsdb.config.update = TD_ROW_OVERWRITE_UPDATE;
|
||||
tsdb.config.compression = TWO_STAGE_COMP;
|
||||
|
||||
switch (tsdb.config.precision) {
|
||||
case TSDB_TIME_PRECISION_MILLI:
|
||||
skey1 *= 1e3;
|
||||
break;
|
||||
case TSDB_TIME_PRECISION_MICRO:
|
||||
skey1 *= 1e6;
|
||||
break;
|
||||
case TSDB_TIME_PRECISION_NANO:
|
||||
skey1 *= 1e9;
|
||||
break;
|
||||
default: // ms
|
||||
skey1 *= 1e3;
|
||||
break;
|
||||
}
|
||||
|
||||
char *msg = (char *)calloc(100, 1);
|
||||
EXPECT_EQ(tsdbUpdateSmaWindow(&tsdb, TSDB_SMA_TYPE_TIME_RANGE, msg), 0);
|
||||
|
||||
// init
|
||||
int32_t allocCnt = 0;
|
||||
|
@ -235,21 +307,21 @@ TEST(testCase, tSmaInsertTest) {
|
|||
void * buf = NULL;
|
||||
EXPECT_EQ(tsdbMakeRoom(&buf, allocStep), 0);
|
||||
int32_t bufSize = taosTSizeof(buf);
|
||||
int32_t numOfTables = 25;
|
||||
int32_t numOfTables = 10;
|
||||
col_id_t numOfCols = 4096;
|
||||
EXPECT_GT(numOfCols, 0);
|
||||
|
||||
pSmaData = (STSmaDataWrapper *)buf;
|
||||
printf(">> allocate [%d] time to %d and addr is %p\n", ++allocCnt, bufSize, pSmaData);
|
||||
pSmaData->skey = 1646987196;
|
||||
pSmaData->interval = 10;
|
||||
pSmaData->intervalUnit = TD_TIME_UNIT_MINUTE;
|
||||
pSmaData->indexUid = indexUid;
|
||||
pSmaData->skey = skey1;
|
||||
pSmaData->interval = interval1;
|
||||
pSmaData->intervalUnit = intervalUnit1;
|
||||
pSmaData->indexUid = indexUid1;
|
||||
|
||||
int32_t len = sizeof(STSmaDataWrapper);
|
||||
for (int32_t t = 0; t < numOfTables; ++t) {
|
||||
STSmaTbData *pTbData = (STSmaTbData *)POINTER_SHIFT(pSmaData, len);
|
||||
pTbData->tableUid = t;
|
||||
pTbData->tableUid = tbUid + t;
|
||||
|
||||
int32_t tableDataLen = sizeof(STSmaTbData);
|
||||
for (col_id_t c = 0; c < numOfCols; ++c) {
|
||||
|
@ -262,8 +334,17 @@ TEST(testCase, tSmaInsertTest) {
|
|||
}
|
||||
STSmaColData *pColData = (STSmaColData *)POINTER_SHIFT(pSmaData, len + tableDataLen);
|
||||
pColData->colId = c + PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
pColData->blockSize = ((c & 1) == 0) ? 8 : 16;
|
||||
|
||||
// TODO: fill col data
|
||||
if ((c & 1) == 0) {
|
||||
pColData->blockSize = 8;
|
||||
memcpy(pColData->data, &testSmaData1, 8);
|
||||
} else {
|
||||
pColData->blockSize = 16;
|
||||
memcpy(pColData->data, &testSmaData1, 8);
|
||||
memcpy(POINTER_SHIFT(pColData->data, 8), &testSmaData2, 8);
|
||||
}
|
||||
|
||||
tableDataLen += (sizeof(STSmaColData) + pColData->blockSize);
|
||||
}
|
||||
pTbData->dataLen = (tableDataLen - sizeof(STSmaTbData));
|
||||
|
@ -277,8 +358,24 @@ TEST(testCase, tSmaInsertTest) {
|
|||
// execute
|
||||
EXPECT_EQ(tsdbInsertTSmaData(&tsdb, (char *)pSmaData), TSDB_CODE_SUCCESS);
|
||||
|
||||
// release
|
||||
// step 3: query
|
||||
uint32_t checkDataCnt = 0;
|
||||
for (int32_t t = 0; t < numOfTables; ++t) {
|
||||
for (col_id_t c = 0; c < numOfCols; ++c) {
|
||||
EXPECT_EQ(tsdbGetTSmaData(&tsdb, NULL, indexUid1, interval1, intervalUnit1, tbUid + t,
|
||||
c + PRIMARYKEY_TIMESTAMP_COL_ID, skey1, 1),
|
||||
TSDB_CODE_SUCCESS);
|
||||
++checkDataCnt;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s:%d The sma data check count for insert and query is %" PRIu32 "\n", __FILE__, __LINE__, checkDataCnt);
|
||||
|
||||
// release data
|
||||
taosTZfree(buf);
|
||||
// release meta
|
||||
tdDestroyTSma(&tSma);
|
||||
metaClose(pMeta);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ typedef struct SGroupResInfo {
|
|||
int32_t totalGroup;
|
||||
int32_t currentGroup;
|
||||
int32_t index;
|
||||
SArray* pRows; // SArray<SResultRow*>
|
||||
SArray* pRows; // SArray<SResultRowPosition*>
|
||||
bool ordered;
|
||||
int32_t position;
|
||||
} SGroupResInfo;
|
||||
|
@ -67,10 +67,15 @@ typedef struct SResultRow {
|
|||
char *key; // start key of current result row
|
||||
} SResultRow;
|
||||
|
||||
typedef struct SResultRowPosition {
|
||||
int32_t pageId;
|
||||
int32_t offset;
|
||||
} SResultRowPosition;
|
||||
|
||||
typedef struct SResultRowInfo {
|
||||
SList* pRows;
|
||||
SResultRow** pResult; // result list
|
||||
// int16_t type:8; // data type for hash key
|
||||
SList *pRows;
|
||||
SResultRowPosition *pPosition;
|
||||
SResultRow **pResult; // result list
|
||||
int32_t size; // number of result set
|
||||
int32_t capacity; // max capacity
|
||||
int32_t curPos; // current active result row index of pResult list
|
||||
|
@ -131,7 +136,7 @@ static FORCE_INLINE char* getPosInResultPage_rv(SFilePage* page, int32_t rowOffs
|
|||
assert(rowOffset >= 0);
|
||||
|
||||
int32_t numOfRows = 1;//(int32_t)getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery);
|
||||
return ((char *)page->data) + rowOffset + offset * numOfRows;
|
||||
return (char*) page + rowOffset + offset * numOfRows;
|
||||
}
|
||||
|
||||
//bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
|
||||
|
@ -139,12 +144,7 @@ static FORCE_INLINE char* getPosInResultPage_rv(SFilePage* page, int32_t rowOffs
|
|||
|
||||
__filter_func_t getFilterOperator(int32_t lowerOptr, int32_t upperOptr);
|
||||
|
||||
SResultRowPool* initResultRowPool(size_t size);
|
||||
SResultRow* getNewResultRow(SResultRowPool* p);
|
||||
int64_t getResultRowPoolMemSize(SResultRowPool* p);
|
||||
void* destroyResultRowPool(SResultRowPool* p);
|
||||
int32_t getNumOfAllocatedResultRows(SResultRowPool* p);
|
||||
int32_t getNumOfUsedResultRows(SResultRowPool* p);
|
||||
|
||||
typedef struct {
|
||||
SArray* pResult; // SArray<SResPair>
|
||||
|
|
|
@ -240,12 +240,12 @@ typedef struct STaskAttr {
|
|||
SArray* pUdfInfo; // no need to free
|
||||
} STaskAttr;
|
||||
|
||||
typedef int32_t (*__optr_open_fn_t)(void* param);
|
||||
typedef SSDataBlock* (*__optr_fn_t)(void* param, bool* newgroup);
|
||||
typedef void (*__optr_close_fn_t)(void* param, int32_t num);
|
||||
|
||||
struct SOperatorInfo;
|
||||
|
||||
typedef int32_t (*__optr_open_fn_t)(struct SOperatorInfo* param);
|
||||
typedef SSDataBlock* (*__optr_fn_t)(struct SOperatorInfo* param, bool* newgroup);
|
||||
typedef void (*__optr_close_fn_t)(void* param, int32_t num);
|
||||
|
||||
typedef struct STaskIdInfo {
|
||||
uint64_t queryId; // this is also a request id
|
||||
uint64_t subplanId;
|
||||
|
@ -365,28 +365,6 @@ typedef struct SQInfo {
|
|||
STaskCostInfo summary;
|
||||
} SQInfo;
|
||||
|
||||
typedef struct STaskParam {
|
||||
char* sql;
|
||||
char* tagCond;
|
||||
char* colCond;
|
||||
char* tbnameCond;
|
||||
char* prevResult;
|
||||
SArray* pTableIdList;
|
||||
SExprBasicInfo** pExpr;
|
||||
SExprBasicInfo** pSecExpr;
|
||||
SExprInfo* pExprs;
|
||||
SExprInfo* pSecExprs;
|
||||
|
||||
SFilterInfo* pFilters;
|
||||
|
||||
SColIndex* pGroupColIndex;
|
||||
SColumnInfo* pTagColumnInfo;
|
||||
SGroupbyExpr* pGroupbyExpr;
|
||||
int32_t tableScanOperator;
|
||||
SArray* pOperator;
|
||||
struct SUdfInfo* pUdfInfo;
|
||||
} STaskParam;
|
||||
|
||||
enum {
|
||||
EX_SOURCE_DATA_NOT_READY = 0x1,
|
||||
EX_SOURCE_DATA_READY = 0x2,
|
||||
|
@ -485,13 +463,12 @@ typedef struct SAggSupporter {
|
|||
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.
|
||||
SDiskbasedBuf *pResultBuf; // query result buffer based on blocked-wised disk file
|
||||
int32_t resultRowSize; // the result buffer size for each result row, with the meta data size for each row
|
||||
} SAggSupporter;
|
||||
|
||||
typedef struct STableIntervalOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
SDiskbasedBuf *pResultBuf; // query result buffer based on blocked-wised disk file
|
||||
SGroupResInfo groupResInfo;
|
||||
SInterval interval;
|
||||
STimeWindow win;
|
||||
|
@ -515,23 +492,24 @@ typedef struct SAggOperatorInfo {
|
|||
|
||||
typedef struct SProjectOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
SSDataBlock* existDataBlock;
|
||||
SSDataBlock *existDataBlock;
|
||||
int32_t threshold;
|
||||
bool hasVarCol;
|
||||
} SProjectOperatorInfo;
|
||||
|
||||
typedef struct SLimitOperatorInfo {
|
||||
int64_t limit;
|
||||
int64_t total;
|
||||
SLimit limit;
|
||||
int64_t currentOffset;
|
||||
int64_t currentRows;
|
||||
} 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;
|
||||
|
@ -563,14 +541,15 @@ typedef struct SGroupbyOperatorInfo {
|
|||
char* prevData; // previous group by value
|
||||
} SGroupbyOperatorInfo;
|
||||
|
||||
typedef struct SSWindowOperatorInfo {
|
||||
typedef struct SSessionAggOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
SAggSupporter aggSup;
|
||||
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;
|
||||
} SSessionAggOperatorInfo;
|
||||
|
||||
typedef struct SStateWindowOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
|
@ -582,23 +561,6 @@ typedef struct SStateWindowOperatorInfo {
|
|||
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;
|
||||
|
||||
typedef struct SSortedMergeOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
bool hasVarCol;
|
||||
|
@ -630,7 +592,6 @@ typedef struct SOrderOperatorInfo {
|
|||
SArray *orderInfo;
|
||||
bool nullFirst;
|
||||
SSortHandle *pSortHandle;
|
||||
|
||||
int32_t bufPageSize;
|
||||
int32_t numOfRowsInRes;
|
||||
|
||||
|
@ -642,27 +603,44 @@ typedef struct SOrderOperatorInfo {
|
|||
uint64_t totalElapsed; // total elapsed time
|
||||
} SOrderOperatorInfo;
|
||||
|
||||
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;
|
||||
|
||||
SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createTableScanOperatorInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput,
|
||||
int32_t repeatTime, int32_t reverseTime, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv);
|
||||
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SSDataBlock* pResultBlock, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo);
|
||||
SOperatorInfo* createMultiTableAggOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SSDataBlock* pResultBlock, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo);
|
||||
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createOrderOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SArray* pOrderVal, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SArray* pExprInfo, SArray* pOrderVal, SArray* pGroupInfo, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock,
|
||||
SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo);
|
||||
SOperatorInfo* createMultiTableAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo);
|
||||
SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t num, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createOrderOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SArray* pOrderVal, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t numOfDownstream, SExprInfo* pExprInfo, int32_t num, SArray* pOrderVal, SArray* pGroupInfo, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createSysTableScanOperatorInfo(void* pSysTableReadHandle, const SArray* pExprInfo, const SSchema* pSchema,
|
||||
int32_t tableType, SEpSet epset, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createLimitOperatorInfo(SOperatorInfo* downstream, int32_t numOfDownstream, SLimit* pLimit, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream);
|
||||
SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SArray* pExprInfo, SInterval* pInterval, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream);
|
||||
SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResBlock, SInterval* pInterval,
|
||||
const STableGroupInfo* pTableGroupInfo, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv);
|
||||
SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream,
|
||||
SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createSWindowOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr,
|
||||
int32_t numOfOutput);
|
||||
|
||||
SOperatorInfo* createFillOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr,
|
||||
int32_t numOfOutput, bool multigroupResult);
|
||||
SOperatorInfo* createGroupbyOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr,
|
||||
|
@ -699,16 +677,13 @@ SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numO
|
|||
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 finalizeQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput);
|
||||
|
||||
void clearOutputBuf(SOptrBasicInfo* pBInfo, int32_t* bufCapacity);
|
||||
void copyTsColoum(SSDataBlock* pRes, SqlFunctionCtx* pCtx, int32_t numOfOutput);
|
||||
|
||||
int32_t createQueryFilter(char* data, uint16_t len, SFilterInfo** pFilters);
|
||||
|
||||
int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, STaskParam* param, char* start,
|
||||
int32_t prevResultLen, void* merger);
|
||||
|
||||
int32_t createFilterInfo(STaskAttr* pQueryAttr, uint64_t qId);
|
||||
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters);
|
||||
|
||||
|
|
|
@ -115,7 +115,8 @@ static bool allocBuf(SDataDispatchHandle* pDispatcher, const SInputData* pInput,
|
|||
return false;
|
||||
}
|
||||
|
||||
pBuf->allocSize = sizeof(SRetrieveTableRsp) + pDispatcher->pSchema->resultRowSize * pInput->pData->info.rows;
|
||||
// struct size + data payload + length for each column
|
||||
pBuf->allocSize = sizeof(SRetrieveTableRsp) + pDispatcher->pSchema->resultRowSize * pInput->pData->info.rows + pInput->pData->info.numOfCols * sizeof(int32_t);
|
||||
pBuf->pData = malloc(pBuf->allocSize);
|
||||
if (pBuf->pData == NULL) {
|
||||
qError("SinkNode failed to malloc memory, size:%d, code:%d", pBuf->allocSize, TAOS_SYSTEM_ERROR(errno));
|
||||
|
|
|
@ -59,7 +59,8 @@ int32_t initResultRowInfo(SResultRowInfo *pResultRowInfo, int32_t size) {
|
|||
pResultRowInfo->capacity = size;
|
||||
|
||||
pResultRowInfo->pResult = calloc(pResultRowInfo->capacity, POINTER_BYTES);
|
||||
if (pResultRowInfo->pResult == NULL) {
|
||||
pResultRowInfo->pPosition = calloc(pResultRowInfo->capacity, sizeof(SResultRowPosition));
|
||||
if (pResultRowInfo->pResult == NULL || pResultRowInfo->pPosition == NULL) {
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -182,22 +183,6 @@ size_t getResultRowSize(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
|
|||
return rowSize;
|
||||
}
|
||||
|
||||
SResultRowPool* initResultRowPool(size_t size) {
|
||||
SResultRowPool* p = calloc(1, sizeof(SResultRowPool));
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p->numOfElemPerBlock = 128;
|
||||
|
||||
p->elemSize = (int32_t) size;
|
||||
p->blockSize = p->numOfElemPerBlock * p->elemSize;
|
||||
p->position.pos = 0;
|
||||
|
||||
p->pData = taosArrayInit(8, POINTER_BYTES);
|
||||
return p;
|
||||
}
|
||||
|
||||
SResultRow* getNewResultRow(SResultRowPool* p) {
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
|
@ -221,132 +206,6 @@ SResultRow* getNewResultRow(SResultRowPool* p) {
|
|||
return ptr;
|
||||
}
|
||||
|
||||
int64_t getResultRowPoolMemSize(SResultRowPool* p) {
|
||||
if (p == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return taosArrayGetSize(p->pData) * p->blockSize;
|
||||
}
|
||||
|
||||
int32_t getNumOfAllocatedResultRows(SResultRowPool* p) {
|
||||
return (int32_t) taosArrayGetSize(p->pData) * p->numOfElemPerBlock;
|
||||
}
|
||||
|
||||
int32_t getNumOfUsedResultRows(SResultRowPool* p) {
|
||||
return getNumOfAllocatedResultRows(p) - p->numOfElemPerBlock + p->position.pos;
|
||||
}
|
||||
|
||||
void* destroyResultRowPool(SResultRowPool* p) {
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t size = taosArrayGetSize(p->pData);
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
void** ptr = taosArrayGet(p->pData, i);
|
||||
tfree(*ptr);
|
||||
}
|
||||
|
||||
taosArrayDestroy(p->pData);
|
||||
|
||||
tfree(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void interResToBinary(SBufferWriter* bw, SArray* pRes, int32_t tagLen) {
|
||||
uint32_t numOfGroup = (uint32_t) taosArrayGetSize(pRes);
|
||||
tbufWriteUint32(bw, numOfGroup);
|
||||
tbufWriteUint16(bw, tagLen);
|
||||
|
||||
for(int32_t i = 0; i < numOfGroup; ++i) {
|
||||
SInterResult* pOne = taosArrayGet(pRes, i);
|
||||
if (tagLen > 0) {
|
||||
tbufWriteBinary(bw, pOne->tags, tagLen);
|
||||
}
|
||||
|
||||
uint32_t numOfCols = (uint32_t) taosArrayGetSize(pOne->pResult);
|
||||
tbufWriteUint32(bw, numOfCols);
|
||||
for(int32_t j = 0; j < numOfCols; ++j) {
|
||||
SStddevInterResult* p = taosArrayGet(pOne->pResult, j);
|
||||
uint32_t numOfRows = (uint32_t) taosArrayGetSize(p->pResult);
|
||||
|
||||
tbufWriteUint16(bw, p->colId);
|
||||
tbufWriteUint32(bw, numOfRows);
|
||||
|
||||
for(int32_t k = 0; k < numOfRows; ++k) {
|
||||
// SResPair v = *(SResPair*) taosArrayGet(p->pResult, k);
|
||||
// tbufWriteDouble(bw, v.avg);
|
||||
// tbufWriteInt64(bw, v.key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SArray* interResFromBinary(const char* data, int32_t len) {
|
||||
SBufferReader br = tbufInitReader(data, len, false);
|
||||
uint32_t numOfGroup = tbufReadUint32(&br);
|
||||
uint16_t tagLen = tbufReadUint16(&br);
|
||||
|
||||
char* tag = NULL;
|
||||
if (tagLen > 0) {
|
||||
tag = calloc(1, tagLen);
|
||||
}
|
||||
|
||||
SArray* pResult = taosArrayInit(4, sizeof(SInterResult));
|
||||
|
||||
for(int32_t i = 0; i < numOfGroup; ++i) {
|
||||
if (tagLen > 0) {
|
||||
memset(tag, 0, tagLen);
|
||||
tbufReadToBinary(&br, tag, tagLen);
|
||||
}
|
||||
|
||||
uint32_t numOfCols = tbufReadUint32(&br);
|
||||
|
||||
SArray* p = taosArrayInit(numOfCols, sizeof(SStddevInterResult));
|
||||
for(int32_t j = 0; j < numOfCols; ++j) {
|
||||
// int16_t colId = tbufReadUint16(&br);
|
||||
int32_t numOfRows = tbufReadUint32(&br);
|
||||
|
||||
// SStddevInterResult interRes = {.colId = colId, .pResult = taosArrayInit(4, sizeof(struct SResPair)),};
|
||||
for(int32_t k = 0; k < numOfRows; ++k) {
|
||||
// SResPair px = {0};
|
||||
// px.avg = tbufReadDouble(&br);
|
||||
// px.key = tbufReadInt64(&br);
|
||||
//
|
||||
// taosArrayPush(interRes.pResult, &px);
|
||||
}
|
||||
|
||||
// taosArrayPush(p, &interRes);
|
||||
}
|
||||
|
||||
char* p1 = NULL;
|
||||
if (tagLen > 0) {
|
||||
p1 = malloc(tagLen);
|
||||
memcpy(p1, tag, tagLen);
|
||||
}
|
||||
|
||||
SInterResult d = {.pResult = p, .tags = p1,};
|
||||
taosArrayPush(pResult, &d);
|
||||
}
|
||||
|
||||
tfree(tag);
|
||||
return pResult;
|
||||
}
|
||||
|
||||
void freeInterResult(void* param) {
|
||||
SInterResult* pResult = (SInterResult*) param;
|
||||
tfree(pResult->tags);
|
||||
|
||||
int32_t numOfCols = (int32_t) taosArrayGetSize(pResult->pResult);
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
SStddevInterResult *p = taosArrayGet(pResult->pResult, i);
|
||||
taosArrayDestroy(p->pResult);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pResult->pResult);
|
||||
}
|
||||
|
||||
void cleanupGroupResInfo(SGroupResInfo* pGroupResInfo) {
|
||||
assert(pGroupResInfo != NULL);
|
||||
|
||||
|
@ -360,7 +219,7 @@ void initGroupResInfo(SGroupResInfo* pGroupResInfo, SResultRowInfo* pResultInfo)
|
|||
taosArrayDestroy(pGroupResInfo->pRows);
|
||||
}
|
||||
|
||||
pGroupResInfo->pRows = taosArrayFromList(pResultInfo->pResult, pResultInfo->size, POINTER_BYTES);
|
||||
pGroupResInfo->pRows = taosArrayFromList(pResultInfo->pPosition, pResultInfo->size, sizeof(SResultRowPosition));
|
||||
pGroupResInfo->index = 0;
|
||||
assert(pGroupResInfo->index <= getNumOfTotalRes(pGroupResInfo));
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,7 +37,6 @@ typedef struct SSortHandle {
|
|||
|
||||
SArray *pOrderInfo;
|
||||
bool nullFirst;
|
||||
bool hasVarCol;
|
||||
SArray *pOrderedSource;
|
||||
|
||||
_sort_fetch_block_fn_t fetchfp;
|
||||
|
@ -77,6 +76,10 @@ static SSDataBlock* createDataBlock_rv(SSchema* pSchema, int32_t numOfCols) {
|
|||
colInfo.info.bytes = pSchema[i].bytes;
|
||||
colInfo.info.colId = pSchema[i].colId;
|
||||
taosArrayPush(pBlock->pDataBlock, &colInfo);
|
||||
|
||||
if (IS_VAR_DATA_TYPE(colInfo.info.type)) {
|
||||
pBlock->info.hasVarCol = true;
|
||||
}
|
||||
}
|
||||
|
||||
return pBlock;
|
||||
|
@ -155,7 +158,7 @@ static int32_t doAddToBuf(SSDataBlock* pDataBlock, SSortHandle* pHandle) {
|
|||
|
||||
while(start < pDataBlock->info.rows) {
|
||||
int32_t stop = 0;
|
||||
blockDataSplitRows(pDataBlock, pHandle->hasVarCol, start, &stop, pHandle->pageSize);
|
||||
blockDataSplitRows(pDataBlock, pDataBlock->info.hasVarCol, start, &stop, pHandle->pageSize);
|
||||
SSDataBlock* p = blockDataExtractBlock(pDataBlock, start, stop - start + 1);
|
||||
if (p == NULL) {
|
||||
return terrno;
|
||||
|
@ -179,7 +182,7 @@ static int32_t doAddToBuf(SSDataBlock* pDataBlock, SSortHandle* pHandle) {
|
|||
start = stop + 1;
|
||||
}
|
||||
|
||||
blockDataClearup(pDataBlock, pHandle->hasVarCol);
|
||||
blockDataClearup(pDataBlock);
|
||||
|
||||
SSDataBlock* pBlock = createOneDataBlock(pDataBlock);
|
||||
int32_t code = doAddNewExternalMemSource(pHandle->pBuf, pHandle->pOrderedSource, pBlock, &pHandle->sourceId);
|
||||
|
@ -309,7 +312,7 @@ static int32_t adjustMergeTreeForNextTuple(SExternalMemSource *pSource, SMultiwa
|
|||
}
|
||||
|
||||
static SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SMsortComparParam* cmpParam, int32_t capacity) {
|
||||
blockDataClearup(pHandle->pDataBlock, pHandle->hasVarCol);
|
||||
blockDataClearup(pHandle->pDataBlock);
|
||||
|
||||
while(1) {
|
||||
if (cmpParam->numOfSources == pHandle->numOfCompletedSources) {
|
||||
|
@ -475,7 +478,7 @@ static int32_t doInternalMergeSort(SSortHandle* pHandle) {
|
|||
setBufPageDirty(pPage, true);
|
||||
releaseBufPage(pHandle->pBuf, pPage);
|
||||
|
||||
blockDataClearup(pDataBlock, pHandle->hasVarCol);
|
||||
blockDataClearup(pDataBlock);
|
||||
}
|
||||
|
||||
tMergeTreeDestroy(pHandle->pMergeTree);
|
||||
|
|
|
@ -55,8 +55,7 @@ typedef struct SDummyInputInfo {
|
|||
SSDataBlock* pBlock;
|
||||
} SDummyInputInfo;
|
||||
|
||||
SSDataBlock* getDummyBlock(void* param, bool* newgroup) {
|
||||
SOperatorInfo* pOperator = static_cast<SOperatorInfo*>(param);
|
||||
SSDataBlock* getDummyBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
||||
SDummyInputInfo* pInfo = static_cast<SDummyInputInfo*>(pOperator->info);
|
||||
if (pInfo->current >= pInfo->totalPages) {
|
||||
return NULL;
|
||||
|
@ -87,7 +86,7 @@ SSDataBlock* getDummyBlock(void* param, bool* newgroup) {
|
|||
//
|
||||
// taosArrayPush(pInfo->pBlock->pDataBlock, &colInfo1);
|
||||
} else {
|
||||
blockDataClearup(pInfo->pBlock, true);
|
||||
blockDataClearup(pInfo->pBlock);
|
||||
}
|
||||
|
||||
SSDataBlock* pBlock = pInfo->pBlock;
|
||||
|
@ -122,8 +121,7 @@ SSDataBlock* getDummyBlock(void* param, bool* newgroup) {
|
|||
return pBlock;
|
||||
}
|
||||
|
||||
SSDataBlock* get2ColsDummyBlock(void* param, bool* newgroup) {
|
||||
SOperatorInfo* pOperator = static_cast<SOperatorInfo*>(param);
|
||||
SSDataBlock* get2ColsDummyBlock(SOperatorInfo* pOperator, bool* newgroup) {
|
||||
SDummyInputInfo* pInfo = static_cast<SDummyInputInfo*>(pOperator->info);
|
||||
if (pInfo->current >= pInfo->totalPages) {
|
||||
return NULL;
|
||||
|
@ -153,7 +151,7 @@ SSDataBlock* get2ColsDummyBlock(void* param, bool* newgroup) {
|
|||
|
||||
taosArrayPush(pInfo->pBlock->pDataBlock, &colInfo1);
|
||||
} else {
|
||||
blockDataClearup(pInfo->pBlock, false);
|
||||
blockDataClearup(pInfo->pBlock);
|
||||
}
|
||||
|
||||
SSDataBlock* pBlock = pInfo->pBlock;
|
||||
|
|
|
@ -46,13 +46,6 @@ extern SAggFunctionInfo aggFunc[35];
|
|||
#define DATA_SET_FLAG ',' // to denote the output area has data, not null value
|
||||
#define DATA_SET_FLAG_SIZE sizeof(DATA_SET_FLAG)
|
||||
|
||||
#define TOP_BOTTOM_QUERY_LIMIT 100
|
||||
|
||||
#define QUERY_IS_STABLE_QUERY(type) (((type)&TSDB_QUERY_TYPE_STABLE_QUERY) != 0)
|
||||
#define QUERY_IS_JOIN_QUERY(type) (TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_JOIN_QUERY))
|
||||
#define QUERY_IS_PROJECTION_QUERY(type) (((type)&TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0)
|
||||
#define QUERY_IS_FREE_RESOURCE(type) (((type)&TSDB_QUERY_TYPE_FREE_RESOURCE) != 0)
|
||||
|
||||
typedef struct SInterpInfoDetail {
|
||||
TSKEY ts; // interp specified timestamp
|
||||
int8_t type;
|
||||
|
@ -61,9 +54,6 @@ typedef struct SInterpInfoDetail {
|
|||
|
||||
#define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowEntryInfo)))
|
||||
|
||||
#define IS_STREAM_QUERY_VALID(x) (((x)&TSDB_FUNCSTATE_STREAM) != 0)
|
||||
#define IS_MULTIOUTPUT(x) (((x)&TSDB_FUNCSTATE_MO) != 0)
|
||||
|
||||
typedef struct STwaInfo {
|
||||
int8_t hasResult; // flag to denote has value
|
||||
double dOutput;
|
||||
|
@ -71,8 +61,6 @@ typedef struct STwaInfo {
|
|||
STimeWindow win;
|
||||
} STwaInfo;
|
||||
|
||||
extern int32_t functionCompatList[]; // compatible check array list
|
||||
|
||||
bool topbot_datablock_filter(SqlFunctionCtx *pCtx, const char *minval, const char *maxval);
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,10 +52,6 @@ static void doFinalizer(SResultRowEntryInfo* pResInfo) { cleanupResultRowEntry(p
|
|||
|
||||
void functionFinalizer(SqlFunctionCtx *pCtx) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
if (pResInfo->hasResult != DATA_SET_FLAG) {
|
||||
// setNull(pCtx->pOutput, pCtx->resDataInfo.type, pCtx->resDataInfo.bytes);
|
||||
}
|
||||
|
||||
doFinalizer(pResInfo);
|
||||
}
|
||||
|
||||
|
@ -398,7 +394,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx *pCtx, int32_t isMinFunc) {
|
|||
int32_t *pData = (int32_t*)pCol->pData;
|
||||
int32_t *val = (int32_t*) buf;
|
||||
|
||||
for (int32_t i = 0; i < pCtx->size; ++i) {
|
||||
for (int32_t i = start; i < start + numOfRows; ++i) {
|
||||
if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1,415 +0,0 @@
|
|||
#include "os.h"
|
||||
#include "tarray.h"
|
||||
#include "function.h"
|
||||
#include "thash.h"
|
||||
#include "taggfunction.h"
|
||||
|
||||
static SHashObj* functionHashTable = NULL;
|
||||
static SHashObj* udfHashTable = NULL;
|
||||
|
||||
static void doInitFunctionHashTable() {
|
||||
int numOfEntries = tListLen(aggFunc);
|
||||
functionHashTable = taosHashInit(numOfEntries, MurmurHash3_32, false, false);
|
||||
for (int32_t i = 0; i < numOfEntries; i++) {
|
||||
int32_t len = (uint32_t)strlen(aggFunc[i].name);
|
||||
|
||||
SAggFunctionInfo* ptr = &aggFunc[i];
|
||||
taosHashPut(functionHashTable, aggFunc[i].name, len, (void*)&ptr, POINTER_BYTES);
|
||||
}
|
||||
|
||||
/*
|
||||
numOfEntries = tListLen(scalarFunc);
|
||||
for(int32_t i = 0; i < numOfEntries; ++i) {
|
||||
int32_t len = (int32_t) strlen(scalarFunc[i].name);
|
||||
SScalarFunctionInfo* ptr = &scalarFunc[i];
|
||||
taosHashPut(functionHashTable, scalarFunc[i].name, len, (void*)&ptr, POINTER_BYTES);
|
||||
}
|
||||
*/
|
||||
|
||||
udfHashTable = taosHashInit(numOfEntries, MurmurHash3_32, true, true);
|
||||
}
|
||||
|
||||
static pthread_once_t functionHashTableInit = PTHREAD_ONCE_INIT;
|
||||
|
||||
int32_t qIsBuiltinFunction(const char* name, int32_t len, bool* scalarFunction) {
|
||||
pthread_once(&functionHashTableInit, doInitFunctionHashTable);
|
||||
|
||||
SAggFunctionInfo** pInfo = taosHashGet(functionHashTable, name, len);
|
||||
if (pInfo != NULL) {
|
||||
*scalarFunction = ((*pInfo)->type == FUNCTION_TYPE_SCALAR);
|
||||
return (*pInfo)->functionId;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* functionId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool qIsAggregateFunction(const char* functionName) {
|
||||
assert(functionName != NULL);
|
||||
bool scalarfunc = false;
|
||||
qIsBuiltinFunction(functionName, strlen(functionName), &scalarfunc);
|
||||
|
||||
return !scalarfunc;
|
||||
}
|
||||
|
||||
bool qIsSelectivityFunction(const char* functionName) {
|
||||
assert(functionName != NULL);
|
||||
pthread_once(&functionHashTableInit, doInitFunctionHashTable);
|
||||
|
||||
size_t len = strlen(functionName);
|
||||
SAggFunctionInfo** pInfo = taosHashGet(functionHashTable, functionName, len);
|
||||
if (pInfo != NULL) {
|
||||
return ((*pInfo)->status | FUNCSTATE_SELECTIVITY) != 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SAggFunctionInfo* qGetFunctionInfo(const char* name, int32_t len) {
|
||||
pthread_once(&functionHashTableInit, doInitFunctionHashTable);
|
||||
|
||||
SAggFunctionInfo** pInfo = taosHashGet(functionHashTable, name, len);
|
||||
if (pInfo != NULL) {
|
||||
return (*pInfo);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void qAddUdfInfo(uint64_t id, SUdfInfo* pUdfInfo) {
|
||||
int32_t len = (uint32_t)strlen(pUdfInfo->name);
|
||||
taosHashPut(udfHashTable, pUdfInfo->name, len, (void*)&pUdfInfo, POINTER_BYTES);
|
||||
}
|
||||
|
||||
void qRemoveUdfInfo(uint64_t id, SUdfInfo* pUdfInfo) {
|
||||
int32_t len = (uint32_t)strlen(pUdfInfo->name);
|
||||
taosHashRemove(udfHashTable, pUdfInfo->name, len);
|
||||
}
|
||||
|
||||
bool isTagsQuery(SArray* pFunctionIdList) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
char* f = *(char**) taosArrayGet(pFunctionIdList, i);
|
||||
|
||||
// todo handle count(tbname) query
|
||||
if (strcmp(f, "project") != 0 && strcmp(f, "count") != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// "select count(tbname)" query
|
||||
// if (functId == FUNCTION_COUNT && pExpr->base.colpDesc->colId == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
// continue;
|
||||
// }
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//bool tscMultiRoundQuery(SArray* pFunctionIdList, int32_t index) {
|
||||
// if (!UTIL_TABLE_IS_SUPER_TABLE(pQueryInfo->pTableMetaInfo[index])) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// size_t numOfExprs = (int32_t) getNumOfExprs(pQueryInfo);
|
||||
// for(int32_t i = 0; i < numOfExprs; ++i) {
|
||||
// SExprInfo* pExpr = getExprInfo(pQueryInfo, i);
|
||||
// if (pExpr->base.functionId == FUNCTION_STDDEV_DST) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
|
||||
bool isProjectionQuery(SArray* pFunctionIdList) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
char* f = *(char**) taosArrayGet(pFunctionIdList, i);
|
||||
if (strcmp(f, "project") == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isDiffDerivativeQuery(SArray* pFunctionIdList) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
|
||||
if (f == FUNCTION_TS_DUMMY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f == FUNCTION_DIFF || f == FUNCTION_DERIVATIVE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isInterpQuery(SArray* pFunctionIdList) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
|
||||
if (f == FUNCTION_TAG || f == FUNCTION_TS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f != FUNCTION_INTERP) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isArithmeticQueryOnAggResult(SArray* pFunctionIdList) {
|
||||
if (isProjectionQuery(pFunctionIdList)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
|
||||
// size_t numOfOutput = getNumOfFields(pQueryInfo);
|
||||
// for(int32_t i = 0; i < numOfOutput; ++i) {
|
||||
// SExprInfo* pExprInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i)->pExpr;
|
||||
// if (pExprInfo->pExpr != NULL) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isGroupbyColumn(SGroupbyExpr* pGroupby) {
|
||||
return !pGroupby->groupbyTag;
|
||||
}
|
||||
|
||||
bool isTopBotQuery(SArray* pFunctionIdList) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
char* f = *(char**) taosArrayGet(pFunctionIdList, i);
|
||||
if (strcmp(f, "project") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(f, "top") == 0 || strcmp(f, "bottom") == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isTsCompQuery(SArray* pFunctionIdList) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
if (num != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, 0);
|
||||
return f == FUNCTION_TS_COMP;
|
||||
}
|
||||
|
||||
bool isTWAQuery(SArray* pFunctionIdList) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
|
||||
if (f == FUNCTION_TWA) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isIrateQuery(SArray* pFunctionIdList) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
|
||||
if (f == FUNCTION_IRATE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isStabledev(SArray* pFunctionIdList) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
|
||||
if (f == FUNCTION_STDDEV_DST) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool needReverseScan(SArray* pFunctionIdList) {
|
||||
assert(0);
|
||||
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
|
||||
if (f == FUNCTION_TS || f == FUNCTION_TS_DUMMY || f == FUNCTION_TAG) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if ((f == FUNCTION_FIRST || f == FUNCTION_FIRST_DST) && pQueryInfo->order.order == TSDB_ORDER_DESC) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (f == FUNCTION_LAST || f == FUNCTION_LAST_DST) {
|
||||
// the scan order to acquire the last result of the specified column
|
||||
// int32_t order = (int32_t)pExpr->base.param[0].i64;
|
||||
// if (order != pQueryInfo->order.order) {
|
||||
// return true;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isAgg(SArray* pFunctionIdList) {
|
||||
size_t size = taosArrayGetSize(pFunctionIdList);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
char* f = *(char**) taosArrayGet(pFunctionIdList, i);
|
||||
if (strcmp(f, "project") == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (qIsAggregateFunction(f)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isBlockDistQuery(SArray* pFunctionIdList) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
char* f = *(char**) taosArrayGet(pFunctionIdList, 0);
|
||||
return (num == 1 && strcmp(f, "block_dist") == 0);
|
||||
}
|
||||
|
||||
bool isTwoStageSTableQuery(SArray* pFunctionIdList, int32_t tableIndex) {
|
||||
// if (pQueryInfo == NULL) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
|
||||
// if (pTableMetaInfo == NULL) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if ((pQueryInfo->type & TSDB_QUERY_TYPE_FREE_RESOURCE) == TSDB_QUERY_TYPE_FREE_RESOURCE) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// // for ordered projection query, iterate all qualified vnodes sequentially
|
||||
// if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, tableIndex)) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_SUBQUERY) && pQueryInfo->command == TSDB_SQL_SELECT) {
|
||||
// return UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isProjectionQueryOnSTable(SArray* pFunctionIdList, int32_t tableIndex) {
|
||||
// STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
|
||||
//
|
||||
// /*
|
||||
// * In following cases, return false for non ordered project query on super table
|
||||
// * 1. failed to get tableMeta from server; 2. not a super table; 3. limitation is 0;
|
||||
// * 4. show queries, instead of a select query
|
||||
// */
|
||||
// size_t numOfExprs = getNumOfExprs(pQueryInfo);
|
||||
// if (pTableMetaInfo == NULL || !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo) ||
|
||||
// pQueryInfo->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT || numOfExprs == 0) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||
// int32_t functionId = getExprInfo(pQueryInfo, i)->base.functionId;
|
||||
//
|
||||
// if (functionId < 0) {
|
||||
// SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * functionId - 1);
|
||||
// if (pUdfInfo->funcType == TSDB_FUNC_TYPE_AGGREGATE) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if (functionId != FUNCTION_PRJ &&
|
||||
// functionId != FUNCTION_TAGPRJ &&
|
||||
// functionId != FUNCTION_TAG &&
|
||||
// functionId != FUNCTION_TS &&
|
||||
// functionId != FUNCTION_ARITHM &&
|
||||
// functionId != FUNCTION_TS_COMP &&
|
||||
// functionId != FUNCTION_DIFF &&
|
||||
// functionId != FUNCTION_DERIVATIVE &&
|
||||
// functionId != FUNCTION_TS_DUMMY &&
|
||||
// functionId != FUNCTION_TID_TAG) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hasTagValOutput(SArray* pFunctionIdList) {
|
||||
size_t size = taosArrayGetSize(pFunctionIdList);
|
||||
|
||||
// if (numOfExprs == 1 && pExpr1->base.functionId == FUNCTION_TS_COMP) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
int32_t functionId = *(int16_t*) taosArrayGet(pFunctionIdList, i);
|
||||
|
||||
// ts_comp column required the tag value for join filter
|
||||
if (functionId == FUNCTION_TAG || functionId == FUNCTION_TAGPRJ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//bool timeWindowInterpoRequired(SArray* pFunctionIdList) {
|
||||
// int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
|
||||
// for (int32_t i = 0; i < num; ++i) {
|
||||
// int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
|
||||
// if (f == FUNCTION_TWA || f == FUNCTION_INTERP) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
|
||||
void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc) {
|
||||
assert(pFunctionIdList != NULL);
|
||||
|
||||
pDesc->blockDistribution = isBlockDistQuery(pFunctionIdList);
|
||||
if (pDesc->blockDistribution) {
|
||||
return;
|
||||
}
|
||||
|
||||
// pDesc->projectionQuery = isProjectionQuery(pFunctionIdList);
|
||||
// pDesc->onlyTagQuery = isTagsQuery(pFunctionIdList);
|
||||
pDesc->interpQuery = isInterpQuery(pFunctionIdList);
|
||||
pDesc->topbotQuery = isTopBotQuery(pFunctionIdList);
|
||||
pDesc->agg = isAgg(pFunctionIdList);
|
||||
}
|
|
@ -183,6 +183,12 @@ static SNode* groupingSetNodeCopy(const SGroupingSetNode* pSrc, SGroupingSetNode
|
|||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* fillNodeCopy(const SFillNode* pSrc, SFillNode* pDst) {
|
||||
COPY_SCALAR_FIELD(mode);
|
||||
CLONE_NODE_FIELD(pValues);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) {
|
||||
COPY_SCALAR_FIELD(id);
|
||||
CLONE_NODE_LIST_FIELD(pTargets);
|
||||
|
@ -248,6 +254,17 @@ static SNode* logicExchangeCopy(const SExchangeLogicNode* pSrc, SExchangeLogicNo
|
|||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* pDst) {
|
||||
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
|
||||
COPY_SCALAR_FIELD(winType);
|
||||
CLONE_NODE_LIST_FIELD(pFuncs);
|
||||
COPY_SCALAR_FIELD(interval);
|
||||
COPY_SCALAR_FIELD(offset);
|
||||
COPY_SCALAR_FIELD(sliding);
|
||||
CLONE_NODE_FIELD(pFill);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* logicSubplanCopy(const SSubLogicPlan* pSrc, SSubLogicPlan* pDst) {
|
||||
CLONE_NODE_FIELD(pNode);
|
||||
COPY_SCALAR_FIELD(subplanType);
|
||||
|
@ -309,6 +326,8 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) {
|
|||
case QUERY_NODE_ORDER_BY_EXPR:
|
||||
case QUERY_NODE_LIMIT:
|
||||
break;
|
||||
case QUERY_NODE_FILL:
|
||||
return fillNodeCopy((const SFillNode*)pNode, (SFillNode*)pDst);
|
||||
case QUERY_NODE_DATABLOCK_DESC:
|
||||
return dataBlockDescCopy((const SDataBlockDescNode*)pNode, (SDataBlockDescNode*)pDst);
|
||||
case QUERY_NODE_SLOT_DESC:
|
||||
|
@ -325,6 +344,8 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) {
|
|||
return logicVnodeModifCopy((const SVnodeModifLogicNode*)pNode, (SVnodeModifLogicNode*)pDst);
|
||||
case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
|
||||
return logicExchangeCopy((const SExchangeLogicNode*)pNode, (SExchangeLogicNode*)pDst);
|
||||
case QUERY_NODE_LOGIC_PLAN_WINDOW:
|
||||
return logicWindowCopy((const SWindowLogicNode*)pNode, (SWindowLogicNode*)pDst);
|
||||
case QUERY_NODE_LOGIC_SUBPLAN:
|
||||
return logicSubplanCopy((const SSubLogicPlan*)pNode, (SSubLogicPlan*)pDst);
|
||||
default:
|
||||
|
|
|
@ -117,6 +117,8 @@ const char* nodesNodeName(ENodeType type) {
|
|||
return "PhysiExchange";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SORT:
|
||||
return "PhysiSort";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
return "PhysiInterval";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||
return "PhysiDispatch";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
||||
|
@ -149,8 +151,7 @@ static int32_t nodeListToJson(SJson* pJson, const char* pName, const SNodeList*
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t jsonToNodeList(const SJson* pJson, const char* pName, SNodeList** pList) {
|
||||
const SJson* pJsonArray = tjsonGetObjectItem(pJson, pName);
|
||||
static int32_t jsonToNodeListImpl(const SJson* pJsonArray, SNodeList** pList) {
|
||||
int32_t size = (NULL == pJsonArray ? 0 : tjsonGetArraySize(pJsonArray));
|
||||
if (size > 0) {
|
||||
*pList = nodesMakeList();
|
||||
|
@ -174,6 +175,10 @@ static int32_t jsonToNodeList(const SJson* pJson, const char* pName, SNodeList**
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t jsonToNodeList(const SJson* pJson, const char* pName, SNodeList** pList) {
|
||||
return jsonToNodeListImpl(tjsonGetObjectItem(pJson, pName), pList);
|
||||
}
|
||||
|
||||
static const char* jkTableMetaUid = "TableMetaUid";
|
||||
static const char* jkTableMetaSuid = "TableMetaSuid";
|
||||
|
||||
|
@ -573,6 +578,79 @@ static int32_t jsonToPhysiExchangeNode(const SJson* pJson, void* pObj) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static const char* jkIntervalPhysiPlanExprs = "Exprs";
|
||||
static const char* jkIntervalPhysiPlanFuncs = "Funcs";
|
||||
static const char* jkIntervalPhysiPlanInterval = "Interval";
|
||||
static const char* jkIntervalPhysiPlanOffset = "Offset";
|
||||
static const char* jkIntervalPhysiPlanSliding = "Sliding";
|
||||
static const char* jkIntervalPhysiPlanIntervalUnit = "intervalUnit";
|
||||
static const char* jkIntervalPhysiPlanSlidingUnit = "slidingUnit";
|
||||
static const char* jkIntervalPhysiPlanFill = "Fill";
|
||||
|
||||
static int32_t physiIntervalNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SIntervalPhysiNode* pNode = (const SIntervalPhysiNode*)pObj;
|
||||
|
||||
int32_t code = physicPlanNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodeListToJson(pJson, jkIntervalPhysiPlanExprs, pNode->pExprs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = nodeListToJson(pJson, jkIntervalPhysiPlanFuncs, pNode->pFuncs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanInterval, pNode->interval);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanOffset, pNode->offset);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanSliding, pNode->sliding);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanIntervalUnit, pNode->intervalUnit);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanSlidingUnit, pNode->slidingUnit);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkIntervalPhysiPlanFill, nodeToJson, pNode->pFill);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t jsonToPhysiIntervalNode(const SJson* pJson, void* pObj) {
|
||||
SIntervalPhysiNode* pNode = (SIntervalPhysiNode*)pObj;
|
||||
|
||||
int32_t code = jsonToPhysicPlanNode(pJson, pObj);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeList(pJson, jkIntervalPhysiPlanExprs, &pNode->pExprs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeList(pJson, jkIntervalPhysiPlanFuncs, &pNode->pFuncs);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkIntervalPhysiPlanInterval, &pNode->interval);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkIntervalPhysiPlanOffset, &pNode->offset);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetBigIntValue(pJson, jkIntervalPhysiPlanSliding, &pNode->sliding);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetTinyIntValue(pJson, jkIntervalPhysiPlanIntervalUnit, &pNode->intervalUnit);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetTinyIntValue(pJson, jkIntervalPhysiPlanSlidingUnit, &pNode->slidingUnit);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = jsonToNodeObject(pJson, jkIntervalPhysiPlanFill, (SNode**)&pNode->pFill);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkDataSinkInputDataBlockDesc = "InputDataBlockDesc";
|
||||
|
||||
static int32_t physicDataSinkNodeToJson(const void* pObj, SJson* pJson) {
|
||||
|
@ -1500,6 +1578,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
|||
return physiExchangeNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SORT:
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
return physiIntervalNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||
return physiDispatchNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
||||
|
@ -1581,7 +1661,10 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
|||
return jsonToSubplan(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN:
|
||||
return jsonToPlan(pJson, pObj);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
return jsonToPhysiIntervalNode(pJson, pObj);
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
nodesWarn("jsonToSpecificNode unknown node = %s", nodesNodeName(nodeType(pObj)));
|
||||
|
@ -1687,3 +1770,52 @@ int32_t nodesStringToNode(const char* pStr, SNode** pNode) {
|
|||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t nodesListToString(const SNodeList* pList, bool format, char** pStr, int32_t* pLen) {
|
||||
if (NULL == pList || NULL == pStr || NULL == pLen) {
|
||||
terrno = TSDB_CODE_FAILED;
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
if (0 == LIST_LENGTH(pList)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SJson* pJson = tjsonCreateArray();
|
||||
if (NULL == pJson) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SNode* pNode;
|
||||
FOREACH(pNode, pList) {
|
||||
int32_t code = tjsonAddItem(pJson, nodeToJson, pNode);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
terrno = code;
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
*pStr = format ? tjsonToString(pJson) : tjsonToUnformattedString(pJson);
|
||||
tjsonDelete(pJson);
|
||||
|
||||
*pLen = strlen(*pStr) + 1;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t nodesStringToList(const char* pStr, SNodeList** pList) {
|
||||
if (NULL == pStr || NULL == pList) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
SJson* pJson = tjsonParse(pStr);
|
||||
if (NULL == pJson) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
int32_t code = jsonToNodeListImpl(pJson, pList);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesDestroyList(*pList);
|
||||
terrno = code;
|
||||
return code;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,12 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
|||
return makeNode(type, sizeof(SColumnDefNode));
|
||||
case QUERY_NODE_DOWNSTREAM_SOURCE:
|
||||
return makeNode(type, sizeof(SDownstreamSourceNode));
|
||||
case QUERY_NODE_DATABASE_OPTIONS:
|
||||
return makeNode(type, sizeof(SDatabaseOptions));
|
||||
case QUERY_NODE_TABLE_OPTIONS:
|
||||
return makeNode(type, sizeof(STableOptions));
|
||||
case QUERY_NODE_INDEX_OPTIONS:
|
||||
return makeNode(type, sizeof(SIndexOptions));
|
||||
case QUERY_NODE_SET_OPERATOR:
|
||||
return makeNode(type, sizeof(SSetOperator));
|
||||
case QUERY_NODE_SELECT_STMT:
|
||||
|
@ -121,7 +127,12 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
|||
return makeNode(type, sizeof(SShowStmt));
|
||||
case QUERY_NODE_SHOW_VGROUPS_STMT:
|
||||
case QUERY_NODE_SHOW_MNODES_STMT:
|
||||
case QUERY_NODE_SHOW_QNODES_STMT:
|
||||
return makeNode(type, sizeof(SShowStmt));
|
||||
case QUERY_NODE_CREATE_INDEX_STMT:
|
||||
return makeNode(type, sizeof(SCreateIndexStmt));
|
||||
case QUERY_NODE_CREATE_QNODE_STMT:
|
||||
return makeNode(type, sizeof(SCreateQnodeStmt));
|
||||
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
||||
return makeNode(type, sizeof(SScanLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
||||
|
@ -134,6 +145,8 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
|||
return makeNode(type, sizeof(SVnodeModifLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
|
||||
return makeNode(type, sizeof(SExchangeLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_WINDOW:
|
||||
return makeNode(type, sizeof(SWindowLogicNode));
|
||||
case QUERY_NODE_LOGIC_SUBPLAN:
|
||||
return makeNode(type, sizeof(SSubLogicPlan));
|
||||
case QUERY_NODE_LOGIC_PLAN:
|
||||
|
@ -156,6 +169,8 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
|||
return makeNode(type, sizeof(SExchangePhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SORT:
|
||||
return makeNode(type, sizeof(SNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
|
||||
return makeNode(type, sizeof(SIntervalPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||
return makeNode(type, sizeof(SDataDispatcherNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INSERT:
|
||||
|
@ -204,6 +219,14 @@ static EDealRes destroyNode(SNode** pNode, void* pContext) {
|
|||
case QUERY_NODE_NODE_LIST:
|
||||
nodesClearList(((SNodeListNode*)(*pNode))->pNodeList);
|
||||
break;
|
||||
case QUERY_NODE_INDEX_OPTIONS: {
|
||||
SIndexOptions* pStmt = (SIndexOptions*)*pNode;
|
||||
nodesDestroyList(pStmt->pFuncs);
|
||||
nodesDestroyNode(pStmt->pInterval);
|
||||
nodesDestroyNode(pStmt->pOffset);
|
||||
nodesDestroyNode(pStmt->pSliding);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_SELECT_STMT: {
|
||||
SSelectStmt* pStmt = (SSelectStmt*)*pNode;
|
||||
nodesDestroyList(pStmt->pProjectionList);
|
||||
|
@ -244,6 +267,12 @@ static EDealRes destroyNode(SNode** pNode, void* pContext) {
|
|||
case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
|
||||
nodesDestroyList(((SCreateMultiTableStmt*)(*pNode))->pSubTables);
|
||||
break;
|
||||
case QUERY_NODE_CREATE_INDEX_STMT: {
|
||||
SCreateIndexStmt* pStmt = (SCreateIndexStmt*)*pNode;
|
||||
nodesDestroyNode(pStmt->pOptions);
|
||||
nodesDestroyList(pStmt->pCols);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -109,17 +109,17 @@ SNode* addLimitClause(SAstCreateContext* pCxt, SNode* pStmt, SNode* pLimit);
|
|||
SNode* createSelectStmt(SAstCreateContext* pCxt, bool isDistinct, SNodeList* pProjectionList, SNode* pTable);
|
||||
SNode* createSetOperator(SAstCreateContext* pCxt, ESetOperatorType type, SNode* pLeft, SNode* pRight);
|
||||
|
||||
SDatabaseOptions* createDefaultDatabaseOptions(SAstCreateContext* pCxt);
|
||||
SDatabaseOptions* setDatabaseOption(SAstCreateContext* pCxt, SDatabaseOptions* pOptions, EDatabaseOptionType type, const SToken* pVal);
|
||||
SNode* createCreateDatabaseStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pDbName, SDatabaseOptions* pOptions);
|
||||
SNode* createDefaultDatabaseOptions(SAstCreateContext* pCxt);
|
||||
SNode* setDatabaseOption(SAstCreateContext* pCxt, SNode* pOptions, EDatabaseOptionType type, const SToken* pVal);
|
||||
SNode* createCreateDatabaseStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pDbName, SNode* pOptions);
|
||||
SNode* createDropDatabaseStmt(SAstCreateContext* pCxt, bool ignoreNotExists, const SToken* pDbName);
|
||||
STableOptions* createDefaultTableOptions(SAstCreateContext* pCxt);
|
||||
STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions, ETableOptionType type, const SToken* pVal);
|
||||
STableOptions* setTableSmaOption(SAstCreateContext* pCxt, STableOptions* pOptions, SNodeList* pSma);
|
||||
SNode* createDefaultTableOptions(SAstCreateContext* pCxt);
|
||||
SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType type, const SToken* pVal);
|
||||
SNode* setTableSmaOption(SAstCreateContext* pCxt, SNode* pOptions, SNodeList* pSma);
|
||||
SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDataType dataType, const SToken* pComment);
|
||||
SDataType createDataType(uint8_t type);
|
||||
SDataType createVarLenDataType(uint8_t type, const SToken* pLen);
|
||||
SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols, SNodeList* pTags, STableOptions* pOptions);
|
||||
SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols, SNodeList* pTags, SNode* pOptions);
|
||||
SNode* createCreateSubTableClause(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNode* pUseRealTable, SNodeList* pSpecificTags, SNodeList* pValsOfTags);
|
||||
SNode* createCreateMultiTableStmt(SAstCreateContext* pCxt, SNodeList* pSubTables);
|
||||
SNode* createDropTableClause(SAstCreateContext* pCxt, bool ignoreNotExists, SNode* pRealTable);
|
||||
|
@ -132,6 +132,9 @@ SNode* createAlterUserStmt(SAstCreateContext* pCxt, const SToken* pUserName, int
|
|||
SNode* createDropUserStmt(SAstCreateContext* pCxt, const SToken* pUserName);
|
||||
SNode* createCreateDnodeStmt(SAstCreateContext* pCxt, const SToken* pFqdn, const SToken* pPort);
|
||||
SNode* createDropDnodeStmt(SAstCreateContext* pCxt, const SToken* pDnode);
|
||||
SNode* createCreateIndexStmt(SAstCreateContext* pCxt, EIndexType type, const SToken* pIndexName, const SToken* pTableName, SNodeList* pCols, SNode* pOptions);
|
||||
SNode* createIndexOption(SAstCreateContext* pCxt, SNodeList* pFuncs, SNode* pInterval, SNode* pOffset, SNode* pSliding);
|
||||
SNode* createCreateQnodeStmt(SAstCreateContext* pCxt, const SToken* pDnodeId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -64,6 +64,10 @@ dnode_endpoint(A) ::= NK_STRING(B).
|
|||
dnode_host_name(A) ::= NK_ID(B). { A = B; }
|
||||
dnode_host_name(A) ::= NK_IPTOKEN(B). { A = B; }
|
||||
|
||||
/************************************************ create qnode ********************************************************/
|
||||
cmd ::= CREATE QNODE ON DNODE NK_INTEGER(A). { pCxt->pRootNode = createCreateQnodeStmt(pCxt, &A); }
|
||||
cmd ::= SHOW QNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QNODES_STMT, NULL); }
|
||||
|
||||
/************************************************ create/drop/show/use database ***************************************/
|
||||
cmd ::= CREATE DATABASE not_exists_opt(A) db_name(B) db_options(C). { pCxt->pRootNode = createCreateDatabaseStmt(pCxt, A, &B, C);}
|
||||
cmd ::= DROP DATABASE exists_opt(A) db_name(B). { pCxt->pRootNode = createDropDatabaseStmt(pCxt, A, &B); }
|
||||
|
@ -80,8 +84,6 @@ not_exists_opt(A) ::= .
|
|||
exists_opt(A) ::= IF EXISTS. { A = true; }
|
||||
exists_opt(A) ::= . { A = false; }
|
||||
|
||||
%type db_options { SDatabaseOptions* }
|
||||
%destructor db_options { tfree($$); }
|
||||
db_options(A) ::= . { A = createDefaultDatabaseOptions(pCxt); }
|
||||
db_options(A) ::= db_options(B) BLOCKS NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_BLOCKS, &C); }
|
||||
db_options(A) ::= db_options(B) CACHE NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_CACHE, &C); }
|
||||
|
@ -179,8 +181,6 @@ tags_def_opt(A) ::= tags_def(B).
|
|||
%destructor tags_def { nodesDestroyList($$); }
|
||||
tags_def(A) ::= TAGS NK_LP column_def_list(B) NK_RP. { A = B; }
|
||||
|
||||
%type table_options { STableOptions* }
|
||||
%destructor table_options { tfree($$); }
|
||||
table_options(A) ::= . { A = createDefaultTableOptions(pCxt);}
|
||||
table_options(A) ::= table_options(B) COMMENT NK_STRING(C). { A = setTableOption(pCxt, B, TABLE_OPTION_COMMENT, &C); }
|
||||
table_options(A) ::= table_options(B) KEEP NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_KEEP, &C); }
|
||||
|
@ -194,11 +194,29 @@ col_name_list(A) ::= col_name_list(B) NK_COMMA col_name(C).
|
|||
|
||||
col_name(A) ::= column_name(B). { A = createColumnNode(pCxt, NULL, &B); }
|
||||
|
||||
/************************************************ create index ********************************************************/
|
||||
cmd ::= CREATE SMA INDEX index_name(A) ON table_name(B) index_options(C). { pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, &A, &B, NULL, C); }
|
||||
cmd ::= CREATE FULLTEXT INDEX
|
||||
index_name(A) ON table_name(B) NK_LP col_name_list(C) NK_RP. { pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_FULLTEXT, &A, &B, C, NULL); }
|
||||
|
||||
index_options(A) ::= . { A = NULL; }
|
||||
index_options(A) ::= FUNCTION NK_LP func_list(B) NK_RP INTERVAL
|
||||
NK_LP duration_literal(C) NK_RP sliding_opt(D). { A = createIndexOption(pCxt, B, releaseRawExprNode(pCxt, C), NULL, D); }
|
||||
index_options(A) ::= FUNCTION NK_LP func_list(B) NK_RP INTERVAL
|
||||
NK_LP duration_literal(C) NK_COMMA duration_literal(D) NK_RP sliding_opt(E). { A = createIndexOption(pCxt, B, releaseRawExprNode(pCxt, C), releaseRawExprNode(pCxt, D), E); }
|
||||
|
||||
%type func_list { SNodeList* }
|
||||
%destructor func_list { nodesDestroyList($$); }
|
||||
func_list(A) ::= func(B). { A = createNodeList(pCxt, B); }
|
||||
func_list(A) ::= func_list(B) NK_COMMA func(C). { A = addNodeToList(pCxt, B, C); }
|
||||
|
||||
func(A) ::= function_name(B) NK_LP expression_list(C) NK_RP. { A = createFunctionNode(pCxt, &B, C); }
|
||||
|
||||
/************************************************ show vgroups ********************************************************/
|
||||
cmd ::= SHOW VGROUPS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, NULL); }
|
||||
cmd ::= SHOW db_name(B) NK_DOT VGROUPS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, &B); }
|
||||
|
||||
/************************************************ show vgroups ********************************************************/
|
||||
/************************************************ show mnodes *********************************************************/
|
||||
cmd ::= SHOW MNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT, NULL); }
|
||||
|
||||
/************************************************ select **************************************************************/
|
||||
|
@ -248,6 +266,10 @@ column_alias(A) ::= NK_ID(B).
|
|||
%destructor user_name { }
|
||||
user_name(A) ::= NK_ID(B). { A = B; }
|
||||
|
||||
%type index_name { SToken }
|
||||
%destructor index_name { }
|
||||
index_name(A) ::= NK_ID(B). { A = B; }
|
||||
|
||||
/************************************************ expression **********************************************************/
|
||||
expression(A) ::= literal(B). { A = B; }
|
||||
//expression(A) ::= NK_QUESTION(B). { A = B; }
|
||||
|
@ -463,13 +485,13 @@ twindow_clause_opt(A) ::=
|
|||
SESSION NK_LP column_reference(B) NK_COMMA NK_INTEGER(C) NK_RP. { A = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
||||
twindow_clause_opt(A) ::= STATE_WINDOW NK_LP column_reference(B) NK_RP. { A = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, B)); }
|
||||
twindow_clause_opt(A) ::=
|
||||
INTERVAL NK_LP duration_literal(B) NK_RP sliding_opt(C) fill_opt(D). { A = createIntervalWindowNode(pCxt, B, NULL, C, D); }
|
||||
INTERVAL NK_LP duration_literal(B) NK_RP sliding_opt(C) fill_opt(D). { A = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, B), NULL, C, D); }
|
||||
twindow_clause_opt(A) ::=
|
||||
INTERVAL NK_LP duration_literal(B) NK_COMMA duration_literal(C) NK_RP
|
||||
sliding_opt(D) fill_opt(E). { A = createIntervalWindowNode(pCxt, B, C, D, E); }
|
||||
sliding_opt(D) fill_opt(E). { A = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C), D, E); }
|
||||
|
||||
sliding_opt(A) ::= . { A = NULL; }
|
||||
sliding_opt(A) ::= SLIDING NK_LP duration_literal(B) NK_RP. { A = B; }
|
||||
sliding_opt(A) ::= SLIDING NK_LP duration_literal(B) NK_RP. { A = releaseRawExprNode(pCxt, B); }
|
||||
|
||||
fill_opt(A) ::= . { A = NULL; }
|
||||
fill_opt(A) ::= FILL NK_LP fill_mode(B) NK_RP. { A = createFillNode(pCxt, B, NULL); }
|
||||
|
|
|
@ -420,6 +420,14 @@ static bool checkColumnName(SAstCreateContext* pCxt, const SToken* pColumnName)
|
|||
return pCxt->valid;
|
||||
}
|
||||
|
||||
static bool checkIndexName(SAstCreateContext* pCxt, const SToken* pIndexName) {
|
||||
if (NULL == pIndexName) {
|
||||
return false;
|
||||
}
|
||||
pCxt->valid = pIndexName->n < TSDB_INDEX_NAME_LEN ? true : false;
|
||||
return pCxt->valid;
|
||||
}
|
||||
|
||||
SNode* createRawExprNode(SAstCreateContext* pCxt, const SToken* pToken, SNode* pNode) {
|
||||
SRawExprNode* target = (SRawExprNode*)nodesMakeNode(QUERY_NODE_RAW_EXPR);
|
||||
CHECK_OUT_OF_MEM(target);
|
||||
|
@ -741,8 +749,8 @@ SNode* createSetOperator(SAstCreateContext* pCxt, ESetOperatorType type, SNode*
|
|||
return (SNode*)setOp;
|
||||
}
|
||||
|
||||
SDatabaseOptions* createDefaultDatabaseOptions(SAstCreateContext* pCxt) {
|
||||
SDatabaseOptions* pOptions = calloc(1, sizeof(SDatabaseOptions));
|
||||
SNode* createDefaultDatabaseOptions(SAstCreateContext* pCxt) {
|
||||
SDatabaseOptions* pOptions = nodesMakeNode(QUERY_NODE_DATABASE_OPTIONS);
|
||||
CHECK_OUT_OF_MEM(pOptions);
|
||||
pOptions->numOfBlocks = TSDB_DEFAULT_TOTAL_BLOCKS;
|
||||
pOptions->cacheBlockSize = TSDB_DEFAULT_CACHE_BLOCK_SIZE;
|
||||
|
@ -761,14 +769,14 @@ SDatabaseOptions* createDefaultDatabaseOptions(SAstCreateContext* pCxt) {
|
|||
pOptions->numOfVgroups = TSDB_DEFAULT_VN_PER_DB;
|
||||
pOptions->singleStable = TSDB_DEFAULT_DB_SINGLE_STABLE_OPTION;
|
||||
pOptions->streamMode = TSDB_DEFAULT_DB_STREAM_MODE_OPTION;
|
||||
return pOptions;
|
||||
return (SNode*)pOptions;
|
||||
}
|
||||
|
||||
SDatabaseOptions* setDatabaseOption(SAstCreateContext* pCxt, SDatabaseOptions* pOptions, EDatabaseOptionType type, const SToken* pVal) {
|
||||
return setDbOptionFuncs[type](pCxt, pOptions, pVal);
|
||||
SNode* setDatabaseOption(SAstCreateContext* pCxt, SNode* pOptions, EDatabaseOptionType type, const SToken* pVal) {
|
||||
return (SNode*)setDbOptionFuncs[type](pCxt, (SDatabaseOptions*)pOptions, pVal);
|
||||
}
|
||||
|
||||
SNode* createCreateDatabaseStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pDbName, SDatabaseOptions* pOptions) {
|
||||
SNode* createCreateDatabaseStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pDbName, SNode* pOptions) {
|
||||
if (!checkDbName(pCxt, pDbName)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -776,8 +784,7 @@ SNode* createCreateDatabaseStmt(SAstCreateContext* pCxt, bool ignoreExists, cons
|
|||
CHECK_OUT_OF_MEM(pStmt);
|
||||
strncpy(pStmt->dbName, pDbName->z, pDbName->n);
|
||||
pStmt->ignoreExists = ignoreExists;
|
||||
pStmt->options = *pOptions;
|
||||
tfree(pOptions);
|
||||
pStmt->pOptions = (SDatabaseOptions*)pOptions;
|
||||
return (SNode*)pStmt;
|
||||
}
|
||||
|
||||
|
@ -792,20 +799,20 @@ SNode* createDropDatabaseStmt(SAstCreateContext* pCxt, bool ignoreNotExists, con
|
|||
return (SNode*)pStmt;
|
||||
}
|
||||
|
||||
STableOptions* createDefaultTableOptions(SAstCreateContext* pCxt) {
|
||||
STableOptions* pOptions = calloc(1, sizeof(STableOptions));
|
||||
SNode* createDefaultTableOptions(SAstCreateContext* pCxt) {
|
||||
STableOptions* pOptions = nodesMakeNode(QUERY_NODE_TABLE_OPTIONS);
|
||||
CHECK_OUT_OF_MEM(pOptions);
|
||||
pOptions->keep = TSDB_DEFAULT_KEEP;
|
||||
pOptions->ttl = TSDB_DEFAULT_DB_TTL_OPTION;
|
||||
return pOptions;
|
||||
return (SNode*)pOptions;
|
||||
}
|
||||
|
||||
STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions, ETableOptionType type, const SToken* pVal) {
|
||||
return setTableOptionFuncs[type](pCxt, pOptions, pVal);
|
||||
SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType type, const SToken* pVal) {
|
||||
return (SNode*)setTableOptionFuncs[type](pCxt, (STableOptions*)pOptions, pVal);
|
||||
}
|
||||
|
||||
STableOptions* setTableSmaOption(SAstCreateContext* pCxt, STableOptions* pOptions, SNodeList* pSma) {
|
||||
pOptions->pSma = pSma;
|
||||
SNode* setTableSmaOption(SAstCreateContext* pCxt, SNode* pOptions, SNodeList* pSma) {
|
||||
((STableOptions*)pOptions)->pSma = pSma;
|
||||
return pOptions;
|
||||
}
|
||||
|
||||
|
@ -831,7 +838,7 @@ SDataType createVarLenDataType(uint8_t type, const SToken* pLen) {
|
|||
}
|
||||
|
||||
SNode* createCreateTableStmt(SAstCreateContext* pCxt,
|
||||
bool ignoreExists, SNode* pRealTable, SNodeList* pCols, SNodeList* pTags, STableOptions* pOptions) {
|
||||
bool ignoreExists, SNode* pRealTable, SNodeList* pCols, SNodeList* pTags, SNode* pOptions) {
|
||||
SCreateTableStmt* pStmt = (SCreateTableStmt*)nodesMakeNode(QUERY_NODE_CREATE_TABLE_STMT);
|
||||
CHECK_OUT_OF_MEM(pStmt);
|
||||
strcpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName);
|
||||
|
@ -839,9 +846,7 @@ SNode* createCreateTableStmt(SAstCreateContext* pCxt,
|
|||
pStmt->ignoreExists = ignoreExists;
|
||||
pStmt->pCols = pCols;
|
||||
pStmt->pTags = pTags;
|
||||
pStmt->options = *pOptions;
|
||||
nodesDestroyList(pOptions->pSma);
|
||||
tfree(pOptions);
|
||||
pStmt->pOptions = (STableOptions*)pOptions;
|
||||
nodesDestroyNode(pRealTable);
|
||||
return (SNode*)pStmt;
|
||||
}
|
||||
|
@ -992,3 +997,34 @@ SNode* createDropDnodeStmt(SAstCreateContext* pCxt, const SToken* pDnode) {
|
|||
}
|
||||
return (SNode*)pStmt;
|
||||
}
|
||||
|
||||
SNode* createCreateIndexStmt(SAstCreateContext* pCxt, EIndexType type, const SToken* pIndexName, const SToken* pTableName, SNodeList* pCols, SNode* pOptions) {
|
||||
if (!checkIndexName(pCxt, pIndexName) || !checkTableName(pCxt, pTableName)) {
|
||||
return NULL;
|
||||
}
|
||||
SCreateIndexStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_INDEX_STMT);
|
||||
CHECK_OUT_OF_MEM(pStmt);
|
||||
pStmt->indexType = type;
|
||||
strncpy(pStmt->indexName, pIndexName->z, pIndexName->n);
|
||||
strncpy(pStmt->tableName, pTableName->z, pTableName->n);
|
||||
pStmt->pCols = pCols;
|
||||
pStmt->pOptions = (SIndexOptions*)pOptions;
|
||||
return (SNode*)pStmt;
|
||||
}
|
||||
|
||||
SNode* createIndexOption(SAstCreateContext* pCxt, SNodeList* pFuncs, SNode* pInterval, SNode* pOffset, SNode* pSliding) {
|
||||
SIndexOptions* pOptions = nodesMakeNode(QUERY_NODE_INDEX_OPTIONS);
|
||||
CHECK_OUT_OF_MEM(pOptions);
|
||||
pOptions->pFuncs = pFuncs;
|
||||
pOptions->pInterval = pInterval;
|
||||
pOptions->pOffset = pOffset;
|
||||
pOptions->pSliding = pSliding;
|
||||
return (SNode*)pOptions;
|
||||
}
|
||||
|
||||
SNode* createCreateQnodeStmt(SAstCreateContext* pCxt, const SToken* pDnodeId) {
|
||||
SCreateQnodeStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_QNODE_STMT);
|
||||
CHECK_OUT_OF_MEM(pStmt);
|
||||
pStmt->dnodeId = strtol(pDnodeId->z, NULL, 10);;
|
||||
return (SNode*)pStmt;
|
||||
}
|
||||
|
|
|
@ -59,11 +59,13 @@ static SKeyword keywordTable[] = {
|
|||
{"FLOAT", TK_FLOAT},
|
||||
{"FROM", TK_FROM},
|
||||
{"FSYNC", TK_FSYNC},
|
||||
{"FUNCTION", TK_FUNCTION},
|
||||
{"GROUP", TK_GROUP},
|
||||
{"HAVING", TK_HAVING},
|
||||
{"IF", TK_IF},
|
||||
{"IMPORT", TK_IMPORT},
|
||||
{"IN", TK_IN},
|
||||
{"INDEX", TK_INDEX},
|
||||
{"INNER", TK_INNER},
|
||||
{"INT", TK_INT},
|
||||
{"INSERT", TK_INSERT},
|
||||
|
@ -97,6 +99,8 @@ static SKeyword keywordTable[] = {
|
|||
{"PRECISION", TK_PRECISION},
|
||||
{"PRIVILEGE", TK_PRIVILEGE},
|
||||
{"PREV", TK_PREV},
|
||||
{"QNODE", TK_QNODE},
|
||||
{"QNODES", TK_QNODES},
|
||||
{"QUORUM", TK_QUORUM},
|
||||
{"REPLICA", TK_REPLICA},
|
||||
{"SELECT", TK_SELECT},
|
||||
|
@ -230,7 +234,6 @@ static SKeyword keywordTable[] = {
|
|||
// {"TOPICS", TK_TOPICS},
|
||||
// {"COMPACT", TK_COMPACT},
|
||||
// {"MODIFY", TK_MODIFY},
|
||||
// {"FUNCTION", TK_FUNCTION},
|
||||
// {"FUNCTIONS", TK_FUNCTIONS},
|
||||
// {"OUTPUTTYPE", TK_OUTPUTTYPE},
|
||||
// {"AGGREGATE", TK_AGGREGATE},
|
||||
|
|
|
@ -254,8 +254,7 @@ static int32_t trimStringWithVarFormat(const char* src, int32_t len, bool format
|
|||
|
||||
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
||||
if (pVal->isDuration) {
|
||||
char unit = 0;
|
||||
if (parseAbsoluteDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &unit, pVal->node.resType.precision) != TSDB_CODE_SUCCESS) {
|
||||
if (parseAbsoluteDuration(pVal->literal, strlen(pVal->literal), &pVal->datum.i, &pVal->unit, pVal->node.resType.precision) != TSDB_CODE_SUCCESS) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
||||
}
|
||||
} else {
|
||||
|
@ -706,9 +705,17 @@ static int32_t translateGroupBy(STranslateContext* pCxt, SNodeList* pGroupByList
|
|||
return translateExprList(pCxt, pGroupByList);
|
||||
}
|
||||
|
||||
static int32_t doTranslateWindow(STranslateContext* pCxt, SNode* pWindow) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateWindow(STranslateContext* pCxt, SNode* pWindow) {
|
||||
pCxt->currClause = SQL_CLAUSE_WINDOW;
|
||||
return translateExpr(pCxt, pWindow);
|
||||
int32_t code = translateExpr(pCxt, pWindow);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = doTranslateWindow(pCxt, pWindow);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t translatePartitionBy(STranslateContext* pCxt, SNodeList* pPartitionByList) {
|
||||
|
@ -760,26 +767,26 @@ static void buildCreateDbReq(STranslateContext* pCxt, SCreateDatabaseStmt* pStmt
|
|||
SName name = {0};
|
||||
tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
|
||||
tNameGetFullDbName(&name, pReq->db);
|
||||
pReq->numOfVgroups = pStmt->options.numOfVgroups;
|
||||
pReq->cacheBlockSize = pStmt->options.cacheBlockSize;
|
||||
pReq->totalBlocks = pStmt->options.numOfBlocks;
|
||||
pReq->daysPerFile = pStmt->options.daysPerFile;
|
||||
pReq->daysToKeep0 = pStmt->options.keep;
|
||||
pReq->numOfVgroups = pStmt->pOptions->numOfVgroups;
|
||||
pReq->cacheBlockSize = pStmt->pOptions->cacheBlockSize;
|
||||
pReq->totalBlocks = pStmt->pOptions->numOfBlocks;
|
||||
pReq->daysPerFile = pStmt->pOptions->daysPerFile;
|
||||
pReq->daysToKeep0 = pStmt->pOptions->keep;
|
||||
pReq->daysToKeep1 = -1;
|
||||
pReq->daysToKeep2 = -1;
|
||||
pReq->minRows = pStmt->options.minRowsPerBlock;
|
||||
pReq->maxRows = pStmt->options.maxRowsPerBlock;
|
||||
pReq->minRows = pStmt->pOptions->minRowsPerBlock;
|
||||
pReq->maxRows = pStmt->pOptions->maxRowsPerBlock;
|
||||
pReq->commitTime = -1;
|
||||
pReq->fsyncPeriod = pStmt->options.fsyncPeriod;
|
||||
pReq->walLevel = pStmt->options.walLevel;
|
||||
pReq->precision = pStmt->options.precision;
|
||||
pReq->compression = pStmt->options.compressionLevel;
|
||||
pReq->replications = pStmt->options.replica;
|
||||
pReq->quorum = pStmt->options.quorum;
|
||||
pReq->fsyncPeriod = pStmt->pOptions->fsyncPeriod;
|
||||
pReq->walLevel = pStmt->pOptions->walLevel;
|
||||
pReq->precision = pStmt->pOptions->precision;
|
||||
pReq->compression = pStmt->pOptions->compressionLevel;
|
||||
pReq->replications = pStmt->pOptions->replica;
|
||||
pReq->quorum = pStmt->pOptions->quorum;
|
||||
pReq->update = -1;
|
||||
pReq->cacheLastRow = pStmt->options.cachelast;
|
||||
pReq->cacheLastRow = pStmt->pOptions->cachelast;
|
||||
pReq->ignoreExist = pStmt->ignoreExists;
|
||||
pReq->streamMode = pStmt->options.streamMode;
|
||||
pReq->streamMode = pStmt->pOptions->streamMode;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -788,14 +795,14 @@ static int32_t translateCreateDatabase(STranslateContext* pCxt, SCreateDatabaseS
|
|||
buildCreateDbReq(pCxt, pStmt, &createReq);
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_MND_CREATE_DB;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSCreateDbReq(NULL, 0, &createReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
tSerializeSCreateDbReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &createReq);
|
||||
|
@ -811,14 +818,14 @@ static int32_t translateDropDatabase(STranslateContext* pCxt, SDropDatabaseStmt*
|
|||
dropReq.ignoreNotExists = pStmt->ignoreNotExists;
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_MND_DROP_DB;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSDropDbReq(NULL, 0, &dropReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
tSerializeSDropDbReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &dropReq);
|
||||
|
@ -852,7 +859,7 @@ static int32_t translateCreateSuperTable(STranslateContext* pCxt, SCreateTableSt
|
|||
tNameExtractFullName(&tableName, createReq.name);
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
tFreeSMCreateStbReq(&createReq);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -860,7 +867,7 @@ static int32_t translateCreateSuperTable(STranslateContext* pCxt, SCreateTableSt
|
|||
pCxt->pCmdMsg->msgType = TDMT_MND_CREATE_STB;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSMCreateStbReq(NULL, 0, &createReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
tFreeSMCreateStbReq(&createReq);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -876,14 +883,14 @@ static int32_t doTranslateDropSuperTable(STranslateContext* pCxt, const SName* p
|
|||
dropReq.igNotExists = ignoreNotExists;
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_MND_DROP_STB;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSMDropStbReq(NULL, 0, &dropReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
tSerializeSMDropStbReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &dropReq);
|
||||
|
@ -929,14 +936,14 @@ static int32_t translateUseDatabase(STranslateContext* pCxt, SUseDatabaseStmt* p
|
|||
catalogGetDBVgVersion(pCxt->pParseCxt->pCatalog, usedbReq.db, &usedbReq.vgVersion, &usedbReq.dbId, &usedbReq.numOfTable);
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_MND_USE_DB;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSUseDbReq(NULL, 0, &usedbReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
tSerializeSUseDbReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &usedbReq);
|
||||
|
@ -952,14 +959,14 @@ static int32_t translateCreateUser(STranslateContext* pCxt, SCreateUserStmt* pSt
|
|||
strcpy(createReq.pass, pStmt->password);
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_MND_CREATE_USER;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSCreateUserReq(NULL, 0, &createReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
tSerializeSCreateUserReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &createReq);
|
||||
|
@ -978,14 +985,14 @@ static int32_t translateAlterUser(STranslateContext* pCxt, SAlterUserStmt* pStmt
|
|||
}
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_MND_ALTER_USER;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSAlterUserReq(NULL, 0, &alterReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
tSerializeSAlterUserReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &alterReq);
|
||||
|
@ -998,14 +1005,14 @@ static int32_t translateDropUser(STranslateContext* pCxt, SDropUserStmt* pStmt)
|
|||
strcpy(dropReq.user, pStmt->useName);
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_MND_DROP_USER;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSDropUserReq(NULL, 0, &dropReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
tSerializeSDropUserReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &dropReq);
|
||||
|
@ -1019,14 +1026,14 @@ static int32_t translateCreateDnode(STranslateContext* pCxt, SCreateDnodeStmt* p
|
|||
createReq.port = pStmt->port;
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_MND_CREATE_DNODE;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSCreateDnodeReq(NULL, 0, &createReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
tSerializeSCreateDnodeReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &createReq);
|
||||
|
@ -1041,14 +1048,14 @@ static int32_t translateDropDnode(STranslateContext* pCxt, SDropDnodeStmt* pStmt
|
|||
dropReq.port = pStmt->port;
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_MND_DROP_DNODE;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSDropDnodeReq(NULL, 0, &dropReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
tSerializeSDropDnodeReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &dropReq);
|
||||
|
@ -1070,6 +1077,8 @@ static int32_t nodeTypeToShowType(ENodeType nt) {
|
|||
return TSDB_MGMT_TABLE_VGROUP;
|
||||
case QUERY_NODE_SHOW_MNODES_STMT:
|
||||
return TSDB_MGMT_TABLE_MNODE;
|
||||
case QUERY_NODE_SHOW_QNODES_STMT:
|
||||
return TSDB_MGMT_TABLE_QNODE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1086,14 +1095,14 @@ static int32_t translateShow(STranslateContext* pCxt, SShowStmt* pStmt) {
|
|||
}
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_MND_SHOW;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSShowReq(NULL, 0, &showReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
tSerializeSShowReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &showReq);
|
||||
|
@ -1121,7 +1130,7 @@ static int32_t translateShowTables(STranslateContext* pCxt) {
|
|||
pShowReq->head.vgId = htonl(info->vgId);
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL== pCxt->pCmdMsg) {
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = info->epSet;
|
||||
|
@ -1133,6 +1142,84 @@ static int32_t translateShowTables(STranslateContext* pCxt) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateCreateSmaIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) {
|
||||
SVCreateTSmaReq createSmaReq = {0};
|
||||
|
||||
if (DEAL_RES_ERROR == translateValue(pCxt, (SValueNode*)pStmt->pOptions->pInterval) ||
|
||||
(NULL != pStmt->pOptions->pOffset && DEAL_RES_ERROR == translateValue(pCxt, (SValueNode*)pStmt->pOptions->pOffset)) ||
|
||||
(NULL != pStmt->pOptions->pSliding && DEAL_RES_ERROR == translateValue(pCxt, (SValueNode*)pStmt->pOptions->pSliding))) {
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
createSmaReq.tSma.intervalUnit = ((SValueNode*)pStmt->pOptions->pInterval)->unit;
|
||||
createSmaReq.tSma.slidingUnit = (NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->unit : 0);
|
||||
strcpy(createSmaReq.tSma.indexName, pStmt->indexName);
|
||||
|
||||
SName name;
|
||||
name.type = TSDB_TABLE_NAME_T;
|
||||
name.acctId = pCxt->pParseCxt->acctId;
|
||||
strcpy(name.dbname, pCxt->pParseCxt->db);
|
||||
strcpy(name.tname, pStmt->tableName);
|
||||
STableMeta* pMeta = NULL;
|
||||
int32_t code = catalogGetTableMeta(pCxt->pParseCxt->pCatalog, pCxt->pParseCxt->pTransporter, &pCxt->pParseCxt->mgmtEpSet, &name, &pMeta);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
|
||||
createSmaReq.tSma.tableUid = pMeta->uid;
|
||||
createSmaReq.tSma.interval = ((SValueNode*)pStmt->pOptions->pInterval)->datum.i;
|
||||
createSmaReq.tSma.sliding = (NULL != pStmt->pOptions->pSliding ? ((SValueNode*)pStmt->pOptions->pSliding)->datum.i : 0);
|
||||
code = nodesListToString(pStmt->pOptions->pFuncs, false, &createSmaReq.tSma.expr, &createSmaReq.tSma.exprLen);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_VND_CREATE_SMA;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSVCreateTSmaReq(NULL, &createSmaReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
void* pBuf = pCxt->pCmdMsg->pMsg;
|
||||
tSerializeSVCreateTSmaReq(&pBuf, &createSmaReq);
|
||||
tdDestroyTSma(&createSmaReq.tSma);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateCreateIndex(STranslateContext* pCxt, SCreateIndexStmt* pStmt) {
|
||||
if (INDEX_TYPE_SMA == pStmt->indexType) {
|
||||
return translateCreateSmaIndex(pCxt, pStmt);
|
||||
} else {
|
||||
// todo fulltext index
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t translateCreateQnode(STranslateContext* pCxt, SCreateQnodeStmt* pStmt) {
|
||||
SMCreateQnodeReq createReq = { .dnodeId = pStmt->dnodeId };
|
||||
|
||||
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||
if (NULL == pCxt->pCmdMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||
pCxt->pCmdMsg->msgType = TDMT_DND_CREATE_QNODE;
|
||||
pCxt->pCmdMsg->msgLen = tSerializeSMCreateDropQSBNodeReq(NULL, 0, &createReq);
|
||||
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||
if (NULL == pCxt->pCmdMsg->pMsg) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
tSerializeSMCreateDropQSBNodeReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &createReq);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
switch (nodeType(pNode)) {
|
||||
|
@ -1178,11 +1265,18 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
|
|||
case QUERY_NODE_SHOW_DNODES_STMT:
|
||||
case QUERY_NODE_SHOW_VGROUPS_STMT:
|
||||
case QUERY_NODE_SHOW_MNODES_STMT:
|
||||
case QUERY_NODE_SHOW_QNODES_STMT:
|
||||
code = translateShow(pCxt, (SShowStmt*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_SHOW_TABLES_STMT:
|
||||
code = translateShowTables(pCxt);
|
||||
break;
|
||||
case QUERY_NODE_CREATE_INDEX_STMT:
|
||||
code = translateCreateIndex(pCxt, (SCreateIndexStmt*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_CREATE_QNODE_STMT:
|
||||
code = translateCreateQnode(pCxt, (SCreateQnodeStmt*)pNode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -183,6 +183,13 @@ TEST_F(ParserTest, selectClause) {
|
|||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
||||
TEST_F(ParserTest, selectWindow) {
|
||||
setDatabase("root", "test");
|
||||
|
||||
bind("SELECT count(*) FROM t1 interval(10s)");
|
||||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
||||
TEST_F(ParserTest, selectSyntaxError) {
|
||||
setDatabase("root", "test");
|
||||
|
||||
|
@ -391,3 +398,17 @@ TEST_F(ParserTest, createTable) {
|
|||
);
|
||||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
||||
TEST_F(ParserTest, createSmaIndex) {
|
||||
setDatabase("root", "test");
|
||||
|
||||
bind("create sma index index1 on t1 function(max(c1), min(c3 + 10), sum(c4)) INTERVAL(10s)");
|
||||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
||||
TEST_F(ParserTest, createQnode) {
|
||||
setDatabase("root", "test");
|
||||
|
||||
bind("create qnode on dnode 1");
|
||||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
|
|
@ -304,6 +304,53 @@ static SLogicNode* createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSel
|
|||
return (SLogicNode*)pAgg;
|
||||
}
|
||||
|
||||
static SLogicNode* createWindowLogicNodeByInterval(SLogicPlanContext* pCxt, SIntervalWindowNode* pInterval, SSelectStmt* pSelect) {
|
||||
SWindowLogicNode* pWindow = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_WINDOW);
|
||||
CHECK_ALLOC(pWindow, NULL);
|
||||
pWindow->node.id = pCxt->planNodeId++;
|
||||
|
||||
pWindow->winType = WINDOW_TYPE_INTERVAL;
|
||||
SValueNode* pIntervalNode = (SValueNode*)((SRawExprNode*)(pInterval->pInterval))->pNode;
|
||||
|
||||
pWindow->interval = pIntervalNode->datum.i;
|
||||
pWindow->offset = (NULL != pInterval->pOffset ? ((SValueNode*)pInterval->pOffset)->datum.i : 0);
|
||||
pWindow->sliding = (NULL != pInterval->pSliding ? ((SValueNode*)pInterval->pSliding)->datum.i : pWindow->interval);
|
||||
|
||||
if (NULL != pInterval->pFill) {
|
||||
pWindow->pFill = nodesCloneNode(pInterval->pFill);
|
||||
CHECK_ALLOC(pWindow->pFill, (SLogicNode*)pWindow);
|
||||
}
|
||||
|
||||
SNodeList* pFuncs = NULL;
|
||||
CHECK_CODE(nodesCollectFuncs(pSelect, fmIsAggFunc, &pFuncs), NULL);
|
||||
if (NULL != pFuncs) {
|
||||
pWindow->pFuncs = nodesCloneList(pFuncs);
|
||||
CHECK_ALLOC(pWindow->pFuncs, (SLogicNode*)pWindow);
|
||||
}
|
||||
|
||||
CHECK_CODE(rewriteExpr(pWindow->node.id, 1, pWindow->pFuncs, pSelect, SQL_CLAUSE_WINDOW), (SLogicNode*)pWindow);
|
||||
|
||||
pWindow->node.pTargets = createColumnByRewriteExps(pCxt, pWindow->pFuncs);
|
||||
CHECK_ALLOC(pWindow->node.pTargets, (SLogicNode*)pWindow);
|
||||
|
||||
return (SLogicNode*)pWindow;
|
||||
}
|
||||
|
||||
static SLogicNode* createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (NULL == pSelect->pWindow) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (nodeType(pSelect->pWindow)) {
|
||||
case QUERY_NODE_INTERVAL_WINDOW:
|
||||
return createWindowLogicNodeByInterval(pCxt, (SIntervalWindowNode*)pSelect->pWindow, pSelect);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SNodeList* createColumnByProjections(SLogicPlanContext* pCxt, SNodeList* pExprs) {
|
||||
SNodeList* pList = nodesMakeList();
|
||||
CHECK_ALLOC(pList, NULL);
|
||||
|
@ -345,6 +392,9 @@ static SLogicNode* createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* p
|
|||
pRoot->pConditions = nodesCloneNode(pSelect->pWhere);
|
||||
CHECK_ALLOC(pRoot->pConditions, pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
pRoot = pushLogicNode(pCxt, pRoot, createWindowLogicNode(pCxt, pSelect));
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
pRoot = pushLogicNode(pCxt, pRoot, createAggLogicNode(pCxt, pSelect));
|
||||
}
|
||||
|
|
|
@ -473,14 +473,61 @@ static SPhysiNode* createExchangePhysiNode(SPhysiPlanContext* pCxt, SExchangeLog
|
|||
return (SPhysiNode*)pExchange;
|
||||
}
|
||||
|
||||
static SPhysiNode* createIntervalPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SWindowLogicNode* pWindowLogicNode) {
|
||||
SIntervalPhysiNode* pInterval = (SIntervalPhysiNode*)makePhysiNode(pCxt, QUERY_NODE_PHYSICAL_PLAN_INTERVAL);
|
||||
CHECK_ALLOC(pInterval, NULL);
|
||||
|
||||
pInterval->interval = pWindowLogicNode->interval;
|
||||
pInterval->offset = pWindowLogicNode->offset;
|
||||
pInterval->sliding = pWindowLogicNode->sliding;
|
||||
pInterval->intervalUnit = pWindowLogicNode->intervalUnit;
|
||||
pInterval->slidingUnit = pWindowLogicNode->slidingUnit;
|
||||
|
||||
pInterval->pFill = nodesCloneNode(pWindowLogicNode->pFill);
|
||||
|
||||
SNodeList* pPrecalcExprs = NULL;
|
||||
SNodeList* pFuncs = NULL;
|
||||
CHECK_CODE(rewritePrecalcExprs(pCxt, pWindowLogicNode->pFuncs, &pPrecalcExprs, &pFuncs), (SPhysiNode*)pInterval);
|
||||
|
||||
SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc);
|
||||
// push down expression to pOutputDataBlockDesc of child node
|
||||
if (NULL != pPrecalcExprs) {
|
||||
pInterval->pExprs = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pPrecalcExprs);
|
||||
CHECK_ALLOC(pInterval->pExprs, (SPhysiNode*)pInterval);
|
||||
CHECK_CODE(addDataBlockDesc(pCxt, pInterval->pExprs, pChildTupe), (SPhysiNode*)pInterval);
|
||||
}
|
||||
|
||||
if (NULL != pFuncs) {
|
||||
pInterval->pFuncs = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pFuncs);
|
||||
CHECK_ALLOC(pInterval->pFuncs, (SPhysiNode*)pInterval);
|
||||
CHECK_CODE(addDataBlockDesc(pCxt, pInterval->pFuncs, pInterval->node.pOutputDataBlockDesc), (SPhysiNode*)pInterval);
|
||||
}
|
||||
|
||||
CHECK_CODE(setSlotOutput(pCxt, pWindowLogicNode->node.pTargets, pInterval->node.pOutputDataBlockDesc), (SPhysiNode*)pInterval);
|
||||
|
||||
return (SPhysiNode*)pInterval;
|
||||
}
|
||||
|
||||
static SPhysiNode* createWindowPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SWindowLogicNode* pWindowLogicNode) {
|
||||
switch (pWindowLogicNode->winType) {
|
||||
case WINDOW_TYPE_INTERVAL:
|
||||
return createIntervalPhysiNode(pCxt, pChildren, pWindowLogicNode);
|
||||
case WINDOW_TYPE_SESSION:
|
||||
case WINDOW_TYPE_STATE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SPhysiNode* createPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SLogicNode* pLogicPlan) {
|
||||
SNodeList* pChildren = nodesMakeList();
|
||||
CHECK_ALLOC(pChildren, NULL);
|
||||
|
||||
SNode* pLogicChild;
|
||||
FOREACH(pLogicChild, pLogicPlan->pChildren) {
|
||||
SNode* pChildPhyNode = (SNode*)createPhysiNode(pCxt, pSubplan, (SLogicNode*)pLogicChild);
|
||||
if (TSDB_CODE_SUCCESS != nodesListAppend(pChildren, pChildPhyNode)) {
|
||||
if (TSDB_CODE_SUCCESS != nodesListStrictAppend(pChildren, createPhysiNode(pCxt, pSubplan, (SLogicNode*)pLogicChild))) {
|
||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
nodesDestroyList(pChildren);
|
||||
return NULL;
|
||||
|
@ -504,6 +551,9 @@ static SPhysiNode* createPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan,
|
|||
case QUERY_NODE_LOGIC_PLAN_EXCHANGE:
|
||||
pPhyNode = createExchangePhysiNode(pCxt, (SExchangeLogicNode*)pLogicPlan);
|
||||
break;
|
||||
case QUERY_NODE_LOGIC_PLAN_WINDOW:
|
||||
pPhyNode = createWindowPhysiNode(pCxt, pChildren, (SWindowLogicNode*)pLogicPlan);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -166,3 +166,10 @@ TEST_F(PlannerTest, subquery) {
|
|||
bind("SELECT count(*) FROM (SELECT c1 + c3 a, c1 + count(*) b FROM t1 where c2 = 'abc' GROUP BY c1, c3) where a > 100 group by b");
|
||||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
||||
TEST_F(PlannerTest, interval) {
|
||||
setDatabase("root", "test");
|
||||
|
||||
bind("SELECT count(*) FROM t1 interval(10s)");
|
||||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
|
|
@ -13,26 +13,21 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "catalog.h"
|
||||
#include "query.h"
|
||||
#include "schedulerInt.h"
|
||||
#include "tmsg.h"
|
||||
#include "query.h"
|
||||
#include "catalog.h"
|
||||
#include "tref.h"
|
||||
|
||||
SSchedulerMgmt schMgmt = {0};
|
||||
|
||||
FORCE_INLINE SSchJob *schAcquireJob(int64_t refId) {
|
||||
return (SSchJob *)taosAcquireRef(schMgmt.jobRef, refId);
|
||||
}
|
||||
FORCE_INLINE SSchJob *schAcquireJob(int64_t refId) { return (SSchJob *)taosAcquireRef(schMgmt.jobRef, refId); }
|
||||
|
||||
FORCE_INLINE int32_t schReleaseJob(int64_t refId) {
|
||||
return taosReleaseRef(schMgmt.jobRef, refId);
|
||||
}
|
||||
FORCE_INLINE int32_t schReleaseJob(int64_t refId) { return taosReleaseRef(schMgmt.jobRef, refId); }
|
||||
|
||||
uint64_t schGenTaskId(void) {
|
||||
return atomic_add_fetch_64(&schMgmt.taskId, 1);
|
||||
}
|
||||
uint64_t schGenTaskId(void) { return atomic_add_fetch_64(&schMgmt.taskId, 1); }
|
||||
|
||||
#if 0
|
||||
uint64_t schGenUUID(void) {
|
||||
static uint64_t hashId = 0;
|
||||
static int32_t requestSerialId = 0;
|
||||
|
@ -54,9 +49,9 @@ uint64_t schGenUUID(void) {
|
|||
uint64_t id = ((hashId & 0x0FFF) << 52) | ((pid & 0x0FFF) << 40) | ((ts & 0xFFFFFF) << 16) | (val & 0xFFFF);
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int32_t schInitTask(SSchJob* pJob, SSchTask *pTask, SSubplan* pPlan, SSchLevel *pLevel) {
|
||||
int32_t schInitTask(SSchJob *pJob, SSchTask *pTask, SSubplan *pPlan, SSchLevel *pLevel) {
|
||||
pTask->plan = pPlan;
|
||||
pTask->level = pLevel;
|
||||
SCH_SET_TASK_STATUS(pTask, JOB_TASK_STATUS_NOT_START);
|
||||
|
@ -70,7 +65,7 @@ int32_t schInitTask(SSchJob* pJob, SSchTask *pTask, SSubplan* pPlan, SSchLevel *
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void schFreeTask(SSchTask* pTask) {
|
||||
void schFreeTask(SSchTask *pTask) {
|
||||
if (pTask->candidateAddrs) {
|
||||
taosArrayDestroy(pTask->candidateAddrs);
|
||||
}
|
||||
|
@ -90,19 +85,17 @@ void schFreeTask(SSchTask* pTask) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static FORCE_INLINE bool schJobNeedToStop(SSchJob *pJob, int8_t *pStatus) {
|
||||
int8_t status = SCH_GET_JOB_STATUS(pJob);
|
||||
if (pStatus) {
|
||||
*pStatus = status;
|
||||
}
|
||||
|
||||
return (status == JOB_TASK_STATUS_FAILED || status == JOB_TASK_STATUS_CANCELLED
|
||||
|| status == JOB_TASK_STATUS_CANCELLING || status == JOB_TASK_STATUS_DROPPING
|
||||
|| status == JOB_TASK_STATUS_SUCCEED);
|
||||
return (status == JOB_TASK_STATUS_FAILED || status == JOB_TASK_STATUS_CANCELLED ||
|
||||
status == JOB_TASK_STATUS_CANCELLING || status == JOB_TASK_STATUS_DROPPING ||
|
||||
status == JOB_TASK_STATUS_SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
int32_t schValidateTaskReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t msgType) {
|
||||
int32_t lastMsgType = SCH_GET_TASK_LASTMSG_TYPE(pTask);
|
||||
|
||||
|
@ -114,12 +107,15 @@ int32_t schValidateTaskReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t m
|
|||
case TDMT_VND_FETCH_RSP:
|
||||
case TDMT_VND_DROP_TASK:
|
||||
if (lastMsgType != (msgType - 1)) {
|
||||
SCH_TASK_ELOG("rsp msg type mis-match, last sent msgType:%s, rspType:%s", TMSG_INFO(lastMsgType), TMSG_INFO(msgType));
|
||||
SCH_TASK_ELOG("rsp msg type mis-match, last sent msgType:%s, rspType:%s", TMSG_INFO(lastMsgType),
|
||||
TMSG_INFO(msgType));
|
||||
SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR);
|
||||
}
|
||||
|
||||
if (SCH_GET_TASK_STATUS(pTask) != JOB_TASK_STATUS_EXECUTING && SCH_GET_TASK_STATUS(pTask) != JOB_TASK_STATUS_PARTIAL_SUCCEED) {
|
||||
SCH_TASK_ELOG("rsp msg conflicted with task status, status:%d, rspType:%s", SCH_GET_TASK_STATUS(pTask), TMSG_INFO(msgType));
|
||||
if (SCH_GET_TASK_STATUS(pTask) != JOB_TASK_STATUS_EXECUTING &&
|
||||
SCH_GET_TASK_STATUS(pTask) != JOB_TASK_STATUS_PARTIAL_SUCCEED) {
|
||||
SCH_TASK_ELOG("rsp msg conflicted with task status, status:%d, rspType:%s", SCH_GET_TASK_STATUS(pTask),
|
||||
TMSG_INFO(msgType));
|
||||
SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR);
|
||||
}
|
||||
|
||||
|
@ -135,7 +131,6 @@ int32_t schValidateTaskReceivedMsgType(SSchJob *pJob, SSchTask *pTask, int32_t m
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t schCheckAndUpdateJobStatus(SSchJob *pJob, int8_t newStatus) {
|
||||
int32_t code = 0;
|
||||
|
||||
|
@ -162,19 +157,16 @@ int32_t schCheckAndUpdateJobStatus(SSchJob *pJob, int8_t newStatus) {
|
|||
|
||||
break;
|
||||
case JOB_TASK_STATUS_EXECUTING:
|
||||
if (newStatus != JOB_TASK_STATUS_PARTIAL_SUCCEED
|
||||
&& newStatus != JOB_TASK_STATUS_FAILED
|
||||
&& newStatus != JOB_TASK_STATUS_CANCELLING
|
||||
&& newStatus != JOB_TASK_STATUS_CANCELLED
|
||||
&& newStatus != JOB_TASK_STATUS_DROPPING) {
|
||||
if (newStatus != JOB_TASK_STATUS_PARTIAL_SUCCEED && newStatus != JOB_TASK_STATUS_FAILED &&
|
||||
newStatus != JOB_TASK_STATUS_CANCELLING && newStatus != JOB_TASK_STATUS_CANCELLED &&
|
||||
newStatus != JOB_TASK_STATUS_DROPPING) {
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
break;
|
||||
case JOB_TASK_STATUS_PARTIAL_SUCCEED:
|
||||
if (newStatus != JOB_TASK_STATUS_FAILED
|
||||
&& newStatus != JOB_TASK_STATUS_SUCCEED
|
||||
&& newStatus != JOB_TASK_STATUS_DROPPING) {
|
||||
if (newStatus != JOB_TASK_STATUS_FAILED && newStatus != JOB_TASK_STATUS_SUCCEED &&
|
||||
newStatus != JOB_TASK_STATUS_DROPPING) {
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
|
@ -215,7 +207,6 @@ _return:
|
|||
SCH_ERR_RET(code);
|
||||
}
|
||||
|
||||
|
||||
int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) {
|
||||
for (int32_t i = 0; i < pJob->levelNum; ++i) {
|
||||
SSchLevel *pLevel = taosArrayGet(pJob->levels, i);
|
||||
|
@ -240,7 +231,7 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) {
|
|||
}
|
||||
|
||||
for (int32_t n = 0; n < childNum; ++n) {
|
||||
SSubplan *child = (SSubplan*)nodesListGetNode(pPlan->pChildren, n);
|
||||
SSubplan *child = (SSubplan *)nodesListGetNode(pPlan->pChildren, n);
|
||||
SSchTask **childTask = taosHashGet(planToTask, &child, POINTER_BYTES);
|
||||
if (NULL == childTask || NULL == *childTask) {
|
||||
SCH_TASK_ELOG("subplan children relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n);
|
||||
|
@ -272,7 +263,7 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) {
|
|||
}
|
||||
|
||||
for (int32_t n = 0; n < parentNum; ++n) {
|
||||
SSubplan *parent = (SSubplan*)nodesListGetNode(pPlan->pParents, n);
|
||||
SSubplan *parent = (SSubplan *)nodesListGetNode(pPlan->pParents, n);
|
||||
SSchTask **parentTask = taosHashGet(planToTask, &parent, POINTER_BYTES);
|
||||
if (NULL == parentTask || NULL == *parentTask) {
|
||||
SCH_TASK_ELOG("subplan parent relationship error, level:%d, taskIdx:%d, childIdx:%d", i, m, n);
|
||||
|
@ -298,11 +289,11 @@ int32_t schBuildTaskRalation(SSchJob *pJob, SHashObj *planToTask) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t schRecordTaskSucceedNode(SSchJob *pJob, SSchTask *pTask) {
|
||||
SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx);
|
||||
if (NULL == addr) {
|
||||
SCH_TASK_ELOG("taosArrayGet candidate addr failed, idx:%d, size:%d", pTask->candidateIdx, (int32_t)taosArrayGetSize(pTask->candidateAddrs));
|
||||
SCH_TASK_ELOG("taosArrayGet candidate addr failed, idx:%d, size:%d", pTask->candidateIdx,
|
||||
(int32_t)taosArrayGetSize(pTask->candidateAddrs));
|
||||
SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
|
@ -311,7 +302,6 @@ int32_t schRecordTaskSucceedNode(SSchJob *pJob, SSchTask *pTask) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t schRecordTaskExecNode(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr) {
|
||||
if (NULL == taosArrayPush(pTask->execAddrs, addr)) {
|
||||
SCH_TASK_ELOG("taosArrayPush addr to execAddr list failed, errno:%d", errno);
|
||||
|
@ -321,7 +311,6 @@ int32_t schRecordTaskExecNode(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *ad
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) {
|
||||
int32_t code = 0;
|
||||
pJob->queryId = pDag->queryId;
|
||||
|
@ -337,7 +326,10 @@ int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) {
|
|||
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SHashObj *planToTask = taosHashInit(SCHEDULE_DEFAULT_MAX_TASK_NUM, taosGetDefaultHashFunction(POINTER_BYTES == sizeof(int64_t) ? TSDB_DATA_TYPE_BIGINT : TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
|
||||
SHashObj *planToTask = taosHashInit(
|
||||
SCHEDULE_DEFAULT_MAX_TASK_NUM,
|
||||
taosGetDefaultHashFunction(POINTER_BYTES == sizeof(int64_t) ? TSDB_DATA_TYPE_BIGINT : TSDB_DATA_TYPE_INT), false,
|
||||
HASH_NO_LOCK);
|
||||
if (NULL == planToTask) {
|
||||
SCH_JOB_ELOG("taosHashInit %d failed", SCHEDULE_DEFAULT_MAX_TASK_NUM);
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
|
@ -370,7 +362,7 @@ int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) {
|
|||
pLevel = taosArrayGet(pJob->levels, i);
|
||||
pLevel->level = i;
|
||||
|
||||
plans = (SNodeListNode*)nodesListGetNode(pDag->pSubplans, i);
|
||||
plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
|
||||
if (NULL == plans) {
|
||||
SCH_JOB_ELOG("empty level plan, level:%d", i);
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
|
@ -391,7 +383,7 @@ int32_t schValidateAndBuildJob(SQueryPlan *pDag, SSchJob *pJob) {
|
|||
}
|
||||
|
||||
for (int32_t n = 0; n < taskNum; ++n) {
|
||||
SSubplan *plan = (SSubplan*)nodesListGetNode(plans->pNodeList, n);
|
||||
SSubplan *plan = (SSubplan *)nodesListGetNode(plans->pNodeList, n);
|
||||
|
||||
SCH_SET_JOB_TYPE(pJob, plan->subplanType);
|
||||
|
||||
|
@ -470,14 +462,14 @@ int32_t schSetTaskCandidateAddrs(SSchJob *pJob, SSchTask *pTask) {
|
|||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
for (int32_t i = 0; i < job->dataSrcEps.numOfEps && addNum < SCH_MAX_CANDIDATE_EP_NUM; ++i) {
|
||||
strncpy(epSet->fqdn[epSet->numOfEps], job->dataSrcEps.fqdn[i], sizeof(job->dataSrcEps.fqdn[i]));
|
||||
epSet->port[epSet->numOfEps] = job->dataSrcEps.port[i];
|
||||
|
||||
++epSet->numOfEps;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -553,7 +545,6 @@ int32_t schMoveTaskToFailList(SSchJob *pJob, SSchTask *pTask, bool *moved) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t schMoveTaskToExecList(SSchJob *pJob, SSchTask *pTask, bool *moved) {
|
||||
if (0 != taosHashRemove(pJob->succTasks, &pTask->taskId, sizeof(pTask->taskId))) {
|
||||
SCH_TASK_WLOG("remove task from succTask list failed, may not exist, status:%d", SCH_GET_TASK_STATUS(pTask));
|
||||
|
@ -579,7 +570,6 @@ int32_t schMoveTaskToExecList(SSchJob *pJob, SSchTask *pTask, bool *moved) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t schTaskCheckSetRetry(SSchJob *pJob, SSchTask *pTask, int32_t errCode, bool *needRetry) {
|
||||
// TODO set retry or not based on task type/errCode/retry times/job status/available eps...
|
||||
|
||||
|
@ -587,9 +577,8 @@ int32_t schTaskCheckSetRetry(SSchJob *pJob, SSchTask *pTask, int32_t errCode, bo
|
|||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
//TODO CHECK epList/condidateList
|
||||
// TODO CHECK epList/condidateList
|
||||
if (SCH_IS_DATA_SRC_TASK(pTask)) {
|
||||
|
||||
} else {
|
||||
int32_t candidateNum = taosArrayGetSize(pTask->candidateAddrs);
|
||||
|
||||
|
@ -599,8 +588,6 @@ int32_t schTaskCheckSetRetry(SSchJob *pJob, SSchTask *pTask, int32_t errCode, bo
|
|||
|
||||
++pTask->candidateIdx;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int32_t schHandleTaskRetry(SSchJob *pJob, SSchTask *pTask) {
|
||||
|
@ -639,8 +626,10 @@ int32_t schUpdateHbConnection(SQueryNodeEpId *epId, SSchHbTrans *trans) {
|
|||
SCH_ERR_RET(code);
|
||||
}
|
||||
|
||||
qDebug("hb connection updated, seqId:%" PRIx64 ", sId:%" PRIx64 ", nodeId:%d, fqdn:%s, port:%d, instance:%p, connection:%p",
|
||||
trans->seqId, schMgmt.sId, epId->nodeId, epId->ep.fqdn, epId->ep.port, trans->trans.transInst, trans->trans.transHandle);
|
||||
qDebug("hb connection updated, seqId:%" PRIx64 ", sId:%" PRIx64
|
||||
", nodeId:%d, fqdn:%s, port:%d, instance:%p, connection:%p",
|
||||
trans->seqId, schMgmt.sId, epId->nodeId, epId->ep.fqdn, epId->ep.port, trans->trans.transInst,
|
||||
trans->trans.transHandle);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -651,8 +640,8 @@ int32_t schUpdateHbConnection(SQueryNodeEpId *epId, SSchHbTrans *trans) {
|
|||
SCH_LOCK(SCH_WRITE, &hb->lock);
|
||||
|
||||
if (hb->seqId >= trans->seqId) {
|
||||
qDebug("hb trans seqId is old, seqId:%" PRId64 ", currentId:%" PRId64 ", nodeId:%d, fqdn:%s, port:%d",
|
||||
trans->seqId, hb->seqId, epId->nodeId, epId->ep.fqdn, epId->ep.port);
|
||||
qDebug("hb trans seqId is old, seqId:%" PRId64 ", currentId:%" PRId64 ", nodeId:%d, fqdn:%s, port:%d", trans->seqId,
|
||||
hb->seqId, epId->nodeId, epId->ep.fqdn, epId->ep.port);
|
||||
|
||||
SCH_UNLOCK(SCH_WRITE, &hb->lock);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -663,8 +652,10 @@ int32_t schUpdateHbConnection(SQueryNodeEpId *epId, SSchHbTrans *trans) {
|
|||
|
||||
SCH_UNLOCK(SCH_WRITE, &hb->lock);
|
||||
|
||||
qDebug("hb connection updated, seqId:%" PRIx64 ", sId:%" PRIx64 ", nodeId:%d, fqdn:%s, port:%d, instance:%p, connection:%p",
|
||||
trans->seqId, schMgmt.sId, epId->nodeId, epId->ep.fqdn, epId->ep.port, trans->trans.transInst, trans->trans.transHandle);
|
||||
qDebug("hb connection updated, seqId:%" PRIx64 ", sId:%" PRIx64
|
||||
", nodeId:%d, fqdn:%s, port:%d, instance:%p, connection:%p",
|
||||
trans->seqId, schMgmt.sId, epId->nodeId, epId->ep.fqdn, epId->ep.port, trans->trans.transInst,
|
||||
trans->trans.transHandle);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -688,7 +679,6 @@ int32_t schProcessOnJobFailureImpl(SSchJob *pJob, int32_t status, int32_t errCod
|
|||
SCH_RET(code);
|
||||
}
|
||||
|
||||
|
||||
// Note: no more task error processing, handled in function internal
|
||||
int32_t schProcessOnJobFailure(SSchJob *pJob, int32_t errCode) {
|
||||
SCH_RET(schProcessOnJobFailureImpl(pJob, JOB_TASK_STATUS_FAILED, errCode));
|
||||
|
@ -699,8 +689,6 @@ int32_t schProcessOnJobDropped(SSchJob *pJob, int32_t errCode) {
|
|||
SCH_RET(schProcessOnJobFailureImpl(pJob, JOB_TASK_STATUS_DROPPING, errCode));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Note: no more task error processing, handled in function internal
|
||||
int32_t schProcessOnJobPartialSuccess(SSchJob *pJob) {
|
||||
int32_t code = 0;
|
||||
|
@ -830,21 +818,24 @@ int32_t schProcessOnTaskSuccess(SSchJob *pJob, SSchTask *pTask) {
|
|||
SCH_RET(schProcessOnJobPartialSuccess(pJob));
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
if (SCH_IS_DATA_SRC_TASK(task) && job->dataSrcEps.numOfEps < SCH_MAX_CANDIDATE_EP_NUM) {
|
||||
strncpy(job->dataSrcEps.fqdn[job->dataSrcEps.numOfEps], task->execAddr.fqdn, sizeof(task->execAddr.fqdn));
|
||||
job->dataSrcEps.port[job->dataSrcEps.numOfEps] = task->execAddr.port;
|
||||
|
||||
++job->dataSrcEps.numOfEps;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
for (int32_t i = 0; i < parentNum; ++i) {
|
||||
SSchTask *par = *(SSchTask **)taosArrayGet(pTask->parents, i);
|
||||
int32_t readyNum = atomic_add_fetch_32(&par->childReady, 1);
|
||||
|
||||
SCH_LOCK(SCH_WRITE, &par->lock);
|
||||
SDownstreamSourceNode source = {.type = QUERY_NODE_DOWNSTREAM_SOURCE, .taskId = pTask->taskId, .schedId = schMgmt.sId, .addr = pTask->succeedAddr};
|
||||
SDownstreamSourceNode source = {.type = QUERY_NODE_DOWNSTREAM_SOURCE,
|
||||
.taskId = pTask->taskId,
|
||||
.schedId = schMgmt.sId,
|
||||
.addr = pTask->succeedAddr};
|
||||
qSetSubplanExecutionNode(par->plan, pTask->plan->id.groupId, &source);
|
||||
SCH_UNLOCK(SCH_WRITE, &par->lock);
|
||||
|
||||
|
@ -860,7 +851,6 @@ _return:
|
|||
SCH_RET(schProcessOnJobFailure(pJob, code));
|
||||
}
|
||||
|
||||
|
||||
// Note: no more error processing, handled in function internal
|
||||
int32_t schFetchFromRemote(SSchJob *pJob) {
|
||||
int32_t code = 0;
|
||||
|
@ -889,9 +879,9 @@ _return:
|
|||
SCH_RET(schProcessOnTaskFailure(pJob, pJob->fetchTask, code));
|
||||
}
|
||||
|
||||
|
||||
// Note: no more task error processing, handled in function internal
|
||||
int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, char *msg, int32_t msgSize, int32_t rspCode) {
|
||||
int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, char *msg, int32_t msgSize,
|
||||
int32_t rspCode) {
|
||||
int32_t code = 0;
|
||||
int8_t status = 0;
|
||||
|
||||
|
@ -911,7 +901,7 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
break;
|
||||
}
|
||||
case TDMT_VND_SUBMIT_RSP: {
|
||||
#if 0 //TODO OPEN THIS
|
||||
#if 0 // TODO OPEN THIS
|
||||
SShellSubmitRspMsg *rsp = (SShellSubmitRspMsg *)msg;
|
||||
|
||||
if (rspCode != TSDB_CODE_SUCCESS || NULL == msg || rsp->code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -919,14 +909,14 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
}
|
||||
|
||||
pJob->resNumOfRows += rsp->affectedRows;
|
||||
#else
|
||||
#else
|
||||
SCH_ERR_JRET(rspCode);
|
||||
|
||||
SSubmitRsp *rsp = (SSubmitRsp *)msg;
|
||||
if (rsp) {
|
||||
pJob->resNumOfRows += rsp->affectedRows;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
SCH_ERR_RET(schProcessOnTaskSuccess(pJob, pTask));
|
||||
|
||||
|
@ -1002,15 +992,15 @@ _return:
|
|||
SCH_RET(schProcessOnTaskFailure(pJob, pTask, code));
|
||||
}
|
||||
|
||||
|
||||
int32_t schHandleCallback(void* param, const SDataBuf* pMsg, int32_t msgType, int32_t rspCode) {
|
||||
int32_t schHandleCallback(void *param, const SDataBuf *pMsg, int32_t msgType, int32_t rspCode) {
|
||||
int32_t code = 0;
|
||||
SSchCallbackParam *pParam = (SSchCallbackParam *)param;
|
||||
SSchTask *pTask = NULL;
|
||||
|
||||
SSchJob *pJob = schAcquireJob(pParam->refId);
|
||||
if (NULL == pJob) {
|
||||
qError("QID:0x%" PRIx64 ",TID:0x%" PRIx64 "taosAcquireRef job failed, may be dropped, refId:%" PRIx64, pParam->queryId, pParam->taskId, pParam->refId);
|
||||
qError("QID:0x%" PRIx64 ",TID:0x%" PRIx64 "taosAcquireRef job failed, may be dropped, refId:%" PRIx64,
|
||||
pParam->queryId, pParam->taskId, pParam->refId);
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_JOB_FREED);
|
||||
}
|
||||
|
||||
|
@ -1042,33 +1032,32 @@ _return:
|
|||
SCH_RET(code);
|
||||
}
|
||||
|
||||
int32_t schHandleSubmitCallback(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||
int32_t schHandleSubmitCallback(void *param, const SDataBuf *pMsg, int32_t code) {
|
||||
return schHandleCallback(param, pMsg, TDMT_VND_SUBMIT_RSP, code);
|
||||
}
|
||||
|
||||
int32_t schHandleCreateTableCallback(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||
int32_t schHandleCreateTableCallback(void *param, const SDataBuf *pMsg, int32_t code) {
|
||||
return schHandleCallback(param, pMsg, TDMT_VND_CREATE_TABLE_RSP, code);
|
||||
}
|
||||
|
||||
int32_t schHandleQueryCallback(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||
int32_t schHandleQueryCallback(void *param, const SDataBuf *pMsg, int32_t code) {
|
||||
return schHandleCallback(param, pMsg, TDMT_VND_QUERY_RSP, code);
|
||||
}
|
||||
|
||||
int32_t schHandleFetchCallback(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||
int32_t schHandleFetchCallback(void *param, const SDataBuf *pMsg, int32_t code) {
|
||||
return schHandleCallback(param, pMsg, TDMT_VND_FETCH_RSP, code);
|
||||
}
|
||||
|
||||
int32_t schHandleReadyCallback(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||
int32_t schHandleReadyCallback(void *param, const SDataBuf *pMsg, int32_t code) {
|
||||
return schHandleCallback(param, pMsg, TDMT_VND_RES_READY_RSP, code);
|
||||
}
|
||||
|
||||
int32_t schHandleDropCallback(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||
int32_t schHandleDropCallback(void *param, const SDataBuf *pMsg, int32_t code) {
|
||||
SSchCallbackParam *pParam = (SSchCallbackParam *)param;
|
||||
qDebug("QID:%"PRIx64",TID:%"PRIx64" drop task rsp received, code:%x", pParam->queryId, pParam->taskId, code);
|
||||
qDebug("QID:%" PRIx64 ",TID:%" PRIx64 " drop task rsp received, code:%x", pParam->queryId, pParam->taskId, code);
|
||||
}
|
||||
|
||||
|
||||
int32_t schHandleHbCallback(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||
int32_t schHandleHbCallback(void *param, const SDataBuf *pMsg, int32_t code) {
|
||||
if (code) {
|
||||
qError("hb rsp error:%s", tstrerror(code));
|
||||
SCH_ERR_RET(code);
|
||||
|
@ -1098,8 +1087,9 @@ int32_t schHandleHbCallback(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
|
||||
SSchJob *pJob = schAcquireJob(taskStatus->refId);
|
||||
if (NULL == pJob) {
|
||||
qWarn("job not found, refId:0x%" PRIx64 ",QID:0x%" PRIx64 ",TID:0x%" PRIx64, taskStatus->refId, taskStatus->queryId, taskStatus->taskId);
|
||||
//TODO DROP TASK FROM SERVER!!!!
|
||||
qWarn("job not found, refId:0x%" PRIx64 ",QID:0x%" PRIx64 ",TID:0x%" PRIx64, taskStatus->refId,
|
||||
taskStatus->queryId, taskStatus->taskId);
|
||||
// TODO DROP TASK FROM SERVER!!!!
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1115,7 +1105,6 @@ _return:
|
|||
SCH_RET(code);
|
||||
}
|
||||
|
||||
|
||||
int32_t schGetCallbackFp(int32_t msgType, __async_send_cb_fn_t *fp) {
|
||||
switch (msgType) {
|
||||
case TDMT_VND_CREATE_TABLE:
|
||||
|
@ -1147,13 +1136,13 @@ int32_t schGetCallbackFp(int32_t msgType, __async_send_cb_fn_t *fp) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t schAsyncSendMsg(SSchJob *pJob, SSchTask *pTask, void *transport, SEpSet* epSet, int32_t msgType, void *msg, uint32_t msgSize) {
|
||||
int32_t schAsyncSendMsg(SSchJob *pJob, SSchTask *pTask, void *transport, SEpSet *epSet, int32_t msgType, void *msg,
|
||||
uint32_t msgSize) {
|
||||
int32_t code = 0;
|
||||
|
||||
SSchTrans *trans = (SSchTrans *)transport;
|
||||
|
||||
SMsgSendInfo* pMsgSendInfo = calloc(1, sizeof(SMsgSendInfo));
|
||||
SMsgSendInfo *pMsgSendInfo = calloc(1, sizeof(SMsgSendInfo));
|
||||
if (NULL == pMsgSendInfo) {
|
||||
SCH_TASK_ELOG("calloc %d failed", (int32_t)sizeof(SMsgSendInfo));
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
|
@ -1173,7 +1162,6 @@ int32_t schAsyncSendMsg(SSchJob *pJob, SSchTask *pTask, void *transport, SEpSet*
|
|||
param->taskId = SCH_TASK_ID(pTask);
|
||||
param->transport = trans->transInst;
|
||||
|
||||
|
||||
pMsgSendInfo->param = param;
|
||||
pMsgSendInfo->msgInfo.pData = msg;
|
||||
pMsgSendInfo->msgInfo.len = msgSize;
|
||||
|
@ -1282,7 +1270,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr,
|
|||
pMsg->taskId = htobe64(pTask->taskId);
|
||||
break;
|
||||
}
|
||||
case TDMT_VND_DROP_TASK:{
|
||||
case TDMT_VND_DROP_TASK: {
|
||||
msgSize = sizeof(STaskDropReq);
|
||||
msg = calloc(1, msgSize);
|
||||
if (NULL == msg) {
|
||||
|
@ -1380,7 +1368,8 @@ int32_t schLaunchTaskImpl(SSchJob *pJob, SSchTask *pTask) {
|
|||
if (NULL == pTask->msg) { // TODO add more detailed reason for failure
|
||||
code = qSubPlanToString(plan, &pTask->msg, &pTask->msgLen);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
SCH_TASK_ELOG("failed to create physical plan, code:%s, msg:%p, len:%d", tstrerror(code), pTask->msg, pTask->msgLen);
|
||||
SCH_TASK_ELOG("failed to create physical plan, code:%s, msg:%p, len:%d", tstrerror(code), pTask->msg,
|
||||
pTask->msgLen);
|
||||
SCH_ERR_RET(code);
|
||||
} else {
|
||||
SCH_TASK_DLOG("physical plan len:%d, %s", pTask->msgLen, pTask->msg);
|
||||
|
@ -1436,8 +1425,6 @@ int32_t schLaunchLevelTasks(SSchJob *pJob, SSchLevel *level) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t schLaunchJob(SSchJob *pJob) {
|
||||
SSchLevel *level = taosArrayGet(pJob->levels, pJob->levelIdx);
|
||||
|
||||
|
@ -1493,10 +1480,9 @@ void schDropJobAllTasks(SSchJob *pJob) {
|
|||
}
|
||||
|
||||
int32_t schCancelJob(SSchJob *pJob) {
|
||||
//TODO
|
||||
|
||||
//TODO MOVE ALL TASKS FROM EXEC LIST TO FAIL LIST
|
||||
// TODO
|
||||
|
||||
// TODO MOVE ALL TASKS FROM EXEC LIST TO FAIL LIST
|
||||
}
|
||||
|
||||
void schFreeJobImpl(void *job) {
|
||||
|
@ -1517,14 +1503,14 @@ void schFreeJobImpl(void *job) {
|
|||
pJob->subPlans = NULL; // it is a reference to pDag->pSubplans
|
||||
|
||||
int32_t numOfLevels = taosArrayGetSize(pJob->levels);
|
||||
for(int32_t i = 0; i < numOfLevels; ++i) {
|
||||
for (int32_t i = 0; i < numOfLevels; ++i) {
|
||||
SSchLevel *pLevel = taosArrayGet(pJob->levels, i);
|
||||
|
||||
schFreeFlowCtrl(pLevel);
|
||||
|
||||
int32_t numOfTasks = taosArrayGetSize(pLevel->subTasks);
|
||||
for(int32_t j = 0; j < numOfTasks; ++j) {
|
||||
SSchTask* pTask = taosArrayGet(pLevel->subTasks, j);
|
||||
for (int32_t j = 0; j < numOfTasks; ++j) {
|
||||
SSchTask *pTask = taosArrayGet(pLevel->subTasks, j);
|
||||
schFreeTask(pTask);
|
||||
}
|
||||
|
||||
|
@ -1542,21 +1528,21 @@ void schFreeJobImpl(void *job) {
|
|||
|
||||
tfree(pJob);
|
||||
|
||||
qDebug("QID:0x%"PRIx64" job freed, refId:%" PRIx64 ", pointer:%p", queryId, refId, pJob);
|
||||
qDebug("QID:0x%" PRIx64 " job freed, refId:%" PRIx64 ", pointer:%p", queryId, refId, pJob);
|
||||
}
|
||||
|
||||
|
||||
static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan* pDag, int64_t *job, const char* sql, bool syncSchedule) {
|
||||
qDebug("QID:0x%"PRIx64" job started", pDag->queryId);
|
||||
static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan *pDag, int64_t *job, const char *sql,
|
||||
bool syncSchedule) {
|
||||
qDebug("QID:0x%" PRIx64 " job started", pDag->queryId);
|
||||
|
||||
if (pNodeList == NULL || (pNodeList && taosArrayGetSize(pNodeList) <= 0)) {
|
||||
qDebug("QID:0x%"PRIx64" input exec nodeList is empty", pDag->queryId);
|
||||
qDebug("QID:0x%" PRIx64 " input exec nodeList is empty", pDag->queryId);
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
SSchJob *pJob = calloc(1, sizeof(SSchJob));
|
||||
if (NULL == pJob) {
|
||||
qError("QID:%"PRIx64" calloc %d failed", pDag->queryId, (int32_t)sizeof(SSchJob));
|
||||
qError("QID:%" PRIx64 " calloc %d failed", pDag->queryId, (int32_t)sizeof(SSchJob));
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
|
@ -1570,19 +1556,22 @@ static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryPlan* pD
|
|||
|
||||
SCH_ERR_JRET(schValidateAndBuildJob(pDag, pJob));
|
||||
|
||||
pJob->execTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK);
|
||||
pJob->execTasks =
|
||||
taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK);
|
||||
if (NULL == pJob->execTasks) {
|
||||
SCH_JOB_ELOG("taosHashInit %d execTasks failed", pDag->numOfSubplans);
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
pJob->succTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK);
|
||||
pJob->succTasks =
|
||||
taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK);
|
||||
if (NULL == pJob->succTasks) {
|
||||
SCH_JOB_ELOG("taosHashInit %d succTasks failed", pDag->numOfSubplans);
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
pJob->failTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK);
|
||||
pJob->failTasks =
|
||||
taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK);
|
||||
if (NULL == pJob->failTasks) {
|
||||
SCH_JOB_ELOG("taosHashInit %d failTasks failed", pDag->numOfSubplans);
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
|
@ -1622,7 +1611,6 @@ _return:
|
|||
SCH_RET(code);
|
||||
}
|
||||
|
||||
|
||||
int32_t schedulerInit(SSchedulerCfg *cfg) {
|
||||
if (schMgmt.jobRef) {
|
||||
qError("scheduler already initialized");
|
||||
|
@ -1660,12 +1648,13 @@ int32_t schedulerInit(SSchedulerCfg *cfg) {
|
|||
SCH_ERR_RET(TSDB_CODE_QRY_SYS_ERROR);
|
||||
}
|
||||
|
||||
qInfo("scheduler %"PRIx64" initizlized, maxJob:%u", schMgmt.sId, schMgmt.cfg.maxJobNum);
|
||||
qInfo("scheduler %" PRIx64 " initizlized, maxJob:%u", schMgmt.sId, schMgmt.cfg.maxJobNum);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan* pDag, int64_t *pJob, const char* sql, SQueryResult *pRes) {
|
||||
int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan *pDag, int64_t *pJob, const char *sql,
|
||||
SQueryResult *pRes) {
|
||||
if (NULL == transport || NULL == pDag || NULL == pDag->pSubplans || NULL == pJob || NULL == pRes) {
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
@ -1680,7 +1669,7 @@ int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan* pDag, in
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryPlan* pDag, const char* sql, int64_t *pJob) {
|
||||
int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryPlan *pDag, const char *sql, int64_t *pJob) {
|
||||
if (NULL == transport || NULL == pDag || NULL == pDag->pSubplans || NULL == pJob) {
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
@ -1690,6 +1679,7 @@ int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryPlan* pD
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t schedulerConvertDagToTaskList(SQueryPlan* pDag, SArray **pTasks) {
|
||||
if (NULL == pDag || pDag->numOfSubplans <= 0 || LIST_LENGTH(pDag->pSubplans) == 0) {
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
|
@ -1810,9 +1800,9 @@ _return:
|
|||
|
||||
SCH_RET(code);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int32_t schedulerFetchRows(int64_t job, void** pData) {
|
||||
int32_t schedulerFetchRows(int64_t job, void **pData) {
|
||||
if (NULL == pData) {
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
@ -1866,7 +1856,6 @@ int32_t schedulerFetchRows(int64_t job, void** pData) {
|
|||
SCH_ERR_JRET(schCheckAndUpdateJobStatus(pJob, JOB_TASK_STATUS_SUCCEED));
|
||||
}
|
||||
|
||||
|
||||
while (true) {
|
||||
*pData = atomic_load_ptr(&pJob->res);
|
||||
if (*pData != atomic_val_compare_exchange_ptr(&pJob->res, *pData, NULL)) {
|
||||
|
|
|
@ -39,7 +39,6 @@ extern "C" {
|
|||
// /\ UNCHANGED <<serverVars, candidateVars, leaderVars, logVars>>
|
||||
//
|
||||
int32_t syncNodeRequestVotePeers(SSyncNode* pSyncNode);
|
||||
|
||||
int32_t syncNodeElect(SSyncNode* pSyncNode);
|
||||
int32_t syncNodeRequestVote(SSyncNode* pSyncNode, const SRaftId* destRaftId, const SyncRequestVote* pMsg);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ extern "C" {
|
|||
#include "ttimer.h"
|
||||
|
||||
#define TIMER_MAX_MS 0x7FFFFFFF
|
||||
#define ENV_TICK_TIMER_MS 1000
|
||||
#define PING_TIMER_MS 1000
|
||||
#define ELECT_TIMER_MS_MIN 150
|
||||
#define ELECT_TIMER_MS_MAX 300
|
||||
|
@ -38,17 +39,28 @@ extern "C" {
|
|||
#define EMPTY_RAFT_ID ((SRaftId){.addr = 0, .vgId = 0})
|
||||
|
||||
typedef struct SSyncEnv {
|
||||
// tick timer
|
||||
tmr_h pEnvTickTimer;
|
||||
int32_t envTickTimerMS;
|
||||
uint64_t envTickTimerLogicClock; // if use queue, should pass logic clock into queue item
|
||||
uint64_t envTickTimerLogicClockUser;
|
||||
TAOS_TMR_CALLBACK FpEnvTickTimer; // Timer Fp
|
||||
uint64_t envTickTimerCounter;
|
||||
|
||||
// timer manager
|
||||
tmr_h pTimerManager;
|
||||
char name[128];
|
||||
|
||||
// other resources shared by SyncNodes
|
||||
// ...
|
||||
|
||||
} SSyncEnv;
|
||||
|
||||
extern SSyncEnv* gSyncEnv;
|
||||
|
||||
int32_t syncEnvStart();
|
||||
int32_t syncEnvStop();
|
||||
tmr_h syncEnvStartTimer(TAOS_TMR_CALLBACK fp, int mseconds, void* param);
|
||||
void syncEnvStopTimer(tmr_h* pTimer);
|
||||
int32_t syncEnvStartTimer();
|
||||
int32_t syncEnvStopTimer();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -29,22 +29,28 @@ extern "C" {
|
|||
#include "tqueue.h"
|
||||
#include "trpc.h"
|
||||
|
||||
#define TICK_Q_TIMER_MS 1000
|
||||
#define TICK_Ping_TIMER_MS 1000
|
||||
|
||||
typedef struct SSyncIO {
|
||||
STaosQueue *pMsgQ;
|
||||
STaosQset * pQset;
|
||||
STaosQset *pQset;
|
||||
pthread_t consumerTid;
|
||||
|
||||
void * serverRpc;
|
||||
void * clientRpc;
|
||||
void *serverRpc;
|
||||
void *clientRpc;
|
||||
SEpSet myAddr;
|
||||
|
||||
void *ioTimerTickQ;
|
||||
void *ioTimerTickPing;
|
||||
void *ioTimerManager;
|
||||
tmr_h qTimer;
|
||||
int32_t qTimerMS;
|
||||
tmr_h pingTimer;
|
||||
int32_t pingTimerMS;
|
||||
tmr_h timerMgr;
|
||||
|
||||
void *pSyncNode;
|
||||
int32_t (*FpOnSyncPing)(SSyncNode *pSyncNode, SyncPing *pMsg);
|
||||
int32_t (*FpOnSyncPingReply)(SSyncNode *pSyncNode, SyncPingReply *pMsg);
|
||||
int32_t (*FpOnSyncClientRequest)(SSyncNode *pSyncNode, SyncClientRequest *pMsg);
|
||||
int32_t (*FpOnSyncRequestVote)(SSyncNode *pSyncNode, SyncRequestVote *pMsg);
|
||||
int32_t (*FpOnSyncRequestVoteReply)(SSyncNode *pSyncNode, SyncRequestVoteReply *pMsg);
|
||||
int32_t (*FpOnSyncAppendEntries)(SSyncNode *pSyncNode, SyncAppendEntries *pMsg);
|
||||
|
@ -59,11 +65,14 @@ extern SSyncIO *gSyncIO;
|
|||
|
||||
int32_t syncIOStart(char *host, uint16_t port);
|
||||
int32_t syncIOStop();
|
||||
int32_t syncIOTickQ();
|
||||
int32_t syncIOTickPing();
|
||||
int32_t syncIOSendMsg(void *clientRpc, const SEpSet *pEpSet, SRpcMsg *pMsg);
|
||||
int32_t syncIOEqMsg(void *queue, SRpcMsg *pMsg);
|
||||
|
||||
int32_t syncIOQTimerStart();
|
||||
int32_t syncIOQTimerStop();
|
||||
int32_t syncIOPingTimerStart();
|
||||
int32_t syncIOPingTimerStop();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -67,12 +67,12 @@ extern "C" {
|
|||
} \
|
||||
}
|
||||
|
||||
struct SRaft;
|
||||
typedef struct SRaft SRaft;
|
||||
|
||||
struct SyncTimeout;
|
||||
typedef struct SyncTimeout SyncTimeout;
|
||||
|
||||
struct SyncClientRequest;
|
||||
typedef struct SyncClientRequest SyncClientRequest;
|
||||
|
||||
struct SyncPing;
|
||||
typedef struct SyncPing SyncPing;
|
||||
|
||||
|
@ -117,6 +117,8 @@ typedef struct SSyncNode {
|
|||
SSyncCfg syncCfg;
|
||||
char path[TSDB_FILENAME_LEN];
|
||||
char raftStorePath[TSDB_FILENAME_LEN * 2];
|
||||
|
||||
// sync io
|
||||
SWal* pWal;
|
||||
void* rpcClient;
|
||||
int32_t (*FpSendMsg)(void* rpcClient, const SEpSet* pEpSet, SRpcMsg* pMsg);
|
||||
|
@ -164,7 +166,7 @@ typedef struct SSyncNode {
|
|||
int32_t pingTimerMS;
|
||||
uint64_t pingTimerLogicClock;
|
||||
uint64_t pingTimerLogicClockUser;
|
||||
TAOS_TMR_CALLBACK FpPingTimer; // Timer Fp
|
||||
TAOS_TMR_CALLBACK FpPingTimerCB; // Timer Fp
|
||||
uint64_t pingTimerCounter;
|
||||
|
||||
// elect timer
|
||||
|
@ -172,7 +174,7 @@ typedef struct SSyncNode {
|
|||
int32_t electTimerMS;
|
||||
uint64_t electTimerLogicClock;
|
||||
uint64_t electTimerLogicClockUser;
|
||||
TAOS_TMR_CALLBACK FpElectTimer; // Timer Fp
|
||||
TAOS_TMR_CALLBACK FpElectTimerCB; // Timer Fp
|
||||
uint64_t electTimerCounter;
|
||||
|
||||
// heartbeat timer
|
||||
|
@ -180,12 +182,13 @@ typedef struct SSyncNode {
|
|||
int32_t heartbeatTimerMS;
|
||||
uint64_t heartbeatTimerLogicClock;
|
||||
uint64_t heartbeatTimerLogicClockUser;
|
||||
TAOS_TMR_CALLBACK FpHeartbeatTimer; // Timer Fp
|
||||
TAOS_TMR_CALLBACK FpHeartbeatTimerCB; // Timer Fp
|
||||
uint64_t heartbeatTimerCounter;
|
||||
|
||||
// callback
|
||||
int32_t (*FpOnPing)(SSyncNode* ths, SyncPing* pMsg);
|
||||
int32_t (*FpOnPingReply)(SSyncNode* ths, SyncPingReply* pMsg);
|
||||
int32_t (*FpOnClientRequest)(SSyncNode* ths, SyncClientRequest* pMsg);
|
||||
int32_t (*FpOnRequestVote)(SSyncNode* ths, SyncRequestVote* pMsg);
|
||||
int32_t (*FpOnRequestVoteReply)(SSyncNode* ths, SyncRequestVoteReply* pMsg);
|
||||
int32_t (*FpOnAppendEntries)(SSyncNode* ths, SyncAppendEntries* pMsg);
|
||||
|
@ -194,26 +197,47 @@ typedef struct SSyncNode {
|
|||
|
||||
} SSyncNode;
|
||||
|
||||
// open/close --------------
|
||||
SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo);
|
||||
void syncNodeClose(SSyncNode* pSyncNode);
|
||||
|
||||
int32_t syncNodeSendMsgById(const SRaftId* destRaftId, SSyncNode* pSyncNode, SRpcMsg* pMsg);
|
||||
int32_t syncNodeSendMsgByInfo(const SNodeInfo* nodeInfo, SSyncNode* pSyncNode, SRpcMsg* pMsg);
|
||||
// ping --------------
|
||||
int32_t syncNodePing(SSyncNode* pSyncNode, const SRaftId* destRaftId, SyncPing* pMsg);
|
||||
int32_t syncNodePingAll(SSyncNode* pSyncNode);
|
||||
int32_t syncNodePingPeers(SSyncNode* pSyncNode);
|
||||
int32_t syncNodePingSelf(SSyncNode* pSyncNode);
|
||||
int32_t syncNodePingPeers(SSyncNode* pSyncNode);
|
||||
int32_t syncNodePingAll(SSyncNode* pSyncNode);
|
||||
|
||||
// timer control --------------
|
||||
int32_t syncNodeStartPingTimer(SSyncNode* pSyncNode);
|
||||
int32_t syncNodeStopPingTimer(SSyncNode* pSyncNode);
|
||||
int32_t syncNodeStartElectTimer(SSyncNode* pSyncNode, int32_t ms);
|
||||
int32_t syncNodeStopElectTimer(SSyncNode* pSyncNode);
|
||||
int32_t syncNodeRestartElectTimer(SSyncNode* pSyncNode, int32_t ms);
|
||||
int32_t syncNodeResetElectTimer(SSyncNode* pSyncNode);
|
||||
int32_t syncNodeStartHeartbeatTimer(SSyncNode* pSyncNode);
|
||||
int32_t syncNodeStopHeartbeatTimer(SSyncNode* pSyncNode);
|
||||
|
||||
// utils --------------
|
||||
int32_t syncNodeSendMsgById(const SRaftId* destRaftId, SSyncNode* pSyncNode, SRpcMsg* pMsg);
|
||||
int32_t syncNodeSendMsgByInfo(const SNodeInfo* nodeInfo, SSyncNode* pSyncNode, SRpcMsg* pMsg);
|
||||
cJSON* syncNode2Json(const SSyncNode* pSyncNode);
|
||||
char* syncNode2Str(const SSyncNode* pSyncNode);
|
||||
|
||||
// raft state change --------------
|
||||
void syncNodeUpdateTerm(SSyncNode* pSyncNode, SyncTerm term);
|
||||
void syncNodeBecomeFollower(SSyncNode* pSyncNode);
|
||||
void syncNodeBecomeLeader(SSyncNode* pSyncNode);
|
||||
|
||||
void syncNodeCandidate2Leader(SSyncNode* pSyncNode);
|
||||
void syncNodeFollower2Candidate(SSyncNode* pSyncNode);
|
||||
void syncNodeLeader2Follower(SSyncNode* pSyncNode);
|
||||
void syncNodeCandidate2Follower(SSyncNode* pSyncNode);
|
||||
|
||||
// raft vote --------------
|
||||
void syncNodeVoteForTerm(SSyncNode* pSyncNode, SyncTerm term, SRaftId* pRaftId);
|
||||
void syncNodeVoteForSelf(SSyncNode* pSyncNode);
|
||||
void syncNodeMaybeAdvanceCommitIndex(SSyncNode* pSyncNode);
|
||||
|
||||
// for debug --------------
|
||||
void syncNodePrint(SSyncNode* pObj);
|
||||
void syncNodePrint2(char* s, SSyncNode* pObj);
|
||||
|
|
|
@ -39,6 +39,7 @@ typedef enum ESyncMessageType {
|
|||
SYNC_REQUEST_VOTE_REPLY = 111,
|
||||
SYNC_APPEND_ENTRIES = 113,
|
||||
SYNC_APPEND_ENTRIES_REPLY = 115,
|
||||
SYNC_RESPONSE = 119,
|
||||
|
||||
} ESyncMessageType;
|
||||
|
||||
|
@ -195,7 +196,7 @@ typedef struct SyncRequestVote {
|
|||
SRaftId srcId;
|
||||
SRaftId destId;
|
||||
// private data
|
||||
SyncTerm currentTerm;
|
||||
SyncTerm term;
|
||||
SyncIndex lastLogIndex;
|
||||
SyncTerm lastLogTerm;
|
||||
} SyncRequestVote;
|
||||
|
@ -254,6 +255,7 @@ typedef struct SyncAppendEntries {
|
|||
SRaftId srcId;
|
||||
SRaftId destId;
|
||||
// private data
|
||||
SyncTerm term;
|
||||
SyncIndex prevLogIndex;
|
||||
SyncTerm prevLogTerm;
|
||||
SyncIndex commitIndex;
|
||||
|
@ -286,6 +288,7 @@ typedef struct SyncAppendEntriesReply {
|
|||
SRaftId srcId;
|
||||
SRaftId destId;
|
||||
// private data
|
||||
SyncTerm term;
|
||||
bool success;
|
||||
SyncIndex matchIndex;
|
||||
} SyncAppendEntriesReply;
|
||||
|
|
|
@ -27,6 +27,9 @@ extern "C" {
|
|||
#include "syncRaftEntry.h"
|
||||
#include "taosdef.h"
|
||||
|
||||
#define SYNC_INDEX_BEGIN 0
|
||||
#define SYNC_INDEX_INVALID -1
|
||||
|
||||
typedef struct SSyncLogStoreData {
|
||||
SSyncNode* pSyncNode;
|
||||
SWal* pWal;
|
||||
|
|
|
@ -43,6 +43,12 @@ int32_t raftStorePersist(SRaftStore *pRaftStore);
|
|||
int32_t raftStoreSerialize(SRaftStore *pRaftStore, char *buf, size_t len);
|
||||
int32_t raftStoreDeserialize(SRaftStore *pRaftStore, char *buf, size_t len);
|
||||
|
||||
bool raftStoreHasVoted(SRaftStore *pRaftStore);
|
||||
void raftStoreVote(SRaftStore *pRaftStore, SRaftId *pRaftId);
|
||||
void raftStoreClearVote(SRaftStore *pRaftStore);
|
||||
void raftStoreNextTerm(SRaftStore *pRaftStore);
|
||||
void raftStoreSetTerm(SRaftStore *pRaftStore, SyncTerm term);
|
||||
|
||||
// for debug -------------------
|
||||
void raftStorePrint(SRaftStore *pObj);
|
||||
void raftStorePrint2(char *s, SRaftStore *pObj);
|
||||
|
|
|
@ -52,7 +52,6 @@ extern "C" {
|
|||
// /\ UNCHANGED <<serverVars, candidateVars, leaderVars, logVars>>
|
||||
//
|
||||
int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode);
|
||||
|
||||
int32_t syncNodeReplicate(SSyncNode* pSyncNode);
|
||||
int32_t syncNodeAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, const SyncAppendEntries* pMsg);
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ void syncUtilnodeInfo2EpSet(const SNodeInfo* pNodeInfo, SEpSet* pEpSet);
|
|||
void syncUtilraftId2EpSet(const SRaftId* raftId, SEpSet* pEpSet);
|
||||
void syncUtilnodeInfo2raftId(const SNodeInfo* pNodeInfo, SyncGroupId vgId, SRaftId* raftId);
|
||||
bool syncUtilSameId(const SRaftId* pId1, const SRaftId* pId2);
|
||||
bool syncUtilEmptyId(const SRaftId* pId);
|
||||
|
||||
// ---- SSyncBuffer ----
|
||||
void syncUtilbufBuild(SSyncBuffer* syncBuf, size_t len);
|
||||
|
@ -52,6 +53,8 @@ const char* syncUtilState2String(ESyncState state);
|
|||
bool syncUtilCanPrint(char c);
|
||||
char* syncUtilprintBin(char* ptr, uint32_t len);
|
||||
char* syncUtilprintBin2(char* ptr, uint32_t len);
|
||||
SyncIndex syncUtilMinIndex(SyncIndex a, SyncIndex b);
|
||||
SyncIndex syncUtilMaxIndex(SyncIndex a, SyncIndex b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -14,6 +14,11 @@
|
|||
*/
|
||||
|
||||
#include "syncAppendEntries.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncRaftLog.h"
|
||||
#include "syncRaftStore.h"
|
||||
#include "syncUtil.h"
|
||||
#include "syncVoteMgr.h"
|
||||
|
||||
// TLA+ Spec
|
||||
// HandleAppendEntriesRequest(i, j, m) ==
|
||||
|
@ -80,4 +85,121 @@
|
|||
// /\ UNCHANGED <<serverVars, commitIndex, messages>>
|
||||
// /\ UNCHANGED <<candidateVars, leaderVars>>
|
||||
//
|
||||
int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {}
|
||||
int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
||||
int32_t ret = 0;
|
||||
syncAppendEntriesLog2("==syncNodeOnAppendEntriesCb==", pMsg);
|
||||
|
||||
if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||
syncNodeUpdateTerm(ths, pMsg->term);
|
||||
}
|
||||
assert(pMsg->term <= ths->pRaftStore->currentTerm);
|
||||
|
||||
if (pMsg->term == ths->pRaftStore->currentTerm) {
|
||||
ths->leaderCache = pMsg->srcId;
|
||||
syncNodeResetElectTimer(ths);
|
||||
}
|
||||
assert(pMsg->dataLen >= 0);
|
||||
|
||||
SyncTerm localPreLogTerm = 0;
|
||||
if (pMsg->prevLogTerm >= SYNC_INDEX_BEGIN && pMsg->prevLogTerm <= ths->pLogStore->getLastIndex(ths->pLogStore)) {
|
||||
SSyncRaftEntry* pEntry = logStoreGetEntry(ths->pLogStore, pMsg->prevLogTerm);
|
||||
assert(pEntry != NULL);
|
||||
localPreLogTerm = pEntry->term;
|
||||
syncEntryDestory(pEntry);
|
||||
}
|
||||
|
||||
bool logOK =
|
||||
(pMsg->prevLogIndex == SYNC_INDEX_INVALID) ||
|
||||
((pMsg->prevLogIndex >= SYNC_INDEX_BEGIN) &&
|
||||
(pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)) && (pMsg->prevLogIndex == localPreLogTerm));
|
||||
|
||||
// reject
|
||||
if ((pMsg->term < ths->pRaftStore->currentTerm) ||
|
||||
((pMsg->term == ths->pRaftStore->currentTerm) && (ths->state == TAOS_SYNC_STATE_FOLLOWER) && !logOK)) {
|
||||
SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild();
|
||||
pReply->srcId = ths->myRaftId;
|
||||
pReply->destId = pMsg->srcId;
|
||||
pReply->term = ths->pRaftStore->currentTerm;
|
||||
pReply->success = false;
|
||||
pReply->matchIndex = SYNC_INDEX_INVALID;
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg);
|
||||
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||
syncAppendEntriesReplyDestroy(pReply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// return to follower state
|
||||
if (pMsg->term == ths->pRaftStore->currentTerm && ths->state == TAOS_SYNC_STATE_CANDIDATE) {
|
||||
syncNodeBecomeFollower(ths);
|
||||
}
|
||||
|
||||
// accept request
|
||||
if (pMsg->term == ths->pRaftStore->currentTerm && ths->state == TAOS_SYNC_STATE_FOLLOWER && logOK) {
|
||||
bool matchSuccess = false;
|
||||
if (pMsg->prevLogIndex == SYNC_INDEX_INVALID &&
|
||||
ths->pLogStore->getLastIndex(ths->pLogStore) == SYNC_INDEX_INVALID) {
|
||||
matchSuccess = true;
|
||||
}
|
||||
if (pMsg->prevLogIndex >= SYNC_INDEX_BEGIN && pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)) {
|
||||
SSyncRaftEntry* pEntry = logStoreGetEntry(ths->pLogStore, pMsg->prevLogTerm);
|
||||
assert(pEntry != NULL);
|
||||
if (pMsg->prevLogTerm == pEntry->term) {
|
||||
matchSuccess = true;
|
||||
}
|
||||
syncEntryDestory(pEntry);
|
||||
}
|
||||
|
||||
if (matchSuccess) {
|
||||
// delete conflict entries
|
||||
if (ths->pLogStore->getLastIndex(ths->pLogStore) > pMsg->prevLogIndex) {
|
||||
SyncIndex fromIndex = pMsg->prevLogIndex + 1;
|
||||
ths->pLogStore->truncate(ths->pLogStore, fromIndex);
|
||||
}
|
||||
|
||||
// append one entry
|
||||
if (pMsg->dataLen > 0) {
|
||||
SSyncRaftEntry* pEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen);
|
||||
ths->pLogStore->appendEntry(ths->pLogStore, pEntry);
|
||||
syncEntryDestory(pEntry);
|
||||
}
|
||||
|
||||
SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild();
|
||||
pReply->srcId = ths->myRaftId;
|
||||
pReply->destId = pMsg->srcId;
|
||||
pReply->term = ths->pRaftStore->currentTerm;
|
||||
pReply->success = true;
|
||||
pReply->matchIndex = pMsg->prevLogIndex + 1;
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg);
|
||||
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||
|
||||
syncAppendEntriesReplyDestroy(pReply);
|
||||
} else {
|
||||
SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild();
|
||||
pReply->srcId = ths->myRaftId;
|
||||
pReply->destId = pMsg->srcId;
|
||||
pReply->term = ths->pRaftStore->currentTerm;
|
||||
pReply->success = false;
|
||||
pReply->matchIndex = SYNC_INDEX_INVALID;
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg);
|
||||
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||
syncAppendEntriesReplyDestroy(pReply);
|
||||
}
|
||||
|
||||
if (pMsg->commitIndex > ths->commitIndex) {
|
||||
if (pMsg->commitIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)) {
|
||||
// commit
|
||||
ths->commitIndex = pMsg->commitIndex;
|
||||
ths->pLogStore->updateCommitIndex(ths->pLogStore, ths->commitIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,12 @@
|
|||
*/
|
||||
|
||||
#include "syncAppendEntriesReply.h"
|
||||
#include "syncIndexMgr.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncRaftLog.h"
|
||||
#include "syncRaftStore.h"
|
||||
#include "syncUtil.h"
|
||||
#include "syncVoteMgr.h"
|
||||
|
||||
// TLA+ Spec
|
||||
// HandleAppendEntriesResponse(i, j, m) ==
|
||||
|
@ -28,4 +34,41 @@
|
|||
// /\ Discard(m)
|
||||
// /\ UNCHANGED <<serverVars, candidateVars, logVars, elections>>
|
||||
//
|
||||
int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg) {}
|
||||
int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg) {
|
||||
int32_t ret = 0;
|
||||
syncAppendEntriesReplyLog2("==syncNodeOnAppendEntriesReplyCb==", pMsg);
|
||||
|
||||
if (pMsg->term < ths->pRaftStore->currentTerm) {
|
||||
sTrace("DropStaleResponse, receive term:%lu, current term:%lu", pMsg->term, ths->pRaftStore->currentTerm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// no need this code, because if I receive reply.term, then I must have sent for that term.
|
||||
// if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||
// syncNodeUpdateTerm(ths, pMsg->term);
|
||||
// }
|
||||
|
||||
assert(pMsg->term == ths->pRaftStore->currentTerm);
|
||||
|
||||
if (pMsg->success) {
|
||||
// nextIndex = reply.matchIndex + 1
|
||||
syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), pMsg->matchIndex + 1);
|
||||
|
||||
// matchIndex = reply.matchIndex
|
||||
syncIndexMgrSetIndex(ths->pMatchIndex, &(pMsg->srcId), pMsg->matchIndex);
|
||||
|
||||
// maybe commit
|
||||
syncNodeMaybeAdvanceCommitIndex(ths);
|
||||
|
||||
} else {
|
||||
SyncIndex nextIndex = syncIndexMgrGetIndex(ths->pNextIndex, &(pMsg->srcId));
|
||||
if (nextIndex > SYNC_INDEX_BEGIN) {
|
||||
--nextIndex;
|
||||
} else {
|
||||
nextIndex = SYNC_INDEX_BEGIN;
|
||||
}
|
||||
syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), nextIndex);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "syncElection.h"
|
||||
#include "syncMessage.h"
|
||||
#include "syncRaftStore.h"
|
||||
#include "syncVoteMgr.h"
|
||||
|
||||
// TLA+ Spec
|
||||
// RequestVote(i, j) ==
|
||||
|
@ -37,7 +38,7 @@ int32_t syncNodeRequestVotePeers(SSyncNode* pSyncNode) {
|
|||
SyncRequestVote* pMsg = syncRequestVoteBuild();
|
||||
pMsg->srcId = pSyncNode->myRaftId;
|
||||
pMsg->destId = pSyncNode->peersId[i];
|
||||
pMsg->currentTerm = pSyncNode->pRaftStore->currentTerm;
|
||||
pMsg->term = pSyncNode->pRaftStore->currentTerm;
|
||||
pMsg->lastLogIndex = pSyncNode->pLogStore->getLastIndex(pSyncNode->pLogStore);
|
||||
pMsg->lastLogTerm = pSyncNode->pLogStore->getLastTerm(pSyncNode->pLogStore);
|
||||
|
||||
|
@ -49,10 +50,22 @@ int32_t syncNodeRequestVotePeers(SSyncNode* pSyncNode) {
|
|||
}
|
||||
|
||||
int32_t syncNodeElect(SSyncNode* pSyncNode) {
|
||||
if (pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER) {
|
||||
syncNodeFollower2Candidate(pSyncNode);
|
||||
}
|
||||
assert(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE);
|
||||
|
||||
// start election
|
||||
raftStoreNextTerm(pSyncNode->pRaftStore);
|
||||
raftStoreClearVote(pSyncNode->pRaftStore);
|
||||
voteGrantedReset(pSyncNode->pVotesGranted, pSyncNode->pRaftStore->currentTerm);
|
||||
votesRespondReset(pSyncNode->pVotesRespond, pSyncNode->pRaftStore->currentTerm);
|
||||
|
||||
syncNodeVoteForSelf(pSyncNode);
|
||||
int32_t ret = syncNodeRequestVotePeers(pSyncNode);
|
||||
assert(ret == 0);
|
||||
syncNodeResetElectTimer(pSyncNode);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,19 +19,18 @@
|
|||
SSyncEnv *gSyncEnv = NULL;
|
||||
|
||||
// local function -----------------
|
||||
static void syncEnvTick(void *param, void *tmrId);
|
||||
static int32_t doSyncEnvStart(SSyncEnv *pSyncEnv);
|
||||
static SSyncEnv *doSyncEnvStart();
|
||||
static int32_t doSyncEnvStop(SSyncEnv *pSyncEnv);
|
||||
static tmr_h doSyncEnvStartTimer(SSyncEnv *pSyncEnv, TAOS_TMR_CALLBACK fp, int mseconds, void *param);
|
||||
static void doSyncEnvStopTimer(SSyncEnv *pSyncEnv, tmr_h *pTimer);
|
||||
static int32_t doSyncEnvStartTimer(SSyncEnv *pSyncEnv);
|
||||
static int32_t doSyncEnvStopTimer(SSyncEnv *pSyncEnv);
|
||||
static void syncEnvTick(void *param, void *tmrId);
|
||||
// --------------------------------
|
||||
|
||||
int32_t syncEnvStart() {
|
||||
int32_t ret;
|
||||
int32_t ret = 0;
|
||||
taosSeedRand(taosGetTimestampSec());
|
||||
gSyncEnv = (SSyncEnv *)malloc(sizeof(SSyncEnv));
|
||||
gSyncEnv = doSyncEnvStart(gSyncEnv);
|
||||
assert(gSyncEnv != NULL);
|
||||
ret = doSyncEnvStart(gSyncEnv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -40,31 +39,52 @@ int32_t syncEnvStop() {
|
|||
return ret;
|
||||
}
|
||||
|
||||
tmr_h syncEnvStartTimer(TAOS_TMR_CALLBACK fp, int mseconds, void *param) {
|
||||
return doSyncEnvStartTimer(gSyncEnv, fp, mseconds, param);
|
||||
int32_t syncEnvStartTimer() {
|
||||
int32_t ret = doSyncEnvStartTimer(gSyncEnv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void syncEnvStopTimer(tmr_h *pTimer) { doSyncEnvStopTimer(gSyncEnv, pTimer); }
|
||||
int32_t syncEnvStopTimer() {
|
||||
int32_t ret = doSyncEnvStopTimer(gSyncEnv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// local function -----------------
|
||||
static void syncEnvTick(void *param, void *tmrId) {
|
||||
SSyncEnv *pSyncEnv = (SSyncEnv *)param;
|
||||
sTrace("syncEnvTick ... name:%s ", pSyncEnv->name);
|
||||
if (atomic_load_64(&pSyncEnv->envTickTimerLogicClockUser) <= atomic_load_64(&pSyncEnv->envTickTimerLogicClock)) {
|
||||
++(pSyncEnv->envTickTimerCounter);
|
||||
sTrace(
|
||||
"syncEnvTick do ... envTickTimerLogicClockUser:%lu, envTickTimerLogicClock:%lu, envTickTimerCounter:%lu, "
|
||||
"envTickTimerMS:%d, tmrId:%p",
|
||||
pSyncEnv->envTickTimerLogicClockUser, pSyncEnv->envTickTimerLogicClock, pSyncEnv->envTickTimerCounter,
|
||||
pSyncEnv->envTickTimerMS, tmrId);
|
||||
|
||||
pSyncEnv->pEnvTickTimer = taosTmrStart(syncEnvTick, 1000, pSyncEnv, pSyncEnv->pTimerManager);
|
||||
// do something, tick ...
|
||||
taosTmrReset(syncEnvTick, pSyncEnv->envTickTimerMS, pSyncEnv, pSyncEnv->pTimerManager, &pSyncEnv->pEnvTickTimer);
|
||||
} else {
|
||||
sTrace(
|
||||
"syncEnvTick pass ... envTickTimerLogicClockUser:%lu, envTickTimerLogicClock:%lu, envTickTimerCounter:%lu, "
|
||||
"envTickTimerMS:%d, tmrId:%p",
|
||||
pSyncEnv->envTickTimerLogicClockUser, pSyncEnv->envTickTimerLogicClock, pSyncEnv->envTickTimerCounter,
|
||||
pSyncEnv->envTickTimerMS, tmrId);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t doSyncEnvStart(SSyncEnv *pSyncEnv) {
|
||||
snprintf(pSyncEnv->name, sizeof(pSyncEnv->name), "SyncEnv_%p", pSyncEnv);
|
||||
static SSyncEnv *doSyncEnvStart() {
|
||||
SSyncEnv *pSyncEnv = (SSyncEnv *)malloc(sizeof(SSyncEnv));
|
||||
assert(pSyncEnv != NULL);
|
||||
memset(pSyncEnv, 0, sizeof(pSyncEnv));
|
||||
|
||||
pSyncEnv->envTickTimerCounter = 0;
|
||||
pSyncEnv->envTickTimerMS = ENV_TICK_TIMER_MS;
|
||||
pSyncEnv->FpEnvTickTimer = syncEnvTick;
|
||||
atomic_store_64(&pSyncEnv->envTickTimerLogicClock, 0);
|
||||
atomic_store_64(&pSyncEnv->envTickTimerLogicClockUser, 0);
|
||||
|
||||
// start tmr thread
|
||||
pSyncEnv->pTimerManager = taosTmrInit(1000, 50, 10000, "SYNC-ENV");
|
||||
|
||||
// pSyncEnv->pEnvTickTimer = taosTmrStart(syncEnvTick, 1000, pSyncEnv, pSyncEnv->pTimerManager);
|
||||
|
||||
sTrace("SyncEnv start ok, name:%s", pSyncEnv->name);
|
||||
|
||||
return 0;
|
||||
return pSyncEnv;
|
||||
}
|
||||
|
||||
static int32_t doSyncEnvStop(SSyncEnv *pSyncEnv) {
|
||||
|
@ -72,8 +92,18 @@ static int32_t doSyncEnvStop(SSyncEnv *pSyncEnv) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static tmr_h doSyncEnvStartTimer(SSyncEnv *pSyncEnv, TAOS_TMR_CALLBACK fp, int mseconds, void *param) {
|
||||
return taosTmrStart(fp, mseconds, pSyncEnv, pSyncEnv->pTimerManager);
|
||||
static int32_t doSyncEnvStartTimer(SSyncEnv *pSyncEnv) {
|
||||
int32_t ret = 0;
|
||||
taosTmrReset(pSyncEnv->FpEnvTickTimer, pSyncEnv->envTickTimerMS, pSyncEnv, pSyncEnv->pTimerManager,
|
||||
&pSyncEnv->pEnvTickTimer);
|
||||
atomic_store_64(&pSyncEnv->envTickTimerLogicClock, pSyncEnv->envTickTimerLogicClockUser);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void doSyncEnvStopTimer(SSyncEnv *pSyncEnv, tmr_h *pTimer) {}
|
||||
static int32_t doSyncEnvStopTimer(SSyncEnv *pSyncEnv) {
|
||||
int32_t ret = 0;
|
||||
atomic_add_fetch_64(&pSyncEnv->envTickTimerLogicClockUser, 1);
|
||||
taosTmrStop(pSyncEnv->pEnvTickTimer);
|
||||
pSyncEnv->pEnvTickTimer = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "syncIO.h"
|
||||
#include <tdatablock.h>
|
||||
#include "syncMessage.h"
|
||||
#include "syncUtil.h"
|
||||
#include "tglobal.h"
|
||||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
|
@ -23,33 +24,36 @@
|
|||
SSyncIO *gSyncIO = NULL;
|
||||
|
||||
// local function ------------
|
||||
static int32_t syncIOStartInternal(SSyncIO *io);
|
||||
static int32_t syncIOStopInternal(SSyncIO *io);
|
||||
static SSyncIO *syncIOCreate(char *host, uint16_t port);
|
||||
static int32_t syncIODestroy(SSyncIO *io);
|
||||
static int32_t syncIOStartInternal(SSyncIO *io);
|
||||
static int32_t syncIOStopInternal(SSyncIO *io);
|
||||
|
||||
static void *syncIOConsumerFunc(void *param);
|
||||
static int syncIOAuth(void *parent, char *meterId, char *spi, char *encrypt, char *secret, char *ckey);
|
||||
static void syncIOProcessRequest(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||
static void syncIOProcessReply(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||
static int32_t syncIOAuth(void *parent, char *meterId, char *spi, char *encrypt, char *secret, char *ckey);
|
||||
|
||||
static int32_t syncIOTickQInternal(SSyncIO *io);
|
||||
static void syncIOTickQFunc(void *param, void *tmrId);
|
||||
static int32_t syncIOTickPingInternal(SSyncIO *io);
|
||||
static void syncIOTickPingFunc(void *param, void *tmrId);
|
||||
static int32_t syncIOStartQ(SSyncIO *io);
|
||||
static int32_t syncIOStopQ(SSyncIO *io);
|
||||
static int32_t syncIOStartPing(SSyncIO *io);
|
||||
static int32_t syncIOStopPing(SSyncIO *io);
|
||||
static void syncIOTickQ(void *param, void *tmrId);
|
||||
static void syncIOTickPing(void *param, void *tmrId);
|
||||
// ----------------------------
|
||||
|
||||
// public function ------------
|
||||
int32_t syncIOStart(char *host, uint16_t port) {
|
||||
int32_t ret = 0;
|
||||
gSyncIO = syncIOCreate(host, port);
|
||||
assert(gSyncIO != NULL);
|
||||
|
||||
taosSeedRand(taosGetTimestampSec());
|
||||
int32_t ret = syncIOStartInternal(gSyncIO);
|
||||
ret = syncIOStartInternal(gSyncIO);
|
||||
assert(ret == 0);
|
||||
|
||||
sTrace("syncIOStart ok, gSyncIO:%p gSyncIO->clientRpc:%p", gSyncIO, gSyncIO->clientRpc);
|
||||
return 0;
|
||||
sTrace("syncIOStart ok, gSyncIO:%p", gSyncIO);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncIOStop() {
|
||||
|
@ -61,37 +65,25 @@ int32_t syncIOStop() {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncIOTickQ() {
|
||||
int32_t ret = syncIOTickQInternal(gSyncIO);
|
||||
assert(ret == 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncIOTickPing() {
|
||||
int32_t ret = syncIOTickPingInternal(gSyncIO);
|
||||
assert(ret == 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncIOSendMsg(void *clientRpc, const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
||||
sTrace(
|
||||
"<--- syncIOSendMsg ---> clientRpc:%p, numOfEps:%d, inUse:%d, destAddr:%s-%u, pMsg->ahandle:%p, pMsg->handle:%p, "
|
||||
"pMsg->msgType:%d, pMsg->contLen:%d",
|
||||
clientRpc, pEpSet->numOfEps, pEpSet->inUse, pEpSet->eps[0].fqdn, pEpSet->eps[0].port, pMsg->ahandle, pMsg->handle,
|
||||
pMsg->msgType, pMsg->contLen);
|
||||
{
|
||||
cJSON *pJson = syncRpcMsg2Json(pMsg);
|
||||
char * serialized = cJSON_Print(pJson);
|
||||
sTrace("process syncMessage send: pMsg:%s ", serialized);
|
||||
free(serialized);
|
||||
cJSON_Delete(pJson);
|
||||
}
|
||||
assert(pEpSet->inUse == 0);
|
||||
assert(pEpSet->numOfEps == 1);
|
||||
|
||||
int32_t ret = 0;
|
||||
char logBuf[256];
|
||||
snprintf(logBuf, sizeof(logBuf), "==syncIOSendMsg== %s:%d", pEpSet->eps[0].fqdn, pEpSet->eps[0].port);
|
||||
syncRpcMsgPrint2(logBuf, pMsg);
|
||||
|
||||
pMsg->handle = NULL;
|
||||
rpcSendRequest(clientRpc, pEpSet, pMsg, NULL);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncIOEqMsg(void *queue, SRpcMsg *pMsg) {
|
||||
int32_t ret = 0;
|
||||
char logBuf[128];
|
||||
syncRpcMsgPrint2((char *)"==syncIOEqMsg==", pMsg);
|
||||
|
||||
SRpcMsg *pTemp;
|
||||
pTemp = taosAllocateQitem(sizeof(SRpcMsg));
|
||||
memcpy(pTemp, pMsg, sizeof(SRpcMsg));
|
||||
|
@ -99,11 +91,75 @@ int32_t syncIOEqMsg(void *queue, SRpcMsg *pMsg) {
|
|||
STaosQueue *pMsgQ = queue;
|
||||
taosWriteQitem(pMsgQ, pTemp);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncIOQTimerStart() {
|
||||
int32_t ret = syncIOStartQ(gSyncIO);
|
||||
assert(ret == 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncIOQTimerStop() {
|
||||
int32_t ret = syncIOStopQ(gSyncIO);
|
||||
assert(ret == 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncIOPingTimerStart() {
|
||||
int32_t ret = syncIOStartPing(gSyncIO);
|
||||
assert(ret == 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncIOPingTimerStop() {
|
||||
int32_t ret = syncIOStopPing(gSyncIO);
|
||||
assert(ret == 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// local function ------------
|
||||
static SSyncIO *syncIOCreate(char *host, uint16_t port) {
|
||||
SSyncIO *io = (SSyncIO *)malloc(sizeof(SSyncIO));
|
||||
memset(io, 0, sizeof(*io));
|
||||
|
||||
io->pMsgQ = taosOpenQueue();
|
||||
io->pQset = taosOpenQset();
|
||||
taosAddIntoQset(io->pQset, io->pMsgQ, NULL);
|
||||
|
||||
io->myAddr.inUse = 0;
|
||||
io->myAddr.numOfEps = 0;
|
||||
addEpIntoEpSet(&io->myAddr, host, port);
|
||||
|
||||
io->qTimerMS = TICK_Q_TIMER_MS;
|
||||
io->pingTimerMS = TICK_Ping_TIMER_MS;
|
||||
|
||||
return io;
|
||||
}
|
||||
|
||||
static int32_t syncIODestroy(SSyncIO *io) {
|
||||
int32_t ret = 0;
|
||||
int8_t start = atomic_load_8(&io->isStart);
|
||||
assert(start == 0);
|
||||
|
||||
if (io->serverRpc != NULL) {
|
||||
rpcClose(io->serverRpc);
|
||||
io->serverRpc = NULL;
|
||||
}
|
||||
|
||||
if (io->clientRpc != NULL) {
|
||||
rpcClose(io->clientRpc);
|
||||
io->clientRpc = NULL;
|
||||
}
|
||||
|
||||
taosCloseQueue(io->pMsgQ);
|
||||
taosCloseQset(io->pQset);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t syncIOStartInternal(SSyncIO *io) {
|
||||
int32_t ret = 0;
|
||||
taosBlockSIGPIPE();
|
||||
|
||||
rpcInit();
|
||||
|
@ -163,58 +219,24 @@ static int32_t syncIOStartInternal(SSyncIO *io) {
|
|||
}
|
||||
|
||||
// start tmr thread
|
||||
io->ioTimerManager = taosTmrInit(1000, 50, 10000, "SYNC");
|
||||
io->timerMgr = taosTmrInit(1000, 50, 10000, "SYNC-IO");
|
||||
|
||||
return 0;
|
||||
atomic_store_8(&io->isStart, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t syncIOStopInternal(SSyncIO *io) {
|
||||
int32_t ret = 0;
|
||||
atomic_store_8(&io->isStart, 0);
|
||||
pthread_join(io->consumerTid, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SSyncIO *syncIOCreate(char *host, uint16_t port) {
|
||||
SSyncIO *io = (SSyncIO *)malloc(sizeof(SSyncIO));
|
||||
memset(io, 0, sizeof(*io));
|
||||
|
||||
io->pMsgQ = taosOpenQueue();
|
||||
io->pQset = taosOpenQset();
|
||||
taosAddIntoQset(io->pQset, io->pMsgQ, NULL);
|
||||
|
||||
io->myAddr.inUse = 0;
|
||||
addEpIntoEpSet(&io->myAddr, host, port);
|
||||
|
||||
return io;
|
||||
}
|
||||
|
||||
static int32_t syncIODestroy(SSyncIO *io) {
|
||||
int8_t start = atomic_load_8(&io->isStart);
|
||||
assert(start == 0);
|
||||
|
||||
if (io->serverRpc != NULL) {
|
||||
free(io->serverRpc);
|
||||
io->serverRpc = NULL;
|
||||
}
|
||||
|
||||
if (io->clientRpc != NULL) {
|
||||
free(io->clientRpc);
|
||||
io->clientRpc = NULL;
|
||||
}
|
||||
|
||||
taosCloseQueue(io->pMsgQ);
|
||||
taosCloseQset(io->pQset);
|
||||
|
||||
return 0;
|
||||
taosTmrCleanUp(io->timerMgr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *syncIOConsumerFunc(void *param) {
|
||||
SSyncIO *io = param;
|
||||
|
||||
STaosQall *qall;
|
||||
SRpcMsg * pRpcMsg, rpcMsg;
|
||||
int type;
|
||||
|
||||
SRpcMsg *pRpcMsg, rpcMsg;
|
||||
qall = taosAllocateQall();
|
||||
|
||||
while (1) {
|
||||
|
@ -226,77 +248,74 @@ static void *syncIOConsumerFunc(void *param) {
|
|||
|
||||
for (int i = 0; i < numOfMsgs; ++i) {
|
||||
taosGetQitem(qall, (void **)&pRpcMsg);
|
||||
syncRpcMsgLog2((char *)"==syncIOConsumerFunc==", pRpcMsg);
|
||||
|
||||
char *s = syncRpcMsg2Str(pRpcMsg);
|
||||
sTrace("syncIOConsumerFunc get item from queue: msgType:%d contLen:%d msg:%s", pRpcMsg->msgType, pRpcMsg->contLen,
|
||||
s);
|
||||
free(s);
|
||||
|
||||
// use switch case instead of if else
|
||||
if (pRpcMsg->msgType == SYNC_PING) {
|
||||
if (io->FpOnSyncPing != NULL) {
|
||||
SyncPing *pSyncMsg;
|
||||
SyncPing *pSyncMsg = syncPingFromRpcMsg2(pRpcMsg);
|
||||
assert(pSyncMsg != NULL);
|
||||
io->FpOnSyncPing(io->pSyncNode, pSyncMsg);
|
||||
syncPingDestroy(pSyncMsg);
|
||||
/*
|
||||
pSyncMsg = syncPingBuild(pRpcMsg->contLen);
|
||||
syncPingFromRpcMsg(pRpcMsg, pSyncMsg);
|
||||
// memcpy(pSyncMsg, tmpRpcMsg.pCont, tmpRpcMsg.contLen);
|
||||
io->FpOnSyncPing(io->pSyncNode, pSyncMsg);
|
||||
syncPingDestroy(pSyncMsg);
|
||||
*/
|
||||
}
|
||||
|
||||
} else if (pRpcMsg->msgType == SYNC_PING_REPLY) {
|
||||
if (io->FpOnSyncPingReply != NULL) {
|
||||
SyncPingReply *pSyncMsg;
|
||||
pSyncMsg = syncPingReplyBuild(pRpcMsg->contLen);
|
||||
syncPingReplyFromRpcMsg(pRpcMsg, pSyncMsg);
|
||||
SyncPingReply *pSyncMsg = syncPingReplyFromRpcMsg2(pRpcMsg);
|
||||
io->FpOnSyncPingReply(io->pSyncNode, pSyncMsg);
|
||||
syncPingReplyDestroy(pSyncMsg);
|
||||
}
|
||||
|
||||
} else if (pRpcMsg->msgType == SYNC_CLIENT_REQUEST) {
|
||||
if (io->FpOnSyncClientRequest != NULL) {
|
||||
SyncClientRequest *pSyncMsg = syncClientRequestFromRpcMsg2(pRpcMsg);
|
||||
io->FpOnSyncClientRequest(io->pSyncNode, pSyncMsg);
|
||||
syncClientRequestDestroy(pSyncMsg);
|
||||
}
|
||||
|
||||
} else if (pRpcMsg->msgType == SYNC_REQUEST_VOTE) {
|
||||
if (io->FpOnSyncRequestVote != NULL) {
|
||||
SyncRequestVote *pSyncMsg;
|
||||
pSyncMsg = syncRequestVoteBuild(pRpcMsg->contLen);
|
||||
syncRequestVoteFromRpcMsg(pRpcMsg, pSyncMsg);
|
||||
SyncRequestVote *pSyncMsg = syncRequestVoteFromRpcMsg2(pRpcMsg);
|
||||
io->FpOnSyncRequestVote(io->pSyncNode, pSyncMsg);
|
||||
syncRequestVoteDestroy(pSyncMsg);
|
||||
}
|
||||
|
||||
} else if (pRpcMsg->msgType == SYNC_REQUEST_VOTE_REPLY) {
|
||||
if (io->FpOnSyncRequestVoteReply != NULL) {
|
||||
SyncRequestVoteReply *pSyncMsg;
|
||||
pSyncMsg = syncRequestVoteReplyBuild();
|
||||
syncRequestVoteReplyFromRpcMsg(pRpcMsg, pSyncMsg);
|
||||
SyncRequestVoteReply *pSyncMsg = syncRequestVoteReplyFromRpcMsg2(pRpcMsg);
|
||||
io->FpOnSyncRequestVoteReply(io->pSyncNode, pSyncMsg);
|
||||
syncRequestVoteReplyDestroy(pSyncMsg);
|
||||
}
|
||||
|
||||
} else if (pRpcMsg->msgType == SYNC_APPEND_ENTRIES) {
|
||||
if (io->FpOnSyncAppendEntries != NULL) {
|
||||
SyncAppendEntries *pSyncMsg;
|
||||
pSyncMsg = syncAppendEntriesBuild(pRpcMsg->contLen);
|
||||
syncAppendEntriesFromRpcMsg(pRpcMsg, pSyncMsg);
|
||||
SyncAppendEntries *pSyncMsg = syncAppendEntriesFromRpcMsg2(pRpcMsg);
|
||||
io->FpOnSyncAppendEntries(io->pSyncNode, pSyncMsg);
|
||||
syncAppendEntriesDestroy(pSyncMsg);
|
||||
}
|
||||
|
||||
} else if (pRpcMsg->msgType == SYNC_APPEND_ENTRIES_REPLY) {
|
||||
if (io->FpOnSyncAppendEntriesReply != NULL) {
|
||||
SyncAppendEntriesReply *pSyncMsg;
|
||||
pSyncMsg = syncAppendEntriesReplyBuild();
|
||||
syncAppendEntriesReplyFromRpcMsg(pRpcMsg, pSyncMsg);
|
||||
SyncAppendEntriesReply *pSyncMsg = syncAppendEntriesReplyFromRpcMsg2(pRpcMsg);
|
||||
io->FpOnSyncAppendEntriesReply(io->pSyncNode, pSyncMsg);
|
||||
syncAppendEntriesReplyDestroy(pSyncMsg);
|
||||
}
|
||||
|
||||
} else if (pRpcMsg->msgType == SYNC_TIMEOUT) {
|
||||
if (io->FpOnSyncTimeout != NULL) {
|
||||
SyncTimeout *pSyncMsg;
|
||||
pSyncMsg = syncTimeoutBuild();
|
||||
syncTimeoutFromRpcMsg(pRpcMsg, pSyncMsg);
|
||||
SyncTimeout *pSyncMsg = syncTimeoutFromRpcMsg2(pRpcMsg);
|
||||
io->FpOnSyncTimeout(io->pSyncNode, pSyncMsg);
|
||||
syncTimeoutDestroy(pSyncMsg);
|
||||
}
|
||||
} else {
|
||||
;
|
||||
sTrace("unknown msgType:%d, no operator", pRpcMsg->msgType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,15 +325,16 @@ static void *syncIOConsumerFunc(void *param) {
|
|||
rpcFreeCont(pRpcMsg->pCont);
|
||||
|
||||
if (pRpcMsg->handle != NULL) {
|
||||
int msgSize = 128;
|
||||
int msgSize = 32;
|
||||
memset(&rpcMsg, 0, sizeof(rpcMsg));
|
||||
rpcMsg.msgType = SYNC_RESPONSE;
|
||||
rpcMsg.pCont = rpcMallocCont(msgSize);
|
||||
rpcMsg.contLen = msgSize;
|
||||
snprintf(rpcMsg.pCont, rpcMsg.contLen, "%s", "give a reply");
|
||||
rpcMsg.handle = pRpcMsg->handle;
|
||||
rpcMsg.code = 0;
|
||||
|
||||
sTrace("syncIOConsumerFunc rpcSendResponse ... msgType:%d contLen:%d", pRpcMsg->msgType, rpcMsg.contLen);
|
||||
syncRpcMsgPrint2((char *)"syncIOConsumerFunc rpcSendResponse --> ", &rpcMsg);
|
||||
rpcSendResponse(&rpcMsg);
|
||||
}
|
||||
|
||||
|
@ -326,71 +346,95 @@ static void *syncIOConsumerFunc(void *param) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int syncIOAuth(void *parent, char *meterId, char *spi, char *encrypt, char *secret, char *ckey) {
|
||||
// app shall retrieve the auth info based on meterID from DB or a data file
|
||||
// demo code here only for simple demo
|
||||
int ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void syncIOProcessRequest(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||
sTrace("<-- syncIOProcessRequest --> type:%d, contLen:%d, cont:%s", pMsg->msgType, pMsg->contLen,
|
||||
(char *)pMsg->pCont);
|
||||
|
||||
syncRpcMsgPrint2((char *)"==syncIOProcessRequest==", pMsg);
|
||||
SSyncIO *io = pParent;
|
||||
SRpcMsg *pTemp;
|
||||
|
||||
pTemp = taosAllocateQitem(sizeof(SRpcMsg));
|
||||
memcpy(pTemp, pMsg, sizeof(SRpcMsg));
|
||||
|
||||
taosWriteQitem(io->pMsgQ, pTemp);
|
||||
}
|
||||
|
||||
static void syncIOProcessReply(void *pParent, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||
sTrace("syncIOProcessReply: type:%d, contLen:%d msg:%s", pMsg->msgType, pMsg->contLen, (char *)pMsg->pCont);
|
||||
if (pMsg->msgType == SYNC_RESPONSE) {
|
||||
sTrace("==syncIOProcessReply==");
|
||||
} else {
|
||||
syncRpcMsgPrint2((char *)"==syncIOProcessReply==", pMsg);
|
||||
}
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
}
|
||||
|
||||
static int32_t syncIOTickQInternal(SSyncIO *io) {
|
||||
io->ioTimerTickQ = taosTmrStart(syncIOTickQFunc, 1000, io, io->ioTimerManager);
|
||||
return 0;
|
||||
static int32_t syncIOAuth(void *parent, char *meterId, char *spi, char *encrypt, char *secret, char *ckey) {
|
||||
// app shall retrieve the auth info based on meterID from DB or a data file
|
||||
// demo code here only for simple demo
|
||||
int32_t ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void syncIOTickQFunc(void *param, void *tmrId) {
|
||||
static int32_t syncIOStartQ(SSyncIO *io) {
|
||||
int32_t ret = 0;
|
||||
taosTmrReset(syncIOTickQ, io->qTimerMS, io, io->timerMgr, &io->qTimer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t syncIOStopQ(SSyncIO *io) {
|
||||
int32_t ret = 0;
|
||||
taosTmrStop(io->qTimer);
|
||||
io->qTimer = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t syncIOStartPing(SSyncIO *io) {
|
||||
int32_t ret = 0;
|
||||
taosTmrReset(syncIOTickPing, io->pingTimerMS, io, io->timerMgr, &io->pingTimer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t syncIOStopPing(SSyncIO *io) {
|
||||
int32_t ret = 0;
|
||||
taosTmrStop(io->pingTimer);
|
||||
io->pingTimer = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void syncIOTickQ(void *param, void *tmrId) {
|
||||
SSyncIO *io = (SSyncIO *)param;
|
||||
sTrace("<-- syncIOTickQFunc -->");
|
||||
|
||||
SRaftId srcId, destId;
|
||||
srcId.addr = syncUtilAddr2U64(io->myAddr.eps[0].fqdn, io->myAddr.eps[0].port);
|
||||
srcId.vgId = -1;
|
||||
destId.addr = syncUtilAddr2U64(io->myAddr.eps[0].fqdn, io->myAddr.eps[0].port);
|
||||
destId.vgId = -1;
|
||||
SyncPingReply *pMsg = syncPingReplyBuild2(&srcId, &destId, "syncIOTickQ");
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
rpcMsg.contLen = 64;
|
||||
rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen);
|
||||
snprintf(rpcMsg.pCont, rpcMsg.contLen, "%s", "syncIOTickQ");
|
||||
rpcMsg.handle = NULL;
|
||||
rpcMsg.msgType = 55;
|
||||
|
||||
syncPingReply2RpcMsg(pMsg, &rpcMsg);
|
||||
SRpcMsg *pTemp;
|
||||
pTemp = taosAllocateQitem(sizeof(SRpcMsg));
|
||||
memcpy(pTemp, &rpcMsg, sizeof(SRpcMsg));
|
||||
|
||||
syncRpcMsgPrint2((char *)"==syncIOTickQ==", &rpcMsg);
|
||||
taosWriteQitem(io->pMsgQ, pTemp);
|
||||
taosTmrReset(syncIOTickQFunc, 1000, io, io->ioTimerManager, &io->ioTimerTickQ);
|
||||
syncPingReplyDestroy(pMsg);
|
||||
|
||||
taosTmrReset(syncIOTickQ, io->qTimerMS, io, io->timerMgr, &io->qTimer);
|
||||
}
|
||||
|
||||
static int32_t syncIOTickPingInternal(SSyncIO *io) {
|
||||
io->ioTimerTickPing = taosTmrStart(syncIOTickPingFunc, 1000, io, io->ioTimerManager);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void syncIOTickPingFunc(void *param, void *tmrId) {
|
||||
static void syncIOTickPing(void *param, void *tmrId) {
|
||||
SSyncIO *io = (SSyncIO *)param;
|
||||
sTrace("<-- syncIOTickPingFunc -->");
|
||||
|
||||
SRaftId srcId, destId;
|
||||
srcId.addr = syncUtilAddr2U64(io->myAddr.eps[0].fqdn, io->myAddr.eps[0].port);
|
||||
srcId.vgId = -1;
|
||||
destId.addr = syncUtilAddr2U64(io->myAddr.eps[0].fqdn, io->myAddr.eps[0].port);
|
||||
destId.vgId = -1;
|
||||
SyncPing *pMsg = syncPingBuild2(&srcId, &destId, "syncIOTickPing");
|
||||
// SyncPing *pMsg = syncPingBuild3(&srcId, &destId);
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
rpcMsg.contLen = 64;
|
||||
rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen);
|
||||
snprintf(rpcMsg.pCont, rpcMsg.contLen, "%s", "syncIOTickPing");
|
||||
rpcMsg.handle = NULL;
|
||||
rpcMsg.msgType = 77;
|
||||
|
||||
syncPing2RpcMsg(pMsg, &rpcMsg);
|
||||
syncRpcMsgPrint2((char *)"==syncIOTickPing==", &rpcMsg);
|
||||
rpcSendRequest(io->clientRpc, &io->myAddr, &rpcMsg, NULL);
|
||||
taosTmrReset(syncIOTickPingFunc, 1000, io, io->ioTimerManager, &io->ioTimerTickPing);
|
||||
syncPingDestroy(pMsg);
|
||||
|
||||
taosTmrReset(syncIOTickPing, io->pingTimerMS, io, io->timerMgr, &io->pingTimer);
|
||||
}
|
|
@ -17,11 +17,14 @@
|
|||
#include "sync.h"
|
||||
#include "syncAppendEntries.h"
|
||||
#include "syncAppendEntriesReply.h"
|
||||
#include "syncElection.h"
|
||||
#include "syncEnv.h"
|
||||
#include "syncIndexMgr.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncMessage.h"
|
||||
#include "syncRaftLog.h"
|
||||
#include "syncRaftStore.h"
|
||||
#include "syncReplication.h"
|
||||
#include "syncRequestVote.h"
|
||||
#include "syncRequestVoteReply.h"
|
||||
#include "syncTimeout.h"
|
||||
|
@ -31,33 +34,32 @@
|
|||
static int32_t tsNodeRefId = -1;
|
||||
|
||||
// ------ local funciton ---------
|
||||
// enqueue message ----
|
||||
static void syncNodeEqPingTimer(void* param, void* tmrId);
|
||||
static void syncNodeEqElectTimer(void* param, void* tmrId);
|
||||
static void syncNodeEqHeartbeatTimer(void* param, void* tmrId);
|
||||
|
||||
// on message ----
|
||||
static int32_t syncNodeOnPingCb(SSyncNode* ths, SyncPing* pMsg);
|
||||
static int32_t syncNodeOnPingReplyCb(SSyncNode* ths, SyncPingReply* pMsg);
|
||||
|
||||
static void UpdateTerm(SSyncNode* pSyncNode, SyncTerm term);
|
||||
static void syncNodeBecomeFollower(SSyncNode* pSyncNode);
|
||||
static void syncNodeBecomeLeader(SSyncNode* pSyncNode);
|
||||
static void syncNodeFollower2Candidate(SSyncNode* pSyncNode);
|
||||
static void syncNodeCandidate2Leader(SSyncNode* pSyncNode);
|
||||
static void syncNodeLeader2Follower(SSyncNode* pSyncNode);
|
||||
static void syncNodeCandidate2Follower(SSyncNode* pSyncNode);
|
||||
static int32_t syncNodeOnClientRequestCb(SSyncNode* ths, SyncClientRequest* pMsg);
|
||||
// ---------------------------------
|
||||
|
||||
int32_t syncInit() {
|
||||
sTrace("syncInit ok");
|
||||
return 0;
|
||||
int32_t ret = syncEnvStart();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void syncCleanUp() { sTrace("syncCleanUp ok"); }
|
||||
void syncCleanUp() {
|
||||
int32_t ret = syncEnvStop();
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
int64_t syncStart(const SSyncInfo* pSyncInfo) {
|
||||
int32_t ret = 0;
|
||||
SSyncNode* pSyncNode = syncNodeOpen(pSyncInfo);
|
||||
assert(pSyncNode != NULL);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void syncStop(int64_t rid) {
|
||||
|
@ -65,9 +67,13 @@ void syncStop(int64_t rid) {
|
|||
syncNodeClose(pSyncNode);
|
||||
}
|
||||
|
||||
int32_t syncReconfig(int64_t rid, const SSyncCfg* pSyncCfg) { return 0; }
|
||||
int32_t syncReconfig(int64_t rid, const SSyncCfg* pSyncCfg) {
|
||||
int32_t ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncForwardToPeer(int64_t rid, const SRpcMsg* pMsg, bool isWeak) {
|
||||
int32_t ret = 0;
|
||||
SSyncNode* pSyncNode = NULL; // get pointer from rid
|
||||
if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
||||
SyncClientRequest* pSyncMsg = syncClientRequestBuild2(pMsg, 0, isWeak);
|
||||
|
@ -75,11 +81,13 @@ int32_t syncForwardToPeer(int64_t rid, const SRpcMsg* pMsg, bool isWeak) {
|
|||
syncClientRequest2RpcMsg(pSyncMsg, &rpcMsg);
|
||||
pSyncNode->FpEqMsg(pSyncNode->queue, &rpcMsg);
|
||||
syncClientRequestDestroy(pSyncMsg);
|
||||
ret = 0;
|
||||
|
||||
} else {
|
||||
sTrace("syncForwardToPeer not leader, %s", syncUtilState2String(pSyncNode->state));
|
||||
return -1; // need define err code !!
|
||||
ret = -1; // need define err code !!
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ESyncState syncGetMyRole(int64_t rid) {
|
||||
|
@ -89,6 +97,7 @@ ESyncState syncGetMyRole(int64_t rid) {
|
|||
|
||||
void syncGetNodesRole(int64_t rid, SNodesRole* pNodeRole) {}
|
||||
|
||||
// open/close --------------
|
||||
SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) {
|
||||
SSyncNode* pSyncNode = (SSyncNode*)malloc(sizeof(SSyncNode));
|
||||
assert(pSyncNode != NULL);
|
||||
|
@ -162,7 +171,7 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) {
|
|||
pSyncNode->pingTimerMS = PING_TIMER_MS;
|
||||
atomic_store_64(&pSyncNode->pingTimerLogicClock, 0);
|
||||
atomic_store_64(&pSyncNode->pingTimerLogicClockUser, 0);
|
||||
pSyncNode->FpPingTimer = syncNodeEqPingTimer;
|
||||
pSyncNode->FpPingTimerCB = syncNodeEqPingTimer;
|
||||
pSyncNode->pingTimerCounter = 0;
|
||||
|
||||
// init elect timer
|
||||
|
@ -170,7 +179,7 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) {
|
|||
pSyncNode->electTimerMS = syncUtilElectRandomMS();
|
||||
atomic_store_64(&pSyncNode->electTimerLogicClock, 0);
|
||||
atomic_store_64(&pSyncNode->electTimerLogicClockUser, 0);
|
||||
pSyncNode->FpElectTimer = syncNodeEqElectTimer;
|
||||
pSyncNode->FpElectTimerCB = syncNodeEqElectTimer;
|
||||
pSyncNode->electTimerCounter = 0;
|
||||
|
||||
// init heartbeat timer
|
||||
|
@ -178,12 +187,13 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) {
|
|||
pSyncNode->heartbeatTimerMS = HEARTBEAT_TIMER_MS;
|
||||
atomic_store_64(&pSyncNode->heartbeatTimerLogicClock, 0);
|
||||
atomic_store_64(&pSyncNode->heartbeatTimerLogicClockUser, 0);
|
||||
pSyncNode->FpHeartbeatTimer = syncNodeEqHeartbeatTimer;
|
||||
pSyncNode->FpHeartbeatTimerCB = syncNodeEqHeartbeatTimer;
|
||||
pSyncNode->heartbeatTimerCounter = 0;
|
||||
|
||||
// init callback
|
||||
pSyncNode->FpOnPing = syncNodeOnPingCb;
|
||||
pSyncNode->FpOnPingReply = syncNodeOnPingReplyCb;
|
||||
pSyncNode->FpOnClientRequest = syncNodeOnClientRequestCb;
|
||||
pSyncNode->FpOnRequestVote = syncNodeOnRequestVoteCb;
|
||||
pSyncNode->FpOnRequestVoteReply = syncNodeOnRequestVoteReplyCb;
|
||||
pSyncNode->FpOnAppendEntries = syncNodeOnAppendEntriesCb;
|
||||
|
@ -194,10 +204,153 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pSyncInfo) {
|
|||
}
|
||||
|
||||
void syncNodeClose(SSyncNode* pSyncNode) {
|
||||
int32_t ret;
|
||||
assert(pSyncNode != NULL);
|
||||
|
||||
ret = raftStoreClose(pSyncNode->pRaftStore);
|
||||
assert(ret == 0);
|
||||
|
||||
voteGrantedDestroy(pSyncNode->pVotesGranted);
|
||||
votesRespondDestory(pSyncNode->pVotesRespond);
|
||||
syncIndexMgrDestroy(pSyncNode->pNextIndex);
|
||||
syncIndexMgrDestroy(pSyncNode->pMatchIndex);
|
||||
logStoreDestory(pSyncNode->pLogStore);
|
||||
|
||||
syncNodeStopPingTimer(pSyncNode);
|
||||
syncNodeStopElectTimer(pSyncNode);
|
||||
syncNodeStopHeartbeatTimer(pSyncNode);
|
||||
|
||||
free(pSyncNode);
|
||||
}
|
||||
|
||||
// ping --------------
|
||||
int32_t syncNodePing(SSyncNode* pSyncNode, const SRaftId* destRaftId, SyncPing* pMsg) {
|
||||
syncPingLog2((char*)"==syncNodePing==", pMsg);
|
||||
int32_t ret = 0;
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncPing2RpcMsg(pMsg, &rpcMsg);
|
||||
syncRpcMsgLog2((char*)"==syncNodePing==", &rpcMsg);
|
||||
|
||||
ret = syncNodeSendMsgById(destRaftId, pSyncNode, &rpcMsg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodePingSelf(SSyncNode* pSyncNode) {
|
||||
int32_t ret = 0;
|
||||
SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &pSyncNode->myRaftId);
|
||||
ret = syncNodePing(pSyncNode, &pMsg->destId, pMsg);
|
||||
assert(ret == 0);
|
||||
|
||||
syncPingDestroy(pMsg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodePingPeers(SSyncNode* pSyncNode) {
|
||||
int32_t ret = 0;
|
||||
for (int i = 0; i < pSyncNode->peersNum; ++i) {
|
||||
SRaftId destId;
|
||||
syncUtilnodeInfo2raftId(&pSyncNode->peersNodeInfo[i], pSyncNode->vgId, &destId);
|
||||
SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &destId);
|
||||
ret = syncNodePing(pSyncNode, &destId, pMsg);
|
||||
assert(ret == 0);
|
||||
syncPingDestroy(pMsg);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodePingAll(SSyncNode* pSyncNode) {
|
||||
int32_t ret = 0;
|
||||
for (int i = 0; i < pSyncNode->syncCfg.replicaNum; ++i) {
|
||||
SRaftId destId;
|
||||
syncUtilnodeInfo2raftId(&pSyncNode->syncCfg.nodeInfo[i], pSyncNode->vgId, &destId);
|
||||
SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &destId);
|
||||
ret = syncNodePing(pSyncNode, &destId, pMsg);
|
||||
assert(ret == 0);
|
||||
syncPingDestroy(pMsg);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// timer control --------------
|
||||
int32_t syncNodeStartPingTimer(SSyncNode* pSyncNode) {
|
||||
int32_t ret = 0;
|
||||
taosTmrReset(pSyncNode->FpPingTimerCB, pSyncNode->pingTimerMS, pSyncNode, gSyncEnv->pTimerManager,
|
||||
&pSyncNode->pPingTimer);
|
||||
atomic_store_64(&pSyncNode->pingTimerLogicClock, pSyncNode->pingTimerLogicClockUser);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodeStopPingTimer(SSyncNode* pSyncNode) {
|
||||
int32_t ret = 0;
|
||||
atomic_add_fetch_64(&pSyncNode->pingTimerLogicClockUser, 1);
|
||||
taosTmrStop(pSyncNode->pPingTimer);
|
||||
pSyncNode->pPingTimer = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodeStartElectTimer(SSyncNode* pSyncNode, int32_t ms) {
|
||||
int32_t ret = 0;
|
||||
pSyncNode->electTimerMS = ms;
|
||||
taosTmrReset(pSyncNode->FpElectTimerCB, pSyncNode->electTimerMS, pSyncNode, gSyncEnv->pTimerManager,
|
||||
&pSyncNode->pElectTimer);
|
||||
atomic_store_64(&pSyncNode->electTimerLogicClock, pSyncNode->electTimerLogicClockUser);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodeStopElectTimer(SSyncNode* pSyncNode) {
|
||||
int32_t ret = 0;
|
||||
atomic_add_fetch_64(&pSyncNode->electTimerLogicClockUser, 1);
|
||||
taosTmrStop(pSyncNode->pElectTimer);
|
||||
pSyncNode->pElectTimer = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodeRestartElectTimer(SSyncNode* pSyncNode, int32_t ms) {
|
||||
int32_t ret = 0;
|
||||
syncNodeStopElectTimer(pSyncNode);
|
||||
syncNodeStartElectTimer(pSyncNode, ms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodeResetElectTimer(SSyncNode* pSyncNode) {
|
||||
int32_t ret = 0;
|
||||
int32_t electMS = syncUtilElectRandomMS();
|
||||
ret = syncNodeRestartElectTimer(pSyncNode, electMS);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodeStartHeartbeatTimer(SSyncNode* pSyncNode) {
|
||||
int32_t ret = 0;
|
||||
taosTmrReset(pSyncNode->FpHeartbeatTimerCB, pSyncNode->heartbeatTimerMS, pSyncNode, gSyncEnv->pTimerManager,
|
||||
&pSyncNode->pHeartbeatTimer);
|
||||
atomic_store_64(&pSyncNode->heartbeatTimerLogicClock, pSyncNode->heartbeatTimerLogicClockUser);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodeStopHeartbeatTimer(SSyncNode* pSyncNode) {
|
||||
int32_t ret = 0;
|
||||
atomic_add_fetch_64(&pSyncNode->heartbeatTimerLogicClockUser, 1);
|
||||
taosTmrStop(pSyncNode->pHeartbeatTimer);
|
||||
pSyncNode->pHeartbeatTimer = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// utils --------------
|
||||
int32_t syncNodeSendMsgById(const SRaftId* destRaftId, SSyncNode* pSyncNode, SRpcMsg* pMsg) {
|
||||
SEpSet epSet;
|
||||
syncUtilraftId2EpSet(destRaftId, &epSet);
|
||||
pSyncNode->FpSendMsg(pSyncNode->rpcClient, &epSet, pMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t syncNodeSendMsgByInfo(const SNodeInfo* nodeInfo, SSyncNode* pSyncNode, SRpcMsg* pMsg) {
|
||||
SEpSet epSet;
|
||||
syncUtilnodeInfo2EpSet(nodeInfo, &epSet);
|
||||
pSyncNode->FpSendMsg(pSyncNode->rpcClient, &epSet, pMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cJSON* syncNode2Json(const SSyncNode* pSyncNode) {
|
||||
char u64buf[128];
|
||||
cJSON* pRoot = cJSON_CreateObject();
|
||||
|
@ -253,12 +406,22 @@ cJSON* syncNode2Json(const SSyncNode* pSyncNode) {
|
|||
// tla+ server vars
|
||||
cJSON_AddNumberToObject(pRoot, "state", pSyncNode->state);
|
||||
cJSON_AddStringToObject(pRoot, "state_str", syncUtilState2String(pSyncNode->state));
|
||||
char tmpBuf[RAFT_STORE_BLOCK_SIZE];
|
||||
raftStoreSerialize(pSyncNode->pRaftStore, tmpBuf, sizeof(tmpBuf));
|
||||
cJSON_AddStringToObject(pRoot, "pRaftStore", tmpBuf);
|
||||
|
||||
// tla+ candidate vars
|
||||
cJSON_AddItemToObject(pRoot, "pVotesGranted", voteGranted2Json(pSyncNode->pVotesGranted));
|
||||
cJSON_AddItemToObject(pRoot, "pVotesRespond", votesRespond2Json(pSyncNode->pVotesRespond));
|
||||
|
||||
// tla+ leader vars
|
||||
cJSON_AddItemToObject(pRoot, "pNextIndex", syncIndexMgr2Json(pSyncNode->pNextIndex));
|
||||
cJSON_AddItemToObject(pRoot, "pMatchIndex", syncIndexMgr2Json(pSyncNode->pMatchIndex));
|
||||
|
||||
// tla+ log vars
|
||||
cJSON_AddItemToObject(pRoot, "pLogStore", logStore2Json(pSyncNode->pLogStore));
|
||||
snprintf(u64buf, sizeof(u64buf), "%ld", pSyncNode->commitIndex);
|
||||
cJSON_AddStringToObject(pRoot, "commitIndex", u64buf);
|
||||
|
||||
// ping timer
|
||||
snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->pPingTimer);
|
||||
|
@ -268,8 +431,8 @@ cJSON* syncNode2Json(const SSyncNode* pSyncNode) {
|
|||
cJSON_AddStringToObject(pRoot, "pingTimerLogicClock", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->pingTimerLogicClockUser);
|
||||
cJSON_AddStringToObject(pRoot, "pingTimerLogicClockUser", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpPingTimer);
|
||||
cJSON_AddStringToObject(pRoot, "FpPingTimer", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpPingTimerCB);
|
||||
cJSON_AddStringToObject(pRoot, "FpPingTimerCB", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->pingTimerCounter);
|
||||
cJSON_AddStringToObject(pRoot, "pingTimerCounter", u64buf);
|
||||
|
||||
|
@ -281,8 +444,8 @@ cJSON* syncNode2Json(const SSyncNode* pSyncNode) {
|
|||
cJSON_AddStringToObject(pRoot, "electTimerLogicClock", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->electTimerLogicClockUser);
|
||||
cJSON_AddStringToObject(pRoot, "electTimerLogicClockUser", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpElectTimer);
|
||||
cJSON_AddStringToObject(pRoot, "FpElectTimer", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpElectTimerCB);
|
||||
cJSON_AddStringToObject(pRoot, "FpElectTimerCB", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->electTimerCounter);
|
||||
cJSON_AddStringToObject(pRoot, "electTimerCounter", u64buf);
|
||||
|
||||
|
@ -294,8 +457,8 @@ cJSON* syncNode2Json(const SSyncNode* pSyncNode) {
|
|||
cJSON_AddStringToObject(pRoot, "heartbeatTimerLogicClock", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->heartbeatTimerLogicClockUser);
|
||||
cJSON_AddStringToObject(pRoot, "heartbeatTimerLogicClockUser", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpHeartbeatTimer);
|
||||
cJSON_AddStringToObject(pRoot, "FpHeartbeatTimer", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%p", pSyncNode->FpHeartbeatTimerCB);
|
||||
cJSON_AddStringToObject(pRoot, "FpHeartbeatTimerCB", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pSyncNode->heartbeatTimerCounter);
|
||||
cJSON_AddStringToObject(pRoot, "heartbeatTimerCounter", u64buf);
|
||||
|
||||
|
@ -327,6 +490,107 @@ char* syncNode2Str(const SSyncNode* pSyncNode) {
|
|||
return serialized;
|
||||
}
|
||||
|
||||
// raft state change --------------
|
||||
void syncNodeUpdateTerm(SSyncNode* pSyncNode, SyncTerm term) {
|
||||
if (term > pSyncNode->pRaftStore->currentTerm) {
|
||||
raftStoreSetTerm(pSyncNode->pRaftStore, term);
|
||||
syncNodeBecomeFollower(pSyncNode);
|
||||
raftStoreClearVote(pSyncNode->pRaftStore);
|
||||
}
|
||||
}
|
||||
|
||||
void syncNodeBecomeFollower(SSyncNode* pSyncNode) {
|
||||
if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
||||
pSyncNode->leaderCache = EMPTY_RAFT_ID;
|
||||
}
|
||||
|
||||
pSyncNode->state = TAOS_SYNC_STATE_FOLLOWER;
|
||||
syncNodeStopHeartbeatTimer(pSyncNode);
|
||||
|
||||
int32_t electMS = syncUtilElectRandomMS();
|
||||
syncNodeRestartElectTimer(pSyncNode, electMS);
|
||||
}
|
||||
|
||||
// TLA+ Spec
|
||||
// \* Candidate i transitions to leader.
|
||||
// BecomeLeader(i) ==
|
||||
// /\ state[i] = Candidate
|
||||
// /\ votesGranted[i] \in Quorum
|
||||
// /\ state' = [state EXCEPT ![i] = Leader]
|
||||
// /\ nextIndex' = [nextIndex EXCEPT ![i] =
|
||||
// [j \in Server |-> Len(log[i]) + 1]]
|
||||
// /\ matchIndex' = [matchIndex EXCEPT ![i] =
|
||||
// [j \in Server |-> 0]]
|
||||
// /\ elections' = elections \cup
|
||||
// {[eterm |-> currentTerm[i],
|
||||
// eleader |-> i,
|
||||
// elog |-> log[i],
|
||||
// evotes |-> votesGranted[i],
|
||||
// evoterLog |-> voterLog[i]]}
|
||||
// /\ UNCHANGED <<messages, currentTerm, votedFor, candidateVars, logVars>>
|
||||
//
|
||||
void syncNodeBecomeLeader(SSyncNode* pSyncNode) {
|
||||
pSyncNode->state = TAOS_SYNC_STATE_LEADER;
|
||||
pSyncNode->leaderCache = pSyncNode->myRaftId;
|
||||
|
||||
for (int i = 0; i < pSyncNode->pNextIndex->replicaNum; ++i) {
|
||||
pSyncNode->pNextIndex->index[i] = pSyncNode->pLogStore->getLastIndex(pSyncNode->pLogStore) + 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < pSyncNode->pMatchIndex->replicaNum; ++i) {
|
||||
pSyncNode->pMatchIndex->index[i] = SYNC_INDEX_INVALID;
|
||||
}
|
||||
|
||||
syncNodeStopElectTimer(pSyncNode);
|
||||
syncNodeStartHeartbeatTimer(pSyncNode);
|
||||
syncNodeReplicate(pSyncNode);
|
||||
}
|
||||
|
||||
void syncNodeCandidate2Leader(SSyncNode* pSyncNode) {
|
||||
assert(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE);
|
||||
assert(voteGrantedMajority(pSyncNode->pVotesGranted));
|
||||
syncNodeBecomeLeader(pSyncNode);
|
||||
}
|
||||
|
||||
void syncNodeFollower2Candidate(SSyncNode* pSyncNode) {
|
||||
assert(pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER);
|
||||
pSyncNode->state = TAOS_SYNC_STATE_CANDIDATE;
|
||||
}
|
||||
|
||||
void syncNodeLeader2Follower(SSyncNode* pSyncNode) {
|
||||
assert(pSyncNode->state == TAOS_SYNC_STATE_LEADER);
|
||||
syncNodeBecomeFollower(pSyncNode);
|
||||
}
|
||||
|
||||
void syncNodeCandidate2Follower(SSyncNode* pSyncNode) {
|
||||
assert(pSyncNode->state == TAOS_SYNC_STATE_CANDIDATE);
|
||||
syncNodeBecomeFollower(pSyncNode);
|
||||
}
|
||||
|
||||
// raft vote --------------
|
||||
void syncNodeVoteForTerm(SSyncNode* pSyncNode, SyncTerm term, SRaftId* pRaftId) {
|
||||
assert(term == pSyncNode->pRaftStore->currentTerm);
|
||||
assert(!raftStoreHasVoted(pSyncNode->pRaftStore));
|
||||
|
||||
raftStoreVote(pSyncNode->pRaftStore, pRaftId);
|
||||
}
|
||||
|
||||
void syncNodeVoteForSelf(SSyncNode* pSyncNode) {
|
||||
syncNodeVoteForTerm(pSyncNode, pSyncNode->pRaftStore->currentTerm, &(pSyncNode->myRaftId));
|
||||
|
||||
SyncRequestVoteReply* pMsg = syncRequestVoteReplyBuild();
|
||||
pMsg->srcId = pSyncNode->myRaftId;
|
||||
pMsg->destId = pSyncNode->myRaftId;
|
||||
pMsg->term = pSyncNode->pRaftStore->currentTerm;
|
||||
pMsg->voteGranted = true;
|
||||
|
||||
voteGrantedVote(pSyncNode->pVotesGranted, pMsg);
|
||||
votesRespondAdd(pSyncNode->pVotesRespond, pMsg);
|
||||
syncRequestVoteReplyDestroy(pMsg);
|
||||
}
|
||||
|
||||
void syncNodeMaybeAdvanceCommitIndex(SSyncNode* pSyncNode) {}
|
||||
|
||||
// for debug --------------
|
||||
void syncNodePrint(SSyncNode* pObj) {
|
||||
char* serialized = syncNode2Str(pObj);
|
||||
|
@ -354,199 +618,24 @@ void syncNodeLog2(char* s, SSyncNode* pObj) {
|
|||
free(serialized);
|
||||
}
|
||||
|
||||
int32_t syncNodeSendMsgById(const SRaftId* destRaftId, SSyncNode* pSyncNode, SRpcMsg* pMsg) {
|
||||
SEpSet epSet;
|
||||
syncUtilraftId2EpSet(destRaftId, &epSet);
|
||||
pSyncNode->FpSendMsg(pSyncNode->rpcClient, &epSet, pMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t syncNodeSendMsgByInfo(const SNodeInfo* nodeInfo, SSyncNode* pSyncNode, SRpcMsg* pMsg) {
|
||||
SEpSet epSet;
|
||||
syncUtilnodeInfo2EpSet(nodeInfo, &epSet);
|
||||
pSyncNode->FpSendMsg(pSyncNode->rpcClient, &epSet, pMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t syncNodePing(SSyncNode* pSyncNode, const SRaftId* destRaftId, SyncPing* pMsg) {
|
||||
sTrace("syncNodePing pSyncNode:%p ", pSyncNode);
|
||||
int32_t ret = 0;
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncPing2RpcMsg(pMsg, &rpcMsg);
|
||||
syncNodeSendMsgById(destRaftId, pSyncNode, &rpcMsg);
|
||||
|
||||
{
|
||||
cJSON* pJson = syncPing2Json(pMsg);
|
||||
char* serialized = cJSON_Print(pJson);
|
||||
sTrace("syncNodePing pMsg:%s ", serialized);
|
||||
free(serialized);
|
||||
cJSON_Delete(pJson);
|
||||
}
|
||||
|
||||
{
|
||||
SyncPing* pMsg2 = rpcMsg.pCont;
|
||||
cJSON* pJson = syncPing2Json(pMsg2);
|
||||
char* serialized = cJSON_Print(pJson);
|
||||
sTrace("syncNodePing rpcMsg.pCont:%s ", serialized);
|
||||
free(serialized);
|
||||
cJSON_Delete(pJson);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncNodePingAll(SSyncNode* pSyncNode) {
|
||||
sTrace("syncNodePingAll pSyncNode:%p ", pSyncNode);
|
||||
int32_t ret = 0;
|
||||
for (int i = 0; i < pSyncNode->syncCfg.replicaNum; ++i) {
|
||||
SRaftId destId;
|
||||
syncUtilnodeInfo2raftId(&pSyncNode->syncCfg.nodeInfo[i], pSyncNode->vgId, &destId);
|
||||
SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &destId);
|
||||
ret = syncNodePing(pSyncNode, &destId, pMsg);
|
||||
assert(ret == 0);
|
||||
syncPingDestroy(pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t syncNodePingPeers(SSyncNode* pSyncNode) {
|
||||
int32_t ret = 0;
|
||||
for (int i = 0; i < pSyncNode->peersNum; ++i) {
|
||||
SRaftId destId;
|
||||
syncUtilnodeInfo2raftId(&pSyncNode->peersNodeInfo[i], pSyncNode->vgId, &destId);
|
||||
SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &destId);
|
||||
ret = syncNodePing(pSyncNode, &destId, pMsg);
|
||||
assert(ret == 0);
|
||||
syncPingDestroy(pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t syncNodePingSelf(SSyncNode* pSyncNode) {
|
||||
int32_t ret;
|
||||
SyncPing* pMsg = syncPingBuild3(&pSyncNode->myRaftId, &pSyncNode->myRaftId);
|
||||
ret = syncNodePing(pSyncNode, &pMsg->destId, pMsg);
|
||||
assert(ret == 0);
|
||||
syncPingDestroy(pMsg);
|
||||
}
|
||||
|
||||
int32_t syncNodeStartPingTimer(SSyncNode* pSyncNode) {
|
||||
atomic_store_64(&pSyncNode->pingTimerLogicClock, pSyncNode->pingTimerLogicClockUser);
|
||||
pSyncNode->pingTimerMS = PING_TIMER_MS;
|
||||
if (pSyncNode->pPingTimer == NULL) {
|
||||
pSyncNode->pPingTimer =
|
||||
taosTmrStart(pSyncNode->FpPingTimer, pSyncNode->pingTimerMS, pSyncNode, gSyncEnv->pTimerManager);
|
||||
} else {
|
||||
taosTmrReset(pSyncNode->FpPingTimer, pSyncNode->pingTimerMS, pSyncNode, gSyncEnv->pTimerManager,
|
||||
&pSyncNode->pPingTimer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t syncNodeStopPingTimer(SSyncNode* pSyncNode) {
|
||||
atomic_add_fetch_64(&pSyncNode->pingTimerLogicClockUser, 1);
|
||||
pSyncNode->pingTimerMS = TIMER_MAX_MS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t syncNodeStartElectTimer(SSyncNode* pSyncNode, int32_t ms) {
|
||||
pSyncNode->electTimerMS = ms;
|
||||
atomic_store_64(&pSyncNode->electTimerLogicClock, pSyncNode->electTimerLogicClockUser);
|
||||
if (pSyncNode->pElectTimer == NULL) {
|
||||
pSyncNode->pElectTimer =
|
||||
taosTmrStart(pSyncNode->FpElectTimer, pSyncNode->electTimerMS, pSyncNode, gSyncEnv->pTimerManager);
|
||||
} else {
|
||||
taosTmrReset(pSyncNode->FpElectTimer, pSyncNode->electTimerMS, pSyncNode, gSyncEnv->pTimerManager,
|
||||
&pSyncNode->pElectTimer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t syncNodeStopElectTimer(SSyncNode* pSyncNode) {
|
||||
atomic_add_fetch_64(&pSyncNode->electTimerLogicClockUser, 1);
|
||||
pSyncNode->electTimerMS = TIMER_MAX_MS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t syncNodeRestartElectTimer(SSyncNode* pSyncNode, int32_t ms) {
|
||||
syncNodeStopElectTimer(pSyncNode);
|
||||
syncNodeStartElectTimer(pSyncNode, ms);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t syncNodeStartHeartbeatTimer(SSyncNode* pSyncNode) {
|
||||
atomic_store_64(&pSyncNode->heartbeatTimerLogicClock, pSyncNode->heartbeatTimerLogicClockUser);
|
||||
if (pSyncNode->pHeartbeatTimer == NULL) {
|
||||
pSyncNode->pHeartbeatTimer =
|
||||
taosTmrStart(pSyncNode->FpHeartbeatTimer, pSyncNode->heartbeatTimerMS, pSyncNode, gSyncEnv->pTimerManager);
|
||||
} else {
|
||||
taosTmrReset(pSyncNode->FpHeartbeatTimer, pSyncNode->heartbeatTimerMS, pSyncNode, gSyncEnv->pTimerManager,
|
||||
&pSyncNode->pHeartbeatTimer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t syncNodeStopHeartbeatTimer(SSyncNode* pSyncNode) {
|
||||
atomic_add_fetch_64(&pSyncNode->heartbeatTimerLogicClockUser, 1);
|
||||
pSyncNode->heartbeatTimerMS = TIMER_MAX_MS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------ local funciton ---------
|
||||
static int32_t syncNodeOnPingCb(SSyncNode* ths, SyncPing* pMsg) {
|
||||
int32_t ret = 0;
|
||||
sTrace("<-- syncNodeOnPingCb -->");
|
||||
|
||||
{
|
||||
cJSON* pJson = syncPing2Json(pMsg);
|
||||
char* serialized = cJSON_Print(pJson);
|
||||
sTrace("process syncMessage recv: syncNodeOnPingCb pMsg:%s ", serialized);
|
||||
free(serialized);
|
||||
cJSON_Delete(pJson);
|
||||
}
|
||||
|
||||
SyncPingReply* pMsgReply = syncPingReplyBuild3(&ths->myRaftId, &pMsg->srcId);
|
||||
SRpcMsg rpcMsg;
|
||||
syncPingReply2RpcMsg(pMsgReply, &rpcMsg);
|
||||
syncNodeSendMsgById(&pMsgReply->destId, ths, &rpcMsg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t syncNodeOnPingReplyCb(SSyncNode* ths, SyncPingReply* pMsg) {
|
||||
int32_t ret = 0;
|
||||
sTrace("<-- syncNodeOnPingReplyCb -->");
|
||||
|
||||
{
|
||||
cJSON* pJson = syncPingReply2Json(pMsg);
|
||||
char* serialized = cJSON_Print(pJson);
|
||||
sTrace("process syncMessage recv: syncNodeOnPingReplyCb pMsg:%s ", serialized);
|
||||
free(serialized);
|
||||
cJSON_Delete(pJson);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// enqueue message ----
|
||||
static void syncNodeEqPingTimer(void* param, void* tmrId) {
|
||||
sTrace("<-- syncNodeEqPingTimer -->");
|
||||
|
||||
SSyncNode* pSyncNode = (SSyncNode*)param;
|
||||
if (atomic_load_64(&pSyncNode->pingTimerLogicClockUser) <= atomic_load_64(&pSyncNode->pingTimerLogicClock)) {
|
||||
SyncTimeout* pSyncMsg = syncTimeoutBuild2(SYNC_TIMEOUT_PING, atomic_load_64(&pSyncNode->pingTimerLogicClock),
|
||||
pSyncNode->pingTimerMS, pSyncNode);
|
||||
SRpcMsg rpcMsg;
|
||||
syncTimeout2RpcMsg(pSyncMsg, &rpcMsg);
|
||||
syncRpcMsgLog2((char*)"==syncNodeEqPingTimer==", &rpcMsg);
|
||||
pSyncNode->FpEqMsg(pSyncNode->queue, &rpcMsg);
|
||||
syncTimeoutDestroy(pSyncMsg);
|
||||
|
||||
// reset timer ms
|
||||
// pSyncNode->pingTimerMS += 100;
|
||||
|
||||
taosTmrReset(syncNodeEqPingTimer, pSyncNode->pingTimerMS, pSyncNode, gSyncEnv->pTimerManager,
|
||||
&pSyncNode->pPingTimer);
|
||||
} else {
|
||||
sTrace("syncNodeEqPingTimer: pingTimerLogicClock:%lu, pingTimerLogicClockUser:%lu", pSyncNode->pingTimerLogicClock,
|
||||
pSyncNode->pingTimerLogicClockUser);
|
||||
sTrace("==syncNodeEqPingTimer== pingTimerLogicClock:%lu, pingTimerLogicClockUser:%lu",
|
||||
pSyncNode->pingTimerLogicClock, pSyncNode->pingTimerLogicClockUser);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -555,19 +644,18 @@ static void syncNodeEqElectTimer(void* param, void* tmrId) {
|
|||
if (atomic_load_64(&pSyncNode->electTimerLogicClockUser) <= atomic_load_64(&pSyncNode->electTimerLogicClock)) {
|
||||
SyncTimeout* pSyncMsg = syncTimeoutBuild2(SYNC_TIMEOUT_ELECTION, atomic_load_64(&pSyncNode->electTimerLogicClock),
|
||||
pSyncNode->electTimerMS, pSyncNode);
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncTimeout2RpcMsg(pSyncMsg, &rpcMsg);
|
||||
syncRpcMsgLog2((char*)"==syncNodeEqElectTimer==", &rpcMsg);
|
||||
pSyncNode->FpEqMsg(pSyncNode->queue, &rpcMsg);
|
||||
syncTimeoutDestroy(pSyncMsg);
|
||||
|
||||
// reset timer ms
|
||||
pSyncNode->electTimerMS = syncUtilElectRandomMS();
|
||||
|
||||
taosTmrReset(syncNodeEqPingTimer, pSyncNode->pingTimerMS, pSyncNode, gSyncEnv->pTimerManager,
|
||||
&pSyncNode->pPingTimer);
|
||||
} else {
|
||||
sTrace("syncNodeEqElectTimer: electTimerLogicClock:%lu, electTimerLogicClockUser:%lu",
|
||||
sTrace("==syncNodeEqElectTimer== electTimerLogicClock:%lu, electTimerLogicClockUser:%lu",
|
||||
pSyncNode->electTimerLogicClock, pSyncNode->electTimerLogicClockUser);
|
||||
}
|
||||
}
|
||||
|
@ -579,80 +667,50 @@ static void syncNodeEqHeartbeatTimer(void* param, void* tmrId) {
|
|||
SyncTimeout* pSyncMsg =
|
||||
syncTimeoutBuild2(SYNC_TIMEOUT_HEARTBEAT, atomic_load_64(&pSyncNode->heartbeatTimerLogicClock),
|
||||
pSyncNode->heartbeatTimerMS, pSyncNode);
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncTimeout2RpcMsg(pSyncMsg, &rpcMsg);
|
||||
syncRpcMsgLog2((char*)"==syncNodeEqHeartbeatTimer==", &rpcMsg);
|
||||
pSyncNode->FpEqMsg(pSyncNode->queue, &rpcMsg);
|
||||
syncTimeoutDestroy(pSyncMsg);
|
||||
|
||||
// reset timer ms
|
||||
// pSyncNode->heartbeatTimerMS += 100;
|
||||
|
||||
taosTmrReset(syncNodeEqHeartbeatTimer, pSyncNode->heartbeatTimerMS, pSyncNode, gSyncEnv->pTimerManager,
|
||||
&pSyncNode->pHeartbeatTimer);
|
||||
} else {
|
||||
sTrace("syncNodeEqHeartbeatTimer: heartbeatTimerLogicClock:%lu, heartbeatTimerLogicClockUser:%lu",
|
||||
sTrace("==syncNodeEqHeartbeatTimer== heartbeatTimerLogicClock:%lu, heartbeatTimerLogicClockUser:%lu",
|
||||
pSyncNode->heartbeatTimerLogicClock, pSyncNode->heartbeatTimerLogicClockUser);
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateTerm(SSyncNode* pSyncNode, SyncTerm term) {
|
||||
if (term > pSyncNode->pRaftStore->currentTerm) {
|
||||
pSyncNode->pRaftStore->currentTerm = term;
|
||||
pSyncNode->pRaftStore->voteFor = EMPTY_RAFT_ID;
|
||||
raftStorePersist(pSyncNode->pRaftStore);
|
||||
syncNodeBecomeFollower(pSyncNode);
|
||||
}
|
||||
// on message ----
|
||||
static int32_t syncNodeOnPingCb(SSyncNode* ths, SyncPing* pMsg) {
|
||||
int32_t ret = 0;
|
||||
syncPingLog2("==syncNodeOnPingCb==", pMsg);
|
||||
SyncPingReply* pMsgReply = syncPingReplyBuild3(&ths->myRaftId, &pMsg->srcId);
|
||||
SRpcMsg rpcMsg;
|
||||
syncPingReply2RpcMsg(pMsgReply, &rpcMsg);
|
||||
syncNodeSendMsgById(&pMsgReply->destId, ths, &rpcMsg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void syncNodeBecomeFollower(SSyncNode* pSyncNode) {
|
||||
if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
||||
pSyncNode->leaderCache = EMPTY_RAFT_ID;
|
||||
static int32_t syncNodeOnPingReplyCb(SSyncNode* ths, SyncPingReply* pMsg) {
|
||||
int32_t ret = 0;
|
||||
syncPingReplyLog2("==syncNodeOnPingReplyCb==", pMsg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t syncNodeOnClientRequestCb(SSyncNode* ths, SyncClientRequest* pMsg) {
|
||||
int32_t ret = 0;
|
||||
syncClientRequestLog2("==syncNodeOnClientRequestCb==", pMsg);
|
||||
|
||||
if (ths->state == TAOS_SYNC_STATE_LEADER) {
|
||||
SSyncRaftEntry* pEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen);
|
||||
ths->pLogStore->appendEntry(ths->pLogStore, pEntry);
|
||||
syncNodeReplicate(ths);
|
||||
syncEntryDestory(pEntry);
|
||||
} else {
|
||||
// ths->pFsm->FpCommitCb(-1)
|
||||
}
|
||||
|
||||
syncNodeStopHeartbeatTimer(pSyncNode);
|
||||
int32_t electMS = syncUtilElectRandomMS();
|
||||
syncNodeStartElectTimer(pSyncNode, electMS);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TLA+ Spec
|
||||
// \* Candidate i transitions to leader.
|
||||
// BecomeLeader(i) ==
|
||||
// /\ state[i] = Candidate
|
||||
// /\ votesGranted[i] \in Quorum
|
||||
// /\ state' = [state EXCEPT ![i] = Leader]
|
||||
// /\ nextIndex' = [nextIndex EXCEPT ![i] =
|
||||
// [j \in Server |-> Len(log[i]) + 1]]
|
||||
// /\ matchIndex' = [matchIndex EXCEPT ![i] =
|
||||
// [j \in Server |-> 0]]
|
||||
// /\ elections' = elections \cup
|
||||
// {[eterm |-> currentTerm[i],
|
||||
// eleader |-> i,
|
||||
// elog |-> log[i],
|
||||
// evotes |-> votesGranted[i],
|
||||
// evoterLog |-> voterLog[i]]}
|
||||
// /\ UNCHANGED <<messages, currentTerm, votedFor, candidateVars, logVars>>
|
||||
//
|
||||
static void syncNodeBecomeLeader(SSyncNode* pSyncNode) {
|
||||
pSyncNode->state = TAOS_SYNC_STATE_LEADER;
|
||||
pSyncNode->leaderCache = pSyncNode->myRaftId;
|
||||
|
||||
// next Index +=1
|
||||
// match Index = 0;
|
||||
|
||||
syncNodeStopElectTimer(pSyncNode);
|
||||
syncNodeStartHeartbeatTimer(pSyncNode);
|
||||
|
||||
// appendEntries;
|
||||
}
|
||||
|
||||
static void syncNodeFollower2Candidate(SSyncNode* pSyncNode) {
|
||||
assert(pSyncNode->state == TAOS_SYNC_STATE_FOLLOWER);
|
||||
pSyncNode->state = TAOS_SYNC_STATE_CANDIDATE;
|
||||
}
|
||||
|
||||
static void syncNodeCandidate2Leader(SSyncNode* pSyncNode) {}
|
||||
|
||||
static void syncNodeLeader2Follower(SSyncNode* pSyncNode) {}
|
||||
|
||||
static void syncNodeCandidate2Follower(SSyncNode* pSyncNode) {}
|
||||
|
|
|
@ -65,10 +65,32 @@ cJSON* syncRpcMsg2Json(SRpcMsg* pRpcMsg) {
|
|||
pRoot = syncAppendEntriesReply2Json(pSyncMsg);
|
||||
syncAppendEntriesReplyDestroy(pSyncMsg);
|
||||
|
||||
} else if (pRpcMsg->msgType == SYNC_RESPONSE) {
|
||||
pRoot = cJSON_CreateObject();
|
||||
char* s;
|
||||
s = syncUtilprintBin((char*)(pRpcMsg->pCont), pRpcMsg->contLen);
|
||||
cJSON_AddStringToObject(pRoot, "pCont", s);
|
||||
free(s);
|
||||
s = syncUtilprintBin2((char*)(pRpcMsg->pCont), pRpcMsg->contLen);
|
||||
cJSON_AddStringToObject(pRoot, "pCont2", s);
|
||||
free(s);
|
||||
|
||||
} else {
|
||||
pRoot = syncRpcUnknownMsg2Json();
|
||||
char* s;
|
||||
s = syncUtilprintBin((char*)(pRpcMsg->pCont), pRpcMsg->contLen);
|
||||
cJSON_AddStringToObject(pRoot, "pCont", s);
|
||||
free(s);
|
||||
s = syncUtilprintBin2((char*)(pRpcMsg->pCont), pRpcMsg->contLen);
|
||||
cJSON_AddStringToObject(pRoot, "pCont2", s);
|
||||
free(s);
|
||||
}
|
||||
|
||||
cJSON_AddNumberToObject(pRoot, "msgType", pRpcMsg->msgType);
|
||||
cJSON_AddNumberToObject(pRoot, "contLen", pRpcMsg->contLen);
|
||||
cJSON_AddNumberToObject(pRoot, "code", pRpcMsg->code);
|
||||
// cJSON_AddNumberToObject(pRoot, "persist", pRpcMsg->persist);
|
||||
|
||||
cJSON* pJson = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(pJson, "RpcMsg", pRoot);
|
||||
return pJson;
|
||||
|
@ -77,7 +99,7 @@ cJSON* syncRpcMsg2Json(SRpcMsg* pRpcMsg) {
|
|||
cJSON* syncRpcUnknownMsg2Json() {
|
||||
cJSON* pRoot = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(pRoot, "msgType", SYNC_UNKNOWN);
|
||||
cJSON_AddStringToObject(pRoot, "data", "known message");
|
||||
cJSON_AddStringToObject(pRoot, "data", "unknown message");
|
||||
|
||||
cJSON* pJson = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(pJson, "SyncUnknown", pRoot);
|
||||
|
@ -798,8 +820,8 @@ cJSON* syncRequestVote2Json(const SyncRequestVote* pMsg) {
|
|||
cJSON_AddNumberToObject(pDestId, "vgId", pMsg->destId.vgId);
|
||||
cJSON_AddItemToObject(pRoot, "destId", pDestId);
|
||||
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->currentTerm);
|
||||
cJSON_AddStringToObject(pRoot, "currentTerm", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->term);
|
||||
cJSON_AddStringToObject(pRoot, "term", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->lastLogIndex);
|
||||
cJSON_AddStringToObject(pRoot, "lastLogIndex", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->lastLogTerm);
|
||||
|
@ -1086,6 +1108,9 @@ cJSON* syncAppendEntries2Json(const SyncAppendEntries* pMsg) {
|
|||
cJSON_AddNumberToObject(pDestId, "vgId", pMsg->destId.vgId);
|
||||
cJSON_AddItemToObject(pRoot, "destId", pDestId);
|
||||
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->term);
|
||||
cJSON_AddStringToObject(pRoot, "term", u64buf);
|
||||
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->prevLogIndex);
|
||||
cJSON_AddStringToObject(pRoot, "pre_log_index", u64buf);
|
||||
|
||||
|
@ -1242,9 +1267,11 @@ cJSON* syncAppendEntriesReply2Json(const SyncAppendEntriesReply* pMsg) {
|
|||
cJSON_AddNumberToObject(pDestId, "vgId", pMsg->destId.vgId);
|
||||
cJSON_AddItemToObject(pRoot, "destId", pDestId);
|
||||
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->term);
|
||||
cJSON_AddStringToObject(pRoot, "term", u64buf);
|
||||
cJSON_AddNumberToObject(pRoot, "success", pMsg->success);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", pMsg->matchIndex);
|
||||
cJSON_AddStringToObject(pRoot, "match_index", u64buf);
|
||||
cJSON_AddStringToObject(pRoot, "matchIndex", u64buf);
|
||||
|
||||
cJSON* pJson = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(pJson, "SyncAppendEntriesReply", pRoot);
|
||||
|
|
|
@ -130,7 +130,7 @@ cJSON* logStore2Json(SSyncLogStore* pLogStore) {
|
|||
cJSON_AddStringToObject(pRoot, "pSyncNode", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%p", pData->pWal);
|
||||
cJSON_AddStringToObject(pRoot, "pWal", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", logStoreLastIndex(pLogStore));
|
||||
snprintf(u64buf, sizeof(u64buf), "%ld", logStoreLastIndex(pLogStore));
|
||||
cJSON_AddStringToObject(pRoot, "LastIndex", u64buf);
|
||||
snprintf(u64buf, sizeof(u64buf), "%lu", logStoreLastTerm(pLogStore));
|
||||
cJSON_AddStringToObject(pRoot, "LastTerm", u64buf);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#include "syncRaftStore.h"
|
||||
#include "cJSON.h"
|
||||
#include "syncEnv.h"
|
||||
#include "syncUtil.h"
|
||||
|
||||
// private function
|
||||
static int32_t raftStoreInit(SRaftStore *pRaftStore);
|
||||
|
@ -135,6 +137,33 @@ int32_t raftStoreDeserialize(SRaftStore *pRaftStore, char *buf, size_t len) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool raftStoreHasVoted(SRaftStore *pRaftStore) {
|
||||
bool b = syncUtilEmptyId(&(pRaftStore->voteFor));
|
||||
return b;
|
||||
}
|
||||
|
||||
void raftStoreVote(SRaftStore *pRaftStore, SRaftId *pRaftId) {
|
||||
assert(!raftStoreHasVoted(pRaftStore));
|
||||
assert(!syncUtilEmptyId(pRaftId));
|
||||
pRaftStore->voteFor = *pRaftId;
|
||||
raftStorePersist(pRaftStore);
|
||||
}
|
||||
|
||||
void raftStoreClearVote(SRaftStore *pRaftStore) {
|
||||
pRaftStore->voteFor = EMPTY_RAFT_ID;
|
||||
raftStorePersist(pRaftStore);
|
||||
}
|
||||
|
||||
void raftStoreNextTerm(SRaftStore *pRaftStore) {
|
||||
++(pRaftStore->currentTerm);
|
||||
raftStorePersist(pRaftStore);
|
||||
}
|
||||
|
||||
void raftStoreSetTerm(SRaftStore *pRaftStore, SyncTerm term) {
|
||||
pRaftStore->currentTerm = term;
|
||||
raftStorePersist(pRaftStore);
|
||||
}
|
||||
|
||||
// for debug -------------------
|
||||
void raftStorePrint(SRaftStore *pObj) {
|
||||
char serialized[RAFT_STORE_BLOCK_SIZE];
|
||||
|
|
|
@ -14,7 +14,11 @@
|
|||
*/
|
||||
|
||||
#include "syncReplication.h"
|
||||
#include "syncIndexMgr.h"
|
||||
#include "syncMessage.h"
|
||||
#include "syncRaftEntry.h"
|
||||
#include "syncRaftLog.h"
|
||||
#include "syncUtil.h"
|
||||
|
||||
// TLA+ Spec
|
||||
// AppendEntries(i, j) ==
|
||||
|
@ -42,7 +46,39 @@
|
|||
// /\ UNCHANGED <<serverVars, candidateVars, leaderVars, logVars>>
|
||||
//
|
||||
int32_t syncNodeAppendEntriesPeers(SSyncNode* pSyncNode) {
|
||||
assert(pSyncNode->state == TAOS_SYNC_STATE_LEADER);
|
||||
|
||||
int32_t ret = 0;
|
||||
for (int i = 0; i < pSyncNode->peersNum; ++i) {
|
||||
SRaftId* pDestId = &(pSyncNode->peersId[i]);
|
||||
SyncIndex nextIndex = syncIndexMgrGetIndex(pSyncNode->pNextIndex, pDestId);
|
||||
|
||||
SyncIndex preLogIndex = nextIndex - 1;
|
||||
|
||||
SyncTerm preLogTerm = 0;
|
||||
if (preLogIndex >= SYNC_INDEX_BEGIN) {
|
||||
SSyncRaftEntry* pPreEntry = pSyncNode->pLogStore->getEntry(pSyncNode->pLogStore, preLogIndex);
|
||||
preLogTerm = pPreEntry->term;
|
||||
}
|
||||
|
||||
SyncIndex lastIndex = syncUtilMinIndex(pSyncNode->pLogStore->getLastIndex(pSyncNode->pLogStore), nextIndex);
|
||||
assert(nextIndex == lastIndex);
|
||||
|
||||
SSyncRaftEntry* pEntry = logStoreGetEntry(pSyncNode->pLogStore, nextIndex);
|
||||
assert(pEntry != NULL);
|
||||
|
||||
SyncAppendEntries* pMsg = syncAppendEntriesBuild(pEntry->bytes);
|
||||
pMsg->srcId = pSyncNode->myRaftId;
|
||||
pMsg->destId = *pDestId;
|
||||
pMsg->prevLogIndex = preLogIndex;
|
||||
pMsg->prevLogTerm = preLogTerm;
|
||||
pMsg->commitIndex = pSyncNode->commitIndex;
|
||||
pMsg->dataLen = pEntry->bytes;
|
||||
// add pEntry into msg
|
||||
|
||||
syncNodeAppendEntries(pSyncNode, pDestId, pMsg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
*/
|
||||
|
||||
#include "syncRequestVote.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncRaftStore.h"
|
||||
#include "syncUtil.h"
|
||||
#include "syncVoteMgr.h"
|
||||
|
||||
// TLA+ Spec
|
||||
// HandleRequestVoteRequest(i, j, m) ==
|
||||
|
@ -37,4 +41,34 @@
|
|||
// m)
|
||||
// /\ UNCHANGED <<state, currentTerm, candidateVars, leaderVars, logVars>>
|
||||
//
|
||||
int32_t syncNodeOnRequestVoteCb(SSyncNode* ths, SyncRequestVote* pMsg) {}
|
||||
int32_t syncNodeOnRequestVoteCb(SSyncNode* ths, SyncRequestVote* pMsg) {
|
||||
int32_t ret = 0;
|
||||
syncRequestVoteLog2("==syncNodeOnRequestVoteCb==", pMsg);
|
||||
|
||||
if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||
syncNodeUpdateTerm(ths, pMsg->term);
|
||||
}
|
||||
assert(pMsg->term <= ths->pRaftStore->currentTerm);
|
||||
|
||||
bool logOK = (pMsg->lastLogTerm > ths->pLogStore->getLastTerm(ths->pLogStore)) ||
|
||||
((pMsg->lastLogTerm == ths->pLogStore->getLastTerm(ths->pLogStore)) &&
|
||||
(pMsg->lastLogIndex >= ths->pLogStore->getLastIndex(ths->pLogStore)));
|
||||
bool grant = (pMsg->term == ths->pRaftStore->currentTerm) && logOK &&
|
||||
((!raftStoreHasVoted(ths->pRaftStore)) || (syncUtilSameId(&(ths->pRaftStore->voteFor), &(pMsg->srcId))));
|
||||
if (grant) {
|
||||
raftStoreVote(ths->pRaftStore, &(pMsg->srcId));
|
||||
}
|
||||
|
||||
SyncRequestVoteReply* pReply = syncRequestVoteReplyBuild();
|
||||
pReply->srcId = ths->myRaftId;
|
||||
pReply->destId = pMsg->srcId;
|
||||
pReply->term = ths->pRaftStore->currentTerm;
|
||||
pReply->voteGranted = grant;
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncRequestVoteReply2RpcMsg(pReply, &rpcMsg);
|
||||
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||
syncRequestVoteReplyDestroy(pReply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
*/
|
||||
|
||||
#include "syncRequestVoteReply.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncRaftStore.h"
|
||||
#include "syncUtil.h"
|
||||
#include "syncVoteMgr.h"
|
||||
|
||||
// TLA+ Spec
|
||||
// HandleRequestVoteResponse(i, j, m) ==
|
||||
|
@ -32,4 +36,33 @@
|
|||
// /\ Discard(m)
|
||||
// /\ UNCHANGED <<serverVars, votedFor, leaderVars, logVars>>
|
||||
//
|
||||
int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg) {}
|
||||
int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg) {
|
||||
int32_t ret = 0;
|
||||
syncRequestVoteReplyLog2("==syncNodeOnRequestVoteReplyCb==", pMsg);
|
||||
|
||||
if (pMsg->term < ths->pRaftStore->currentTerm) {
|
||||
sTrace("DropStaleResponse, receive term:%lu, current term:%lu", pMsg->term, ths->pRaftStore->currentTerm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// no need this code, because if I receive reply.term, then I must have sent for that term.
|
||||
// if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||
// syncNodeUpdateTerm(ths, pMsg->term);
|
||||
// }
|
||||
|
||||
assert(pMsg->term == ths->pRaftStore->currentTerm);
|
||||
|
||||
if (ths->state == TAOS_SYNC_STATE_CANDIDATE) {
|
||||
votesRespondAdd(ths->pVotesRespond, pMsg);
|
||||
if (pMsg->voteGranted) {
|
||||
voteGrantedVote(ths->pVotesGranted, pMsg);
|
||||
if (voteGrantedMajority(ths->pVotesGranted)) {
|
||||
if (ths->pVotesGranted->toLeader) {
|
||||
syncNodeCandidate2Leader(ths);
|
||||
ths->pVotesGranted->toLeader = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -19,15 +19,7 @@
|
|||
|
||||
int32_t syncNodeOnTimeoutCb(SSyncNode* ths, SyncTimeout* pMsg) {
|
||||
int32_t ret = 0;
|
||||
sTrace("<-- syncNodeOnTimeoutCb -->");
|
||||
|
||||
{
|
||||
cJSON* pJson = syncTimeout2Json(pMsg);
|
||||
char* serialized = cJSON_Print(pJson);
|
||||
sTrace("process syncMessage recv: syncNodeOnTimeoutCb pMsg:%s ", serialized);
|
||||
free(serialized);
|
||||
cJSON_Delete(pJson);
|
||||
}
|
||||
syncTimeoutLog2("==syncNodeOnTimeoutCb==", pMsg);
|
||||
|
||||
if (pMsg->timeoutType == SYNC_TIMEOUT_PING) {
|
||||
if (atomic_load_64(&ths->pingTimerLogicClockUser) <= pMsg->logicClock) {
|
||||
|
|
|
@ -74,6 +74,8 @@ bool syncUtilSameId(const SRaftId* pId1, const SRaftId* pId2) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool syncUtilEmptyId(const SRaftId* pId) { return (pId->addr == 0 && pId->vgId == 0); }
|
||||
|
||||
// ---- SSyncBuffer -----
|
||||
void syncUtilbufBuild(SSyncBuffer* syncBuf, size_t len) {
|
||||
syncBuf->len = len;
|
||||
|
@ -185,3 +187,13 @@ char* syncUtilprintBin2(char* ptr, uint32_t len) {
|
|||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
SyncIndex syncUtilMinIndex(SyncIndex a, SyncIndex b) {
|
||||
SyncIndex r = a < b ? a : b;
|
||||
return r;
|
||||
}
|
||||
|
||||
SyncIndex syncUtilMaxIndex(SyncIndex a, SyncIndex b) {
|
||||
SyncIndex r = a > b ? a : b;
|
||||
return r;
|
||||
}
|
|
@ -4,8 +4,8 @@ add_executable(syncPingTimerTest "")
|
|||
add_executable(syncIOTickQTest "")
|
||||
add_executable(syncIOTickPingTest "")
|
||||
add_executable(syncIOSendMsgTest "")
|
||||
add_executable(syncIOSendMsgClientTest "")
|
||||
add_executable(syncIOSendMsgServerTest "")
|
||||
add_executable(syncIOClientTest "")
|
||||
add_executable(syncIOServerTest "")
|
||||
add_executable(syncRaftStoreTest "")
|
||||
add_executable(syncEnqTest "")
|
||||
add_executable(syncIndexTest "")
|
||||
|
@ -51,13 +51,13 @@ target_sources(syncIOSendMsgTest
|
|||
PRIVATE
|
||||
"syncIOSendMsgTest.cpp"
|
||||
)
|
||||
target_sources(syncIOSendMsgClientTest
|
||||
target_sources(syncIOClientTest
|
||||
PRIVATE
|
||||
"syncIOSendMsgClientTest.cpp"
|
||||
"syncIOClientTest.cpp"
|
||||
)
|
||||
target_sources(syncIOSendMsgServerTest
|
||||
target_sources(syncIOServerTest
|
||||
PRIVATE
|
||||
"syncIOSendMsgServerTest.cpp"
|
||||
"syncIOServerTest.cpp"
|
||||
)
|
||||
target_sources(syncRaftStoreTest
|
||||
PRIVATE
|
||||
|
@ -167,12 +167,12 @@ target_include_directories(syncIOSendMsgTest
|
|||
"${CMAKE_SOURCE_DIR}/include/libs/sync"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||
)
|
||||
target_include_directories(syncIOSendMsgClientTest
|
||||
target_include_directories(syncIOClientTest
|
||||
PUBLIC
|
||||
"${CMAKE_SOURCE_DIR}/include/libs/sync"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||
)
|
||||
target_include_directories(syncIOSendMsgServerTest
|
||||
target_include_directories(syncIOServerTest
|
||||
PUBLIC
|
||||
"${CMAKE_SOURCE_DIR}/include/libs/sync"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||
|
@ -298,11 +298,11 @@ target_link_libraries(syncIOSendMsgTest
|
|||
sync
|
||||
gtest_main
|
||||
)
|
||||
target_link_libraries(syncIOSendMsgClientTest
|
||||
target_link_libraries(syncIOClientTest
|
||||
sync
|
||||
gtest_main
|
||||
)
|
||||
target_link_libraries(syncIOSendMsgServerTest
|
||||
target_link_libraries(syncIOServerTest
|
||||
sync
|
||||
gtest_main
|
||||
)
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <stdio.h>
|
||||
#include "syncEnv.h"
|
||||
#include "syncIO.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncMessage.h"
|
||||
#include "syncRaftStore.h"
|
||||
#include "syncUtil.h"
|
||||
|
||||
void logTest() {
|
||||
sTrace("--- sync log test: trace");
|
||||
|
@ -14,64 +15,69 @@ void logTest() {
|
|||
sFatal("--- sync log test: fatal");
|
||||
}
|
||||
|
||||
uint16_t ports[3] = {7010, 7110, 7210};
|
||||
uint16_t ports[] = {7010, 7110, 7210, 7310, 7410};
|
||||
int32_t replicaNum = 5;
|
||||
int32_t myIndex = 0;
|
||||
|
||||
SSyncNode* doSync(int myIndex) {
|
||||
SSyncFSM* pFsm;
|
||||
SRaftId ids[TSDB_MAX_REPLICA];
|
||||
SSyncInfo syncInfo;
|
||||
SSyncFSM* pFsm;
|
||||
|
||||
SSyncInfo syncInfo;
|
||||
syncInfo.vgId = 1;
|
||||
SSyncNode* syncNodeInit() {
|
||||
syncInfo.vgId = 1234;
|
||||
syncInfo.rpcClient = gSyncIO->clientRpc;
|
||||
syncInfo.FpSendMsg = syncIOSendMsg;
|
||||
syncInfo.queue = gSyncIO->pMsgQ;
|
||||
syncInfo.FpEqMsg = syncIOEqMsg;
|
||||
syncInfo.pFsm = pFsm;
|
||||
snprintf(syncInfo.path, sizeof(syncInfo.path), "%s", "./test_sync_ping");
|
||||
snprintf(syncInfo.path, sizeof(syncInfo.path), "%s", "./");
|
||||
|
||||
SSyncCfg* pCfg = &syncInfo.syncCfg;
|
||||
pCfg->myIndex = myIndex;
|
||||
pCfg->replicaNum = 3;
|
||||
pCfg->replicaNum = replicaNum;
|
||||
|
||||
pCfg->nodeInfo[0].nodePort = ports[0];
|
||||
snprintf(pCfg->nodeInfo[0].nodeFqdn, sizeof(pCfg->nodeInfo[0].nodeFqdn), "%s", "127.0.0.1");
|
||||
for (int i = 0; i < replicaNum; ++i) {
|
||||
pCfg->nodeInfo[i].nodePort = ports[i];
|
||||
snprintf(pCfg->nodeInfo[i].nodeFqdn, sizeof(pCfg->nodeInfo[i].nodeFqdn), "%s", "127.0.0.1");
|
||||
// taosGetFqdn(pCfg->nodeInfo[0].nodeFqdn);
|
||||
|
||||
pCfg->nodeInfo[1].nodePort = ports[1];
|
||||
snprintf(pCfg->nodeInfo[1].nodeFqdn, sizeof(pCfg->nodeInfo[1].nodeFqdn), "%s", "127.0.0.1");
|
||||
// taosGetFqdn(pCfg->nodeInfo[1].nodeFqdn);
|
||||
|
||||
pCfg->nodeInfo[2].nodePort = ports[2];
|
||||
snprintf(pCfg->nodeInfo[2].nodeFqdn, sizeof(pCfg->nodeInfo[2].nodeFqdn), "%s", "127.0.0.1");
|
||||
// taosGetFqdn(pCfg->nodeInfo[2].nodeFqdn);
|
||||
}
|
||||
|
||||
SSyncNode* pSyncNode = syncNodeOpen(&syncInfo);
|
||||
assert(pSyncNode != NULL);
|
||||
|
||||
gSyncIO->FpOnSyncPing = pSyncNode->FpOnPing;
|
||||
gSyncIO->FpOnSyncPingReply = pSyncNode->FpOnPingReply;
|
||||
gSyncIO->FpOnSyncRequestVote = pSyncNode->FpOnRequestVote;
|
||||
gSyncIO->FpOnSyncRequestVoteReply = pSyncNode->FpOnRequestVoteReply;
|
||||
gSyncIO->FpOnSyncAppendEntries = pSyncNode->FpOnAppendEntries;
|
||||
gSyncIO->FpOnSyncAppendEntriesReply = pSyncNode->FpOnAppendEntriesReply;
|
||||
gSyncIO->FpOnSyncPing = pSyncNode->FpOnPing;
|
||||
gSyncIO->FpOnSyncPingReply = pSyncNode->FpOnPingReply;
|
||||
gSyncIO->FpOnSyncTimeout = pSyncNode->FpOnTimeout;
|
||||
gSyncIO->pSyncNode = pSyncNode;
|
||||
|
||||
return pSyncNode;
|
||||
}
|
||||
|
||||
void timerPingAll(void* param, void* tmrId) {
|
||||
SSyncNode* pSyncNode = (SSyncNode*)param;
|
||||
syncNodePingAll(pSyncNode);
|
||||
SSyncNode* syncInitTest() { return syncNodeInit(); }
|
||||
|
||||
void initRaftId(SSyncNode* pSyncNode) {
|
||||
for (int i = 0; i < replicaNum; ++i) {
|
||||
ids[i] = pSyncNode->replicasId[i];
|
||||
char* s = syncUtilRaftId2Str(&ids[i]);
|
||||
printf("raftId[%d] : %s\n", i, s);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// taosInitLog((char*)"syncPingTest.log", 100000, 10);
|
||||
// taosInitLog((char *)"syncTest.log", 100000, 10);
|
||||
tsAsyncLog = 0;
|
||||
sDebugFlag = 143 + 64;
|
||||
|
||||
logTest();
|
||||
|
||||
int myIndex = 0;
|
||||
myIndex = 0;
|
||||
if (argc >= 2) {
|
||||
myIndex = atoi(argv[1]);
|
||||
if (myIndex > 2 || myIndex < 0) {
|
||||
fprintf(stderr, "myIndex:%d error. should be 0 - 2", myIndex);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ret = syncIOStart((char*)"127.0.0.1", ports[myIndex]);
|
||||
|
@ -80,21 +86,22 @@ int main(int argc, char** argv) {
|
|||
ret = syncEnvStart();
|
||||
assert(ret == 0);
|
||||
|
||||
SSyncNode* pSyncNode = doSync(myIndex);
|
||||
gSyncIO->FpOnSyncPing = pSyncNode->FpOnPing;
|
||||
gSyncIO->FpOnSyncPingReply = pSyncNode->FpOnPingReply;
|
||||
SSyncNode* pSyncNode = syncInitTest();
|
||||
assert(pSyncNode != NULL);
|
||||
|
||||
syncNodePrint2((char*)"syncInitTest", pSyncNode);
|
||||
|
||||
initRaftId(pSyncNode);
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
SyncPingReply* pSyncMsg = syncPingReplyBuild3(&pSyncNode->myRaftId, &pSyncNode->myRaftId);
|
||||
SyncPingReply* pSyncMsg = syncPingReplyBuild2(&pSyncNode->myRaftId, &pSyncNode->myRaftId, "syncEnqTest");
|
||||
SRpcMsg rpcMsg;
|
||||
syncPingReply2RpcMsg(pSyncMsg, &rpcMsg);
|
||||
pSyncNode->FpEqMsg(pSyncNode->queue, &rpcMsg);
|
||||
taosMsleep(1000);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
taosMsleep(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -14,15 +14,6 @@ void logTest() {
|
|||
sFatal("--- sync log test: fatal");
|
||||
}
|
||||
|
||||
void *pTimer = NULL;
|
||||
void *pTimerMgr = NULL;
|
||||
int g = 300;
|
||||
|
||||
static void timerFp(void *param, void *tmrId) {
|
||||
printf("param:%p, tmrId:%p, pTimer:%p, pTimerMgr:%p \n", param, tmrId, pTimer, pTimerMgr);
|
||||
taosTmrReset(timerFp, 1000, param, pTimerMgr, &pTimer);
|
||||
}
|
||||
|
||||
int main() {
|
||||
// taosInitLog((char*)"syncEnvTest.log", 100000, 10);
|
||||
tsAsyncLog = 0;
|
||||
|
@ -34,13 +25,20 @@ int main() {
|
|||
ret = syncEnvStart();
|
||||
assert(ret == 0);
|
||||
|
||||
// timer
|
||||
pTimerMgr = taosTmrInit(1000, 50, 10000, "SYNC-ENV-TEST");
|
||||
taosTmrStart(timerFp, 1000, &g, pTimerMgr);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
ret = syncEnvStartTimer();
|
||||
assert(ret == 0);
|
||||
|
||||
while (1) {
|
||||
taosMsleep(1000);
|
||||
taosMsleep(5000);
|
||||
|
||||
ret = syncEnvStopTimer();
|
||||
assert(ret == 0);
|
||||
|
||||
taosMsleep(5000);
|
||||
}
|
||||
|
||||
ret = syncEnvStop();
|
||||
assert(ret == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
#include <stdio.h>
|
||||
#include "syncIO.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncRaftStore.h"
|
||||
#include "syncMessage.h"
|
||||
#include "syncUtil.h"
|
||||
|
||||
void logTest() {
|
||||
sTrace("--- sync log test: trace");
|
||||
|
@ -22,7 +23,7 @@ int main() {
|
|||
|
||||
int32_t ret;
|
||||
|
||||
ret = syncIOStart((char *)"127.0.0.1", 7010);
|
||||
ret = syncIOStart((char*)"127.0.0.1", 7010);
|
||||
assert(ret == 0);
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
|
@ -31,20 +32,19 @@ int main() {
|
|||
epSet.numOfEps = 0;
|
||||
addEpIntoEpSet(&epSet, "127.0.0.1", 7030);
|
||||
|
||||
SRaftId srcId, destId;
|
||||
srcId.addr = syncUtilAddr2U64("127.0.0.1", 1234);
|
||||
srcId.vgId = 100;
|
||||
destId.addr = syncUtilAddr2U64("127.0.0.1", 5678);
|
||||
destId.vgId = 100;
|
||||
|
||||
SyncPingReply* pSyncMsg = syncPingReplyBuild2(&srcId, &destId, "syncIOClientTest");
|
||||
SRpcMsg rpcMsg;
|
||||
rpcMsg.contLen = 64;
|
||||
rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen);
|
||||
snprintf((char *)rpcMsg.pCont, rpcMsg.contLen, "%s", "syncIOSendMsgTest");
|
||||
rpcMsg.handle = NULL;
|
||||
rpcMsg.msgType = 77;
|
||||
syncPingReply2RpcMsg(pSyncMsg, &rpcMsg);
|
||||
|
||||
syncIOSendMsg(gSyncIO->clientRpc, &epSet, &rpcMsg);
|
||||
taosSsleep(1);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
taosSsleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <stdio.h>
|
||||
#include "syncEnv.h"
|
||||
#include "syncIO.h"
|
||||
#include "syncInt.h"
|
||||
#include "syncRaftStore.h"
|
||||
#include "syncUtil.h"
|
||||
|
||||
void logTest() {
|
||||
sTrace("--- sync log test: trace");
|
||||
|
@ -13,37 +15,96 @@ void logTest() {
|
|||
sFatal("--- sync log test: fatal");
|
||||
}
|
||||
|
||||
int main() {
|
||||
uint16_t ports[] = {7010, 7110, 7210, 7310, 7410};
|
||||
int32_t replicaNum = 5;
|
||||
int32_t myIndex = 0;
|
||||
|
||||
SRaftId ids[TSDB_MAX_REPLICA];
|
||||
SSyncInfo syncInfo;
|
||||
SSyncFSM* pFsm;
|
||||
|
||||
SSyncNode* syncNodeInit() {
|
||||
syncInfo.vgId = 1234;
|
||||
syncInfo.rpcClient = gSyncIO->clientRpc;
|
||||
syncInfo.FpSendMsg = syncIOSendMsg;
|
||||
syncInfo.queue = gSyncIO->pMsgQ;
|
||||
syncInfo.FpEqMsg = syncIOEqMsg;
|
||||
syncInfo.pFsm = pFsm;
|
||||
snprintf(syncInfo.path, sizeof(syncInfo.path), "%s", "./");
|
||||
|
||||
SSyncCfg* pCfg = &syncInfo.syncCfg;
|
||||
pCfg->myIndex = myIndex;
|
||||
pCfg->replicaNum = replicaNum;
|
||||
|
||||
for (int i = 0; i < replicaNum; ++i) {
|
||||
pCfg->nodeInfo[i].nodePort = ports[i];
|
||||
snprintf(pCfg->nodeInfo[i].nodeFqdn, sizeof(pCfg->nodeInfo[i].nodeFqdn), "%s", "127.0.0.1");
|
||||
// taosGetFqdn(pCfg->nodeInfo[0].nodeFqdn);
|
||||
}
|
||||
|
||||
SSyncNode* pSyncNode = syncNodeOpen(&syncInfo);
|
||||
assert(pSyncNode != NULL);
|
||||
|
||||
gSyncIO->FpOnSyncPing = pSyncNode->FpOnPing;
|
||||
gSyncIO->FpOnSyncPingReply = pSyncNode->FpOnPingReply;
|
||||
gSyncIO->FpOnSyncRequestVote = pSyncNode->FpOnRequestVote;
|
||||
gSyncIO->FpOnSyncRequestVoteReply = pSyncNode->FpOnRequestVoteReply;
|
||||
gSyncIO->FpOnSyncAppendEntries = pSyncNode->FpOnAppendEntries;
|
||||
gSyncIO->FpOnSyncAppendEntriesReply = pSyncNode->FpOnAppendEntriesReply;
|
||||
gSyncIO->FpOnSyncPing = pSyncNode->FpOnPing;
|
||||
gSyncIO->FpOnSyncPingReply = pSyncNode->FpOnPingReply;
|
||||
gSyncIO->FpOnSyncTimeout = pSyncNode->FpOnTimeout;
|
||||
gSyncIO->pSyncNode = pSyncNode;
|
||||
|
||||
return pSyncNode;
|
||||
}
|
||||
|
||||
SSyncNode* syncInitTest() { return syncNodeInit(); }
|
||||
|
||||
void initRaftId(SSyncNode* pSyncNode) {
|
||||
for (int i = 0; i < replicaNum; ++i) {
|
||||
ids[i] = pSyncNode->replicasId[i];
|
||||
char* s = syncUtilRaftId2Str(&ids[i]);
|
||||
printf("raftId[%d] : %s\n", i, s);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// taosInitLog((char *)"syncTest.log", 100000, 10);
|
||||
tsAsyncLog = 0;
|
||||
sDebugFlag = 143 + 64;
|
||||
|
||||
logTest();
|
||||
|
||||
int32_t ret;
|
||||
|
||||
ret = syncIOStart((char *)"127.0.0.1", 7010);
|
||||
assert(ret == 0);
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
SEpSet epSet;
|
||||
epSet.inUse = 0;
|
||||
epSet.numOfEps = 0;
|
||||
addEpIntoEpSet(&epSet, "127.0.0.1", 7010);
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
rpcMsg.contLen = 64;
|
||||
rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen);
|
||||
snprintf((char *)rpcMsg.pCont, rpcMsg.contLen, "%s", "syncIOSendMsgTest");
|
||||
rpcMsg.handle = NULL;
|
||||
rpcMsg.msgType = 77;
|
||||
|
||||
syncIOSendMsg(gSyncIO->clientRpc, &epSet, &rpcMsg);
|
||||
taosSsleep(1);
|
||||
myIndex = 0;
|
||||
if (argc >= 2) {
|
||||
myIndex = atoi(argv[1]);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
taosSsleep(1);
|
||||
int32_t ret = syncIOStart((char*)"127.0.0.1", ports[myIndex]);
|
||||
assert(ret == 0);
|
||||
|
||||
ret = syncEnvStart();
|
||||
assert(ret == 0);
|
||||
|
||||
SSyncNode* pSyncNode = syncInitTest();
|
||||
assert(pSyncNode != NULL);
|
||||
|
||||
syncNodePrint2((char*)"syncInitTest", pSyncNode);
|
||||
|
||||
initRaftId(pSyncNode);
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
SyncPingReply* pSyncMsg = syncPingReplyBuild2(&pSyncNode->myRaftId, &pSyncNode->myRaftId, "syncIOSendMsgTest");
|
||||
SRpcMsg rpcMsg;
|
||||
syncPingReply2RpcMsg(pSyncMsg, &rpcMsg);
|
||||
|
||||
SEpSet epSet;
|
||||
syncUtilnodeInfo2EpSet(&pSyncNode->myNodeInfo, &epSet);
|
||||
pSyncNode->FpSendMsg(pSyncNode->rpcClient, &epSet, &rpcMsg);
|
||||
|
||||
taosMsleep(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue