From 4bb5ba8bd5fe382cd3f4945c2a2478d8e2188471 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Thu, 17 Feb 2022 20:53:39 +0800 Subject: [PATCH 01/12] test open UV --- cmake/cmake.options | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/cmake.options b/cmake/cmake.options index e84d02800c..b1558b7789 100644 --- a/cmake/cmake.options +++ b/cmake/cmake.options @@ -47,13 +47,13 @@ option( option( BUILD_WITH_UV "If build with libuv" - OFF + ON ) option( BUILD_WITH_UV_TRANS "If build with libuv_trans " - OFF + ON ) option( From adb813f09e9ff2d36f52be83080273386cba7f72 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Thu, 17 Feb 2022 21:12:55 +0800 Subject: [PATCH 02/12] test open UV --- cmake/cmake.options | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/cmake.options b/cmake/cmake.options index b1558b7789..343bc16260 100644 --- a/cmake/cmake.options +++ b/cmake/cmake.options @@ -47,13 +47,13 @@ option( option( BUILD_WITH_UV "If build with libuv" - ON + OFF ) option( BUILD_WITH_UV_TRANS "If build with libuv_trans " - ON + OFF ) option( From 4c19f566864336808834dde07298c69afcfdbae3 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 21 Feb 2022 00:11:35 +0800 Subject: [PATCH 03/12] fix bug --- cmake/cmake.options | 4 +- include/libs/transport/trpc.h | 1 + source/dnode/mgmt/impl/src/dndTransport.c | 7 +- source/dnode/mgmt/impl/test/sut/inc/client.h | 7 +- source/dnode/mgmt/impl/test/sut/inc/sut.h | 7 +- .../dnode/mgmt/impl/test/sut/src/client.cpp | 33 ++++-- source/dnode/mgmt/impl/test/sut/src/sut.cpp | 17 +-- source/dnode/mnode/impl/src/mnode.c | 9 +- source/dnode/mnode/impl/test/qnode/qnode.cpp | 7 +- source/dnode/mnode/impl/test/trans/trans.cpp | 4 +- source/dnode/mnode/impl/test/user/user.cpp | 3 +- source/libs/transport/inc/transComm.h | 2 +- source/libs/transport/inc/transportInt.h | 1 + source/libs/transport/src/rpcMain.c | 1 + source/libs/transport/src/trans.c | 4 +- source/libs/transport/src/transCli.c | 82 +++++++++----- source/libs/transport/src/transComm.c | 21 ++-- source/libs/transport/src/transSrv.c | 101 ++++++++++++------ source/os/src/osTimer.c | 82 +++++++------- source/util/src/ttimer.c | 67 +++++++++--- 20 files changed, 294 insertions(+), 166 deletions(-) diff --git a/cmake/cmake.options b/cmake/cmake.options index 343bc16260..e19c10f6b2 100644 --- a/cmake/cmake.options +++ b/cmake/cmake.options @@ -47,13 +47,13 @@ option( option( BUILD_WITH_UV "If build with libuv" - OFF + ON ) option( BUILD_WITH_UV_TRANS "If build with libuv_trans " - OFF + ON ) option( diff --git a/include/libs/transport/trpc.h b/include/libs/transport/trpc.h index f913ba06d0..538aeb1a0e 100644 --- a/include/libs/transport/trpc.h +++ b/include/libs/transport/trpc.h @@ -64,6 +64,7 @@ typedef struct SRpcInit { int8_t connType; // TAOS_CONN_UDP, TAOS_CONN_TCPC, TAOS_CONN_TCPS int idleTime; // milliseconds, 0 means idle timer is disabled + bool noPool; // create conn pool or not // the following is for client app ecurity only char *user; // user name char spi; // security parameter index diff --git a/source/dnode/mgmt/impl/src/dndTransport.c b/source/dnode/mgmt/impl/src/dndTransport.c index 931cda475c..a006712355 100644 --- a/source/dnode/mgmt/impl/src/dndTransport.c +++ b/source/dnode/mgmt/impl/src/dndTransport.c @@ -154,7 +154,7 @@ static void dndInitMsgFp(STransMgmt *pMgmt) { } static void dndProcessResponse(void *parent, SRpcMsg *pRsp, SEpSet *pEpSet) { - SDnode *pDnode = parent; + SDnode * pDnode = parent; STransMgmt *pMgmt = &pDnode->tmgmt; tmsg_t msgType = pRsp->msgType; @@ -192,6 +192,7 @@ static int32_t dndInitClient(SDnode *pDnode) { rpcInit.ckey = INTERNAL_CKEY; rpcInit.spi = 1; rpcInit.parent = pDnode; + rpcInit.noPool = true; char pass[TSDB_PASSWORD_LEN + 1] = {0}; taosEncryptPass_c((uint8_t *)(INTERNAL_SECRET), strlen(INTERNAL_SECRET), pass); @@ -217,7 +218,7 @@ static void dndCleanupClient(SDnode *pDnode) { } static void dndProcessRequest(void *param, SRpcMsg *pReq, SEpSet *pEpSet) { - SDnode *pDnode = param; + SDnode * pDnode = param; STransMgmt *pMgmt = &pDnode->tmgmt; tmsg_t msgType = pReq->msgType; @@ -311,7 +312,7 @@ static int32_t dndRetrieveUserAuthInfo(void *parent, char *user, char *spi, char SAuthReq authReq = {0}; tstrncpy(authReq.user, user, TSDB_USER_LEN); int32_t contLen = tSerializeSAuthReq(NULL, 0, &authReq); - void *pReq = rpcMallocCont(contLen); + void * pReq = rpcMallocCont(contLen); tSerializeSAuthReq(pReq, contLen, &authReq); SRpcMsg rpcMsg = {.pCont = pReq, .contLen = contLen, .msgType = TDMT_MND_AUTH, .ahandle = (void *)9528}; diff --git a/source/dnode/mgmt/impl/test/sut/inc/client.h b/source/dnode/mgmt/impl/test/sut/inc/client.h index 9cf688fc02..925680d528 100644 --- a/source/dnode/mgmt/impl/test/sut/inc/client.h +++ b/source/dnode/mgmt/impl/test/sut/inc/client.h @@ -21,16 +21,21 @@ class TestClient { bool Init(const char* user, const char* pass, const char* fqdn, uint16_t port); void Cleanup(); + void DoInit(); + SRpcMsg* SendReq(SRpcMsg* pReq); void SetRpcRsp(SRpcMsg* pRsp); tsem_t* GetSem(); + void Restart(); private: char fqdn[TSDB_FQDN_LEN]; uint16_t port; + char user[128]; + char pass[128]; void* clientRpc; SRpcMsg* pRsp; tsem_t sem; }; -#endif /* _TD_TEST_CLIENT_H_ */ \ No newline at end of file +#endif /* _TD_TEST_CLIENT_H_ */ diff --git a/source/dnode/mgmt/impl/test/sut/inc/sut.h b/source/dnode/mgmt/impl/test/sut/inc/sut.h index 23913b0531..250d563a8b 100644 --- a/source/dnode/mgmt/impl/test/sut/inc/sut.h +++ b/source/dnode/mgmt/impl/test/sut/inc/sut.h @@ -20,10 +20,10 @@ #include "os.h" #include "dnode.h" -#include "tmsg.h" #include "tconfig.h" #include "tdataformat.h" #include "tglobal.h" +#include "tmsg.h" #include "tnote.h" #include "trpc.h" #include "tthread.h" @@ -39,6 +39,7 @@ class Testbase { void Restart(); void ServerStop(); void ServerStart(); + void ClientRestart(); SRpcMsg* SendReq(tmsg_t msgType, void* pCont, int32_t contLen); private: @@ -100,7 +101,7 @@ class Testbase { { \ char* bytes = (char*)calloc(1, len); \ for (int32_t i = 0; i < len - 1; ++i) { \ - bytes[i] = b; \ + bytes[i] = b; \ } \ EXPECT_STREQ(test.GetShowBinary(len), bytes); \ } @@ -138,4 +139,4 @@ class Testbase { #define IgnoreTimestamp() \ { test.GetShowTimestamp(); } -#endif /* _TD_TEST_BASE_H_ */ \ No newline at end of file +#endif /* _TD_TEST_BASE_H_ */ diff --git a/source/dnode/mgmt/impl/test/sut/src/client.cpp b/source/dnode/mgmt/impl/test/sut/src/client.cpp index 8403dbf034..589c015013 100644 --- a/source/dnode/mgmt/impl/test/sut/src/client.cpp +++ b/source/dnode/mgmt/impl/test/sut/src/client.cpp @@ -13,33 +13,38 @@ * along with this program. If not, see . */ -#include "tep.h" #include "sut.h" +#include "tep.h" static void processClientRsp(void* parent, SRpcMsg* pRsp, SEpSet* pEpSet) { TestClient* client = (TestClient*)parent; client->SetRpcRsp(pRsp); - uInfo("response:%s from dnode, code:0x%x", TMSG_INFO(pRsp->msgType), pRsp->code); + uInfo("x response:%s from dnode, code:0x%x, msgSize: %d", TMSG_INFO(pRsp->msgType), pRsp->code, pRsp->contLen); tsem_post(client->GetSem()); } -void TestClient::SetRpcRsp(SRpcMsg* pRsp) { this->pRsp = pRsp; }; +void TestClient::SetRpcRsp(SRpcMsg* rsp) { + this->pRsp = (SRpcMsg*)calloc(1, sizeof(SRpcMsg)); + this->pRsp->msgType = rsp->msgType; + this->pRsp->code = rsp->code; + this->pRsp->pCont = rsp->pCont; + this->pRsp->contLen = rsp->contLen; +}; tsem_t* TestClient::GetSem() { return &sem; } -bool TestClient::Init(const char* user, const char* pass, const char* fqdn, uint16_t port) { +void TestClient::DoInit() { char secretEncrypt[TSDB_PASSWORD_LEN + 1] = {0}; taosEncryptPass_c((uint8_t*)pass, strlen(pass), secretEncrypt); - SRpcInit rpcInit; memset(&rpcInit, 0, sizeof(rpcInit)); - rpcInit.label = (char*)"DND-C"; + rpcInit.label = (char*)"shell"; rpcInit.numOfThreads = 1; rpcInit.cfp = processClientRsp; rpcInit.sessions = 1024; rpcInit.connType = TAOS_CONN_CLIENT; rpcInit.idleTime = 30 * 1000; - rpcInit.user = (char*)user; + rpcInit.user = (char*)this->user; rpcInit.ckey = (char*)"key"; rpcInit.parent = this; rpcInit.secret = (char*)secretEncrypt; @@ -47,11 +52,16 @@ bool TestClient::Init(const char* user, const char* pass, const char* fqdn, uint clientRpc = rpcOpen(&rpcInit); ASSERT(clientRpc); + tsem_init(&this->sem, 0, 0); +} - tsem_init(&sem, 0, 0); +bool TestClient::Init(const char* user, const char* pass, const char* fqdn, uint16_t port) { strcpy(this->fqdn, fqdn); + strcpy(this->user, user); + strcpy(this->pass, pass); this->port = port; - + // this->pRsp = NULL; + this->DoInit(); return true; } @@ -60,11 +70,16 @@ void TestClient::Cleanup() { rpcClose(clientRpc); } +void TestClient::Restart() { + this->Cleanup(); + this->DoInit(); +} SRpcMsg* TestClient::SendReq(SRpcMsg* pReq) { SEpSet epSet = {0}; addEpIntoEpSet(&epSet, fqdn, port); rpcSendRequest(clientRpc, &epSet, pReq, NULL); tsem_wait(&sem); + uInfo("y response:%s from dnode, code:0x%x, msgSize: %d", TMSG_INFO(pRsp->msgType), pRsp->code, pRsp->contLen); return pRsp; } diff --git a/source/dnode/mgmt/impl/test/sut/src/sut.cpp b/source/dnode/mgmt/impl/test/sut/src/sut.cpp index 09a738be3b..771c5886ef 100644 --- a/source/dnode/mgmt/impl/test/sut/src/sut.cpp +++ b/source/dnode/mgmt/impl/test/sut/src/sut.cpp @@ -21,9 +21,9 @@ void Testbase::InitLog(const char* path) { mDebugFlag = 143; cDebugFlag = 0; jniDebugFlag = 0; - tmrDebugFlag = 0; - uDebugFlag = 0; - rpcDebugFlag = 0; + tmrDebugFlag = 143; + uDebugFlag = 143; + rpcDebugFlag = 143; qDebugFlag = 0; wDebugFlag = 0; sDebugFlag = 0; @@ -66,16 +66,21 @@ void Testbase::Init(const char* path, int16_t port) { void Testbase::Cleanup() { tFreeSTableMetaRsp(&metaRsp); - server.Stop(); client.Cleanup(); + taosMsleep(10); + server.Stop(); dndCleanup(); } -void Testbase::Restart() { server.Restart(); } +void Testbase::Restart() { + server.Restart(); + client.Restart(); +} void Testbase::ServerStop() { server.Stop(); } void Testbase::ServerStart() { server.DoStart(); } +void Testbase::ClientRestart() { client.Restart(); } SRpcMsg* Testbase::SendReq(tmsg_t msgType, void* pCont, int32_t contLen) { SRpcMsg rpcMsg = {0}; @@ -194,4 +199,4 @@ int32_t Testbase::GetShowRows() { return pRetrieveRsp->numOfRows; } STableMetaRsp* Testbase::GetShowMeta() { return &metaRsp; } -SRetrieveTableRsp* Testbase::GetRetrieveRsp() { return pRetrieveRsp; } \ No newline at end of file +SRetrieveTableRsp* Testbase::GetRetrieveRsp() { return pRetrieveRsp; } diff --git a/source/dnode/mnode/impl/src/mnode.c b/source/dnode/mnode/impl/src/mnode.c index 699ccab92c..64b4aa6dd7 100644 --- a/source/dnode/mnode/impl/src/mnode.c +++ b/source/dnode/mnode/impl/src/mnode.c @@ -77,7 +77,7 @@ static void mndTransReExecute(void *param, void *tmrId) { SMnode *pMnode = param; if (mndIsMaster(pMnode)) { int32_t contLen = 0; - void *pReq = mndBuildTimerMsg(&contLen); + void * pReq = mndBuildTimerMsg(&contLen); SRpcMsg rpcMsg = {.msgType = TDMT_MND_TRANS, .pCont = pReq, .contLen = contLen}; pMnode->putReqToMWriteQFp(pMnode->pDnode, &rpcMsg); } @@ -89,7 +89,7 @@ static void mndCalMqRebalance(void *param, void *tmrId) { SMnode *pMnode = param; if (mndIsMaster(pMnode)) { int32_t contLen = 0; - void *pReq = mndBuildTimerMsg(&contLen); + void * pReq = mndBuildTimerMsg(&contLen); SRpcMsg rpcMsg = {.msgType = TDMT_MND_MQ_TIMER, .pCont = pReq, .contLen = contLen}; pMnode->putReqToMReadQFp(pMnode->pDnode, &rpcMsg); } @@ -404,7 +404,8 @@ SMnodeMsg *mndInitMsg(SMnode *pMnode, SRpcMsg *pRpcMsg) { return NULL; } - if (pRpcMsg->msgType != TDMT_MND_TRANS && pRpcMsg->msgType != TDMT_MND_MQ_TIMER && pRpcMsg->msgType != TDMT_MND_MQ_DO_REBALANCE) { + if (pRpcMsg->msgType != TDMT_MND_TRANS && pRpcMsg->msgType != TDMT_MND_MQ_TIMER && + pRpcMsg->msgType != TDMT_MND_MQ_DO_REBALANCE) { SRpcConnInfo connInfo = {0}; if ((pRpcMsg->msgType & 1U) && rpcGetConnInfo(pRpcMsg->handle, &connInfo) != 0) { taosFreeQitem(pMsg); @@ -439,7 +440,7 @@ void mndProcessMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; int32_t code = 0; tmsg_t msgType = pMsg->rpcMsg.msgType; - void *ahandle = pMsg->rpcMsg.ahandle; + void * ahandle = pMsg->rpcMsg.ahandle; bool isReq = (msgType & 1U); mTrace("msg:%p, type:%s will be processed, app:%p", pMsg, TMSG_INFO(msgType), ahandle); diff --git a/source/dnode/mnode/impl/test/qnode/qnode.cpp b/source/dnode/mnode/impl/test/qnode/qnode.cpp index d4e308268a..b8a0e61ca3 100644 --- a/source/dnode/mnode/impl/test/qnode/qnode.cpp +++ b/source/dnode/mnode/impl/test/qnode/qnode.cpp @@ -190,6 +190,9 @@ TEST_F(MndTestQnode, 03_Create_Qnode_Rollback) { tSerializeSMCreateDropQSBNodeReq(pReq, contLen, &createReq); server2.Stop(); + taosMsleep(1000); + // test.ClientRestart(); + SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen); ASSERT_NE(pRsp, nullptr); ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL); @@ -226,6 +229,7 @@ TEST_F(MndTestQnode, 03_Create_Qnode_Rollback) { { // server start, wait until the rollback finished server2.DoStart(); + test.ClientRestart(); taosMsleep(1000); int32_t retry = 0; @@ -248,7 +252,6 @@ TEST_F(MndTestQnode, 03_Create_Qnode_Rollback) { ASSERT_NE(retry, retryMax); } } - TEST_F(MndTestQnode, 04_Drop_Qnode_Rollback) { { // send message first, then dnode2 crash, result is returned, and rollback is started @@ -315,4 +318,4 @@ TEST_F(MndTestQnode, 04_Drop_Qnode_Rollback) { ASSERT_NE(retry, retryMax); } -} \ No newline at end of file +} diff --git a/source/dnode/mnode/impl/test/trans/trans.cpp b/source/dnode/mnode/impl/test/trans/trans.cpp index 8a62ed639a..fe3872aba8 100644 --- a/source/dnode/mnode/impl/test/trans/trans.cpp +++ b/source/dnode/mnode/impl/test/trans/trans.cpp @@ -46,8 +46,10 @@ class MndTestTrans : public ::testing::Test { free(buffer); taosFsyncFile(fd); taosCloseFile(fd); + taosMsleep(1000); test.ServerStart(); + test.ClientRestart(); } static Testbase test; @@ -200,4 +202,4 @@ TEST_F(MndTestTrans, 03_Create_Qnode2_Crash) { test.SendShowRetrieveReq(); EXPECT_EQ(test.GetShowRows(), 2); } -} \ No newline at end of file +} diff --git a/source/dnode/mnode/impl/test/user/user.cpp b/source/dnode/mnode/impl/test/user/user.cpp index d8ce599be1..61b99beeb7 100644 --- a/source/dnode/mnode/impl/test/user/user.cpp +++ b/source/dnode/mnode/impl/test/user/user.cpp @@ -617,6 +617,7 @@ TEST_F(MndTestUser, 06_Create_Drop_Alter_User) { // restart test.Restart(); + taosMsleep(1000); test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, ""); CHECK_META("show users", 4); @@ -631,4 +632,4 @@ TEST_F(MndTestUser, 06_Create_Drop_Alter_User) { CheckTimestamp(); CheckBinary("root", TSDB_USER_LEN); CheckBinary("root", TSDB_USER_LEN); -} \ No newline at end of file +} diff --git a/source/libs/transport/inc/transComm.h b/source/libs/transport/inc/transComm.h index d5a8cf5f84..2078a218ee 100644 --- a/source/libs/transport/inc/transComm.h +++ b/source/libs/transport/inc/transComm.h @@ -217,7 +217,7 @@ typedef struct SConnBuffer { char* buf; int len; int cap; - int left; + int total; } SConnBuffer; typedef void (*AsyncCB)(uv_async_t* handle); diff --git a/source/libs/transport/inc/transportInt.h b/source/libs/transport/inc/transportInt.h index 3c8c922d83..a36b671eb4 100644 --- a/source/libs/transport/inc/transportInt.h +++ b/source/libs/transport/inc/transportInt.h @@ -56,6 +56,7 @@ typedef struct { int8_t connType; int64_t index; char label[TSDB_LABEL_LEN]; + bool noPool; // pool or not char user[TSDB_UNI_LEN]; // meter ID char spi; // security parameter index diff --git a/source/libs/transport/src/rpcMain.c b/source/libs/transport/src/rpcMain.c index 3bb7d103d7..72c1ff6893 100644 --- a/source/libs/transport/src/rpcMain.c +++ b/source/libs/transport/src/rpcMain.c @@ -64,6 +64,7 @@ typedef struct { void (*cfp)(void *parent, SRpcMsg *, SEpSet *); int (*afp)(void *parent, char *user, char *spi, char *encrypt, char *secret, char *ckey); + bool noPool; int32_t refCount; void * parent; void * idPool; // handle to ID pool diff --git a/source/libs/transport/src/trans.c b/source/libs/transport/src/trans.c index c3d3cfa2ab..48c15ca286 100644 --- a/source/libs/transport/src/trans.c +++ b/source/libs/transport/src/trans.c @@ -27,7 +27,7 @@ void* rpcOpen(const SRpcInit* pInit) { return NULL; } if (pInit->label) { - tstrncpy(pRpc->label, pInit->label, strlen(pInit->label)); + tstrncpy(pRpc->label, pInit->label, strlen(pInit->label) + 1); } pRpc->cfp = pInit->cfp; if (pInit->connType == TAOS_CONN_SERVER) { @@ -35,6 +35,8 @@ void* rpcOpen(const SRpcInit* pInit) { } else { pRpc->numOfThreads = pInit->numOfThreads; } + + pRpc->noPool = pInit->noPool; pRpc->connType = pInit->connType; pRpc->idleTime = pInit->idleTime; pRpc->tcphandle = (*taosInitHandle[pRpc->connType])(0, pInit->localPort, pRpc->label, pRpc->numOfThreads, NULL, pRpc); diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c index f1bd1ba980..4ed1cc2e73 100644 --- a/source/libs/transport/src/transCli.c +++ b/source/libs/transport/src/transCli.c @@ -126,6 +126,9 @@ static void clientHandleResp(SCliConn* conn) { pHead->code = htonl(pHead->code); pHead->msgLen = htonl(pHead->msgLen); + // buf's mem alread translated to rpcMsg.pCont + transClearBuffer(&conn->readBuf); + SRpcMsg rpcMsg; rpcMsg.contLen = transContLenFromMsg(pHead->msgLen); rpcMsg.pCont = transContFromHead((char*)pHead); @@ -140,9 +143,9 @@ static void clientHandleResp(SCliConn* conn) { tDebug("client conn %p persist by app", conn); } - tDebug("client conn %p %s received from %s:%d, local info: %s:%d", conn, TMSG_INFO(pHead->msgType), - inet_ntoa(conn->addr.sin_addr), ntohs(conn->addr.sin_port), inet_ntoa(conn->locaddr.sin_addr), - ntohs(conn->locaddr.sin_port)); + tDebug("%s client conn %p %s received from %s:%d, local info: %s:%d, msg size: %d", pRpc->label, conn, + TMSG_INFO(pHead->msgType), inet_ntoa(conn->addr.sin_addr), ntohs(conn->addr.sin_port), + inet_ntoa(conn->locaddr.sin_addr), ntohs(conn->locaddr.sin_port), rpcMsg.contLen); conn->secured = pHead->secured; if (conn->push != NULL && conn->ctnRdCnt != 0) { @@ -150,26 +153,26 @@ static void clientHandleResp(SCliConn* conn) { conn->push = NULL; } else { if (pCtx->pSem == NULL) { - tTrace("client conn %p handle resp", conn); + tTrace("%s client conn %p handle resp", pRpc->label, conn); (pRpc->cfp)(pRpc->parent, &rpcMsg, NULL); } else { - tTrace("client conn(sync) %p handle resp", conn); + tTrace("%s client conn(sync) %p handle resp", pRpc->label, conn); memcpy((char*)pCtx->pRsp, (char*)&rpcMsg, sizeof(rpcMsg)); tsem_post(pCtx->pSem); } } conn->ctnRdCnt += 1; - // buf's mem alread translated to rpcMsg.pCont - transClearBuffer(&conn->readBuf); - uv_read_start((uv_stream_t*)conn->stream, clientAllocBufferCb, clientReadCb); SCliThrdObj* pThrd = conn->hostThrd; // user owns conn->persist = 1 if (conn->push == NULL && conn->persist == 0) { - addConnToPool(pThrd->pool, pCtx->ip, pCtx->port, conn); + if (pRpc->noPool == true) { + } else { + addConnToPool(pThrd->pool, pCtx->ip, pCtx->port, conn); + } } destroyCmsg(conn->data); conn->data = NULL; @@ -184,7 +187,6 @@ static void clientHandleExcept(SCliConn* pConn) { clientConnDestroy(pConn, true); return; } - tTrace("client conn %p start to destroy", pConn); SCliMsg* pMsg = pConn->data; tmsg_t msgType = TDMT_MND_CONNECT; @@ -213,6 +215,7 @@ static void clientHandleExcept(SCliConn* pConn) { } pConn->push = NULL; } + tTrace("%s client conn %p start to destroy", pCtx->pTransInst->label, pConn); if (pConn->push == NULL) { destroyCmsg(pConn->data); pConn->data = NULL; @@ -226,7 +229,7 @@ static void clientTimeoutCb(uv_timer_t* handle) { SCliThrdObj* pThrd = handle->data; SRpcInfo* pRpc = pThrd->pTransInst; int64_t currentTime = pThrd->nextTimeout; - tTrace("client conn timeout, try to remove expire conn from conn pool"); + tTrace("%s, client conn timeout, try to remove expire conn from conn pool", pRpc->label); SConnList* p = taosHashIterate((SHashObj*)pThrd->pool, NULL); while (p != NULL) { @@ -307,21 +310,30 @@ static void addConnToPool(void* pool, char* ip, uint32_t port, SCliConn* conn) { QUEUE_PUSH(&plist->conn, &conn->conn); } static bool clientReadComplete(SConnBuffer* data) { - STransMsgHead head; - int32_t headLen = sizeof(head); - if (data->len >= headLen) { - memcpy((char*)&head, data->buf, headLen); - int32_t msgLen = (int32_t)htonl((uint32_t)head.msgLen); - if (msgLen > data->len) { - data->left = msgLen - data->len; - return false; - } else if (msgLen == data->len) { - data->left = 0; - return true; - } - } else { - return false; + if (data->len >= sizeof(STransMsgHead)) { + STransMsgHead head; + memcpy((char*)&head, data->buf, sizeof(head)); + int32_t msgLen = (int32_t)htonl(head.msgLen); + data->total = msgLen; } + + if (data->len == data->cap && data->total == data->cap) { + return true; + } + return false; + // if (data->len >= headLen) { + // memcpy((char*)&head, data->buf, headLen); + // int32_t msgLen = (int32_t)htonl((uint32_t)head.msgLen); + // if (msgLen > data->len) { + // data->left = msgLen - data->len; + // return false; + // } else if (msgLen == data->len) { + // data->left = 0; + // return true; + // } + //} else { + // return false; + //} } static void clientAllocBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { SCliConn* conn = handle->data; @@ -338,7 +350,7 @@ static void clientReadCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf if (nread > 0) { pBuf->len += nread; if (clientReadComplete(pBuf)) { - uv_read_stop((uv_stream_t*)conn->stream); + // uv_read_stop((uv_stream_t*)conn->stream); tTrace("client conn %p read complete", conn); clientHandleResp(conn); } else { @@ -346,6 +358,10 @@ static void clientReadCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf } return; } + if (nread == UV_EOF) { + tError("client conn %p read error: %s", conn, uv_err_name(nread)); + clientHandleExcept(conn); + } assert(nread <= 0); if (nread == 0) { // ref http://docs.libuv.org/en/v1.x/stream.html?highlight=uv_read_start#c.uv_read_cb @@ -353,7 +369,7 @@ static void clientReadCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf // read(2). return; } - if (nread < 0 || nread == UV_EOF) { + if (nread < 0) { tError("client conn %p read error: %s", conn, uv_err_name(nread)); clientHandleExcept(conn); } @@ -467,6 +483,7 @@ static void clientConnCb(uv_connect_t* req, int status) { static void clientHandleQuit(SCliMsg* pMsg, SCliThrdObj* pThrd) { tDebug("client work thread %p start to quit", pThrd); destroyCmsg(pMsg); + destroyConnPool(pThrd->pool); // transDestroyAsyncPool(pThr) uv_close((uv_handle_t*)pThrd->cliAsync, NULL); uv_timer_stop(pThrd->timer); pThrd->quit = true; @@ -483,7 +500,10 @@ static void clientHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) { SCliConn* conn = NULL; if (pMsg->msg.handle == NULL) { - conn = getConnFromPool(pThrd->pool, pCtx->ip, pCtx->port); + if (pCtx->pTransInst->noPool == true) { + } else { + conn = getConnFromPool(pThrd->pool, pCtx->ip, pCtx->port); + } if (conn != NULL) { tTrace("client conn %p get from conn pool", conn); } @@ -512,7 +532,11 @@ static void clientHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) { conn->stream = (uv_stream_t*)malloc(sizeof(uv_tcp_t)); uv_tcp_init(pThrd->loop, (uv_tcp_t*)(conn->stream)); conn->stream->data = conn; - + uv_tcp_nodelay((uv_tcp_t*)conn->stream, 1); + int ret = uv_tcp_keepalive((uv_tcp_t*)conn->stream, 1, 1); + if (ret) { + tTrace("client conn %p failed to set keepalive, %s", conn, uv_err_name(ret)); + } // write req handle conn->writeReq = malloc(sizeof(uv_write_t)); conn->writeReq->data = conn; diff --git a/source/libs/transport/src/transComm.c b/source/libs/transport/src/transComm.c index 7aa5aa16f1..388e0da4e0 100644 --- a/source/libs/transport/src/transComm.c +++ b/source/libs/transport/src/transComm.c @@ -205,6 +205,7 @@ int transInitBuffer(SConnBuffer* buf) { } int transClearBuffer(SConnBuffer* buf) { memset(buf, 0, sizeof(*buf)); + buf->total = -1; return 0; } int transAllocBuffer(SConnBuffer* connBuf, uv_buf_t* uvBuf) { @@ -214,27 +215,25 @@ int transAllocBuffer(SConnBuffer* connBuf, uv_buf_t* uvBuf) { * |<------STransMsgHead------->|<-------------------userdata--------------->|<-----auth data----->|<----user * info--->| */ - static const int CAPACITY = 1024; + static const int CAPACITY = sizeof(STransMsgHead); SConnBuffer* p = connBuf; if (p->cap == 0) { p->buf = (char*)calloc(CAPACITY, sizeof(char)); p->len = 0; p->cap = CAPACITY; - p->left = -1; + p->total = 0; uvBuf->base = p->buf; uvBuf->len = CAPACITY; } else { - if (p->len >= p->cap) { - if (p->left == -1) { - p->cap *= 2; - p->buf = realloc(p->buf, p->cap); - } else if (p->len + p->left > p->cap) { - p->cap = p->len + p->left; - p->buf = realloc(p->buf, p->len + p->left); - } - } + STransMsgHead head; + memcpy((char*)&head, p->buf, sizeof(head)); + int32_t msgLen = (int32_t)htonl(head.msgLen); + + p->total = msgLen; + p->cap = msgLen; + p->buf = realloc(p->buf, p->cap); uvBuf->base = p->buf + p->len; uvBuf->len = p->cap - p->len; } diff --git a/source/libs/transport/src/transSrv.c b/source/libs/transport/src/transSrv.c index 7ddeb99c9d..5292bad209 100644 --- a/source/libs/transport/src/transSrv.c +++ b/source/libs/transport/src/transSrv.c @@ -61,6 +61,7 @@ typedef struct SWorkThrdObj { SAsyncPool* asyncPool; // uv_async_t* workerAsync; // queue msg; + queue conn; pthread_mutex_t msgMtx; void* pTransInst; } SWorkThrdObj; @@ -103,7 +104,7 @@ static void uvStartSendResp(SSrvMsg* msg); static void destroySmsg(SSrvMsg* smsg); // check whether already read complete packet static bool readComplete(SConnBuffer* buf); -static SSrvConn* createConn(); +static SSrvConn* createConn(void* hThrd); static void destroyConn(SSrvConn* conn, bool clear /*clear handle or not*/); static void uvDestroyConn(uv_handle_t* handle); @@ -117,11 +118,6 @@ static bool addHandleToWorkloop(void* arg); static bool addHandleToAcceptloop(void* arg); void uvAllocReadBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { - /* - * formate of data buffer: - * |<--------------------------data from socket------------------------------->| - * |<------STransMsgHead------->|<-------------------other data--------------->| - */ SSrvConn* conn = handle->data; SConnBuffer* pBuf = &conn->readBuf; transAllocBuffer(pBuf, buf); @@ -131,23 +127,27 @@ void uvAllocReadBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* b // static bool readComplete(SConnBuffer* data) { // TODO(yihao): handle pipeline later - STransMsgHead head; - int32_t headLen = sizeof(head); - if (data->len >= headLen) { - memcpy((char*)&head, data->buf, headLen); - int32_t msgLen = (int32_t)htonl((uint32_t)head.msgLen); - if (msgLen > data->len) { - data->left = msgLen - data->len; - return false; - } else if (msgLen == data->len) { - return true; - } else if (msgLen < data->len) { - return false; - // handle other packet later - } - } else { - return false; + if (data->len == data->cap && data->total == data->cap) { + return true; } + return false; + // STransMsgHead head; + // int32_t headLen = sizeof(head); + // if (data->len >= headLen) { + // memcpy((char*)&head, data->buf, headLen); + // int32_t msgLen = (int32_t)htonl((uint32_t)head.msgLen); + // if (msgLen > data->len) { + // data->left = msgLen - data->len; + // return false; + // } else if (msgLen == data->len) { + // return true; + // } else if (msgLen < data->len) { + // return false; + // // handle other packet later + // } + //} else { + // return false; + //} } // static void uvDoProcess(SRecvInfo* pRecv) { @@ -241,7 +241,7 @@ static void uvHandleReq(SSrvConn* pConn) { } pConn->inType = pHead->msgType; - assert(transIsReq(pHead->msgType)); + // assert(transIsReq(pHead->msgType)); SRpcInfo* pRpc = (SRpcInfo*)p->shandle; pHead->code = htonl(pHead->code); @@ -266,9 +266,9 @@ static void uvHandleReq(SSrvConn* pConn) { transClearBuffer(&pConn->readBuf); pConn->ref++; - tDebug("server conn %p %s received from %s:%d, local info: %s:%d", pConn, TMSG_INFO(rpcMsg.msgType), + tDebug("server conn %p %s received from %s:%d, local info: %s:%d, msg size: %d", pConn, TMSG_INFO(rpcMsg.msgType), inet_ntoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port), inet_ntoa(pConn->locaddr.sin_addr), - ntohs(pConn->locaddr.sin_port)); + ntohs(pConn->locaddr.sin_port), rpcMsg.contLen); (*(pRpc->cfp))(pRpc->parent, &rpcMsg, NULL); // uv_timer_start(pConn->pTimer, uvHandleActivityTimeout, pRpc->idleTime * 10000, 0); // auth @@ -290,6 +290,14 @@ void uvOnReadCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) { } return; } + if (nread == UV_EOF) { + tError("server conn %p read error: %s", conn, uv_err_name(nread)); + if (conn->ref > 1) { + conn->ref++; // ref > 1 signed that write is in progress + } + destroyConn(conn, true); + return; + } if (nread == 0) { return; } @@ -302,8 +310,8 @@ void uvOnReadCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) { } } void uvAllocConnBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { - buf->base = malloc(sizeof(char)); buf->len = 2; + buf->base = calloc(1, sizeof(char) * buf->len); } void uvOnTimeoutCb(uv_timer_t* handle) { @@ -386,6 +394,7 @@ static void uvStartSendRespInternal(SSrvMsg* smsg) { static void uvStartSendResp(SSrvMsg* smsg) { // impl SSrvConn* pConn = smsg->pConn; + pConn->ref--; // if (taosArrayGetSize(pConn->srvMsgs) > 0) { tDebug("server conn %p push data to client %s:%d, local info: %s:%d", pConn, inet_ntoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port), inet_ntoa(pConn->locaddr.sin_addr), ntohs(pConn->locaddr.sin_port)); @@ -403,6 +412,16 @@ static void destroySmsg(SSrvMsg* smsg) { transFreeMsg(smsg->msg.pCont); free(smsg); } +static void destroyAllConn(SWorkThrdObj* pThrd) { + while (!QUEUE_IS_EMPTY(&pThrd->conn)) { + queue* h = QUEUE_HEAD(&pThrd->conn); + QUEUE_REMOVE(h); + QUEUE_INIT(h); + + SSrvConn* c = QUEUE_DATA(h, SSrvConn, queue); + destroyConn(c, true); + } +} void uvWorkerAsyncCb(uv_async_t* handle) { SAsyncItem* item = handle->data; SWorkThrdObj* pThrd = item->pThrd; @@ -424,8 +443,9 @@ void uvWorkerAsyncCb(uv_async_t* handle) { continue; } if (msg->pConn == NULL) { - // free(msg); + + destroyAllConn(pThrd); uv_stop(pThrd->loop); } else { uvStartSendResp(msg); @@ -439,6 +459,7 @@ void uvWorkerAsyncCb(uv_async_t* handle) { } static void uvAcceptAsyncCb(uv_async_t* async) { SServerObj* srv = async->data; + uv_close((uv_handle_t*)&srv->server, NULL); uv_stop(srv->loop); } @@ -491,7 +512,7 @@ void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) { uv_handle_type pending = uv_pipe_pending_type(pipe); assert(pending == UV_TCP); - SSrvConn* pConn = createConn(); + SSrvConn* pConn = createConn(pThrd); pConn->pTransInst = pThrd->pTransInst; /* init conn timer*/ @@ -507,6 +528,9 @@ void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) { uv_tcp_init(pThrd->loop, pConn->pTcp); pConn->pTcp->data = pConn; + uv_tcp_nodelay(pConn->pTcp, 1); + uv_tcp_keepalive(pConn->pTcp, 1, 1); + // init write request, just pConn->pWriter = calloc(1, sizeof(uv_write_t)); pConn->pWriter->data = pConn; @@ -560,6 +584,9 @@ static bool addHandleToWorkloop(void* arg) { QUEUE_INIT(&pThrd->msg); pthread_mutex_init(&pThrd->msgMtx, NULL); + // conn set + QUEUE_INIT(&pThrd->conn); + pThrd->asyncPool = transCreateAsyncPool(pThrd->loop, 4, pThrd, uvWorkerAsyncCb); uv_read_start((uv_stream_t*)pThrd->pipe, uvAllocConnBufferCb, uvOnConnectionCb); return true; @@ -598,8 +625,13 @@ void* workerThread(void* arg) { uv_run(pThrd->loop, UV_RUN_DEFAULT); } -static SSrvConn* createConn() { +static SSrvConn* createConn(void* hThrd) { + SWorkThrdObj* pThrd = hThrd; + SSrvConn* pConn = (SSrvConn*)calloc(1, sizeof(SSrvConn)); + QUEUE_INIT(&pConn->queue); + + QUEUE_PUSH(&pThrd->conn, &pConn->queue); pConn->srvMsgs = taosArrayInit(2, sizeof(void*)); // tTrace("conn %p created", pConn); ++pConn->ref; @@ -610,7 +642,7 @@ static void destroyConn(SSrvConn* conn, bool clear) { if (conn == NULL) { return; } - tTrace("server conn %p try to destroy", conn); + tTrace("server conn %p try to destroy, ref: %d", conn, conn->ref); if (--conn->ref > 0) { return; } @@ -621,19 +653,18 @@ static void destroyConn(SSrvConn* conn, bool clear) { destroySmsg(msg); } taosArrayDestroy(conn->srvMsgs); - - // destroySmsg(conn->pSrvMsg); - // conn->pSrvMsg = NULL; + QUEUE_REMOVE(&conn->queue); if (clear) { - uv_close((uv_handle_t*)conn->pTcp, uvDestroyConn); + uv_tcp_close_reset(conn->pTcp, uvDestroyConn); + // uv_close((uv_handle_t*)conn->pTcp, uvDestroyConn); } } static void uvDestroyConn(uv_handle_t* handle) { SSrvConn* conn = handle->data; tDebug("server conn %p destroy", conn); uv_timer_stop(conn->pTimer); - free(conn->pTimer); + // free(conn->pTimer); // free(conn->pTcp); free(conn->pWriter); free(conn); diff --git a/source/os/src/osTimer.c b/source/os/src/osTimer.c index 7e542ef80f..bb526e0ba0 100644 --- a/source/os/src/osTimer.c +++ b/source/os/src/osTimer.c @@ -22,13 +22,12 @@ * windows implementation */ - -#include #include -#include +#include #include +#include -#pragma warning( disable : 4244 ) +#pragma warning(disable : 4244) typedef void (*win_timer_f)(int signo); @@ -40,8 +39,8 @@ void WINAPI taosWinOnTimer(UINT wTimerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR } static MMRESULT timerId; -int taosInitTimer(win_timer_f callback, int ms) { - DWORD_PTR param = *((int64_t *) & callback); +int taosInitTimer(win_timer_f callback, int ms) { + DWORD_PTR param = *((int64_t *)&callback); timerId = timeSetEvent(ms, 1, (LPTIMECALLBACK)taosWinOnTimer, param, TIME_PERIODIC); if (timerId == 0) { @@ -50,9 +49,7 @@ int taosInitTimer(win_timer_f callback, int ms) { return 0; } -void taosUninitTimer() { - timeKillEvent(timerId); -} +void taosUninitTimer() { timeKillEvent(timerId); } #elif defined(_TD_DARWIN_64) @@ -60,32 +57,32 @@ void taosUninitTimer() { * darwin implementation */ -#include #include +#include #include static void (*timer_callback)(int); -static int timer_ms = 0; -static pthread_t timer_thread; -static int timer_kq = -1; -static volatile int timer_stop = 0; +static int timer_ms = 0; +static pthread_t timer_thread; +static int timer_kq = -1; +static volatile int timer_stop = 0; -static void* timer_routine(void *arg) { +static void* timer_routine(void* arg) { (void)arg; setThreadName("timer"); - int r = 0; + int r = 0; struct timespec to = {0}; - to.tv_sec = timer_ms / 1000; - to.tv_nsec = (timer_ms % 1000) * 1000000; + to.tv_sec = timer_ms / 1000; + to.tv_nsec = (timer_ms % 1000) * 1000000; while (!timer_stop) { struct kevent64_s kev[10] = {0}; - r = kevent64(timer_kq, NULL, 0, kev, sizeof(kev)/sizeof(kev[0]), 0, &to); - if (r!=0) { + r = kevent64(timer_kq, NULL, 0, kev, sizeof(kev) / sizeof(kev[0]), 0, &to); + if (r != 0) { fprintf(stderr, "==%s[%d]%s()==kevent64 failed\n", basename(__FILE__), __LINE__, __func__); abort(); } - timer_callback(SIGALRM); // just mock + timer_callback(SIGALRM); // just mock } return NULL; @@ -93,11 +90,13 @@ static void* timer_routine(void *arg) { int taosInitTimer(void (*callback)(int), int ms) { int r = 0; - timer_ms = ms; + timer_kq = -1; + timer_stop = 0; + timer_ms = ms; timer_callback = callback; timer_kq = kqueue(); - if (timer_kq==-1) { + if (timer_kq == -1) { fprintf(stderr, "==%s[%d]%s()==failed to create timer kq\n", basename(__FILE__), __LINE__, __func__); // since no caller of this func checks the return value for the moment abort(); @@ -144,10 +143,10 @@ static void taosDeleteTimer(void *tharg) { timer_delete(*pTimer); } -static pthread_t timerThread; -static timer_t timerId; +static pthread_t timerThread; +static timer_t timerId; static volatile bool stopTimer = false; -static void *taosProcessAlarmSignal(void *tharg) { +static void * taosProcessAlarmSignal(void *tharg) { // Block the signal sigset_t sigset; sigemptyset(&sigset); @@ -159,18 +158,18 @@ static void *taosProcessAlarmSignal(void *tharg) { setThreadName("tmr"); - #ifdef _ALPINE - sevent.sigev_notify = SIGEV_THREAD; - sevent.sigev_value.sival_int = syscall(__NR_gettid); - #else - sevent.sigev_notify = SIGEV_THREAD_ID; - sevent._sigev_un._tid = syscall(__NR_gettid); - #endif - +#ifdef _ALPINE + sevent.sigev_notify = SIGEV_THREAD; + sevent.sigev_value.sival_int = syscall(__NR_gettid); +#else + sevent.sigev_notify = SIGEV_THREAD_ID; + sevent._sigev_un._tid = syscall(__NR_gettid); +#endif + sevent.sigev_signo = SIGALRM; if (timer_create(CLOCK_REALTIME, &sevent, &timerId) == -1) { - //printf("Failed to create timer"); + // printf("Failed to create timer"); } pthread_cleanup_push(taosDeleteTimer, &timerId); @@ -182,36 +181,37 @@ static void *taosProcessAlarmSignal(void *tharg) { ts.it_interval.tv_nsec = 1000000 * MSECONDS_PER_TICK; if (timer_settime(timerId, 0, &ts, NULL)) { - //printf("Failed to init timer"); + // printf("Failed to init timer"); return NULL; } int signo; while (!stopTimer) { if (sigwait(&sigset, &signo)) { - //printf("Failed to wait signal: number %d", signo); + // printf("Failed to wait signal: number %d", signo); continue; } /* //printf("Signal handling: number %d ......\n", signo); */ callback(0); } - + pthread_cleanup_pop(1); return NULL; } int taosInitTimer(void (*callback)(int), int ms) { + stopTimer = false; pthread_attr_t tattr; pthread_attr_init(&tattr); int code = pthread_create(&timerThread, &tattr, taosProcessAlarmSignal, callback); pthread_attr_destroy(&tattr); if (code != 0) { - //printf("failed to create timer thread"); + // printf("failed to create timer thread"); return -1; } else { - //printf("timer thread:0x%08" PRIx64 " is created", taosGetPthreadId(timerThread)); + // printf("timer thread:0x%08" PRIx64 " is created", taosGetPthreadId(timerThread)); } return 0; @@ -220,7 +220,7 @@ int taosInitTimer(void (*callback)(int), int ms) { void taosUninitTimer() { stopTimer = true; - //printf("join timer thread:0x%08" PRIx64, taosGetPthreadId(timerThread)); + // printf("join timer thread:0x%08" PRIx64, taosGetPthreadId(timerThread)); pthread_join(timerThread, NULL); } diff --git a/source/util/src/ttimer.c b/source/util/src/ttimer.c index 1fdc2257d7..65101a5e07 100644 --- a/source/util/src/ttimer.c +++ b/source/util/src/ttimer.c @@ -13,19 +13,49 @@ * along with this program. If not, see . */ +#include "ttimer.h" #include "os.h" +#include "taoserror.h" #include "tlog.h" #include "tsched.h" -#include "ttimer.h" #include "tutil.h" -#include "taoserror.h" -#define tmrFatal(...) { if (tmrDebugFlag & DEBUG_FATAL) { taosPrintLog("TMR FATAL ", tmrDebugFlag, __VA_ARGS__); }} -#define tmrError(...) { if (tmrDebugFlag & DEBUG_ERROR) { taosPrintLog("TMR ERROR ", tmrDebugFlag, __VA_ARGS__); }} -#define tmrWarn(...) { if (tmrDebugFlag & DEBUG_WARN) { taosPrintLog("TMR WARN ", tmrDebugFlag, __VA_ARGS__); }} -#define tmrInfo(...) { if (tmrDebugFlag & DEBUG_INFO) { taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); }} -#define tmrDebug(...) { if (tmrDebugFlag & DEBUG_DEBUG) { taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); }} -#define tmrTrace(...) { if (tmrDebugFlag & DEBUG_TRACE) { taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); }} +#define tmrFatal(...) \ + { \ + if (tmrDebugFlag & DEBUG_FATAL) { \ + taosPrintLog("TMR FATAL ", tmrDebugFlag, __VA_ARGS__); \ + } \ + } +#define tmrError(...) \ + { \ + if (tmrDebugFlag & DEBUG_ERROR) { \ + taosPrintLog("TMR ERROR ", tmrDebugFlag, __VA_ARGS__); \ + } \ + } +#define tmrWarn(...) \ + { \ + if (tmrDebugFlag & DEBUG_WARN) { \ + taosPrintLog("TMR WARN ", tmrDebugFlag, __VA_ARGS__); \ + } \ + } +#define tmrInfo(...) \ + { \ + if (tmrDebugFlag & DEBUG_INFO) { \ + taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); \ + } \ + } +#define tmrDebug(...) \ + { \ + if (tmrDebugFlag & DEBUG_DEBUG) { \ + taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); \ + } \ + } +#define tmrTrace(...) \ + { \ + if (tmrDebugFlag & DEBUG_TRACE) { \ + taosPrintLog("TMR ", tmrDebugFlag, __VA_ARGS__); \ + } \ + } #define TIMER_STATE_WAITING 0 #define TIMER_STATE_EXPIRED 1 @@ -81,7 +111,7 @@ typedef struct time_wheel_t { tmr_obj_t** slots; } time_wheel_t; -int32_t tmrDebugFlag = 131; +int32_t tmrDebugFlag = 131; uint32_t tsMaxTmrCtrl = 512; static pthread_once_t tmrModuleInit = PTHREAD_ONCE_INIT; @@ -91,7 +121,7 @@ static tmr_ctrl_t* unusedTmrCtrl = NULL; static void* tmrQhandle; static int numOfTmrCtrl = 0; -int taosTmrThreads = 1; +int taosTmrThreads = 1; static uintptr_t nextTimerId = 0; static time_wheel_t wheels[] = { @@ -119,7 +149,7 @@ static void timerDecRef(tmr_obj_t* timer) { static void lockTimerList(timer_list_t* list) { int64_t tid = taosGetSelfPthreadId(); - int i = 0; + int i = 0; while (atomic_val_compare_exchange_64(&(list->lockedBy), 0, tid) != 0) { if (++i % 1000 == 0) { sched_yield(); @@ -276,11 +306,11 @@ static void addToExpired(tmr_obj_t* head) { const char* fmt = "%s adding expired timer[id=%" PRIuPTR ", fp=%p, param=%p] to queue."; while (head != NULL) { - uintptr_t id = head->id; + uintptr_t id = head->id; tmr_obj_t* next = head->next; tmrDebug(fmt, head->ctrl->label, id, head->fp, head->param); - SSchedMsg schedMsg; + SSchedMsg schedMsg; schedMsg.fp = NULL; schedMsg.tfp = processExpiredTimer; schedMsg.msg = NULL; @@ -491,6 +521,8 @@ static void taosTmrModuleInit(void) { return; } + memset(&timerMap, 0, sizeof(timerMap)); + for (uint32_t i = 0; i < tsMaxTmrCtrl - 1; ++i) { tmr_ctrl_t* ctrl = tmrCtrls + i; ctrl->next = ctrl + 1; @@ -570,7 +602,8 @@ void taosTmrCleanUp(void* handle) { unusedTmrCtrl = ctrl; pthread_mutex_unlock(&tmrCtrlMutex); - if (numOfTmrCtrl <=0) { + tmrDebug("time controller's tmr ctrl size: %d", numOfTmrCtrl); + if (numOfTmrCtrl <= 0) { taosUninitTimer(); taosCleanUpScheduler(tmrQhandle); @@ -585,7 +618,7 @@ void taosTmrCleanUp(void* handle) { for (size_t i = 0; i < timerMap.size; i++) { timer_list_t* list = timerMap.slots + i; - tmr_obj_t* t = list->timers; + tmr_obj_t* t = list->timers; while (t != NULL) { tmr_obj_t* next = t->mnext; free(t); @@ -595,6 +628,8 @@ void taosTmrCleanUp(void* handle) { free(timerMap.slots); free(tmrCtrls); - tmrDebug("timer module is cleaned up"); + tmrCtrls = NULL; + unusedTmrCtrl = NULL; + tmrModuleInit = PTHREAD_ONCE_INIT; // to support restart } } From 7ee6657cf72ec203281d409580ebc7709339bcb7 Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Mon, 21 Feb 2022 10:48:23 +0800 Subject: [PATCH 04/12] extract convert to set msg --- include/util/tdef.h | 518 ++++++++++++++-------------- source/client/src/tmq.c | 6 +- source/common/src/tmsg.c | 2 + source/dnode/vnode/inc/vnode.h | 6 +- source/dnode/vnode/src/tq/tqRead.c | 33 +- source/libs/executor/src/executor.c | 11 +- 6 files changed, 296 insertions(+), 280 deletions(-) diff --git a/include/util/tdef.h b/include/util/tdef.h index 9b18c2dfb8..c46469a8c2 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -24,369 +24,367 @@ extern "C" { #define TSDB__packed -#define TSKEY int64_t -#define TSKEY_MIN INT64_MIN -#define TSKEY_MAX (INT64_MAX - 1) +#define TSKEY int64_t +#define TSKEY_MIN INT64_MIN +#define TSKEY_MAX (INT64_MAX - 1) #define TSKEY_INITIAL_VAL TSKEY_MIN // Bytes for each type. extern const int32_t TYPE_BYTES[15]; // TODO: replace and remove code below -#define CHAR_BYTES sizeof(char) -#define SHORT_BYTES sizeof(int16_t) -#define INT_BYTES sizeof(int32_t) -#define LONG_BYTES sizeof(int64_t) -#define FLOAT_BYTES sizeof(float) -#define DOUBLE_BYTES sizeof(double) -#define POINTER_BYTES sizeof(void *) // 8 by default assert(sizeof(ptrdiff_t) == sizseof(void*) -#define TSDB_KEYSIZE sizeof(TSKEY) -#define TSDB_NCHAR_SIZE sizeof(int32_t) +#define CHAR_BYTES sizeof(char) +#define SHORT_BYTES sizeof(int16_t) +#define INT_BYTES sizeof(int32_t) +#define LONG_BYTES sizeof(int64_t) +#define FLOAT_BYTES sizeof(float) +#define DOUBLE_BYTES sizeof(double) +#define POINTER_BYTES sizeof(void *) // 8 by default assert(sizeof(ptrdiff_t) == sizseof(void*) +#define TSDB_KEYSIZE sizeof(TSKEY) +#define TSDB_NCHAR_SIZE sizeof(int32_t) // NULL definition -#define TSDB_DATA_BOOL_NULL 0x02 -#define TSDB_DATA_TINYINT_NULL 0x80 -#define TSDB_DATA_SMALLINT_NULL 0x8000 -#define TSDB_DATA_INT_NULL 0x80000000L -#define TSDB_DATA_BIGINT_NULL 0x8000000000000000L -#define TSDB_DATA_TIMESTAMP_NULL TSDB_DATA_BIGINT_NULL +#define TSDB_DATA_BOOL_NULL 0x02 +#define TSDB_DATA_TINYINT_NULL 0x80 +#define TSDB_DATA_SMALLINT_NULL 0x8000 +#define TSDB_DATA_INT_NULL 0x80000000L +#define TSDB_DATA_BIGINT_NULL 0x8000000000000000L +#define TSDB_DATA_TIMESTAMP_NULL TSDB_DATA_BIGINT_NULL -#define TSDB_DATA_FLOAT_NULL 0x7FF00000 // it is an NAN -#define TSDB_DATA_DOUBLE_NULL 0x7FFFFF0000000000L // an NAN -#define TSDB_DATA_NCHAR_NULL 0xFFFFFFFF -#define TSDB_DATA_BINARY_NULL 0xFF +#define TSDB_DATA_FLOAT_NULL 0x7FF00000 // it is an NAN +#define TSDB_DATA_DOUBLE_NULL 0x7FFFFF0000000000L // an NAN +#define TSDB_DATA_NCHAR_NULL 0xFFFFFFFF +#define TSDB_DATA_BINARY_NULL 0xFF -#define TSDB_DATA_UTINYINT_NULL 0xFF -#define TSDB_DATA_USMALLINT_NULL 0xFFFF -#define TSDB_DATA_UINT_NULL 0xFFFFFFFF -#define TSDB_DATA_UBIGINT_NULL 0xFFFFFFFFFFFFFFFFL +#define TSDB_DATA_UTINYINT_NULL 0xFF +#define TSDB_DATA_USMALLINT_NULL 0xFFFF +#define TSDB_DATA_UINT_NULL 0xFFFFFFFF +#define TSDB_DATA_UBIGINT_NULL 0xFFFFFFFFFFFFFFFFL -#define TSDB_DATA_NULL_STR "NULL" -#define TSDB_DATA_NULL_STR_L "null" +#define TSDB_DATA_NULL_STR "NULL" +#define TSDB_DATA_NULL_STR_L "null" -#define TSDB_NETTEST_USER "nettestinternal" -#define TSDB_DEFAULT_USER "root" +#define TSDB_NETTEST_USER "nettestinternal" +#define TSDB_DEFAULT_USER "root" #ifdef _TD_POWER_ -#define TSDB_DEFAULT_PASS "powerdb" +#define TSDB_DEFAULT_PASS "powerdb" #elif (_TD_TQ_ == true) -#define TSDB_DEFAULT_PASS "tqueue" +#define TSDB_DEFAULT_PASS "tqueue" #elif (_TD_PRO_ == true) -#define TSDB_DEFAULT_PASS "prodb" +#define TSDB_DEFAULT_PASS "prodb" #else -#define TSDB_DEFAULT_PASS "taosdata" +#define TSDB_DEFAULT_PASS "taosdata" #endif -#define SHELL_MAX_PASSWORD_LEN 20 +#define SHELL_MAX_PASSWORD_LEN 20 -#define TSDB_TRUE 1 -#define TSDB_FALSE 0 -#define TSDB_OK 0 +#define TSDB_TRUE 1 +#define TSDB_FALSE 0 +#define TSDB_OK 0 #define TSDB_ERR -1 #define TS_PATH_DELIMITER "." #define TS_ESCAPE_CHAR '`' -#define TSDB_TIME_PRECISION_MILLI 0 -#define TSDB_TIME_PRECISION_MICRO 1 -#define TSDB_TIME_PRECISION_NANO 2 +#define TSDB_TIME_PRECISION_MILLI 0 +#define TSDB_TIME_PRECISION_MICRO 1 +#define TSDB_TIME_PRECISION_NANO 2 #define TSDB_TIME_PRECISION_MILLI_STR "ms" #define TSDB_TIME_PRECISION_MICRO_STR "us" #define TSDB_TIME_PRECISION_NANO_STR "ns" -#define TSDB_TICK_PER_SECOND(precision) ((int64_t)((precision)==TSDB_TIME_PRECISION_MILLI ? 1e3L : ((precision)==TSDB_TIME_PRECISION_MICRO ? 1e6L : 1e9L))) +#define TSDB_TICK_PER_SECOND(precision) \ + ((int64_t)((precision) == TSDB_TIME_PRECISION_MILLI ? 1e3L \ + : ((precision) == TSDB_TIME_PRECISION_MICRO ? 1e6L : 1e9L))) #define T_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#define T_APPEND_MEMBER(dst, ptr, type, member) \ -do {\ - memcpy((void *)(dst), (void *)(&((ptr)->member)), T_MEMBER_SIZE(type, member));\ - dst = (void *)((char *)(dst) + T_MEMBER_SIZE(type, member));\ -} while(0) -#define T_READ_MEMBER(src, type, target) \ -do { \ - (target) = *(type *)(src); \ - (src) = (void *)((char *)src + sizeof(type));\ -} while(0) - +#define T_APPEND_MEMBER(dst, ptr, type, member) \ + do { \ + memcpy((void *)(dst), (void *)(&((ptr)->member)), T_MEMBER_SIZE(type, member)); \ + dst = (void *)((char *)(dst) + T_MEMBER_SIZE(type, member)); \ + } while (0) +#define T_READ_MEMBER(src, type, target) \ + do { \ + (target) = *(type *)(src); \ + (src) = (void *)((char *)src + sizeof(type)); \ + } while (0) // TODO: check if below is necessary -#define TSDB_RELATION_INVALID 0 -#define TSDB_RELATION_LESS 1 -#define TSDB_RELATION_GREATER 2 -#define TSDB_RELATION_EQUAL 3 -#define TSDB_RELATION_LESS_EQUAL 4 +#define TSDB_RELATION_INVALID 0 +#define TSDB_RELATION_LESS 1 +#define TSDB_RELATION_GREATER 2 +#define TSDB_RELATION_EQUAL 3 +#define TSDB_RELATION_LESS_EQUAL 4 #define TSDB_RELATION_GREATER_EQUAL 5 -#define TSDB_RELATION_NOT_EQUAL 6 -#define TSDB_RELATION_LIKE 7 -#define TSDB_RELATION_ISNULL 8 -#define TSDB_RELATION_NOTNULL 9 -#define TSDB_RELATION_IN 10 +#define TSDB_RELATION_NOT_EQUAL 6 +#define TSDB_RELATION_LIKE 7 +#define TSDB_RELATION_ISNULL 8 +#define TSDB_RELATION_NOTNULL 9 +#define TSDB_RELATION_IN 10 -#define TSDB_RELATION_AND 11 -#define TSDB_RELATION_OR 12 -#define TSDB_RELATION_NOT 13 +#define TSDB_RELATION_AND 11 +#define TSDB_RELATION_OR 12 +#define TSDB_RELATION_NOT 13 -#define TSDB_RELATION_MATCH 14 -#define TSDB_RELATION_NMATCH 15 +#define TSDB_RELATION_MATCH 14 +#define TSDB_RELATION_NMATCH 15 -#define TSDB_BINARY_OP_ADD 4000 -#define TSDB_BINARY_OP_SUBTRACT 4001 -#define TSDB_BINARY_OP_MULTIPLY 4002 -#define TSDB_BINARY_OP_DIVIDE 4003 -#define TSDB_BINARY_OP_REMAINDER 4004 -#define TSDB_BINARY_OP_CONCAT 4005 +#define TSDB_BINARY_OP_ADD 4000 +#define TSDB_BINARY_OP_SUBTRACT 4001 +#define TSDB_BINARY_OP_MULTIPLY 4002 +#define TSDB_BINARY_OP_DIVIDE 4003 +#define TSDB_BINARY_OP_REMAINDER 4004 +#define TSDB_BINARY_OP_CONCAT 4005 -#define FUNCTION_CEIL 4500 -#define FUNCTION_FLOOR 4501 -#define FUNCTION_ABS 4502 -#define FUNCTION_ROUND 4503 +#define FUNCTION_CEIL 4500 +#define FUNCTION_FLOOR 4501 +#define FUNCTION_ABS 4502 +#define FUNCTION_ROUND 4503 -#define FUNCTION_LENGTH 4800 -#define FUNCTION_CONCAT 4801 -#define FUNCTION_LTRIM 4802 -#define FUNCTION_RTRIM 4803 +#define FUNCTION_LENGTH 4800 +#define FUNCTION_CONCAT 4801 +#define FUNCTION_LTRIM 4802 +#define FUNCTION_RTRIM 4803 -#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN)) +#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN)) #define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER)) -#define TSDB_NAME_DELIMITER_LEN 1 +#define TSDB_NAME_DELIMITER_LEN 1 -#define TSDB_UNI_LEN 24 -#define TSDB_USER_LEN TSDB_UNI_LEN +#define TSDB_UNI_LEN 24 +#define TSDB_USER_LEN TSDB_UNI_LEN // ACCOUNT is a 32 bit positive integer // this is the length of its string representation, including the terminator zero -#define TSDB_ACCT_ID_LEN 11 +#define TSDB_ACCT_ID_LEN 11 -#define TSDB_MAX_COLUMNS 4096 -#define TSDB_MIN_COLUMNS 2 //PRIMARY COLUMN(timestamp) + other columns +#define TSDB_MAX_COLUMNS 4096 +#define TSDB_MIN_COLUMNS 2 // PRIMARY COLUMN(timestamp) + other columns -#define TSDB_NODE_NAME_LEN 64 -#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string -#define TSDB_TOPIC_NAME_LEN 193 // it is a null-terminated string -#define TSDB_DB_NAME_LEN 65 -#define TSDB_DB_FNAME_LEN (TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN) +#define TSDB_NODE_NAME_LEN 64 +#define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string +#define TSDB_TOPIC_NAME_LEN 193 // it is a null-terminated string +#define TSDB_DB_NAME_LEN 65 +#define TSDB_DB_FNAME_LEN (TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN) -#define TSDB_FUNC_NAME_LEN 65 -#define TSDB_FUNC_COMMENT_LEN 4096 -#define TSDB_FUNC_CODE_LEN (65535 - 512) -#define TSDB_FUNC_BUF_SIZE 512 -#define TSDB_FUNC_TYPE_SCALAR 1 -#define TSDB_FUNC_TYPE_AGGREGATE 2 -#define TSDB_FUNC_MAX_RETRIEVE 1024 +#define TSDB_FUNC_NAME_LEN 65 +#define TSDB_FUNC_COMMENT_LEN 4096 +#define TSDB_FUNC_CODE_LEN (65535 - 512) +#define TSDB_FUNC_BUF_SIZE 512 +#define TSDB_FUNC_TYPE_SCALAR 1 +#define TSDB_FUNC_TYPE_AGGREGATE 2 +#define TSDB_FUNC_MAX_RETRIEVE 1024 -#define TSDB_TYPE_STR_MAX_LEN 32 -#define TSDB_TABLE_FNAME_LEN (TSDB_DB_FNAME_LEN + TSDB_TABLE_NAME_LEN + TSDB_NAME_DELIMITER_LEN) -#define TSDB_TOPIC_FNAME_LEN TSDB_TABLE_FNAME_LEN -#define TSDB_CONSUMER_GROUP_LEN 192 -#define TSDB_SUBSCRIBE_KEY_LEN (TSDB_CONSUMER_GROUP_LEN + TSDB_TOPIC_FNAME_LEN + 2) -#define TSDB_COL_NAME_LEN 65 -#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64 -#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE -#define TSDB_MAX_SQL_SHOW_LEN 1024 -#define TSDB_MAX_ALLOWED_SQL_LEN (1*1024*1024u) // sql length should be less than 1mb +#define TSDB_TYPE_STR_MAX_LEN 32 +#define TSDB_TABLE_FNAME_LEN (TSDB_DB_FNAME_LEN + TSDB_TABLE_NAME_LEN + TSDB_NAME_DELIMITER_LEN) +#define TSDB_TOPIC_FNAME_LEN TSDB_TABLE_FNAME_LEN +#define TSDB_CONSUMER_GROUP_LEN 192 +#define TSDB_SUBSCRIBE_KEY_LEN (TSDB_CONSUMER_GROUP_LEN + TSDB_TOPIC_FNAME_LEN + 2) +#define TSDB_COL_NAME_LEN 65 +#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64 +#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE +#define TSDB_MAX_SQL_SHOW_LEN 1024 +#define TSDB_MAX_ALLOWED_SQL_LEN (1 * 1024 * 1024u) // sql length should be less than 1mb -#define TSDB_APP_NAME_LEN TSDB_UNI_LEN -#define TSDB_STB_COMMENT_LEN 1024 - /** - * In some scenarios uint16_t (0~65535) is used to store the row len. - * - Firstly, we use 65531(65535 - 4), as the SDataRow/SKVRow contains 4 bits header. - * - Secondly, if all cols are VarDataT type except primary key, we need 4 bits to store the offset, thus - * the final value is 65531-(4096-1)*4 = 49151. - */ -#define TSDB_MAX_BYTES_PER_ROW 49151 -#define TSDB_MAX_TAGS_LEN 16384 -#define TSDB_MAX_TAGS 128 -#define TSDB_MAX_TAG_CONDITIONS 1024 +#define TSDB_APP_NAME_LEN TSDB_UNI_LEN +#define TSDB_STB_COMMENT_LEN 1024 +/** + * In some scenarios uint16_t (0~65535) is used to store the row len. + * - Firstly, we use 65531(65535 - 4), as the SDataRow/SKVRow contains 4 bits header. + * - Secondly, if all cols are VarDataT type except primary key, we need 4 bits to store the offset, thus + * the final value is 65531-(4096-1)*4 = 49151. + */ +#define TSDB_MAX_BYTES_PER_ROW 49151 +#define TSDB_MAX_TAGS_LEN 16384 +#define TSDB_MAX_TAGS 128 +#define TSDB_MAX_TAG_CONDITIONS 1024 -#define TSDB_AUTH_LEN 16 -#define TSDB_PASSWORD_LEN 32 -#define TSDB_USET_PASSWORD_LEN 129 -#define TSDB_VERSION_LEN 12 -#define TSDB_LABEL_LEN 8 +#define TSDB_AUTH_LEN 16 +#define TSDB_PASSWORD_LEN 32 +#define TSDB_USET_PASSWORD_LEN 129 +#define TSDB_VERSION_LEN 12 +#define TSDB_LABEL_LEN 8 -#define TSDB_CLUSTER_ID_LEN 40 -#define TSDB_FQDN_LEN 128 -#define TSDB_EP_LEN (TSDB_FQDN_LEN + 6) -#define TSDB_IPv4ADDR_LEN 16 -#define TSDB_FILENAME_LEN 128 -#define TSDB_SHOW_SQL_LEN 512 -#define TSDB_SHOW_SUBQUERY_LEN 1000 -#define TSDB_SLOW_QUERY_SQL_LEN 512 +#define TSDB_CLUSTER_ID_LEN 40 +#define TSDB_FQDN_LEN 128 +#define TSDB_EP_LEN (TSDB_FQDN_LEN + 6) +#define TSDB_IPv4ADDR_LEN 16 +#define TSDB_FILENAME_LEN 128 +#define TSDB_SHOW_SQL_LEN 512 +#define TSDB_SHOW_SUBQUERY_LEN 1000 +#define TSDB_SLOW_QUERY_SQL_LEN 512 -#define TSDB_TRANS_STAGE_LEN 12 -#define TSDB_TRANS_DESC_LEN 16 -#define TSDB_TRANS_ERROR_LEN 128 +#define TSDB_TRANS_STAGE_LEN 12 +#define TSDB_TRANS_DESC_LEN 16 +#define TSDB_TRANS_ERROR_LEN 128 -#define TSDB_STEP_NAME_LEN 32 -#define TSDB_STEP_DESC_LEN 128 +#define TSDB_STEP_NAME_LEN 32 +#define TSDB_STEP_DESC_LEN 128 -#define TSDB_ERROR_MSG_LEN 1024 -#define TSDB_DNODE_CONFIG_LEN 128 -#define TSDB_DNODE_VALUE_LEN 256 +#define TSDB_ERROR_MSG_LEN 1024 +#define TSDB_DNODE_CONFIG_LEN 128 +#define TSDB_DNODE_VALUE_LEN 256 -#define TSDB_MQTT_HOSTNAME_LEN 64 -#define TSDB_MQTT_PORT_LEN 8 -#define TSDB_MQTT_USER_LEN 24 -#define TSDB_MQTT_PASS_LEN 24 -#define TSDB_MQTT_TOPIC_LEN 64 -#define TSDB_MQTT_CLIENT_ID_LEN 32 +#define TSDB_MQTT_HOSTNAME_LEN 64 +#define TSDB_MQTT_PORT_LEN 8 +#define TSDB_MQTT_USER_LEN 24 +#define TSDB_MQTT_PASS_LEN 24 +#define TSDB_MQTT_TOPIC_LEN 64 +#define TSDB_MQTT_CLIENT_ID_LEN 32 -#define TSDB_DB_TYPE_DEFAULT 0 -#define TSDB_DB_TYPE_TOPIC 1 +#define TSDB_DB_TYPE_DEFAULT 0 +#define TSDB_DB_TYPE_TOPIC 1 -#define TSDB_DEFAULT_PKT_SIZE 65480 //same as RPC_MAX_UDP_SIZE +#define TSDB_DEFAULT_PKT_SIZE 65480 // same as RPC_MAX_UDP_SIZE #define TSDB_PAYLOAD_SIZE TSDB_DEFAULT_PKT_SIZE -#define TSDB_DEFAULT_PAYLOAD_SIZE 5120 // default payload size, greater than PATH_MAX value -#define TSDB_EXTRA_PAYLOAD_SIZE 128 // extra bytes for auth +#define TSDB_DEFAULT_PAYLOAD_SIZE 5120 // default payload size, greater than PATH_MAX value +#define TSDB_EXTRA_PAYLOAD_SIZE 128 // extra bytes for auth #define TSDB_CQ_SQL_SIZE 1024 #define TSDB_MIN_VNODES 16 #define TSDB_MAX_VNODES 512 #define TSDB_MIN_VNODES_PER_DB 1 #define TSDB_MAX_VNODES_PER_DB 4096 -#define TSDB_DEFAULT_VN_PER_DB 2 +#define TSDB_DEFAULT_VN_PER_DB 2 -#define TSDB_DNODE_ROLE_ANY 0 -#define TSDB_DNODE_ROLE_MGMT 1 -#define TSDB_DNODE_ROLE_VNODE 2 +#define TSDB_DNODE_ROLE_ANY 0 +#define TSDB_DNODE_ROLE_MGMT 1 +#define TSDB_DNODE_ROLE_VNODE 2 -#define TSDB_MAX_REPLICA 5 +#define TSDB_MAX_REPLICA 5 -#define TSDB_TBNAME_COLUMN_INDEX (-1) -#define TSDB_UD_COLUMN_INDEX (-1000) -#define TSDB_RES_COL_ID (-5000) +#define TSDB_TBNAME_COLUMN_INDEX (-1) +#define TSDB_UD_COLUMN_INDEX (-1000) +#define TSDB_RES_COL_ID (-5000) -#define TSDB_MULTI_TABLEMETA_MAX_NUM 100000 // maximum batch size allowed to load table meta - -#define TSDB_MIN_CACHE_BLOCK_SIZE 1 -#define TSDB_MAX_CACHE_BLOCK_SIZE 128 // 128MB for each vnode -#define TSDB_DEFAULT_CACHE_BLOCK_SIZE 16 +#define TSDB_MULTI_TABLEMETA_MAX_NUM 100000 // maximum batch size allowed to load table meta -#define TSDB_MIN_TOTAL_BLOCKS 3 -#define TSDB_MAX_TOTAL_BLOCKS 10000 -#define TSDB_DEFAULT_TOTAL_BLOCKS 6 +#define TSDB_MIN_CACHE_BLOCK_SIZE 1 +#define TSDB_MAX_CACHE_BLOCK_SIZE 128 // 128MB for each vnode +#define TSDB_DEFAULT_CACHE_BLOCK_SIZE 16 -#define TSDB_MIN_DAYS_PER_FILE 1 -#define TSDB_MAX_DAYS_PER_FILE 3650 -#define TSDB_DEFAULT_DAYS_PER_FILE 10 +#define TSDB_MIN_TOTAL_BLOCKS 3 +#define TSDB_MAX_TOTAL_BLOCKS 10000 +#define TSDB_DEFAULT_TOTAL_BLOCKS 6 -#define TSDB_MIN_KEEP 1 // data in db to be reserved. -#define TSDB_MAX_KEEP 365000 // data in db to be reserved. -#define TSDB_DEFAULT_KEEP 3650 // ten years +#define TSDB_MIN_DAYS_PER_FILE 1 +#define TSDB_MAX_DAYS_PER_FILE 3650 +#define TSDB_DEFAULT_DAYS_PER_FILE 10 -#define TSDB_MIN_MIN_ROW_FBLOCK 10 -#define TSDB_MAX_MIN_ROW_FBLOCK 1000 -#define TSDB_DEFAULT_MIN_ROW_FBLOCK 100 +#define TSDB_MIN_KEEP 1 // data in db to be reserved. +#define TSDB_MAX_KEEP 365000 // data in db to be reserved. +#define TSDB_DEFAULT_KEEP 3650 // ten years -#define TSDB_MIN_MAX_ROW_FBLOCK 200 -#define TSDB_MAX_MAX_ROW_FBLOCK 10000 -#define TSDB_DEFAULT_MAX_ROW_FBLOCK 4096 +#define TSDB_MIN_MIN_ROW_FBLOCK 10 +#define TSDB_MAX_MIN_ROW_FBLOCK 1000 +#define TSDB_DEFAULT_MIN_ROW_FBLOCK 100 -#define TSDB_MIN_COMMIT_TIME 30 -#define TSDB_MAX_COMMIT_TIME 40960 -#define TSDB_DEFAULT_COMMIT_TIME 3600 +#define TSDB_MIN_MAX_ROW_FBLOCK 200 +#define TSDB_MAX_MAX_ROW_FBLOCK 10000 +#define TSDB_DEFAULT_MAX_ROW_FBLOCK 4096 -#define TSDB_MIN_FSYNC_PERIOD 0 -#define TSDB_MAX_FSYNC_PERIOD 180000 // millisecond -#define TSDB_DEFAULT_FSYNC_PERIOD 3000 // three second +#define TSDB_MIN_COMMIT_TIME 30 +#define TSDB_MAX_COMMIT_TIME 40960 +#define TSDB_DEFAULT_COMMIT_TIME 3600 -#define TSDB_MIN_WAL_LEVEL 0 -#define TSDB_MAX_WAL_LEVEL 2 -#define TSDB_DEFAULT_WAL_LEVEL 1 +#define TSDB_MIN_FSYNC_PERIOD 0 +#define TSDB_MAX_FSYNC_PERIOD 180000 // millisecond +#define TSDB_DEFAULT_FSYNC_PERIOD 3000 // three second -#define TSDB_MIN_PRECISION TSDB_TIME_PRECISION_MILLI -#define TSDB_MAX_PRECISION TSDB_TIME_PRECISION_NANO -#define TSDB_DEFAULT_PRECISION TSDB_TIME_PRECISION_MILLI +#define TSDB_MIN_WAL_LEVEL 0 +#define TSDB_MAX_WAL_LEVEL 2 +#define TSDB_DEFAULT_WAL_LEVEL 1 -#define TSDB_MIN_COMP_LEVEL 0 -#define TSDB_MAX_COMP_LEVEL 2 -#define TSDB_DEFAULT_COMP_LEVEL 2 +#define TSDB_MIN_PRECISION TSDB_TIME_PRECISION_MILLI +#define TSDB_MAX_PRECISION TSDB_TIME_PRECISION_NANO +#define TSDB_DEFAULT_PRECISION TSDB_TIME_PRECISION_MILLI -#define TSDB_MIN_DB_REPLICA_OPTION 1 -#define TSDB_MAX_DB_REPLICA_OPTION 3 -#define TSDB_DEFAULT_DB_REPLICA_OPTION 1 +#define TSDB_MIN_COMP_LEVEL 0 +#define TSDB_MAX_COMP_LEVEL 2 +#define TSDB_DEFAULT_COMP_LEVEL 2 -#define TSDB_MIN_DB_QUORUM_OPTION 1 -#define TSDB_MAX_DB_QUORUM_OPTION 2 -#define TSDB_DEFAULT_DB_QUORUM_OPTION 1 +#define TSDB_MIN_DB_REPLICA_OPTION 1 +#define TSDB_MAX_DB_REPLICA_OPTION 3 +#define TSDB_DEFAULT_DB_REPLICA_OPTION 1 -#define TSDB_MIN_DB_UPDATE 0 -#define TSDB_MAX_DB_UPDATE 2 -#define TSDB_DEFAULT_DB_UPDATE_OPTION 0 +#define TSDB_MIN_DB_QUORUM_OPTION 1 +#define TSDB_MAX_DB_QUORUM_OPTION 2 +#define TSDB_DEFAULT_DB_QUORUM_OPTION 1 -#define TSDB_MIN_DB_CACHE_LAST_ROW 0 -#define TSDB_MAX_DB_CACHE_LAST_ROW 3 -#define TSDB_DEFAULT_CACHE_LAST_ROW 0 +#define TSDB_MIN_DB_UPDATE 0 +#define TSDB_MAX_DB_UPDATE 2 +#define TSDB_DEFAULT_DB_UPDATE_OPTION 0 -#define TSDB_MAX_JOIN_TABLE_NUM 10 -#define TSDB_MAX_UNION_CLAUSE 5 +#define TSDB_MIN_DB_CACHE_LAST_ROW 0 +#define TSDB_MAX_DB_CACHE_LAST_ROW 3 +#define TSDB_DEFAULT_CACHE_LAST_ROW 0 -#define TSDB_MAX_FIELD_LEN 16384 -#define TSDB_MAX_BINARY_LEN (TSDB_MAX_FIELD_LEN-TSDB_KEYSIZE) // keep 16384 -#define TSDB_MAX_NCHAR_LEN (TSDB_MAX_FIELD_LEN-TSDB_KEYSIZE) // keep 16384 -#define PRIMARYKEY_TIMESTAMP_COL_ID 1 -#define COL_REACH_END(colId, maxColId) ((colId) > (maxColId)) +#define TSDB_MAX_JOIN_TABLE_NUM 10 +#define TSDB_MAX_UNION_CLAUSE 5 -#define TSDB_MAX_RPC_THREADS 5 +#define TSDB_MAX_FIELD_LEN 16384 +#define TSDB_MAX_BINARY_LEN (TSDB_MAX_FIELD_LEN - TSDB_KEYSIZE) // keep 16384 +#define TSDB_MAX_NCHAR_LEN (TSDB_MAX_FIELD_LEN - TSDB_KEYSIZE) // keep 16384 +#define PRIMARYKEY_TIMESTAMP_COL_ID 1 +#define COL_REACH_END(colId, maxColId) ((colId) > (maxColId)) -#define TSDB_QUERY_TYPE_NON_TYPE 0x00u // none type -#define TSDB_QUERY_TYPE_FREE_RESOURCE 0x01u // free qhandle at vnode - - -#define TSDB_META_COMPACT_RATIO 0 // disable tsdb meta compact by default +#define TSDB_MAX_RPC_THREADS 5 +#define TSDB_QUERY_TYPE_NON_TYPE 0x00u // none type +#define TSDB_QUERY_TYPE_FREE_RESOURCE 0x01u // free qhandle at vnode +#define TSDB_META_COMPACT_RATIO 0 // disable tsdb meta compact by default /* * 1. ordinary sub query for select * from super_table * 2. all sqlobj generated by createSubqueryObj with this flag */ -#define TSDB_QUERY_TYPE_SUBQUERY 0x02u -#define TSDB_QUERY_TYPE_STABLE_SUBQUERY 0x04u // two-stage subquery for super table +#define TSDB_QUERY_TYPE_SUBQUERY 0x02u +#define TSDB_QUERY_TYPE_STABLE_SUBQUERY 0x04u // two-stage subquery for super table -#define TSDB_QUERY_TYPE_TABLE_QUERY 0x08u // query ordinary table; below only apply to client side -#define TSDB_QUERY_TYPE_STABLE_QUERY 0x10u // query on super table -#define TSDB_QUERY_TYPE_JOIN_QUERY 0x20u // join query -#define TSDB_QUERY_TYPE_PROJECTION_QUERY 0x40u // select *,columns... query -#define TSDB_QUERY_TYPE_JOIN_SEC_STAGE 0x80u // join sub query at the second stage +#define TSDB_QUERY_TYPE_TABLE_QUERY 0x08u // query ordinary table; below only apply to client side +#define TSDB_QUERY_TYPE_STABLE_QUERY 0x10u // query on super table +#define TSDB_QUERY_TYPE_JOIN_QUERY 0x20u // join query +#define TSDB_QUERY_TYPE_PROJECTION_QUERY 0x40u // select *,columns... query +#define TSDB_QUERY_TYPE_JOIN_SEC_STAGE 0x80u // join sub query at the second stage -#define TSDB_QUERY_TYPE_TAG_FILTER_QUERY 0x400u -#define TSDB_QUERY_TYPE_INSERT 0x100u // insert type -#define TSDB_QUERY_TYPE_MULTITABLE_QUERY 0x200u -#define TSDB_QUERY_TYPE_FILE_INSERT 0x400u // insert data from file -#define TSDB_QUERY_TYPE_STMT_INSERT 0x800u // stmt insert type -#define TSDB_QUERY_TYPE_NEST_SUBQUERY 0x1000u // nested sub query +#define TSDB_QUERY_TYPE_TAG_FILTER_QUERY 0x400u +#define TSDB_QUERY_TYPE_INSERT 0x100u // insert type +#define TSDB_QUERY_TYPE_MULTITABLE_QUERY 0x200u +#define TSDB_QUERY_TYPE_FILE_INSERT 0x400u // insert data from file +#define TSDB_QUERY_TYPE_STMT_INSERT 0x800u // stmt insert type +#define TSDB_QUERY_TYPE_NEST_SUBQUERY 0x1000u // nested sub query -#define TSDB_QUERY_HAS_TYPE(x, _type) (((x) & (_type)) != 0) -#define TSDB_QUERY_SET_TYPE(x, _type) ((x) |= (_type)) -#define TSDB_QUERY_CLEAR_TYPE(x, _type) ((x) &= (~_type)) -#define TSDB_QUERY_RESET_TYPE(x) ((x) = TSDB_QUERY_TYPE_NON_TYPE) +#define TSDB_QUERY_HAS_TYPE(x, _type) (((x) & (_type)) != 0) +#define TSDB_QUERY_SET_TYPE(x, _type) ((x) |= (_type)) +#define TSDB_QUERY_CLEAR_TYPE(x, _type) ((x) &= (~_type)) +#define TSDB_QUERY_RESET_TYPE(x) ((x) = TSDB_QUERY_TYPE_NON_TYPE) -#define TSDB_ORDER_ASC 1 -#define TSDB_ORDER_DESC 2 - -#define TSDB_DEFAULT_CLUSTER_HASH_SIZE 1 -#define TSDB_DEFAULT_MNODES_HASH_SIZE 5 -#define TSDB_DEFAULT_DNODES_HASH_SIZE 10 -#define TSDB_DEFAULT_ACCOUNTS_HASH_SIZE 10 -#define TSDB_DEFAULT_USERS_HASH_SIZE 20 -#define TSDB_DEFAULT_DBS_HASH_SIZE 100 -#define TSDB_DEFAULT_VGROUPS_HASH_SIZE 100 -#define TSDB_DEFAULT_STABLES_HASH_SIZE 100 -#define TSDB_DEFAULT_CTABLES_HASH_SIZE 20000 +#define TSDB_ORDER_ASC 1 +#define TSDB_ORDER_DESC 2 -#define TSDB_MAX_WAL_SIZE (1024*1024*3) +#define TSDB_DEFAULT_CLUSTER_HASH_SIZE 1 +#define TSDB_DEFAULT_MNODES_HASH_SIZE 5 +#define TSDB_DEFAULT_DNODES_HASH_SIZE 10 +#define TSDB_DEFAULT_ACCOUNTS_HASH_SIZE 10 +#define TSDB_DEFAULT_USERS_HASH_SIZE 20 +#define TSDB_DEFAULT_DBS_HASH_SIZE 100 +#define TSDB_DEFAULT_VGROUPS_HASH_SIZE 100 +#define TSDB_DEFAULT_STABLES_HASH_SIZE 100 +#define TSDB_DEFAULT_CTABLES_HASH_SIZE 20000 -#define TSDB_ARB_DUMMY_TIME 4765104000000 // 2121-01-01 00:00:00.000, :P +#define TSDB_MAX_WAL_SIZE (1024 * 1024 * 3) -#define TFS_MAX_TIERS 3 +#define TSDB_ARB_DUMMY_TIME 4765104000000 // 2121-01-01 00:00:00.000, :P + +#define TFS_MAX_TIERS 3 #define TFS_MAX_DISKS_PER_TIER 16 -#define TFS_MAX_DISKS (TFS_MAX_TIERS * TFS_MAX_DISKS_PER_TIER) -#define TFS_MIN_LEVEL 0 -#define TFS_MAX_LEVEL (TFS_MAX_TIERS - 1) -#define TFS_PRIMARY_LEVEL 0 -#define TFS_PRIMARY_ID 0 +#define TFS_MAX_DISKS (TFS_MAX_TIERS * TFS_MAX_DISKS_PER_TIER) +#define TFS_MIN_LEVEL 0 +#define TFS_MAX_LEVEL (TFS_MAX_TIERS - 1) +#define TFS_PRIMARY_LEVEL 0 +#define TFS_PRIMARY_ID 0 #define TFS_MIN_DISK_FREE_SIZE 50 * 1024 * 1024 enum { TRANS_STAT_INIT = 0, TRANS_STAT_EXECUTING, TRANS_STAT_EXECUTED, TRANS_STAT_ROLLBACKING, TRANS_STAT_ROLLBACKED }; diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 9855a65b0b..229d3a9ec3 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -75,7 +75,7 @@ struct tmq_message_t { SMqConsumeRsp rsp; }; -typedef struct SMqClientVg { +typedef struct { // statistics int64_t pollCnt; // offset @@ -86,7 +86,7 @@ typedef struct SMqClientVg { SEpSet epSet; } SMqClientVg; -typedef struct SMqClientTopic { +typedef struct { // subscribe info int32_t sqlLen; char* sql; @@ -779,11 +779,9 @@ tmq_message_t* tmq_consumer_poll(tmq_t* tmq, int64_t blocking_time) { param->pVg = pVg; tsem_init(¶m->rspSem, 0, 0); - SRequestObj* pRequest = createRequest(tmq->pTscObj, NULL, NULL, TDMT_VND_CONSUME); pRequest->body.requestMsg = (SDataBuf){.pData = pReq, .len = sizeof(SMqConsumeReq), .handle = NULL}; - SMsgSendInfo* sendInfo = buildMsgInfoImpl(pRequest); sendInfo->requestObjRefId = 0; sendInfo->param = param; diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index ac46c0c48c..46feab7791 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -34,6 +34,7 @@ int32_t tInitSubmitMsgIter(SSubmitReq *pMsg, SSubmitMsgIter *pIter) { } pIter->totalLen = pMsg->length; + ASSERT(pIter->totalLen > 0); pIter->len = 0; pIter->pMsg = pMsg; if (pMsg->length <= sizeof(SSubmitReq)) { @@ -52,6 +53,7 @@ int32_t tGetSubmitMsgNext(SSubmitMsgIter *pIter, SSubmitBlk **pPBlock) { } else { SSubmitBlk *pSubmitBlk = (SSubmitBlk *)POINTER_SHIFT(pIter->pMsg, pIter->len); pIter->len += (sizeof(SSubmitBlk) + pSubmitBlk->dataLen + pSubmitBlk->schemaLen); + ASSERT(pIter->len > 0); } if (pIter->len > pIter->totalLen) { diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 1fb0b05f9e..3a06674e3c 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -226,9 +226,9 @@ static FORCE_INLINE int tqReadHandleSetTbUidList(STqReadHandle *pHandle, const S return 0; } -void tqReadHandleSetMsg(STqReadHandle *pHandle, SSubmitReq *pMsg, int64_t ver); -bool tqNextDataBlock(STqReadHandle *pHandle); -int tqRetrieveDataBlockInfo(STqReadHandle *pHandle, SDataBlockInfo *pBlockInfo); +int32_t tqReadHandleSetMsg(STqReadHandle *pHandle, SSubmitReq *pMsg, int64_t ver); +bool tqNextDataBlock(STqReadHandle *pHandle); +int tqRetrieveDataBlockInfo(STqReadHandle *pHandle, SDataBlockInfo *pBlockInfo); // return SArray SArray *tqRetrieveDataBlock(STqReadHandle *pHandle); diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index e76d43becd..bfa811feec 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -31,13 +31,28 @@ STqReadHandle* tqInitSubmitMsgScanner(SMeta* pMeta) { return pReadHandle; } -void tqReadHandleSetMsg(STqReadHandle* pReadHandle, SSubmitReq* pMsg, int64_t ver) { +int32_t tqReadHandleSetMsg(STqReadHandle* pReadHandle, SSubmitReq* pMsg, int64_t ver) { pReadHandle->pMsg = pMsg; pMsg->length = htonl(pMsg->length); pMsg->numOfBlocks = htonl(pMsg->numOfBlocks); - tInitSubmitMsgIter(pMsg, &pReadHandle->msgIter); + + if (tInitSubmitMsgIter(pMsg, &pReadHandle->msgIter) < 0) return -1; + while (true) { + if (tGetSubmitMsgNext(&pReadHandle->msgIter, &pReadHandle->pBlock) < 0) return -1; + if (pReadHandle->pBlock == NULL) break; + + pReadHandle->pBlock->uid = htobe64(pReadHandle->pBlock->uid); + pReadHandle->pBlock->tid = htonl(pReadHandle->pBlock->tid); + pReadHandle->pBlock->sversion = htonl(pReadHandle->pBlock->sversion); + pReadHandle->pBlock->dataLen = htonl(pReadHandle->pBlock->dataLen); + pReadHandle->pBlock->schemaLen = htonl(pReadHandle->pBlock->schemaLen); + pReadHandle->pBlock->numOfRows = htons(pReadHandle->pBlock->numOfRows); + } + + if (tInitSubmitMsgIter(pMsg, &pReadHandle->msgIter) < 0) return -1; pReadHandle->ver = ver; memset(&pReadHandle->blkIter, 0, sizeof(SSubmitBlkIter)); + return 0; } bool tqNextDataBlock(STqReadHandle* pHandle) { @@ -47,19 +62,19 @@ bool tqNextDataBlock(STqReadHandle* pHandle) { } if (pHandle->pBlock == NULL) return false; - pHandle->pBlock->uid = htobe64(pHandle->pBlock->uid); + /*pHandle->pBlock->uid = htobe64(pHandle->pBlock->uid);*/ /*if (pHandle->tbUid == pHandle->pBlock->uid) {*/ ASSERT(pHandle->tbIdHash); void* ret = taosHashGet(pHandle->tbIdHash, &pHandle->pBlock->uid, sizeof(int64_t)); if (ret != NULL) { /*printf("retrieve one tb %ld\n", pHandle->pBlock->uid);*/ - pHandle->pBlock->tid = htonl(pHandle->pBlock->tid); - pHandle->pBlock->sversion = htonl(pHandle->pBlock->sversion); - pHandle->pBlock->dataLen = htonl(pHandle->pBlock->dataLen); - pHandle->pBlock->schemaLen = htonl(pHandle->pBlock->schemaLen); - pHandle->pBlock->numOfRows = htons(pHandle->pBlock->numOfRows); + /*pHandle->pBlock->tid = htonl(pHandle->pBlock->tid);*/ + /*pHandle->pBlock->sversion = htonl(pHandle->pBlock->sversion);*/ + /*pHandle->pBlock->dataLen = htonl(pHandle->pBlock->dataLen);*/ + /*pHandle->pBlock->schemaLen = htonl(pHandle->pBlock->schemaLen);*/ + /*pHandle->pBlock->numOfRows = htons(pHandle->pBlock->numOfRows);*/ return true; - } else { + /*} else {*/ /*printf("skip one tb %ld\n", pHandle->pBlock->uid);*/ } } diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c index c47c83ba29..18485249b3 100644 --- a/source/libs/executor/src/executor.c +++ b/source/libs/executor/src/executor.c @@ -14,9 +14,9 @@ */ #include "executor.h" -#include "tq.h" #include "executorimpl.h" #include "planner.h" +#include "tq.h" static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, char* id) { ASSERT(pOperator != NULL); @@ -34,7 +34,10 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, char* id) return doSetStreamBlock(pOperator->pDownstream[0], input, id); } else { SStreamBlockScanInfo* pInfo = pOperator->info; - tqReadHandleSetMsg(pInfo->readerHandle, input, 0); + if (tqReadHandleSetMsg(pInfo->readerHandle, input, 0) < 0) { + qError("submit msg error while set stream msg, %s" PRIx64, id); + return TSDB_CODE_QRY_APP_ERROR; + } return TSDB_CODE_SUCCESS; } } @@ -48,9 +51,9 @@ int32_t qSetStreamInput(qTaskInfo_t tinfo, const void* input) { return TSDB_CODE_SUCCESS; } - SExecTaskInfo* pTaskInfo = (SExecTaskInfo*) tinfo; + SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; - int32_t code = doSetStreamBlock(pTaskInfo->pRoot, (void*) input, GET_TASKID(pTaskInfo)); + int32_t code = doSetStreamBlock(pTaskInfo->pRoot, (void*)input, GET_TASKID(pTaskInfo)); if (code != TSDB_CODE_SUCCESS) { qError("%s failed to set the stream block data", GET_TASKID(pTaskInfo)); } else { From bad804e38dba4e6b6fe08d439fecafa2a2570253 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 21 Feb 2022 11:44:09 +0800 Subject: [PATCH 05/12] handle query crash --- source/libs/transport/src/transCli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c index 4ed1cc2e73..a89b3d7139 100644 --- a/source/libs/transport/src/transCli.c +++ b/source/libs/transport/src/transCli.c @@ -137,7 +137,7 @@ static void clientHandleResp(SCliConn* conn) { rpcMsg.ahandle = pCtx->ahandle; if (rpcMsg.msgType == TDMT_VND_QUERY_RSP || rpcMsg.msgType == TDMT_VND_FETCH_RSP || - rpcMsg.msgType == TDMT_VND_RES_READY) { + rpcMsg.msgType == TDMT_VND_RES_READY_RSP) { rpcMsg.handle = conn; conn->persist = 1; tDebug("client conn %p persist by app", conn); From 6f555efeb1112d80c0928b3da619b4f078f74a12 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Mon, 21 Feb 2022 04:35:30 -0500 Subject: [PATCH 06/12] TD-13495 logic plan UT --- include/libs/nodes/nodes.h | 2 +- include/util/tjson.h | 2 + source/libs/nodes/src/nodesCloneFuncs.c | 26 +- source/libs/nodes/src/nodesCodeFuncs.c | 322 +++++++++++++++++++- source/libs/nodes/src/nodesUtilFuncs.c | 19 +- source/libs/parser/src/parserImpl.c | 8 +- source/libs/parser/test/mockCatalog.cpp | 4 +- source/libs/planner/src/plannerImpl.c | 149 ++++++--- source/libs/planner/test/newPlannerTest.cpp | 55 +++- source/util/src/tjson.c | 8 + 10 files changed, 509 insertions(+), 86 deletions(-) diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 6a0422cd80..3ef832a69b 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -132,7 +132,7 @@ bool nodesEqualNode(const SNode* a, const SNode* b); SNode* nodesCloneNode(const SNode* pNode); SNodeList* nodesCloneList(const SNodeList* pList); -int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen); +int32_t nodesNodeToString(const SNode* pNode, bool format, char** pStr, int32_t* pLen); int32_t nodesStringToNode(const char* pStr, SNode** pNode); #ifdef __cplusplus diff --git a/include/util/tjson.h b/include/util/tjson.h index a4eb6e5385..a0c2fef05b 100644 --- a/include/util/tjson.h +++ b/include/util/tjson.h @@ -30,6 +30,7 @@ void tjsonDelete(SJson* pJson); SJson* tjsonAddArrayToObject(SJson* pJson, const char* pName); int32_t tjsonAddIntegerToObject(SJson* pJson, const char* pName, const uint64_t number); +int32_t tjsonAddDoubleToObject(SJson* pJson, const char* pName, const double number); int32_t tjsonAddStringToObject(SJson* pJson, const char* pName, const char* pVal); int32_t tjsonAddItemToObject(SJson* pJson, const char* pName, SJson* pItem); int32_t tjsonAddItemToArray(SJson* pJson, SJson* pItem); @@ -42,6 +43,7 @@ int32_t tjsonAddItem(SJson* pJson, FToJson func, const void* pObj); typedef int32_t (*FFromJson)(const SJson* pJson, void* pObj); char* tjsonToString(const SJson* pJson); +char* tjsonToUnformattedString(const SJson* pJson); #ifdef __cplusplus } diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index 63bb11a821..78606cd7a2 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -15,6 +15,7 @@ #include "querynodes.h" #include "taos.h" +#include "taoserror.h" #define COPY_SCALAR_FIELD(fldname) \ do { \ @@ -57,14 +58,13 @@ static void dataTypeCopy(const SDataType* pSrc, SDataType* pDst) { } static void exprNodeCopy(const SExprNode* pSrc, SExprNode* pDst) { - COPY_SCALAR_FIELD(type); dataTypeCopy(&pSrc->resType, &pDst->resType); COPY_CHAR_ARRAY_FIELD(aliasName); // COPY_NODE_LIST_FIELD(pAssociationList); } static SNode* columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) { - exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst); + exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst); COPY_SCALAR_FIELD(colId); COPY_SCALAR_FIELD(colType); COPY_CHAR_ARRAY_FIELD(dbName); @@ -76,7 +76,7 @@ static SNode* columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) { } static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) { - exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst); + exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst); COPY_CHAR_POINT_FIELD(literal); COPY_SCALAR_FIELD(isDuration); switch (pSrc->node.resType.type) { @@ -119,7 +119,7 @@ static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) { } static SNode* operatorNodeCopy(const SOperatorNode* pSrc, SOperatorNode* pDst) { - exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst); + exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst); COPY_SCALAR_FIELD(opType); COPY_NODE_FIELD(pLeft); COPY_NODE_FIELD(pRight); @@ -127,14 +127,14 @@ static SNode* operatorNodeCopy(const SOperatorNode* pSrc, SOperatorNode* pDst) { } static SNode* logicConditionNodeCopy(const SLogicConditionNode* pSrc, SLogicConditionNode* pDst) { - exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst); + exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst); COPY_SCALAR_FIELD(condType); COPY_NODE_LIST_FIELD(pParameterList); return (SNode*)pDst; } static SNode* functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst) { - exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst); + exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst); COPY_CHAR_ARRAY_FIELD(functionName); COPY_SCALAR_FIELD(funcId); COPY_SCALAR_FIELD(funcType); @@ -142,12 +142,19 @@ static SNode* functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst) { return (SNode*)pDst; } +static SNode* groupingSetNodeCopy(const SGroupingSetNode* pSrc, SGroupingSetNode* pDst) { + COPY_SCALAR_FIELD(groupingSetType); + COPY_NODE_LIST_FIELD(pParameterList); + return (SNode*)pDst; +} + SNode* nodesCloneNode(const SNode* pNode) { if (NULL == pNode) { return NULL; } SNode* pDst = nodesMakeNode(nodeType(pNode)); if (NULL == pDst) { + terrno = TSDB_CODE_OUT_OF_MEMORY; return NULL; } switch (nodeType(pNode)) { @@ -164,7 +171,9 @@ SNode* nodesCloneNode(const SNode* pNode) { case QUERY_NODE_REAL_TABLE: case QUERY_NODE_TEMP_TABLE: case QUERY_NODE_JOIN_TABLE: + break; case QUERY_NODE_GROUPING_SET: + return groupingSetNodeCopy((const SGroupingSetNode*)pNode, (SGroupingSetNode*)pDst); case QUERY_NODE_ORDER_BY_EXPR: case QUERY_NODE_LIMIT: default: @@ -174,8 +183,13 @@ SNode* nodesCloneNode(const SNode* pNode) { } SNodeList* nodesCloneList(const SNodeList* pList) { + if (NULL == pList) { + return NULL; + } + SNodeList* pDst = nodesMakeList(); if (NULL == pDst) { + terrno = TSDB_CODE_OUT_OF_MEMORY; return NULL; } SNode* pNode; diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index d1f32ae314..8968f0579d 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -26,27 +26,47 @@ static char* nodeName(ENodeType type) { case QUERY_NODE_COLUMN: return "Column"; case QUERY_NODE_VALUE: + return "Value"; case QUERY_NODE_OPERATOR: + return "Operator"; case QUERY_NODE_LOGIC_CONDITION: + return "LogicCondition"; case QUERY_NODE_FUNCTION: + return "Function"; case QUERY_NODE_REAL_TABLE: + return "RealTable"; case QUERY_NODE_TEMP_TABLE: + return "TempTable"; case QUERY_NODE_JOIN_TABLE: + return "JoinTable"; case QUERY_NODE_GROUPING_SET: + return "GroupingSet"; case QUERY_NODE_ORDER_BY_EXPR: + return "OrderByExpr"; case QUERY_NODE_LIMIT: + return "Limit"; case QUERY_NODE_STATE_WINDOW: + return "StateWindow"; case QUERY_NODE_SESSION_WINDOW: + return "SessionWinow"; case QUERY_NODE_INTERVAL_WINDOW: + return "IntervalWindow"; case QUERY_NODE_NODE_LIST: + return "NodeList"; case QUERY_NODE_FILL: + return "Fill"; case QUERY_NODE_COLUMN_REF: + return "ColumnRef"; case QUERY_NODE_TARGET: + return "Target"; case QUERY_NODE_RAW_EXPR: + return "RawExpr"; case QUERY_NODE_SET_OPERATOR: + return "SetOperator"; case QUERY_NODE_SELECT_STMT: + return "SelectStmt"; case QUERY_NODE_SHOW_STMT: - break; + return "ShowStmt"; case QUERY_NODE_LOGIC_PLAN_SCAN: return "LogicScan"; case QUERY_NODE_LOGIC_PLAN_JOIN: @@ -119,7 +139,7 @@ static int32_t logicPlanNodeToJson(const void* pObj, SJson* pJson) { static const char* jkScanLogicPlanScanCols = "ScanCols"; static const char* jkScanLogicPlanTableMeta = "TableMeta"; -static int32_t logicScanToJson(const void* pObj, SJson* pJson) { +static int32_t logicScanNodeToJson(const void* pObj, SJson* pJson) { const SScanLogicNode* pNode = (const SScanLogicNode*)pObj; int32_t code = logicPlanNodeToJson(pObj, pJson); @@ -135,7 +155,7 @@ static int32_t logicScanToJson(const void* pObj, SJson* pJson) { static const char* jkProjectLogicPlanProjections = "Projections"; -static int32_t logicProjectToJson(const void* pObj, SJson* pJson) { +static int32_t logicProjectNodeToJson(const void* pObj, SJson* pJson) { const SProjectLogicNode* pNode = (const SProjectLogicNode*)pObj; int32_t code = logicPlanNodeToJson(pObj, pJson); @@ -149,7 +169,7 @@ static int32_t logicProjectToJson(const void* pObj, SJson* pJson) { static const char* jkJoinLogicPlanJoinType = "JoinType"; static const char* jkJoinLogicPlanOnConditions = "OnConditions"; -static int32_t logicJoinToJson(const void* pObj, SJson* pJson) { +static int32_t logicJoinNodeToJson(const void* pObj, SJson* pJson) { const SJoinLogicNode* pNode = (const SJoinLogicNode*)pObj; int32_t code = logicPlanNodeToJson(pObj, pJson); @@ -163,14 +183,14 @@ static int32_t logicJoinToJson(const void* pObj, SJson* pJson) { return code; } -static int32_t logicFilterToJson(const void* pObj, SJson* pJson) { +static int32_t logicFilterNodeToJson(const void* pObj, SJson* pJson) { return logicPlanNodeToJson(pObj, pJson); } static const char* jkAggLogicPlanGroupKeys = "GroupKeys"; static const char* jkAggLogicPlanAggFuncs = "AggFuncs"; -static int32_t logicAggToJson(const void* pObj, SJson* pJson) { +static int32_t logicAggNodeToJson(const void* pObj, SJson* pJson) { const SAggLogicNode* pNode = (const SAggLogicNode*)pObj; int32_t code = logicPlanNodeToJson(pObj, pJson); @@ -184,17 +204,291 @@ static int32_t logicAggToJson(const void* pObj, SJson* pJson) { return code; } +static const char* jkDataTypeType = "Type"; +static const char* jkDataTypePrecision = "Precision"; +static const char* jkDataTypeScale = "Scale"; +static const char* jkDataTypeDataBytes = "Bytes"; + +static int32_t dataTypeToJson(const void* pObj, SJson* pJson) { + const SDataType* pNode = (const SDataType*)pObj; + + int32_t code = tjsonAddIntegerToObject(pJson, jkDataTypeType, pNode->type); + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkDataTypePrecision, pNode->precision); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkDataTypeScale, pNode->scale); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkDataTypeDataBytes, pNode->bytes); + } + + return code; +} + +static const char* jkExprDataType = "DataType"; +static const char* jkExprAliasName = "AliasName"; + +static int32_t exprNodeToJson(const void* pObj, SJson* pJson) { + const SExprNode* pNode = (const SExprNode*)pObj; + + int32_t code = tjsonAddObject(pJson, jkExprDataType, dataTypeToJson, &pNode->resType); + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddStringToObject(pJson, jkExprAliasName, pNode->aliasName); + } + + return code; +} + +static const char* jkColumnTableId = "TableId"; +static const char* jkColumnColId = "ColId"; +static const char* jkColumnColType = "ColType"; +static const char* jkColumnDbName = "DbName"; +static const char* jkColumnTableName = "TableName"; +static const char* jkColumnTableAlias = "TableAlias"; +static const char* jkColumnColName = "ColName"; + +static int32_t columnNodeToJson(const void* pObj, SJson* pJson) { + const SColumnNode* pNode = (const SColumnNode*)pObj; + + int32_t code = exprNodeToJson(pObj, pJson); + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkColumnTableId, pNode->tableId); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkColumnColId, pNode->colId); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkColumnColType, pNode->colType); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddStringToObject(pJson, jkColumnDbName, pNode->dbName); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddStringToObject(pJson, jkColumnTableName, pNode->tableName); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddStringToObject(pJson, jkColumnTableAlias, pNode->tableAlias); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddStringToObject(pJson, jkColumnColName, pNode->colName); + } + + return code; +} + +// typedef struct SValueNode { +// SExprNode node; // QUERY_NODE_VALUE +// char* ; +// bool ; +// union { +// bool b; +// int64_t i; +// uint64_t u; +// double d; +// char* p; +// } datum; +// } SValueNode; + +static const char* jkValueLiteral = "Literal"; +static const char* jkValueDuration = "Duration"; +static const char* jkValueDatum = "Datum"; + +static int32_t valueNodeToJson(const void* pObj, SJson* pJson) { + const SValueNode* pNode = (const SValueNode*)pObj; + + int32_t code = exprNodeToJson(pObj, pJson); + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddStringToObject(pJson, jkValueLiteral, pNode->literal); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkValueDuration, pNode->isDuration); + } + switch (pNode->node.resType.type) { + case TSDB_DATA_TYPE_NULL: + break; + case TSDB_DATA_TYPE_BOOL: + code = tjsonAddIntegerToObject(pJson, jkValueDuration, pNode->datum.b); + break; + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_TIMESTAMP: + code = tjsonAddIntegerToObject(pJson, jkValueDuration, pNode->datum.i); + break; + case TSDB_DATA_TYPE_UTINYINT: + case TSDB_DATA_TYPE_USMALLINT: + case TSDB_DATA_TYPE_UINT: + case TSDB_DATA_TYPE_UBIGINT: + code = tjsonAddIntegerToObject(pJson, jkValueDuration, pNode->datum.u); + break; + case TSDB_DATA_TYPE_FLOAT: + case TSDB_DATA_TYPE_DOUBLE: + code = tjsonAddDoubleToObject(pJson, jkValueDuration, pNode->datum.d); + break; + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: + case TSDB_DATA_TYPE_VARCHAR: + case TSDB_DATA_TYPE_VARBINARY: + code = tjsonAddStringToObject(pJson, jkValueLiteral, pNode->datum.p); + break; + case TSDB_DATA_TYPE_JSON: + case TSDB_DATA_TYPE_DECIMAL: + case TSDB_DATA_TYPE_BLOB: + // todo + default: + break; + } + + return code; +} + +static const char* jkOperatorType = "OpType"; +static const char* jkOperatorLeft = "Left"; +static const char* jkOperatorRight = "Right"; + +static int32_t operatorNodeToJson(const void* pObj, SJson* pJson) { + const SOperatorNode* pNode = (const SOperatorNode*)pObj; + + int32_t code = exprNodeToJson(pObj, pJson); + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkOperatorType, pNode->opType); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddObject(pJson, jkOperatorLeft, nodeToJson, pNode->pLeft); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddObject(pJson, jkOperatorRight, nodeToJson, pNode->pRight); + } + + return code; +} + +static const char* jkLogicCondType = "CondType"; +static const char* jkLogicCondParameters = "Parameters"; + +static int32_t logicConditionNodeToJson(const void* pObj, SJson* pJson) { + const SLogicConditionNode* pNode = (const SLogicConditionNode*)pObj; + + int32_t code = exprNodeToJson(pObj, pJson); + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkLogicCondType, pNode->condType); + } + if (TSDB_CODE_SUCCESS == code) { + code = addNodeList(pJson, jkLogicCondParameters, nodeToJson, pNode->pParameterList); + } + + return code; +} + +static const char* jkFunctionName = "Name"; +static const char* jkFunctionId = "Id"; +static const char* jkFunctionType = "Type"; +static const char* jkFunctionParameter = "Parameters"; + +static int32_t functionNodeToJson(const void* pObj, SJson* pJson) { + const SFunctionNode* pNode = (const SFunctionNode*)pObj; + + int32_t code = exprNodeToJson(pObj, pJson); + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddStringToObject(pJson, jkFunctionName, pNode->functionName); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkFunctionId, pNode->funcId); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddIntegerToObject(pJson, jkFunctionType, pNode->funcType); + } + if (TSDB_CODE_SUCCESS == code) { + code = addNodeList(pJson, jkFunctionParameter, nodeToJson, pNode->pParameterList); + } + + return code; +} + +static const char* jkGroupingSetType = "GroupingSetType"; +static const char* jkGroupingSetParameter = "Parameters"; + +static int32_t groupingSetNodeToJson(const void* pObj, SJson* pJson) { + const SGroupingSetNode* pNode = (const SGroupingSetNode*)pObj; + + int32_t code = tjsonAddIntegerToObject(pJson, jkGroupingSetType, pNode->groupingSetType); + if (TSDB_CODE_SUCCESS == code) { + code = addNodeList(pJson, jkGroupingSetParameter, nodeToJson, pNode->pParameterList); + } + + return code; +} + +static const char* jkSelectStmtDistinct = "Distinct"; +static const char* jkSelectStmtProjections = "Projections"; +static const char* jkSelectStmtFrom = "From"; +static const char* jkSelectStmtWhere = "Where"; +static const char* jkSelectStmtPartitionBy = "PartitionBy"; +static const char* jkSelectStmtWindow = "Window"; +static const char* jkSelectStmtGroupBy = "GroupBy"; +static const char* jkSelectStmtHaving = "Having"; +static const char* jkSelectStmtOrderBy = "OrderBy"; +static const char* jkSelectStmtLimit = "Limit"; +static const char* jkSelectStmtSlimit = "Slimit"; + +static int32_t selectStmtTojson(const void* pObj, SJson* pJson) { + const SSelectStmt* pNode = (const SSelectStmt*)pObj; + + int32_t code = tjsonAddIntegerToObject(pJson, jkSelectStmtDistinct, pNode->isDistinct); + if (TSDB_CODE_SUCCESS == code) { + code = addNodeList(pJson, jkSelectStmtProjections, nodeToJson, pNode->pProjectionList); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddObject(pJson, jkSelectStmtFrom, nodeToJson, pNode->pFromTable); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddObject(pJson, jkSelectStmtWhere, nodeToJson, pNode->pWhere); + } + if (TSDB_CODE_SUCCESS == code) { + code = addNodeList(pJson, jkSelectStmtPartitionBy, nodeToJson, pNode->pPartitionByList); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddObject(pJson, jkSelectStmtWindow, nodeToJson, pNode->pWindow); + } + if (TSDB_CODE_SUCCESS == code) { + code = addNodeList(pJson, jkSelectStmtGroupBy, nodeToJson, pNode->pGroupByList); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddObject(pJson, jkSelectStmtHaving, nodeToJson, pNode->pHaving); + } + if (TSDB_CODE_SUCCESS == code) { + code = addNodeList(pJson, jkSelectStmtOrderBy, nodeToJson, pNode->pOrderByList); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddObject(pJson, jkSelectStmtLimit, nodeToJson, pNode->pLimit); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddObject(pJson, jkSelectStmtSlimit, nodeToJson, pNode->pSlimit); + } + + return code; +} + static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { switch (nodeType(pObj)) { case QUERY_NODE_COLUMN: + return columnNodeToJson(pObj, pJson); case QUERY_NODE_VALUE: + return valueNodeToJson(pObj, pJson); case QUERY_NODE_OPERATOR: + return operatorNodeToJson(pObj, pJson); case QUERY_NODE_LOGIC_CONDITION: + return logicConditionNodeToJson(pObj, pJson); case QUERY_NODE_FUNCTION: + return functionNodeToJson(pObj, pJson); case QUERY_NODE_REAL_TABLE: case QUERY_NODE_TEMP_TABLE: case QUERY_NODE_JOIN_TABLE: + break; case QUERY_NODE_GROUPING_SET: + return groupingSetNodeToJson(pObj, pJson); case QUERY_NODE_ORDER_BY_EXPR: case QUERY_NODE_LIMIT: case QUERY_NODE_STATE_WINDOW: @@ -206,19 +500,21 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { case QUERY_NODE_TARGET: case QUERY_NODE_RAW_EXPR: case QUERY_NODE_SET_OPERATOR: + break; case QUERY_NODE_SELECT_STMT: + return selectStmtTojson(pObj, pJson); case QUERY_NODE_SHOW_STMT: break; case QUERY_NODE_LOGIC_PLAN_SCAN: - return logicScanToJson(pObj, pJson); + return logicScanNodeToJson(pObj, pJson); case QUERY_NODE_LOGIC_PLAN_JOIN: - return logicJoinToJson(pObj, pJson); + return logicJoinNodeToJson(pObj, pJson); case QUERY_NODE_LOGIC_PLAN_FILTER: - return logicFilterToJson(pObj, pJson); + return logicFilterNodeToJson(pObj, pJson); case QUERY_NODE_LOGIC_PLAN_AGG: - return logicAggToJson(pObj, pJson); + return logicAggNodeToJson(pObj, pJson); case QUERY_NODE_LOGIC_PLAN_PROJECT: - return logicProjectToJson(pObj, pJson); + return logicProjectNodeToJson(pObj, pJson); default: break; } @@ -238,7 +534,7 @@ static int32_t nodeToJson(const void* pObj, SJson* pJson) { return code; } -int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen) { +int32_t nodesNodeToString(const SNode* pNode, bool format, char** pStr, int32_t* pLen) { if (NULL == pNode || NULL == pStr || NULL == pLen) { return TSDB_CODE_SUCCESS; } @@ -255,7 +551,7 @@ int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen) { return code; } - *pStr = tjsonToString(pJson); + *pStr = format ? tjsonToString(pJson) : tjsonToUnformattedString(pJson); tjsonDelete(pJson); *pLen = strlen(*pStr) + 1; diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 868af93c92..e637822fd3 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -132,11 +132,22 @@ int32_t nodesListAppend(SNodeList* pList, SNode* pNode) { } int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc) { - pTarget->pTail->pNext = pSrc->pHead; - pSrc->pHead->pPrev = pTarget->pTail; + if (NULL == pTarget || NULL == pSrc) { + return TSDB_CODE_SUCCESS; + } + + if (NULL == pTarget->pHead) { + pTarget->pHead = pSrc->pHead; + } else { + pTarget->pTail->pNext = pSrc->pHead; + if (NULL != pSrc->pHead) { + pSrc->pHead->pPrev = pTarget->pTail; + } + } pTarget->pTail = pSrc->pTail; pTarget->length += pSrc->length; tfree(pSrc); + return TSDB_CODE_SUCCESS; } @@ -290,6 +301,10 @@ int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char* nodesDestroyList(cxt.pCols); return cxt.errCode; } + if (0 == LIST_LENGTH(cxt.pCols)) { + nodesDestroyList(cxt.pCols); + cxt.pCols = NULL; + } *pCols = cxt.pCols; return TSDB_CODE_SUCCESS; } diff --git a/source/libs/parser/src/parserImpl.c b/source/libs/parser/src/parserImpl.c index d353c245cb..cf8d05975b 100644 --- a/source/libs/parser/src/parserImpl.c +++ b/source/libs/parser/src/parserImpl.c @@ -349,7 +349,7 @@ static SNodeList* getProjectList(SNode* pNode) { return NULL; } -static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* pColSchema, SColumnNode* pCol) { +static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* pColSchema, bool isTag, SColumnNode* pCol) { strcpy(pCol->dbName, pTable->table.dbName); strcpy(pCol->tableAlias, pTable->table.tableAlias); strcpy(pCol->tableName, pTable->table.tableName); @@ -359,7 +359,7 @@ static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* p } pCol->tableId = pTable->pMeta->uid; pCol->colId = pColSchema->colId; - // pCol->colType = pColSchema->type; + pCol->colType = isTag ? COLUMN_TYPE_TAG : COLUMN_TYPE_COLUMN; pCol->node.resType.type = pColSchema->type; pCol->node.resType.bytes = pColSchema->bytes; } @@ -383,7 +383,7 @@ static int32_t createColumnNodeByTable(STranslateContext* pCxt, const STableNode if (NULL == pCol) { return generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY); } - setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, pCol); + setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i < pMeta->tableInfo.numOfTags), pCol); nodesListAppend(pList, (SNode*)pCol); } } else { @@ -408,7 +408,7 @@ static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) { int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns; for (int32_t i = 0; i < nums; ++i) { if (0 == strcmp(pCol->colName, pMeta->schema[i].name)) { - setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, pCol); + setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i < pMeta->tableInfo.numOfTags), pCol); found = true; break; } diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index d68b04a384..8ed67d7f2f 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -29,9 +29,9 @@ namespace { void generateTestT1(MockCatalogService* mcs) { - ITableBuilder& builder = mcs->createTableBuilder("test", "t1", TSDB_NORMAL_TABLE, 3) + ITableBuilder& builder = mcs->createTableBuilder("test", "t1", TSDB_NORMAL_TABLE, 4) .setPrecision(TSDB_TIME_PRECISION_MILLI).setVgid(1).addColumn("ts", TSDB_DATA_TYPE_TIMESTAMP) - .addColumn("c1", TSDB_DATA_TYPE_INT).addColumn("c2", TSDB_DATA_TYPE_BINARY, 20); + .addColumn("c1", TSDB_DATA_TYPE_INT).addColumn("c2", TSDB_DATA_TYPE_BINARY, 20).addColumn("c3", TSDB_DATA_TYPE_BIGINT); builder.done(); } diff --git a/source/libs/planner/src/plannerImpl.c b/source/libs/planner/src/plannerImpl.c index 40a82f4175..54a7330667 100644 --- a/source/libs/planner/src/plannerImpl.c +++ b/source/libs/planner/src/plannerImpl.c @@ -18,20 +18,20 @@ #define CHECK_ALLOC(p, res) \ do { \ - if (NULL == p) { \ + if (NULL == (p)) { \ printf("%s : %d\n", __FUNCTION__, __LINE__); \ pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; \ - return res; \ + return (res); \ } \ } while (0) #define CHECK_CODE(exec, res) \ do { \ - int32_t code = exec; \ + int32_t code = (exec); \ if (TSDB_CODE_SUCCESS != code) { \ printf("%s : %d\n", __FUNCTION__, __LINE__); \ pCxt->errCode = code; \ - return res; \ + return (res); \ } \ } while (0) @@ -83,14 +83,30 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) { return DEAL_RES_CONTINUE; } -static int32_t rewriteExpr(int32_t planNodeId, int32_t rewriteId, SNodeList* pExprs, SSelectStmt* pSelect, ESqlClause clause) { - SNode* pNode; - FOREACH(pNode, pExprs) { - if (QUERY_NODE_COLUMN == nodeType(pNode) || QUERY_NODE_VALUE == nodeType(pNode)) { - continue; +typedef struct SNameExprCxt { + int32_t planNodeId; + int32_t rewriteId; +} SNameExprCxt; + +static EDealRes doNameExpr(SNode* pNode, void* pContext) { + switch (nodeType(pNode)) { + case QUERY_NODE_OPERATOR: + case QUERY_NODE_LOGIC_CONDITION: + case QUERY_NODE_FUNCTION: { + SNameExprCxt* pCxt = (SNameExprCxt*)pContext; + sprintf(((SExprNode*)pNode)->aliasName, "#expr_%d_%d", pCxt->planNodeId, pCxt->rewriteId++); + return DEAL_RES_IGNORE_CHILD; } - sprintf(((SExprNode*)pNode)->aliasName, "#expr_%d_%d", planNodeId, rewriteId); + default: + break; } + + return DEAL_RES_CONTINUE; +} + +static int32_t rewriteExpr(int32_t planNodeId, int32_t rewriteId, SNodeList* pExprs, SSelectStmt* pSelect, ESqlClause clause) { + SNameExprCxt nameCxt = { .planNodeId = planNodeId, .rewriteId = rewriteId }; + nodesWalkList(pExprs, doNameExpr, &nameCxt); SRewriteExprCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs }; nodesRewriteSelectStmt(pSelect, clause, doRewriteExpr, &cxt); return cxt.errCode; @@ -135,12 +151,16 @@ static SLogicNode* createScanLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect, // set columns to scan SNodeList* pCols = NULL; CHECK_CODE(nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pRealTable->table.tableAlias, &pCols), (SLogicNode*)pScan); - pScan->pScanCols = nodesCloneList(pCols); - CHECK_ALLOC(pScan->pScanCols, (SLogicNode*)pScan); + if (NULL != pCols) { + pScan->pScanCols = nodesCloneList(pCols); + CHECK_ALLOC(pScan->pScanCols, (SLogicNode*)pScan); + } // set output - pScan->node.pTargets = nodesCloneList(pCols); - CHECK_ALLOC(pScan->node.pTargets, (SLogicNode*)pScan); + if (NULL != pCols) { + pScan->node.pTargets = nodesCloneList(pCols); + CHECK_ALLOC(pScan->node.pTargets, (SLogicNode*)pScan); + } return (SLogicNode*)pScan; } @@ -173,8 +193,10 @@ static SLogicNode* createJoinLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect, CHECK_CODE(nodesListAppend(pJoin->node.pChildren, (SNode*)pRight), (SLogicNode*)pJoin); // set on conditions - pJoin->pOnConditions = nodesCloneNode(pJoinTable->pOnCond); - CHECK_ALLOC(pJoin->pOnConditions, (SLogicNode*)pJoin); + if (NULL != pJoinTable->pOnCond) { + pJoin->pOnConditions = nodesCloneNode(pJoinTable->pOnCond); + CHECK_ALLOC(pJoin->pOnConditions, (SLogicNode*)pJoin); + } // set the output pJoin->node.pTargets = nodesCloneList(pLeft->pTargets); @@ -220,35 +242,57 @@ static SLogicNode* createWhereFilterLogicNode(SPlanContext* pCxt, SLogicNode* pC return (SLogicNode*)pFilter; } -static SNodeList* createColumnByRewriteExps(SPlanContext* pCxt, SNodeList* pExprs) { - SNodeList* pList = nodesMakeList(); - CHECK_ALLOC(pList, NULL); - SNode* pNode; - FOREACH(pNode, pExprs) { - if (QUERY_NODE_VALUE == nodeType(pNode)) { - continue; - } else if (QUERY_NODE_COLUMN == nodeType(pNode)) { +typedef struct SCreateColumnCxt { + int32_t errCode; + SNodeList* pList; +} SCreateColumnCxt; + +static EDealRes doCreateColumn(SNode* pNode, void* pContext) { + SCreateColumnCxt* pCxt = (SCreateColumnCxt*)pContext; + switch (nodeType(pNode)) { + case QUERY_NODE_COLUMN: { SNode* pCol = nodesCloneNode(pNode); - if (NULL == pCol) { - goto error; + if (NULL == pCol || TSDB_CODE_SUCCESS != nodesListAppend(pCxt->pList, pCol)) { + pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; + return DEAL_RES_ERROR; } - if (TSDB_CODE_SUCCESS != nodesListAppend(pList, pCol)) { - goto error; - } - } else { + return DEAL_RES_IGNORE_CHILD; + } + case QUERY_NODE_OPERATOR: + case QUERY_NODE_LOGIC_CONDITION: + case QUERY_NODE_FUNCTION: { SExprNode* pExpr = (SExprNode*)pNode; SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); if (NULL == pCol) { - goto error; + pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; + return DEAL_RES_ERROR; } pCol->node.resType = pExpr->resType; strcpy(pCol->colName, pExpr->aliasName); + if (TSDB_CODE_SUCCESS != nodesListAppend(pCxt->pList, (SNode*)pCol)) { + pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; + return DEAL_RES_ERROR; + } + return DEAL_RES_IGNORE_CHILD; } + default: + break; } - return pList; -error: - nodesDestroyList(pList); - return NULL; + + return DEAL_RES_CONTINUE; +} + +static SNodeList* createColumnByRewriteExps(SPlanContext* pCxt, SNodeList* pExprs) { + SCreateColumnCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pList = nodesMakeList() }; + if (NULL == cxt.pList) { + return NULL; + } + nodesWalkList(pExprs, doCreateColumn, &cxt); + if (TSDB_CODE_SUCCESS != cxt.errCode) { + nodesDestroyList(cxt.pList); + return NULL; + } + return cxt.pList; } static SLogicNode* createAggLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) { @@ -263,24 +307,37 @@ static SLogicNode* createAggLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) pAgg->node.id = pCxt->planNodeId++; // set grouyp keys, agg funcs and having conditions - pAgg->pGroupKeys = nodesCloneList(pSelect->pGroupByList); - CHECK_ALLOC(pAgg->pGroupKeys, (SLogicNode*)pAgg); - pAgg->pAggFuncs = nodesCloneList(pAggFuncs); - CHECK_ALLOC(pAgg->pAggFuncs, (SLogicNode*)pAgg); + if (NULL != pSelect->pGroupByList) { + pAgg->pGroupKeys = nodesCloneList(pSelect->pGroupByList); + CHECK_ALLOC(pAgg->pGroupKeys, (SLogicNode*)pAgg); + } + if (NULL != pAggFuncs) { + pAgg->pAggFuncs = nodesCloneList(pAggFuncs); + CHECK_ALLOC(pAgg->pAggFuncs, (SLogicNode*)pAgg); + } // rewrite the expression in subsequent clauses CHECK_CODE(rewriteExpr(pAgg->node.id, 1, pAgg->pGroupKeys, pSelect, SQL_CLAUSE_GROUP_BY), (SLogicNode*)pAgg); CHECK_CODE(rewriteExpr(pAgg->node.id, 1 + LIST_LENGTH(pAgg->pGroupKeys), pAgg->pAggFuncs, pSelect, SQL_CLAUSE_GROUP_BY), (SLogicNode*)pAgg); - pAgg->node.pConditions = nodesCloneNode(pSelect->pHaving); - CHECK_ALLOC(pAgg->node.pConditions, (SLogicNode*)pAgg); + if (NULL != pSelect->pHaving) { + pAgg->node.pConditions = nodesCloneNode(pSelect->pHaving); + CHECK_ALLOC(pAgg->node.pConditions, (SLogicNode*)pAgg); + } // set the output - pAgg->node.pTargets = createColumnByRewriteExps(pCxt, pAgg->pGroupKeys); + pAgg->node.pTargets = nodesMakeList(); CHECK_ALLOC(pAgg->node.pTargets, (SLogicNode*)pAgg); - SNodeList* pTargets = createColumnByRewriteExps(pCxt, pAgg->pAggFuncs); - CHECK_ALLOC(pTargets, (SLogicNode*)pAgg); - nodesListAppendList(pAgg->node.pTargets, pTargets); + if (NULL != pAgg->pGroupKeys) { + SNodeList* pTargets = createColumnByRewriteExps(pCxt, pAgg->pGroupKeys); + CHECK_ALLOC(pAgg->node.pTargets, (SLogicNode*)pAgg); + nodesListAppendList(pAgg->node.pTargets, pTargets); + } + if (NULL != pAgg->pAggFuncs) { + SNodeList* pTargets = createColumnByRewriteExps(pCxt, pAgg->pAggFuncs); + CHECK_ALLOC(pTargets, (SLogicNode*)pAgg); + nodesListAppendList(pAgg->node.pTargets, pTargets); + } return (SLogicNode*)pAgg; } @@ -344,7 +401,7 @@ static SLogicNode* createQueryLogicNode(SPlanContext* pCxt, SNode* pStmt) { } int32_t createLogicPlan(SNode* pNode, SLogicNode** pLogicNode) { - SPlanContext cxt = { .errCode = TSDB_CODE_SUCCESS, .planNodeId = 0 }; + SPlanContext cxt = { .errCode = TSDB_CODE_SUCCESS, .planNodeId = 1 }; SLogicNode* pRoot = createQueryLogicNode(&cxt, pNode); if (TSDB_CODE_SUCCESS != cxt.errCode) { nodesDestroyNode((SNode*)pRoot); diff --git a/source/libs/planner/test/newPlannerTest.cpp b/source/libs/planner/test/newPlannerTest.cpp index c227bf88ba..c3ee4fb9a8 100644 --- a/source/libs/planner/test/newPlannerTest.cpp +++ b/source/libs/planner/test/newPlannerTest.cpp @@ -42,26 +42,28 @@ protected: bool run() { int32_t code = parser(&cxt_, &query_); - // cout << "parser return " << code << endl; + if (code != TSDB_CODE_SUCCESS) { - cout << "sql:[" << cxt_.pSql << "] parser code:" << tstrerror(code) << ", msg:" << errMagBuf_ << endl; + cout << "sql:[" << cxt_.pSql << "] parser code:" << code << ", strerror:" << tstrerror(code) << ", msg:" << errMagBuf_ << endl; return false; } + + const string syntaxTreeStr = toString(query_.pRoot, false); + SLogicNode* pLogicPlan = nullptr; code = createLogicPlan(query_.pRoot, &pLogicPlan); if (code != TSDB_CODE_SUCCESS) { - cout << "sql:[" << cxt_.pSql << "] plan code:" << tstrerror(code) << endl; + cout << "sql:[" << cxt_.pSql << "] plan code:" << code << ", strerror:" << tstrerror(code) << endl; return false; } - char* pStr = NULL; - int32_t len = 0; - code = nodesNodeToString((const SNode*)pLogicPlan, &pStr, &len); - if (code != TSDB_CODE_SUCCESS) { - cout << "sql:[" << cxt_.pSql << "] toString code:" << tstrerror(code) << endl; - return false; - } - cout << "logic plan : " << endl; - cout << pStr << endl; + + cout << "sql : [" << cxt_.pSql << "]" << endl; + cout << "syntax test : " << endl; + cout << syntaxTreeStr << endl; + // cout << "logic plan : " << endl; + // cout << toString((const SNode*)pLogicPlan) << endl; + cout << "unformatted logic plan : " << endl; + cout << toString((const SNode*)pLogicPlan, false) << endl; return true; } @@ -75,6 +77,19 @@ private: cxt_.msgLen = max_err_len; } + string toString(const SNode* pRoot, bool format = true) { + char* pStr = NULL; + int32_t len = 0; + int32_t code = nodesNodeToString(pRoot, format, &pStr, &len); + if (code != TSDB_CODE_SUCCESS) { + cout << "sql:[" << cxt_.pSql << "] toString code:" << code << ", strerror:" << tstrerror(code) << endl; + return string(); + } + string str(pStr); + tfree(pStr); + return str; + } + string acctId_; string db_; char errMagBuf_[max_err_len]; @@ -89,3 +104,19 @@ TEST_F(NewPlannerTest, simple) { bind("SELECT * FROM t1"); ASSERT_TRUE(run()); } + +TEST_F(NewPlannerTest, groupBy) { + setDatabase("root", "test"); + + bind("SELECT count(*) FROM t1"); + ASSERT_TRUE(run()); + + bind("SELECT c1, count(*) FROM t1 GROUP BY c1"); + ASSERT_TRUE(run()); + + bind("SELECT c1 + c3, c1 + count(*) FROM t1 where c2 = 'abc' GROUP BY c1, c3"); + ASSERT_TRUE(run()); + + bind("SELECT c1 + c3, count(*) FROM t1 where concat(c2, 'wwww') = 'abcwww' GROUP BY c1 + c3"); + ASSERT_TRUE(run()); +} diff --git a/source/util/src/tjson.c b/source/util/src/tjson.c index 556e8f8060..13367843fc 100644 --- a/source/util/src/tjson.c +++ b/source/util/src/tjson.c @@ -32,6 +32,10 @@ int32_t tjsonAddIntegerToObject(SJson* pJson, const char* pName, const uint64_t return tjsonAddStringToObject(pJson, pName, tmp); } +int32_t tjsonAddDoubleToObject(SJson* pJson, const char* pName, const double number) { + return (NULL == cJSON_AddNumberToObject((cJSON*)pJson, pName, number) ? TSDB_CODE_FAILED : TSDB_CODE_SUCCESS); +} + int32_t tjsonAddStringToObject(SJson* pJson, const char* pName, const char* pVal) { return (NULL == cJSON_AddStringToObject((cJSON*)pJson, pName, pVal) ? TSDB_CODE_FAILED : TSDB_CODE_SUCCESS); } @@ -74,3 +78,7 @@ int32_t tjsonAddItem(SJson* pJson, FToJson func, const void* pObj) { char* tjsonToString(const SJson* pJson) { return cJSON_Print((cJSON*)pJson); } + +char* tjsonToUnformattedString(const SJson* pJson) { + return cJSON_PrintUnformatted((cJSON*)pJson); +} \ No newline at end of file From d687393bf8f575db72c23c9fddd03c7406e987a6 Mon Sep 17 00:00:00 2001 From: dapan Date: Mon, 21 Feb 2022 19:01:23 +0800 Subject: [PATCH 07/12] fix catalog issue --- source/libs/catalog/src/catalog.c | 60 ++++++++++++++++--------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c index b5c7f44f98..d4da79f968 100644 --- a/source/libs/catalog/src/catalog.c +++ b/source/libs/catalog/src/catalog.c @@ -1556,39 +1556,43 @@ int32_t ctgGetTableMeta(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, cons STableMetaOutput *output = NULL; - CTG_ERR_JRET(ctgRefreshTblMeta(pCtg, pRpc, pMgmtEps, pTableName, isSTable, &output)); + while (true) { + CTG_ERR_JRET(ctgRefreshTblMeta(pCtg, pRpc, pMgmtEps, pTableName, isSTable, &output)); - if (CTG_IS_META_TABLE(output->metaType)) { - *pTableMeta = output->tbMeta; - goto _return; - } + if (CTG_IS_META_TABLE(output->metaType)) { + *pTableMeta = output->tbMeta; + goto _return; + } - if (CTG_IS_META_BOTH(output->metaType)) { - memcpy(output->tbMeta, &output->ctbMeta, sizeof(output->ctbMeta)); + if (CTG_IS_META_BOTH(output->metaType)) { + memcpy(output->tbMeta, &output->ctbMeta, sizeof(output->ctbMeta)); + + *pTableMeta = output->tbMeta; + goto _return; + } + + if ((!CTG_IS_META_CTABLE(output->metaType)) || output->tbMeta) { + ctgError("invalid metaType:%d", output->metaType); + tfree(output->tbMeta); + CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); + } + + // HANDLE ONLY CHILD TABLE META + + SName stbName = *pTableName; + strcpy(stbName.tname, output->tbName); - *pTableMeta = output->tbMeta; - goto _return; + CTG_ERR_JRET(ctgGetTableMetaFromCache(pCtg, &stbName, pTableMeta, &exist)); + if (0 == exist) { + ctgDebug("stb no longer exist, dbFName:%s, tbName:%s", output->dbFName, pTableName->tname); + continue; + } + + memcpy(*pTableMeta, &output->ctbMeta, sizeof(output->ctbMeta)); + + break; } - if ((!CTG_IS_META_CTABLE(output->metaType)) || output->tbMeta) { - ctgError("invalid metaType:%d", output->metaType); - tfree(output->tbMeta); - CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); - } - - // HANDLE ONLY CHILD TABLE META - - SName stbName = *pTableName; - strcpy(stbName.tname, output->tbName); - - CTG_ERR_JRET(ctgGetTableMetaFromCache(pCtg, &stbName, pTableMeta, &exist)); - if (0 == exist) { - ctgDebug("stb no longer exist, dbFName:%s, tbName:%s", output->dbFName, pTableName->tname); - CTG_ERR_JRET(TSDB_CODE_VND_TB_NOT_EXIST); - } - - memcpy(*pTableMeta, &output->ctbMeta, sizeof(output->ctbMeta)); - _return: tfree(output); From 9cf07ff8f09bb091845e6acf6f1cc23e01f1cf15 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 21 Feb 2022 22:36:00 +0800 Subject: [PATCH 08/12] add more UT test --- source/libs/transport/src/transCli.c | 1 - source/libs/transport/src/transSrv.c | 19 ++- source/libs/transport/test/transUT.cc | 214 ++++++++++++++++++++------ 3 files changed, 184 insertions(+), 50 deletions(-) diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c index 4ed1cc2e73..f29c47c21e 100644 --- a/source/libs/transport/src/transCli.c +++ b/source/libs/transport/src/transCli.c @@ -350,7 +350,6 @@ static void clientReadCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf if (nread > 0) { pBuf->len += nread; if (clientReadComplete(pBuf)) { - // uv_read_stop((uv_stream_t*)conn->stream); tTrace("client conn %p read complete", conn); clientHandleResp(conn); } else { diff --git a/source/libs/transport/src/transSrv.c b/source/libs/transport/src/transSrv.c index 5292bad209..a038f72adc 100644 --- a/source/libs/transport/src/transSrv.c +++ b/source/libs/transport/src/transSrv.c @@ -96,6 +96,7 @@ static void uvOnAcceptCb(uv_stream_t* stream, int status); static void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf); static void uvWorkerAsyncCb(uv_async_t* handle); static void uvAcceptAsyncCb(uv_async_t* handle); +static void uvShutDownCb(uv_shutdown_t* req, int status); static void uvStartSendRespInternal(SSrvMsg* smsg); static void uvPrepareSendData(SSrvMsg* msg, uv_buf_t* wb); @@ -446,6 +447,8 @@ void uvWorkerAsyncCb(uv_async_t* handle) { free(msg); destroyAllConn(pThrd); + + uv_loop_close(pThrd->loop); uv_stop(pThrd->loop); } else { uvStartSendResp(msg); @@ -463,6 +466,12 @@ static void uvAcceptAsyncCb(uv_async_t* async) { uv_stop(srv->loop); } +static void uvShutDownCb(uv_shutdown_t* req, int status) { + tDebug("conn failed to shut down: %s", uv_err_name(status)); + uv_close((uv_handle_t*)req->handle, uvDestroyConn); + free(req); +} + void uvOnAcceptCb(uv_stream_t* stream, int status) { if (status == -1) { return; @@ -528,8 +537,8 @@ void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) { uv_tcp_init(pThrd->loop, pConn->pTcp); pConn->pTcp->data = pConn; - uv_tcp_nodelay(pConn->pTcp, 1); - uv_tcp_keepalive(pConn->pTcp, 1, 1); + // uv_tcp_nodelay(pConn->pTcp, 1); + // uv_tcp_keepalive(pConn->pTcp, 1, 1); // init write request, just pConn->pWriter = calloc(1, sizeof(uv_write_t)); @@ -656,7 +665,11 @@ static void destroyConn(SSrvConn* conn, bool clear) { QUEUE_REMOVE(&conn->queue); if (clear) { + tTrace("try to destroy conn %p", conn); uv_tcp_close_reset(conn->pTcp, uvDestroyConn); + // uv_shutdown_t* req = malloc(sizeof(uv_shutdown_t)); + // uv_shutdown(req, (uv_stream_t*)conn->pTcp, uvShutDownCb); + // uv_unref((uv_handle_t*)conn->pTcp); // uv_close((uv_handle_t*)conn->pTcp, uvDestroyConn); } } @@ -665,7 +678,7 @@ static void uvDestroyConn(uv_handle_t* handle) { tDebug("server conn %p destroy", conn); uv_timer_stop(conn->pTimer); // free(conn->pTimer); - // free(conn->pTcp); + free(conn->pTcp); free(conn->pWriter); free(conn); } diff --git a/source/libs/transport/test/transUT.cc b/source/libs/transport/test/transUT.cc index 6f80ea42ac..d1fefe2c72 100644 --- a/source/libs/transport/test/transUT.cc +++ b/source/libs/transport/test/transUT.cc @@ -16,69 +16,168 @@ #include #include #include "tep.h" +#include "tglobal.h" #include "trpc.h" +#include "ulog.h" using namespace std; -class TransObj { - public: - TransObj() { - const char *label = "APP"; - const char *secret = "secret"; - const char *user = "user"; - const char *ckey = "ckey"; +const char *label = "APP"; +const char *secret = "secret"; +const char *user = "user"; +const char *ckey = "ckey"; +class Server; +int port = 7000; +// server process +static void processReq(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet); +// client process; +static void processResp(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet); +class Client { + public: + void Init(int nThread) { memset(&rpcInit, 0, sizeof(rpcInit)); rpcInit.localPort = 0; rpcInit.label = (char *)label; - rpcInit.numOfThreads = 5; - rpcInit.cfp = NULL; - rpcInit.sessions = 100; - rpcInit.idleTime = 100; + rpcInit.numOfThreads = nThread; + rpcInit.cfp = processResp; rpcInit.user = (char *)user; rpcInit.secret = (char *)secret; rpcInit.ckey = (char *)ckey; rpcInit.spi = 1; - } - bool startCli() { - trans = NULL; + rpcInit.parent = this; rpcInit.connType = TAOS_CONN_CLIENT; - trans = rpcOpen(&rpcInit); - return trans != NULL ? true : false; + this->transCli = rpcOpen(&rpcInit); + tsem_init(&this->sem, 0, 0); } - bool startSrv() { - trans = NULL; - rpcInit.connType = TAOS_CONN_SERVER; - trans = rpcOpen(&rpcInit); - return trans != NULL ? true : false; + void SetResp(SRpcMsg *pMsg) { + // set up resp; + this->resp = *pMsg; + } + SRpcMsg *Resp() { return &this->resp; } + + void Restart() { + rpcClose(this->transCli); + this->transCli = rpcOpen(&rpcInit); } - bool sendAndRecv() { + void SendAndRecv(SRpcMsg *req, SRpcMsg *resp) { SEpSet epSet = {0}; epSet.inUse = 0; - addEpIntoEpSet(&epSet, "192.168.1.1", 7000); - addEpIntoEpSet(&epSet, "192.168.0.1", 7000); + addEpIntoEpSet(&epSet, "127.0.0.1", 7000); - if (trans == NULL) { - return false; - } - SRpcMsg rpcMsg = {0}, reqMsg = {0}; - reqMsg.pCont = rpcMallocCont(10); - reqMsg.contLen = 10; - reqMsg.ahandle = NULL; - rpcSendRecv(trans, &epSet, &reqMsg, &rpcMsg); - int code = rpcMsg.code; - std::cout << tstrerror(code) << std::endl; - return true; + rpcSendRequest(this->transCli, &epSet, req, NULL); + SemWait(); + *resp = this->resp; } - bool stop() { - rpcClose(trans); - trans = NULL; - return true; + void SemWait() { tsem_wait(&this->sem); } + void SemPost() { tsem_post(&this->sem); } + void Reset() {} + + ~Client() { + if (this->transCli) rpcClose(this->transCli); } private: - void * trans; + tsem_t sem; SRpcInit rpcInit; + void * transCli; + SRpcMsg resp; +}; +class Server { + public: + Server() { + memset(&rpcInit, 0, sizeof(rpcInit)); + rpcInit.localPort = port; + rpcInit.label = (char *)label; + rpcInit.numOfThreads = 5; + rpcInit.cfp = processReq; + rpcInit.user = (char *)user; + rpcInit.secret = (char *)secret; + rpcInit.ckey = (char *)ckey; + rpcInit.spi = 1; + rpcInit.connType = TAOS_CONN_SERVER; + } + void Start() { + this->transSrv = rpcOpen(&this->rpcInit); + taosMsleep(1000); + } + void Stop() { + if (this->transSrv == NULL) return; + rpcClose(this->transSrv); + this->transSrv = NULL; + } + void Restart() { + this->Stop(); + this->Start(); + } + ~Server() { + if (this->transSrv) rpcClose(this->transSrv); + this->transSrv = NULL; + } + + private: + SRpcInit rpcInit; + void * transSrv; +}; +static void processReq(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) { + SRpcMsg rpcMsg = {0}; + rpcMsg.pCont = rpcMallocCont(100); + rpcMsg.contLen = 100; + rpcMsg.handle = pMsg->handle; + rpcMsg.code = 0; + rpcSendResponse(&rpcMsg); +} +// client process; +static void processResp(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) { + Client *client = (Client *)parent; + client->SetResp(pMsg); + client->SemPost(); +} +class TransObj { + public: + TransObj() { + dDebugFlag = 143; + vDebugFlag = 0; + mDebugFlag = 143; + cDebugFlag = 0; + jniDebugFlag = 0; + tmrDebugFlag = 143; + uDebugFlag = 143; + rpcDebugFlag = 143; + qDebugFlag = 0; + wDebugFlag = 0; + sDebugFlag = 0; + tsdbDebugFlag = 0; + cqDebugFlag = 0; + tscEmbeddedInUtil = 1; + tsAsyncLog = 0; + + std::string path = "/tmp/transport"; + taosRemoveDir(path.c_str()); + taosMkDir(path.c_str()); + + char temp[PATH_MAX]; + snprintf(temp, PATH_MAX, "%s/taosdlog", path.c_str()); + if (taosInitLog(temp, tsNumOfLogLines, 1) != 0) { + printf("failed to init log file\n"); + } + cli = new Client; + cli->Init(1); + srv = new Server; + srv->Start(); + } + void RestartCli() { cli->Restart(); } + void StopSrv() { srv->Stop(); } + void RestartSrv() { srv->Restart(); } + void cliSendAndRecv(SRpcMsg *req, SRpcMsg *resp) { cli->SendAndRecv(req, resp); } + ~TransObj() { + delete cli; + delete srv; + } + + private: + Client *cli; + Server *srv; }; class TransEnv : public ::testing::Test { protected: @@ -93,11 +192,34 @@ class TransEnv : public ::testing::Test { TransObj *tr = NULL; }; -TEST_F(TransEnv, test_start_stop) { - assert(tr->startCli()); - assert(tr->sendAndRecv()); - assert(tr->stop()); - assert(tr->startSrv()); - assert(tr->stop()); +// TEST_F(TransEnv, 01sendAndRec) { +// for (int i = 0; i < 1; i++) { +// SRpcMsg req = {0}, resp = {0}; +// req.msgType = 0; +// req.pCont = rpcMallocCont(10); +// req.contLen = 10; +// tr->cliSendAndRecv(&req, &resp); +// assert(resp.code == 0); +// } +//} + +TEST_F(TransEnv, 02StopServer) { + for (int i = 0; i < 1; i++) { + SRpcMsg req = {0}, resp = {0}; + req.msgType = 0; + req.pCont = rpcMallocCont(10); + req.contLen = 10; + tr->cliSendAndRecv(&req, &resp); + assert(resp.code == 0); + } + SRpcMsg req = {0}, resp = {0}; + req.msgType = 1; + req.pCont = rpcMallocCont(10); + req.contLen = 10; + tr->StopSrv(); + // tr->RestartSrv(); + tr->cliSendAndRecv(&req, &resp); + + assert(resp.code != 0); } From 74ccfaec3fbcab0bfd293c5cf5de741cb4b449f5 Mon Sep 17 00:00:00 2001 From: dapan Date: Tue, 22 Feb 2022 11:22:13 +0800 Subject: [PATCH 09/12] fix dbid issue --- source/dnode/vnode/src/vnd/vnodeQuery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dnode/vnode/src/vnd/vnodeQuery.c b/source/dnode/vnode/src/vnd/vnodeQuery.c index f779949f14..4b47413715 100644 --- a/source/dnode/vnode/src/vnd/vnodeQuery.c +++ b/source/dnode/vnode/src/vnd/vnodeQuery.c @@ -126,7 +126,7 @@ static int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg) { goto _exit; } - metaRsp.dbId = htobe64(pVnode->config.dbId); + metaRsp.dbId = pVnode->config.dbId; memcpy(metaRsp.dbFName, infoReq.dbFName, sizeof(metaRsp.dbFName)); strcpy(metaRsp.tbName, infoReq.tbName); if (pTbCfg->type == META_CHILD_TABLE) { From be375fa143252f755e29e8b408ac5ad742078861 Mon Sep 17 00:00:00 2001 From: Minghao Li Date: Tue, 22 Feb 2022 11:28:15 +0800 Subject: [PATCH 10/12] add sync code --- include/libs/sync/sync.h | 11 +- source/libs/sync/CMakeLists.txt | 1 - source/libs/sync/inc/syncAppendEntries.h | 38 ++++++ source/libs/sync/inc/syncAppendEntriesReply.h | 36 ++++++ source/libs/sync/inc/syncElection.h | 32 +++++ source/libs/sync/inc/syncInt.h | 79 ++++++++++++ source/libs/sync/inc/syncMessage.h | 105 ++++++++++++++++ source/libs/sync/inc/syncOnMessage.h | 35 ++++++ source/libs/sync/inc/syncRaft.h | 47 +++++++ source/libs/sync/inc/syncRaftEntry.h | 40 ++++++ source/libs/sync/inc/syncRaftLog.h | 53 ++++++++ source/libs/sync/inc/syncRaftStore.h | 42 +++++++ source/libs/sync/inc/syncReplication.h | 32 +++++ source/libs/sync/inc/syncRequestVote.h | 38 ++++++ source/libs/sync/inc/syncRequestVoteReply.h | 36 ++++++ source/libs/sync/inc/syncSnapshot.h | 38 ++++++ source/libs/sync/inc/syncTimeout.h | 36 ++++++ source/libs/sync/src/sync.c | 1 - source/libs/sync/src/syncAppendEntries.c | 117 ++++++++++++++++++ source/libs/sync/src/syncAppendEntriesReply.c | 34 +++++ source/libs/sync/src/syncElection.c | 16 +++ source/libs/sync/src/syncMain.c | 34 +++++ source/libs/sync/src/syncMessage.c | 20 +++ source/libs/sync/src/syncOnMessage.c | 16 +++ source/libs/sync/src/syncRaft.c | 21 ++++ source/libs/sync/src/syncRaftEntry.c | 16 +++ source/libs/sync/src/syncRaftLog.c | 37 ++++++ source/libs/sync/src/syncRaftStore.c | 25 ++++ source/libs/sync/src/syncReplication.c | 16 +++ source/libs/sync/src/syncRequestVote.c | 59 +++++++++ source/libs/sync/src/syncRequestVoteReply.c | 38 ++++++ source/libs/sync/src/syncSnapshot.c | 22 ++++ source/libs/sync/src/syncTimeout.c | 19 +++ source/libs/sync/test/syncTest.cpp | 7 ++ 34 files changed, 1189 insertions(+), 8 deletions(-) create mode 100644 source/libs/sync/inc/syncAppendEntries.h create mode 100644 source/libs/sync/inc/syncAppendEntriesReply.h create mode 100644 source/libs/sync/inc/syncElection.h create mode 100644 source/libs/sync/inc/syncInt.h create mode 100644 source/libs/sync/inc/syncMessage.h create mode 100644 source/libs/sync/inc/syncOnMessage.h create mode 100644 source/libs/sync/inc/syncRaft.h create mode 100644 source/libs/sync/inc/syncRaftEntry.h create mode 100644 source/libs/sync/inc/syncRaftLog.h create mode 100644 source/libs/sync/inc/syncRaftStore.h create mode 100644 source/libs/sync/inc/syncReplication.h create mode 100644 source/libs/sync/inc/syncRequestVote.h create mode 100644 source/libs/sync/inc/syncRequestVoteReply.h create mode 100644 source/libs/sync/inc/syncSnapshot.h create mode 100644 source/libs/sync/inc/syncTimeout.h delete mode 100644 source/libs/sync/src/sync.c create mode 100644 source/libs/sync/src/syncAppendEntries.c create mode 100644 source/libs/sync/src/syncAppendEntriesReply.c create mode 100644 source/libs/sync/src/syncElection.c create mode 100644 source/libs/sync/src/syncMain.c create mode 100644 source/libs/sync/src/syncMessage.c create mode 100644 source/libs/sync/src/syncOnMessage.c create mode 100644 source/libs/sync/src/syncRaft.c create mode 100644 source/libs/sync/src/syncRaftEntry.c create mode 100644 source/libs/sync/src/syncRaftLog.c create mode 100644 source/libs/sync/src/syncRaftStore.c create mode 100644 source/libs/sync/src/syncReplication.c create mode 100644 source/libs/sync/src/syncRequestVote.c create mode 100644 source/libs/sync/src/syncRequestVoteReply.c create mode 100644 source/libs/sync/src/syncSnapshot.c create mode 100644 source/libs/sync/src/syncTimeout.c create mode 100644 source/libs/sync/test/syncTest.cpp diff --git a/include/libs/sync/sync.h b/include/libs/sync/sync.h index 00ba1120e7..0ec741ec3e 100644 --- a/include/libs/sync/sync.h +++ b/include/libs/sync/sync.h @@ -137,22 +137,21 @@ typedef struct { } SSyncInfo; -// will be defined in syncInt.h, here just for complie -typedef struct SSyncNode { -} SSyncNode; +struct SSyncNode; +typedef struct SSyncNode SSyncNode; int32_t syncInit(); void syncCleanUp(); -int64_t syncStart(const SSyncInfo*); +int64_t syncStart(const SSyncInfo* pSyncInfo); void syncStop(int64_t rid); -int32_t syncReconfig(int64_t rid, const SSyncCfg*); +int32_t syncReconfig(int64_t rid, const SSyncCfg* pSyncCfg); // int32_t syncForwardToPeer(int64_t rid, const SRpcMsg* pBuf, bool isWeak); int32_t syncForwardToPeer(int64_t rid, const SSyncBuffer* pBuf, bool isWeak); ESyncState syncGetMyRole(int64_t rid); -void syncGetNodesRole(int64_t rid, SNodesRole*); +void syncGetNodesRole(int64_t rid, SNodesRole* pNodeRole); extern int32_t sDebugFlag; diff --git a/source/libs/sync/CMakeLists.txt b/source/libs/sync/CMakeLists.txt index 784a864451..37ee5194c8 100644 --- a/source/libs/sync/CMakeLists.txt +++ b/source/libs/sync/CMakeLists.txt @@ -1,4 +1,3 @@ - aux_source_directory(src SYNC_SRC) add_library(sync ${SYNC_SRC}) diff --git a/source/libs/sync/inc/syncAppendEntries.h b/source/libs/sync/inc/syncAppendEntries.h new file mode 100644 index 0000000000..9ca0de19c5 --- /dev/null +++ b/source/libs/sync/inc/syncAppendEntries.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_APPEND_ENTRIES_H +#define _TD_LIBS_SYNC_APPEND_ENTRIES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "syncMessage.h" +#include "syncRaft.h" +#include "taosdef.h" + +void appendEntries(SRaft *pRaft, const SyncAppendEntries *pMsg); + +void onAppendEntries(SRaft *pRaft, const SyncAppendEntries *pMsg); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_APPEND_ENTRIES_H*/ diff --git a/source/libs/sync/inc/syncAppendEntriesReply.h b/source/libs/sync/inc/syncAppendEntriesReply.h new file mode 100644 index 0000000000..8b5cbf1da5 --- /dev/null +++ b/source/libs/sync/inc/syncAppendEntriesReply.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_APPEND_ENTRIES_REPLY_H +#define _TD_LIBS_SYNC_APPEND_ENTRIES_REPLY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "syncMessage.h" +#include "syncRaft.h" +#include "taosdef.h" + +void onAppendEntriesReply(SRaft *pRaft, const SyncAppendEntriesReply *pMsg); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_APPEND_ENTRIES_REPLY_H*/ diff --git a/source/libs/sync/inc/syncElection.h b/source/libs/sync/inc/syncElection.h new file mode 100644 index 0000000000..34dfdb3d09 --- /dev/null +++ b/source/libs/sync/inc/syncElection.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_ELECTION_H +#define _TD_LIBS_SYNC_ELECTION_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "taosdef.h" + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_ELECTION_H*/ diff --git a/source/libs/sync/inc/syncInt.h b/source/libs/sync/inc/syncInt.h new file mode 100644 index 0000000000..551ce83122 --- /dev/null +++ b/source/libs/sync/inc/syncInt.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_INT_H +#define _TD_LIBS_SYNC_INT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "taosdef.h" + +#define sFatal(...) \ + { \ + if (sDebugFlag & DEBUG_FATAL) { \ + taosPrintLog("SYN FATAL ", sDebugFlag, __VA_ARGS__); \ + } \ + } +#define sError(...) \ + { \ + if (sDebugFlag & DEBUG_ERROR) { \ + taosPrintLog("SYN ERROR ", sDebugFlag, __VA_ARGS__); \ + } \ + } +#define sWarn(...) \ + { \ + if (sDebugFlag & DEBUG_WARN) { \ + taosPrintLog("SYN WARN ", sDebugFlag, __VA_ARGS__); \ + } \ + } +#define sInfo(...) \ + { \ + if (sDebugFlag & DEBUG_INFO) { \ + taosPrintLog("SYN ", sDebugFlag, __VA_ARGS__); \ + } \ + } +#define sDebug(...) \ + { \ + if (sDebugFlag & DEBUG_DEBUG) { \ + taosPrintLog("SYN ", sDebugFlag, __VA_ARGS__); \ + } \ + } +#define sTrace(...) \ + { \ + if (sDebugFlag & DEBUG_TRACE) { \ + taosPrintLog("SYN ", sDebugFlag, __VA_ARGS__); \ + } \ + } + +typedef struct SSyncNode { + char path[TSDB_FILENAME_LEN]; + int8_t replica; + int8_t quorum; + int8_t selfIndex; + uint32_t vgId; + int32_t refCount; + int64_t rid; +} SSyncNode; + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_INT_H*/ diff --git a/source/libs/sync/inc/syncMessage.h b/source/libs/sync/inc/syncMessage.h new file mode 100644 index 0000000000..f410c8cf6e --- /dev/null +++ b/source/libs/sync/inc/syncMessage.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_MESSAGE_H +#define _TD_LIBS_SYNC_MESSAGE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "sync.h" +#include "syncRaftEntry.h" +#include "taosdef.h" + +typedef enum ESyncMessageType { + SYNC_PING = 0, + SYNC_PING_REPLY, + SYNC_CLIENT_REQUEST, + SYNC_CLIENT_REQUEST_REPLY, + SYNC_REQUEST_VOTE, + SYNC_REQUEST_VOTE_REPLY, + SYNC_APPEND_ENTRIES, + SYNC_APPEND_ENTRIES_REPLY, +} ESyncMessageType; + +typedef struct SyncPing { + ESyncMessageType msgType; + const SSyncBuffer *pData; +} SyncPing; + +typedef struct SyncPingReply { + ESyncMessageType msgType; + const SSyncBuffer *pData; +} SyncPingReply; + +typedef struct SyncClientRequest { + ESyncMessageType msgType; + const SSyncBuffer *pData; + int64_t seqNum; + bool isWeak; +} SyncClientRequest; + +typedef struct SyncClientRequestReply { + ESyncMessageType msgType; + int32_t errCode; + const SSyncBuffer *pErrMsg; + const SSyncBuffer *pLeaderHint; +} SyncClientRequestReply; + +typedef struct SyncRequestVote { + ESyncMessageType msgType; + SyncTerm currentTerm; + SyncNodeId nodeId; + SyncGroupId vgId; + SyncIndex lastLogIndex; + SyncTerm lastLogTerm; +} SyncRequestVote; + +typedef struct SyncRequestVoteReply { + ESyncMessageType msgType; + SyncTerm currentTerm; + SyncNodeId nodeId; + SyncGroupId vgId; + bool voteGranted; +} SyncRequestVoteReply; + +typedef struct SyncAppendEntries { + ESyncMessageType msgType; + SyncTerm currentTerm; + SyncNodeId nodeId; + SyncIndex prevLogIndex; + SyncTerm prevLogTerm; + int32_t entryCount; + SSyncRaftEntry * logEntries; + SyncIndex commitIndex; +} SyncAppendEntries; + +typedef struct SyncAppendEntriesReply { + ESyncMessageType msgType; + SyncTerm currentTerm; + SyncNodeId nodeId; + bool success; + SyncIndex matchIndex; +} SyncAppendEntriesReply; + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_MESSAGE_H*/ diff --git a/source/libs/sync/inc/syncOnMessage.h b/source/libs/sync/inc/syncOnMessage.h new file mode 100644 index 0000000000..07c44b6199 --- /dev/null +++ b/source/libs/sync/inc/syncOnMessage.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_ON_MESSAGE_H +#define _TD_LIBS_SYNC_ON_MESSAGE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "syncRaft.h" +#include "taosdef.h" + +void onMessage(SRaft *pRaft, void *pMsg); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_ON_MESSAGE_H*/ diff --git a/source/libs/sync/inc/syncRaft.h b/source/libs/sync/inc/syncRaft.h new file mode 100644 index 0000000000..0c7e573572 --- /dev/null +++ b/source/libs/sync/inc/syncRaft.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_RAFT_H +#define _TD_LIBS_SYNC_RAFT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "sync.h" +#include "syncMessage.h" +#include "taosdef.h" + +typedef struct SRaftId { + SyncNodeId nodeId; + SyncGroupId vgId; +} SRaftId; + +typedef struct SRaft { + SRaftId id; +} SRaft; + +int32_t raftPropose(SRaft* pRaft, const SSyncBuffer* pBuf, bool isWeak); + +static int raftSendMsg(SRaftId destRaftId, const void* pMsg, const SRaft* pRaft); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_RAFT_H*/ diff --git a/source/libs/sync/inc/syncRaftEntry.h b/source/libs/sync/inc/syncRaftEntry.h new file mode 100644 index 0000000000..adc82f2c5d --- /dev/null +++ b/source/libs/sync/inc/syncRaftEntry.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_TPL_H +#define _TD_LIBS_TPL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "sync.h" +#include "taosdef.h" + +typedef struct SSyncRaftEntry { + SyncTerm term; + SyncIndex index; + SSyncBuffer data; + int8_t flag; +} SSyncRaftEntry; + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_TPL_H*/ diff --git a/source/libs/sync/inc/syncRaftLog.h b/source/libs/sync/inc/syncRaftLog.h new file mode 100644 index 0000000000..8c4b5116ea --- /dev/null +++ b/source/libs/sync/inc/syncRaftLog.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_RAFT_LOG_H +#define _TD_LIBS_SYNC_RAFT_LOG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "sync.h" +#include "taosdef.h" + +int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncBuffer* pBuf); + +// get one log entry, user need to free pBuf->data +int32_t raftLogGetEntry(struct SSyncLogStore* pLogStore, SyncIndex index, SSyncBuffer* pBuf); + +// update log store commit index with "index" +int32_t raftLogUpdateCommitIndex(struct SSyncLogStore* pLogStore, SyncIndex index); + +// truncate log with index, entries after the given index (>index) will be deleted +int32_t raftLogTruncate(struct SSyncLogStore* pLogStore, SyncIndex index); + +// return commit index of log +SyncIndex raftLogGetCommitIndex(struct SSyncLogStore* pLogStore); + +// return index of last entry +SyncIndex raftLogGetLastIndex(struct SSyncLogStore* pLogStore); + +// return term of last entry +SyncTerm raftLogGetLastTerm(struct SSyncLogStore* pLogStore); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_RAFT_LOG_H*/ diff --git a/source/libs/sync/inc/syncRaftStore.h b/source/libs/sync/inc/syncRaftStore.h new file mode 100644 index 0000000000..4cb852f34a --- /dev/null +++ b/source/libs/sync/inc/syncRaftStore.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_RAFT_STORE_H +#define _TD_LIBS_SYNC_RAFT_STORE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "sync.h" +#include "syncRaft.h" +#include "taosdef.h" + +int32_t currentTerm(SyncTerm *pCurrentTerm); + +int32_t persistCurrentTerm(SyncTerm currentTerm); + +int32_t voteFor(SRaftId *pRaftId); + +int32_t persistVoteFor(SRaftId *pRaftId); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_RAFT_STORE_H*/ diff --git a/source/libs/sync/inc/syncReplication.h b/source/libs/sync/inc/syncReplication.h new file mode 100644 index 0000000000..40c5ff790b --- /dev/null +++ b/source/libs/sync/inc/syncReplication.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_REPLICATION_H +#define _TD_LIBS_SYNC_REPLICATION_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "taosdef.h" + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_REPLICATION_H*/ diff --git a/source/libs/sync/inc/syncRequestVote.h b/source/libs/sync/inc/syncRequestVote.h new file mode 100644 index 0000000000..3ff96bbe8f --- /dev/null +++ b/source/libs/sync/inc/syncRequestVote.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_REQUEST_VOTE_H +#define _TD_LIBS_SYNC_REQUEST_VOTE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "syncMessage.h" +#include "syncRaft.h" +#include "taosdef.h" + +void requestVote(SRaft *pRaft, const SyncRequestVote *pMsg); + +void onRequestVote(SRaft *pRaft, const SyncRequestVote *pMsg); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_REQUEST_VOTE_H*/ diff --git a/source/libs/sync/inc/syncRequestVoteReply.h b/source/libs/sync/inc/syncRequestVoteReply.h new file mode 100644 index 0000000000..033ac89bc2 --- /dev/null +++ b/source/libs/sync/inc/syncRequestVoteReply.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_REQUEST_VOTE_REPLY_H +#define _TD_LIBS_SYNC_REQUEST_VOTE_REPLY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "syncMessage.h" +#include "syncRaft.h" +#include "taosdef.h" + +void onRequestVoteReply(SRaft *pRaft, const SyncRequestVoteReply *pMsg); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_REQUEST_VOTE_REPLY_H*/ diff --git a/source/libs/sync/inc/syncSnapshot.h b/source/libs/sync/inc/syncSnapshot.h new file mode 100644 index 0000000000..3b6121578a --- /dev/null +++ b/source/libs/sync/inc/syncSnapshot.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_SNAPSHOT_H +#define _TD_LIBS_SYNC_SNAPSHOT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "sync.h" +#include "syncRaft.h" +#include "taosdef.h" + +int32_t takeSnapshot(SSyncFSM *pFsm, SSnapshot *pSnapshot); + +int32_t restoreSnapshot(SSyncFSM *pFsm, SSnapshot *pSnapshot); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_SNAPSHOT_H*/ diff --git a/source/libs/sync/inc/syncTimeout.h b/source/libs/sync/inc/syncTimeout.h new file mode 100644 index 0000000000..8159d2566c --- /dev/null +++ b/source/libs/sync/inc/syncTimeout.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_LIBS_SYNC_TIMEOUT_H +#define _TD_LIBS_SYNC_TIMEOUT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "syncMessage.h" +#include "syncRaft.h" +#include "taosdef.h" + +void onTimeout(SRaft *pRaft, void *pMsg); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_LIBS_SYNC_TIMEOUT_H*/ diff --git a/source/libs/sync/src/sync.c b/source/libs/sync/src/sync.c deleted file mode 100644 index 7ded53b6e6..0000000000 --- a/source/libs/sync/src/sync.c +++ /dev/null @@ -1 +0,0 @@ -#include "sync.h" \ No newline at end of file diff --git a/source/libs/sync/src/syncAppendEntries.c b/source/libs/sync/src/syncAppendEntries.c new file mode 100644 index 0000000000..1286108664 --- /dev/null +++ b/source/libs/sync/src/syncAppendEntries.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "syncAppendEntries.h" +#include "sync.h" + +void appendEntries(SRaft *pRaft, const SyncAppendEntries *pMsg) { + +// TLA+ Spec +//AppendEntries(i, j) == +// /\ i /= j +// /\ state[i] = Leader +// /\ LET prevLogIndex == nextIndex[i][j] - 1 +// prevLogTerm == IF prevLogIndex > 0 THEN +// log[i][prevLogIndex].term +// ELSE +// 0 +// \* Send up to 1 entry, constrained by the end of the log. +// lastEntry == Min({Len(log[i]), nextIndex[i][j]}) +// entries == SubSeq(log[i], nextIndex[i][j], lastEntry) +// IN Send([mtype |-> AppendEntriesRequest, +// mterm |-> currentTerm[i], +// mprevLogIndex |-> prevLogIndex, +// mprevLogTerm |-> prevLogTerm, +// mentries |-> entries, +// \* mlog is used as a history variable for the proof. +// \* It would not exist in a real implementation. +// mlog |-> log[i], +// mcommitIndex |-> Min({commitIndex[i], lastEntry}), +// msource |-> i, +// mdest |-> j]) +// /\ UNCHANGED <> + +} + +void onAppendEntries(SRaft *pRaft, const SyncAppendEntries *pMsg) { + +// TLA+ Spec +//HandleAppendEntriesRequest(i, j, m) == +// LET logOk == \/ m.mprevLogIndex = 0 +// \/ /\ m.mprevLogIndex > 0 +// /\ m.mprevLogIndex <= Len(log[i]) +// /\ m.mprevLogTerm = log[i][m.mprevLogIndex].term +// IN /\ m.mterm <= currentTerm[i] +// /\ \/ /\ \* reject request +// \/ m.mterm < currentTerm[i] +// \/ /\ m.mterm = currentTerm[i] +// /\ state[i] = Follower +// /\ \lnot logOk +// /\ Reply([mtype |-> AppendEntriesResponse, +// mterm |-> currentTerm[i], +// msuccess |-> FALSE, +// mmatchIndex |-> 0, +// msource |-> i, +// mdest |-> j], +// m) +// /\ UNCHANGED <> +// \/ \* return to follower state +// /\ m.mterm = currentTerm[i] +// /\ state[i] = Candidate +// /\ state' = [state EXCEPT ![i] = Follower] +// /\ UNCHANGED <> +// \/ \* accept request +// /\ m.mterm = currentTerm[i] +// /\ state[i] = Follower +// /\ logOk +// /\ LET index == m.mprevLogIndex + 1 +// IN \/ \* already done with request +// /\ \/ m.mentries = << >> +// \/ /\ m.mentries /= << >> +// /\ Len(log[i]) >= index +// /\ log[i][index].term = m.mentries[1].term +// \* This could make our commitIndex decrease (for +// \* example if we process an old, duplicated request), +// \* but that doesn't really affect anything. +// /\ commitIndex' = [commitIndex EXCEPT ![i] = +// m.mcommitIndex] +// /\ Reply([mtype |-> AppendEntriesResponse, +// mterm |-> currentTerm[i], +// msuccess |-> TRUE, +// mmatchIndex |-> m.mprevLogIndex + +// Len(m.mentries), +// msource |-> i, +// mdest |-> j], +// m) +// /\ UNCHANGED <> +// \/ \* conflict: remove 1 entry +// /\ m.mentries /= << >> +// /\ Len(log[i]) >= index +// /\ log[i][index].term /= m.mentries[1].term +// /\ LET new == [index2 \in 1..(Len(log[i]) - 1) |-> +// log[i][index2]] +// IN log' = [log EXCEPT ![i] = new] +// /\ UNCHANGED <> +// \/ \* no conflict: append entry +// /\ m.mentries /= << >> +// /\ Len(log[i]) = m.mprevLogIndex +// /\ log' = [log EXCEPT ![i] = +// Append(log[i], m.mentries[1])] +// /\ UNCHANGED <> +// /\ UNCHANGED <> +// + + +} diff --git a/source/libs/sync/src/syncAppendEntriesReply.c b/source/libs/sync/src/syncAppendEntriesReply.c new file mode 100644 index 0000000000..4a9055e172 --- /dev/null +++ b/source/libs/sync/src/syncAppendEntriesReply.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "syncAppendEntriesReply.h" +#include "sync.h" + +void onAppendEntriesReply(SRaft *pRaft, const SyncAppendEntriesReply *pMsg) { + +// TLA+ Spec +//HandleAppendEntriesResponse(i, j, m) == +// /\ m.mterm = currentTerm[i] +// /\ \/ /\ m.msuccess \* successful +// /\ nextIndex' = [nextIndex EXCEPT ![i][j] = m.mmatchIndex + 1] +// /\ matchIndex' = [matchIndex EXCEPT ![i][j] = m.mmatchIndex] +// \/ /\ \lnot m.msuccess \* not successful +// /\ nextIndex' = [nextIndex EXCEPT ![i][j] = +// Max({nextIndex[i][j] - 1, 1})] +// /\ UNCHANGED <> +// /\ Discard(m) +// /\ UNCHANGED <> + +} diff --git a/source/libs/sync/src/syncElection.c b/source/libs/sync/src/syncElection.c new file mode 100644 index 0000000000..738fc4c5e1 --- /dev/null +++ b/source/libs/sync/src/syncElection.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "sync.h" diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c new file mode 100644 index 0000000000..fbb969eb1c --- /dev/null +++ b/source/libs/sync/src/syncMain.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include +#include "sync.h" +#include "syncInt.h" + +int32_t syncInit() { return 0; } + +void syncCleanUp() {} + +int64_t syncStart(const SSyncInfo* pSyncInfo) { return 0; } + +void syncStop(int64_t rid) {} + +int32_t syncReconfig(int64_t rid, const SSyncCfg* pSyncCfg) { return 0; } + +int32_t syncForwardToPeer(int64_t rid, const SSyncBuffer* pBuf, bool isWeak) { return 0; } + +ESyncState syncGetMyRole(int64_t rid) { return TAOS_SYNC_STATE_LEADER; } + +void syncGetNodesRole(int64_t rid, SNodesRole* pNodeRole) {} \ No newline at end of file diff --git a/source/libs/sync/src/syncMessage.c b/source/libs/sync/src/syncMessage.c new file mode 100644 index 0000000000..dcfc940f76 --- /dev/null +++ b/source/libs/sync/src/syncMessage.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "syncMessage.h" +#include "sync.h" +#include "syncRaft.h" + +void onMessage(SRaft *pRaft, void *pMsg) {} \ No newline at end of file diff --git a/source/libs/sync/src/syncOnMessage.c b/source/libs/sync/src/syncOnMessage.c new file mode 100644 index 0000000000..738fc4c5e1 --- /dev/null +++ b/source/libs/sync/src/syncOnMessage.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "sync.h" diff --git a/source/libs/sync/src/syncRaft.c b/source/libs/sync/src/syncRaft.c new file mode 100644 index 0000000000..85c2c6fe27 --- /dev/null +++ b/source/libs/sync/src/syncRaft.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "syncRaft.h" +#include "sync.h" + +int32_t raftPropose(SRaft* pRaft, const SSyncBuffer* pBuf, bool isWeak) { return 0; } + +static int raftSendMsg(SRaftId destRaftId, const void* pMsg, const SRaft* pRaft) { return 0; } diff --git a/source/libs/sync/src/syncRaftEntry.c b/source/libs/sync/src/syncRaftEntry.c new file mode 100644 index 0000000000..738fc4c5e1 --- /dev/null +++ b/source/libs/sync/src/syncRaftEntry.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "sync.h" diff --git a/source/libs/sync/src/syncRaftLog.c b/source/libs/sync/src/syncRaftLog.c new file mode 100644 index 0000000000..4a5fc201b0 --- /dev/null +++ b/source/libs/sync/src/syncRaftLog.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "syncRaftLog.h" +#include "sync.h" + +int32_t raftLogAppendEntry(struct SSyncLogStore* pLogStore, SSyncBuffer* pBuf) { return 0; } + +// get one log entry, user need to free pBuf->data +int32_t raftLogGetEntry(struct SSyncLogStore* pLogStore, SyncIndex index, SSyncBuffer* pBuf) { return 0; } + +// update log store commit index with "index" +int32_t raftLogupdateCommitIndex(struct SSyncLogStore* pLogStore, SyncIndex index) { return 0; } + +// truncate log with index, entries after the given index (>index) will be deleted +int32_t raftLogTruncate(struct SSyncLogStore* pLogStore, SyncIndex index) { return 0; } + +// return commit index of log +SyncIndex raftLogGetCommitIndex(struct SSyncLogStore* pLogStore) { return 0; } + +// return index of last entry +SyncIndex raftLogGetLastIndex(struct SSyncLogStore* pLogStore) { return 0; } + +// return term of last entry +SyncTerm raftLogGetLastTerm(struct SSyncLogStore* pLogStore) { return 0; } \ No newline at end of file diff --git a/source/libs/sync/src/syncRaftStore.c b/source/libs/sync/src/syncRaftStore.c new file mode 100644 index 0000000000..d45e53132c --- /dev/null +++ b/source/libs/sync/src/syncRaftStore.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "syncRaftStore.h" +#include "sync.h" + +int32_t currentTerm(SyncTerm *pCurrentTerm) { return 0; } + +int32_t persistCurrentTerm(SyncTerm currentTerm) { return 0; } + +int32_t voteFor(SRaftId *pRaftId) { return 0; } + +int32_t persistVoteFor(SRaftId *pRaftId) { return 0; } \ No newline at end of file diff --git a/source/libs/sync/src/syncReplication.c b/source/libs/sync/src/syncReplication.c new file mode 100644 index 0000000000..738fc4c5e1 --- /dev/null +++ b/source/libs/sync/src/syncReplication.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "sync.h" diff --git a/source/libs/sync/src/syncRequestVote.c b/source/libs/sync/src/syncRequestVote.c new file mode 100644 index 0000000000..c31ec0f34d --- /dev/null +++ b/source/libs/sync/src/syncRequestVote.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "syncRequestVote.h" +#include "sync.h" + +void requestVote(SRaft *pRaft, const SyncRequestVote *pMsg) { + +// TLA+ Spec +//RequestVote(i, j) == +// /\ state[i] = Candidate +// /\ j \notin votesResponded[i] +// /\ Send([mtype |-> RequestVoteRequest, +// mterm |-> currentTerm[i], +// mlastLogTerm |-> LastTerm(log[i]), +// mlastLogIndex |-> Len(log[i]), +// msource |-> i, +// mdest |-> j]) +// /\ UNCHANGED <> + +} + +void onRequestVote(SRaft *pRaft, const SyncRequestVote *pMsg) { + +// TLA+ Spec +//HandleRequestVoteRequest(i, j, m) == +// LET logOk == \/ m.mlastLogTerm > LastTerm(log[i]) +// \/ /\ m.mlastLogTerm = LastTerm(log[i]) +// /\ m.mlastLogIndex >= Len(log[i]) +// grant == /\ m.mterm = currentTerm[i] +// /\ logOk +// /\ votedFor[i] \in {Nil, j} +// IN /\ m.mterm <= currentTerm[i] +// /\ \/ grant /\ votedFor' = [votedFor EXCEPT ![i] = j] +// \/ ~grant /\ UNCHANGED votedFor +// /\ Reply([mtype |-> RequestVoteResponse, +// mterm |-> currentTerm[i], +// mvoteGranted |-> grant, +// \* mlog is used just for the `elections' history variable for +// \* the proof. It would not exist in a real implementation. +// mlog |-> log[i], +// msource |-> i, +// mdest |-> j], +// m) +// /\ UNCHANGED <> + +} diff --git a/source/libs/sync/src/syncRequestVoteReply.c b/source/libs/sync/src/syncRequestVoteReply.c new file mode 100644 index 0000000000..ba9787f00c --- /dev/null +++ b/source/libs/sync/src/syncRequestVoteReply.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "syncRequestVoteReply.h" +#include "sync.h" + +void onRequestVoteReply(SRaft *pRaft, const SyncRequestVoteReply *pMsg) { + +// TLA+ Spec +//HandleRequestVoteResponse(i, j, m) == +// \* This tallies votes even when the current state is not Candidate, but +// \* they won't be looked at, so it doesn't matter. +// /\ m.mterm = currentTerm[i] +// /\ votesResponded' = [votesResponded EXCEPT ![i] = +// votesResponded[i] \cup {j}] +// /\ \/ /\ m.mvoteGranted +// /\ votesGranted' = [votesGranted EXCEPT ![i] = +// votesGranted[i] \cup {j}] +// /\ voterLog' = [voterLog EXCEPT ![i] = +// voterLog[i] @@ (j :> m.mlog)] +// \/ /\ ~m.mvoteGranted +// /\ UNCHANGED <> +// /\ Discard(m) +// /\ UNCHANGED <> + +} diff --git a/source/libs/sync/src/syncSnapshot.c b/source/libs/sync/src/syncSnapshot.c new file mode 100644 index 0000000000..8a27f097d1 --- /dev/null +++ b/source/libs/sync/src/syncSnapshot.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "syncSnapshot.h" +#include "sync.h" +#include "syncRaft.h" + +int32_t takeSnapshot(SSyncFSM *pFsm, SSnapshot *pSnapshot) { return 0; } + +int32_t restoreSnapshot(SSyncFSM *pFsm, SSnapshot *pSnapshot) { return 0; } \ No newline at end of file diff --git a/source/libs/sync/src/syncTimeout.c b/source/libs/sync/src/syncTimeout.c new file mode 100644 index 0000000000..206dd70046 --- /dev/null +++ b/source/libs/sync/src/syncTimeout.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "syncTimeout.h" +#include "sync.h" + +void onTimeout(SRaft *pRaft, void *pMsg) {} \ No newline at end of file diff --git a/source/libs/sync/test/syncTest.cpp b/source/libs/sync/test/syncTest.cpp new file mode 100644 index 0000000000..47566d537e --- /dev/null +++ b/source/libs/sync/test/syncTest.cpp @@ -0,0 +1,7 @@ +#include + +int main() { + printf("test \n"); + return 0; +} + From 5941437be1beff0ef47193c217607baa40b3f2f9 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 22 Feb 2022 12:51:34 +0800 Subject: [PATCH 11/12] refactor code --- .../dnode/mgmt/impl/test/sut/src/client.cpp | 5 ++- source/libs/transport/inc/transComm.h | 9 ++-- source/libs/transport/src/transCli.c | 30 +------------ source/libs/transport/src/transComm.c | 22 ++++++---- source/libs/transport/src/transSrv.c | 42 +------------------ 5 files changed, 26 insertions(+), 82 deletions(-) diff --git a/source/dnode/mgmt/impl/test/sut/src/client.cpp b/source/dnode/mgmt/impl/test/sut/src/client.cpp index 589c015013..b89cb02834 100644 --- a/source/dnode/mgmt/impl/test/sut/src/client.cpp +++ b/source/dnode/mgmt/impl/test/sut/src/client.cpp @@ -24,6 +24,9 @@ static void processClientRsp(void* parent, SRpcMsg* pRsp, SEpSet* pEpSet) { } void TestClient::SetRpcRsp(SRpcMsg* rsp) { + if (this->pRsp) { + free(this->pRsp); + } this->pRsp = (SRpcMsg*)calloc(1, sizeof(SRpcMsg)); this->pRsp->msgType = rsp->msgType; this->pRsp->code = rsp->code; @@ -60,7 +63,7 @@ bool TestClient::Init(const char* user, const char* pass, const char* fqdn, uint strcpy(this->user, user); strcpy(this->pass, pass); this->port = port; - // this->pRsp = NULL; + this->pRsp = NULL; this->DoInit(); return true; } diff --git a/source/libs/transport/inc/transComm.h b/source/libs/transport/inc/transComm.h index 2078a218ee..d4d9bff56c 100644 --- a/source/libs/transport/inc/transComm.h +++ b/source/libs/transport/inc/transComm.h @@ -238,10 +238,11 @@ SAsyncPool* transCreateAsyncPool(uv_loop_t* loop, int sz, void* arg, AsyncCB cb) void transDestroyAsyncPool(SAsyncPool* pool); int transSendAsync(SAsyncPool* pool, queue* mq); -int transInitBuffer(SConnBuffer* buf); -int transClearBuffer(SConnBuffer* buf); -int transDestroyBuffer(SConnBuffer* buf); -int transAllocBuffer(SConnBuffer* connBuf, uv_buf_t* uvBuf); +int transInitBuffer(SConnBuffer* buf); +int transClearBuffer(SConnBuffer* buf); +int transDestroyBuffer(SConnBuffer* buf); +int transAllocBuffer(SConnBuffer* connBuf, uv_buf_t* uvBuf); +bool transReadComplete(SConnBuffer* connBuf); // int transPackMsg(SRpcMsg *rpcMsg, bool sercured, bool auth, char **msg, int32_t *msgLen); diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c index c70cd933d5..8312c0217c 100644 --- a/source/libs/transport/src/transCli.c +++ b/source/libs/transport/src/transCli.c @@ -84,8 +84,6 @@ static void addConnToPool(void* pool, char* ip, uint32_t port, SCliConn* co // register timer in each thread to clear expire conn static void clientTimeoutCb(uv_timer_t* handle); -// check whether already read complete packet from server -static bool clientReadComplete(SConnBuffer* pBuf); // alloc buf for read static void clientAllocBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); // callback after read nbytes from socket @@ -309,32 +307,6 @@ static void addConnToPool(void* pool, char* ip, uint32_t port, SCliConn* conn) { assert(plist != NULL); QUEUE_PUSH(&plist->conn, &conn->conn); } -static bool clientReadComplete(SConnBuffer* data) { - if (data->len >= sizeof(STransMsgHead)) { - STransMsgHead head; - memcpy((char*)&head, data->buf, sizeof(head)); - int32_t msgLen = (int32_t)htonl(head.msgLen); - data->total = msgLen; - } - - if (data->len == data->cap && data->total == data->cap) { - return true; - } - return false; - // if (data->len >= headLen) { - // memcpy((char*)&head, data->buf, headLen); - // int32_t msgLen = (int32_t)htonl((uint32_t)head.msgLen); - // if (msgLen > data->len) { - // data->left = msgLen - data->len; - // return false; - // } else if (msgLen == data->len) { - // data->left = 0; - // return true; - // } - //} else { - // return false; - //} -} static void clientAllocBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { SCliConn* conn = handle->data; SConnBuffer* pBuf = &conn->readBuf; @@ -349,7 +321,7 @@ static void clientReadCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf SConnBuffer* pBuf = &conn->readBuf; if (nread > 0) { pBuf->len += nread; - if (clientReadComplete(pBuf)) { + if (transReadComplete(pBuf)) { tTrace("client conn %p read complete", conn); clientHandleResp(conn); } else { diff --git a/source/libs/transport/src/transComm.c b/source/libs/transport/src/transComm.c index 388e0da4e0..9a8607b0ed 100644 --- a/source/libs/transport/src/transComm.c +++ b/source/libs/transport/src/transComm.c @@ -222,23 +222,31 @@ int transAllocBuffer(SConnBuffer* connBuf, uv_buf_t* uvBuf) { p->buf = (char*)calloc(CAPACITY, sizeof(char)); p->len = 0; p->cap = CAPACITY; - p->total = 0; + p->total = -1; uvBuf->base = p->buf; uvBuf->len = CAPACITY; } else { - STransMsgHead head; - memcpy((char*)&head, p->buf, sizeof(head)); - int32_t msgLen = (int32_t)htonl(head.msgLen); - - p->total = msgLen; - p->cap = msgLen; + p->cap = p->total; p->buf = realloc(p->buf, p->cap); uvBuf->base = p->buf + p->len; uvBuf->len = p->cap - p->len; } return 0; } +// check whether already read complete +bool transReadComplete(SConnBuffer* connBuf) { + if (connBuf->total == -1 && connBuf->len >= sizeof(STransMsgHead)) { + STransMsgHead head; + memcpy((char*)&head, connBuf->buf, sizeof(head)); + int32_t msgLen = (int32_t)htonl(head.msgLen); + connBuf->total = msgLen; + } + if (connBuf->len == connBuf->cap && connBuf->total == connBuf->cap) { + return true; + } + return false; +} int transPackMsg(STransMsgHead* msgHead, bool sercured, bool auth) {} int transUnpackMsg(STransMsgHead* msgHead) {} diff --git a/source/libs/transport/src/transSrv.c b/source/libs/transport/src/transSrv.c index a038f72adc..9fca371bf3 100644 --- a/source/libs/transport/src/transSrv.c +++ b/source/libs/transport/src/transSrv.c @@ -104,7 +104,6 @@ static void uvStartSendResp(SSrvMsg* msg); static void destroySmsg(SSrvMsg* smsg); // check whether already read complete packet -static bool readComplete(SConnBuffer* buf); static SSrvConn* createConn(void* hThrd); static void destroyConn(SSrvConn* conn, bool clear /*clear handle or not*/); @@ -124,45 +123,6 @@ void uvAllocReadBufferCb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* b transAllocBuffer(pBuf, buf); } -// check data read from socket complete or not -// -static bool readComplete(SConnBuffer* data) { - // TODO(yihao): handle pipeline later - if (data->len == data->cap && data->total == data->cap) { - return true; - } - return false; - // STransMsgHead head; - // int32_t headLen = sizeof(head); - // if (data->len >= headLen) { - // memcpy((char*)&head, data->buf, headLen); - // int32_t msgLen = (int32_t)htonl((uint32_t)head.msgLen); - // if (msgLen > data->len) { - // data->left = msgLen - data->len; - // return false; - // } else if (msgLen == data->len) { - // return true; - // } else if (msgLen < data->len) { - // return false; - // // handle other packet later - // } - //} else { - // return false; - //} -} - -// static void uvDoProcess(SRecvInfo* pRecv) { -// // impl later -// STransMsgHead* pHead = (STransMsgHead*)pRecv->msg; -// SRpcInfo* pRpc = (SRpcInfo*)pRecv->shandle; -// SSrvConn* pConn = pRecv->thandle; -// tDump(pRecv->msg, pRecv->msgLen); -// terrno = 0; -// // SRpcReqContext* pContest; -// -// // do auth and check -//} - static int uvAuthMsg(SSrvConn* pConn, char* msg, int len) { STransMsgHead* pHead = (STransMsgHead*)msg; @@ -283,7 +243,7 @@ void uvOnReadCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) { if (nread > 0) { pBuf->len += nread; tTrace("server conn %p read summary, total read: %d, current read: %d", conn, pBuf->len, (int)nread); - if (readComplete(pBuf)) { + if (transReadComplete(pBuf)) { tTrace("server conn %p alread read complete packet", conn); uvHandleReq(conn); } else { From 9233663a985c4aca1bfd925d006320ebce0da156 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Tue, 22 Feb 2022 22:02:28 +0800 Subject: [PATCH 12/12] add index test U --- source/libs/index/src/index.c | 56 +++-- source/libs/index/src/index_cache.c | 69 ++++-- source/libs/index/src/index_fst.c | 198 +++++++++++----- source/libs/index/src/index_fst_automation.c | 24 +- source/libs/index/src/index_fst_util.c | 25 +- source/libs/index/src/index_tfile.c | 126 +++++++--- source/libs/index/test/CMakeLists.txt | 20 ++ source/libs/index/test/fstTest.cc | 11 +- source/libs/index/test/fstUT.cc | 232 +++++++++++++++++++ 9 files changed, 602 insertions(+), 159 deletions(-) create mode 100644 source/libs/index/test/fstUT.cc diff --git a/source/libs/index/src/index.c b/source/libs/index/src/index.c index 0c222eae1a..9287a91828 100644 --- a/source/libs/index/src/index.c +++ b/source/libs/index/src/index.c @@ -66,7 +66,9 @@ static void indexMergeSameKey(SArray* result, TFileValue* tv); int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) { pthread_once(&isInit, indexInit); SIndex* sIdx = calloc(1, sizeof(SIndex)); - if (sIdx == NULL) { return -1; } + if (sIdx == NULL) { + return -1; + } #ifdef USE_LUCENE index_t* index = index_open(path); @@ -76,7 +78,9 @@ int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) { #ifdef USE_INVERTED_INDEX // sIdx->cache = (void*)indexCacheCreate(sIdx); sIdx->tindex = indexTFileCreate(path); - if (sIdx->tindex == NULL) { goto END; } + if (sIdx->tindex == NULL) { + goto END; + } sIdx->colObj = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); sIdx->cVersion = 1; @@ -87,7 +91,9 @@ int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) { #endif END: - if (sIdx != NULL) { indexClose(sIdx); } + if (sIdx != NULL) { + indexClose(sIdx); + } *index = NULL; return -1; @@ -103,7 +109,9 @@ void indexClose(SIndex* sIdx) { void* iter = taosHashIterate(sIdx->colObj, NULL); while (iter) { IndexCache** pCache = iter; - if (*pCache) { indexCacheUnRef(*pCache); } + if (*pCache) { + indexCacheUnRef(*pCache); + } iter = taosHashIterate(sIdx->colObj, iter); } taosHashCleanup(sIdx->colObj); @@ -161,7 +169,9 @@ int indexPut(SIndex* index, SIndexMultiTerm* fVals, uint64_t uid) { IndexCache** cache = taosHashGet(index->colObj, buf, sz); assert(*cache != NULL); int ret = indexCachePut(*cache, p, uid); - if (ret != 0) { return ret; } + if (ret != 0) { + return ret; + } } #endif @@ -191,7 +201,9 @@ int indexSearch(SIndex* index, SIndexMultiTermQuery* multiQuerys, SArray* result int tsz = 0; index_multi_search(index->index, (const char**)fields, (const char**)keys, types, nQuery, opera, &tResult, &tsz); - for (int i = 0; i < tsz; i++) { taosArrayPush(result, &tResult[i]); } + for (int i = 0; i < tsz; i++) { + taosArrayPush(result, &tResult[i]); + } for (int i = 0; i < nQuery; i++) { free(fields[i]); @@ -248,7 +260,9 @@ void indexOptsDestroy(SIndexOpts* opts) { */ SIndexMultiTermQuery* indexMultiTermQueryCreate(EIndexOperatorType opera) { SIndexMultiTermQuery* p = (SIndexMultiTermQuery*)malloc(sizeof(SIndexMultiTermQuery)); - if (p == NULL) { return NULL; } + if (p == NULL) { + return NULL; + } p->opera = opera; p->query = taosArrayInit(4, sizeof(SIndexTermQuery)); return p; @@ -270,7 +284,9 @@ int indexMultiTermQueryAdd(SIndexMultiTermQuery* pQuery, SIndexTerm* term, EInde SIndexTerm* indexTermCreate(int64_t suid, SIndexOperOnColumn oper, uint8_t colType, const char* colName, int32_t nColName, const char* colVal, int32_t nColVal) { SIndexTerm* t = (SIndexTerm*)calloc(1, (sizeof(SIndexTerm))); - if (t == NULL) { return NULL; } + if (t == NULL) { + return NULL; + } t->suid = suid; t->operType = oper; @@ -343,7 +359,9 @@ static int indexTermSearch(SIndex* sIdx, SIndexTermQuery* query, SArray** result return 0; } static void indexInterResultsDestroy(SArray* results) { - if (results == NULL) { return; } + if (results == NULL) { + return; + } size_t sz = taosArrayGetSize(results); for (size_t i = 0; i < sz; i++) { @@ -419,18 +437,24 @@ static void indexDestroyTempResult(SArray* result) { taosArrayDestroy(result); } int indexFlushCacheToTFile(SIndex* sIdx, void* cache) { - if (sIdx == NULL) { return -1; } + if (sIdx == NULL) { + return -1; + } indexInfo("suid %" PRIu64 " merge cache into tindex", sIdx->suid); int64_t st = taosGetTimestampUs(); IndexCache* pCache = (IndexCache*)cache; TFileReader* pReader = tfileGetReaderByCol(sIdx->tindex, pCache->suid, pCache->colName); - if (pReader == NULL) { indexWarn("empty tfile reader found"); } + if (pReader == NULL) { + indexWarn("empty tfile reader found"); + } // handle flush Iterate* cacheIter = indexCacheIteratorCreate(pCache); Iterate* tfileIter = tfileIteratorCreate(pReader); - if (tfileIter == NULL) { indexWarn("empty tfile reader iterator"); } + if (tfileIter == NULL) { + indexWarn("empty tfile reader iterator"); + } SArray* result = taosArrayInit(1024, sizeof(void*)); @@ -484,7 +508,9 @@ void iterateValueDestroy(IterateValue* value, bool destroy) { taosArrayDestroy(value->val); value->val = NULL; } else { - if (value->val != NULL) { taosArrayClear(value->val); } + if (value->val != NULL) { + taosArrayClear(value->val); + } } free(value->colVal); value->colVal = NULL; @@ -507,7 +533,9 @@ static int indexGenTFile(SIndex* sIdx, IndexCache* cache, SArray* batch) { tfileWriterClose(tw); TFileReader* reader = tfileReaderOpen(sIdx->path, cache->suid, version, cache->colName); - if (reader == NULL) { return -1; } + if (reader == NULL) { + return -1; + } TFileHeader* header = &reader->header; ICacheKey key = {.suid = cache->suid, .colName = header->colName, .nColName = strlen(header->colName)}; diff --git a/source/libs/index/src/index_cache.c b/source/libs/index/src/index_cache.c index 48566a8674..d6a7141825 100644 --- a/source/libs/index/src/index_cache.c +++ b/source/libs/index/src/index_cache.c @@ -119,13 +119,17 @@ void indexCacheDestroySkiplist(SSkipList* slt) { tSkipListDestroy(slt); } void indexCacheDestroyImm(IndexCache* cache) { - if (cache == NULL) { return; } + if (cache == NULL) { + return; + } MemTable* tbl = NULL; pthread_mutex_lock(&cache->mtx); + tbl = cache->imm; cache->imm = NULL; // or throw int bg thread pthread_cond_broadcast(&cache->finished); + pthread_mutex_unlock(&cache->mtx); indexMemUnRef(tbl); @@ -133,7 +137,9 @@ void indexCacheDestroyImm(IndexCache* cache) { } void indexCacheDestroy(void* cache) { IndexCache* pCache = cache; - if (pCache == NULL) { return; } + if (pCache == NULL) { + return; + } indexMemUnRef(pCache->mem); indexMemUnRef(pCache->imm); free(pCache->colName); @@ -146,7 +152,9 @@ void indexCacheDestroy(void* cache) { Iterate* indexCacheIteratorCreate(IndexCache* cache) { Iterate* iiter = calloc(1, sizeof(Iterate)); - if (iiter == NULL) { return NULL; } + if (iiter == NULL) { + return NULL; + } pthread_mutex_lock(&cache->mtx); @@ -164,7 +172,9 @@ Iterate* indexCacheIteratorCreate(IndexCache* cache) { return iiter; } void indexCacheIteratorDestroy(Iterate* iter) { - if (iter == NULL) { return; } + if (iter == NULL) { + return; + } tSkipListDestroyIter(iter->iter); iterateValueDestroy(&iter->val, true); free(iter); @@ -186,9 +196,6 @@ static void indexCacheMakeRoomForWrite(IndexCache* cache) { } else if (cache->imm != NULL) { // TODO: wake up by condition variable pthread_cond_wait(&cache->finished, &cache->mtx); - // pthread_mutex_unlock(&cache->mtx); - // taosMsleep(50); - // pthread_mutex_lock(&cache->mtx); } else { indexCacheRef(cache); cache->imm = cache->mem; @@ -202,13 +209,17 @@ static void indexCacheMakeRoomForWrite(IndexCache* cache) { } int indexCachePut(void* cache, SIndexTerm* term, uint64_t uid) { - if (cache == NULL) { return -1; } + if (cache == NULL) { + return -1; + } IndexCache* pCache = cache; indexCacheRef(pCache); // encode data CacheTerm* ct = calloc(1, sizeof(CacheTerm)); - if (cache == NULL) { return -1; } + if (cache == NULL) { + return -1; + } // set up key ct->colType = term->colType; ct->colVal = (char*)calloc(1, sizeof(char) * (term->nColVal + 1)); @@ -240,7 +251,9 @@ int indexCacheDel(void* cache, const char* fieldValue, int32_t fvlen, uint64_t u } static int indexQueryMem(MemTable* mem, CacheTerm* ct, EIndexQueryType qtype, SArray* result, STermValueType* s) { - if (mem == NULL) { return 0; } + if (mem == NULL) { + return 0; + } char* key = indexCacheTermGet(ct); SSkipListIterator* iter = tSkipListCreateIterFromVal(mem->mem, key, TSDB_DATA_TYPE_BINARY, TSDB_ORDER_ASC); @@ -266,7 +279,9 @@ static int indexQueryMem(MemTable* mem, CacheTerm* ct, EIndexQueryType qtype, SA return 0; } int indexCacheSearch(void* cache, SIndexTermQuery* query, SArray* result, STermValueType* s) { - if (cache == NULL) { return 0; } + if (cache == NULL) { + return 0; + } IndexCache* pCache = cache; MemTable *mem = NULL, *imm = NULL; @@ -294,23 +309,33 @@ int indexCacheSearch(void* cache, SIndexTermQuery* query, SArray* result, STermV } void indexCacheRef(IndexCache* cache) { - if (cache == NULL) { return; } + if (cache == NULL) { + return; + } int ref = T_REF_INC(cache); UNUSED(ref); } void indexCacheUnRef(IndexCache* cache) { - if (cache == NULL) { return; } + if (cache == NULL) { + return; + } int ref = T_REF_DEC(cache); - if (ref == 0) { indexCacheDestroy(cache); } + if (ref == 0) { + indexCacheDestroy(cache); + } } void indexMemRef(MemTable* tbl) { - if (tbl == NULL) { return; } + if (tbl == NULL) { + return; + } int ref = T_REF_INC(tbl); UNUSED(ref); } void indexMemUnRef(MemTable* tbl) { - if (tbl == NULL) { return; } + if (tbl == NULL) { + return; + } int ref = T_REF_DEC(tbl); if (ref == 0) { SSkipList* slt = tbl->mem; @@ -320,7 +345,9 @@ void indexMemUnRef(MemTable* tbl) { } static void indexCacheTermDestroy(CacheTerm* ct) { - if (ct == NULL) { return; } + if (ct == NULL) { + return; + } free(ct->colVal); free(ct); } @@ -333,7 +360,9 @@ static int32_t indexCacheTermCompare(const void* l, const void* r) { CacheTerm* rt = (CacheTerm*)r; // compare colVal int32_t cmp = strcmp(lt->colVal, rt->colVal); - if (cmp == 0) { return rt->version - lt->version; } + if (cmp == 0) { + return rt->version - lt->version; + } return cmp; } @@ -354,7 +383,9 @@ static void doMergeWork(SSchedMsg* msg) { } static bool indexCacheIteratorNext(Iterate* itera) { SSkipListIterator* iter = itera->iter; - if (iter == NULL) { return false; } + if (iter == NULL) { + return false; + } IterateValue* iv = &itera->val; iterateValueDestroy(iv, false); diff --git a/source/libs/index/src/index_fst.c b/source/libs/index/src/index_fst.c index 46b4c9d7c6..3664bcfad0 100644 --- a/source/libs/index/src/index_fst.c +++ b/source/libs/index/src/index_fst.c @@ -31,20 +31,24 @@ static uint8_t fstPackDetla(FstCountingWriter* wrt, CompiledAddr nodeAddr, Compi FstUnFinishedNodes* fstUnFinishedNodesCreate() { FstUnFinishedNodes* nodes = malloc(sizeof(FstUnFinishedNodes)); - if (nodes == NULL) { return NULL; } + if (nodes == NULL) { + return NULL; + } nodes->stack = (SArray*)taosArrayInit(64, sizeof(FstBuilderNodeUnfinished)); fstUnFinishedNodesPushEmpty(nodes, false); return nodes; } -void unFinishedNodeDestroyElem(void* elem) { +static void unFinishedNodeDestroyElem(void* elem) { FstBuilderNodeUnfinished* b = (FstBuilderNodeUnfinished*)elem; fstBuilderNodeDestroy(b->node); free(b->last); b->last = NULL; } void fstUnFinishedNodesDestroy(FstUnFinishedNodes* nodes) { - if (nodes == NULL) { return; } + if (nodes == NULL) { + return; + } taosArrayDestroyEx(nodes->stack, unFinishedNodeDestroyElem); free(nodes); @@ -92,7 +96,9 @@ void fstUnFinishedNodesTopLastFreeze(FstUnFinishedNodes* nodes, CompiledAddr add } void fstUnFinishedNodesAddSuffix(FstUnFinishedNodes* nodes, FstSlice bs, Output out) { FstSlice* s = &bs; - if (fstSliceIsEmpty(s)) { return; } + if (fstSliceIsEmpty(s)) { + return; + } size_t sz = taosArrayGetSize(nodes->stack) - 1; FstBuilderNodeUnfinished* un = taosArrayGet(nodes->stack, sz); assert(un->last == NULL); @@ -172,7 +178,9 @@ uint64_t fstUnFinishedNodesFindCommPrefixAndSetOutput(FstUnFinishedNodes* node, FstState fstStateCreateFrom(FstSlice* slice, CompiledAddr addr) { FstState fs = {.state = EmptyFinal, .val = 0}; - if (addr == EMPTY_ADDRESS) { return fs; } + if (addr == EMPTY_ADDRESS) { + return fs; + } uint8_t* data = fstSliceData(slice, NULL); uint8_t v = data[addr]; @@ -229,7 +237,9 @@ void fstStateCompileForOneTrans(FstCountingWriter* w, CompiledAddr addr, FstTran fstStateSetCommInput(&st, trn->inp); bool null = false; uint8_t inp = fstStateCommInput(&st, &null); - if (null == true) { fstCountingWriterWrite(w, (char*)&trn->inp, sizeof(trn->inp)); } + if (null == true) { + fstCountingWriterWrite(w, (char*)&trn->inp, sizeof(trn->inp)); + } fstCountingWriterWrite(w, (char*)(&(st.val)), sizeof(st.val)); return; } @@ -263,7 +273,9 @@ void fstStateCompileForAnyTrans(FstCountingWriter* w, CompiledAddr addr, FstBuil fstStateSetStateNtrans(&st, (uint8_t)sz); if (anyOuts) { - if (FST_BUILDER_NODE_IS_FINAL(node)) { fstCountingWriterPackUintIn(w, node->finalOutput, oSize); } + if (FST_BUILDER_NODE_IS_FINAL(node)) { + fstCountingWriterPackUintIn(w, node->finalOutput, oSize); + } for (int32_t i = sz - 1; i >= 0; i--) { FstTransition* t = taosArrayGet(node->trans, i); fstCountingWriterPackUintIn(w, t->out, oSize); @@ -428,7 +440,9 @@ Output fstStateOutput(FstState* s, FstNode* node) { assert(s->state == OneTrans); uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(node->sizes); - if (oSizes == 0) { return 0; } + if (oSizes == 0) { + return 0; + } FstSlice* slice = &node->data; uint8_t tSizes = FST_GET_TRANSITION_PACK_SIZE(node->sizes); @@ -440,7 +454,9 @@ Output fstStateOutputForAnyTrans(FstState* s, FstNode* node, uint64_t i) { assert(s->state == AnyTrans); uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(node->sizes); - if (oSizes == 0) { return 0; } + if (oSizes == 0) { + return 0; + } FstSlice* slice = &node->data; uint8_t* data = fstSliceData(slice, NULL); uint64_t at = node->start - fstStateNtransLen(s) - 1 // pack size @@ -453,7 +469,9 @@ Output fstStateOutputForAnyTrans(FstState* s, FstNode* node, uint64_t i) { void fstStateSetFinalState(FstState* s, bool yes) { assert(s->state == AnyTrans); - if (yes) { s->val |= 0b01000000; } + if (yes) { + s->val |= 0b01000000; + } return; } bool fstStateIsFinalState(FstState* s) { @@ -463,7 +481,9 @@ bool fstStateIsFinalState(FstState* s) { void fstStateSetStateNtrans(FstState* s, uint8_t n) { assert(s->state == AnyTrans); - if (n <= 0b00111111) { s->val = (s->val & 0b11000000) | n; } + if (n <= 0b00111111) { + s->val = (s->val & 0b11000000) | n; + } return; } // state_ntrans @@ -495,7 +515,9 @@ uint64_t fstStateNtransLen(FstState* s) { uint64_t fstStateNtrans(FstState* s, FstSlice* slice) { bool null = false; uint8_t n = fstStateStateNtrans(s, &null); - if (null != true) { return n; } + if (null != true) { + return n; + } int32_t len; uint8_t* data = fstSliceData(slice, &len); n = data[len - 2]; @@ -505,7 +527,9 @@ uint64_t fstStateNtrans(FstState* s, FstSlice* slice) { } Output fstStateFinalOutput(FstState* s, uint64_t version, FstSlice* slice, PackSizes sizes, uint64_t nTrans) { uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(sizes); - if (oSizes == 0 || !fstStateIsFinalState(s)) { return 0; } + if (oSizes == 0 || !fstStateIsFinalState(s)) { + return 0; + } uint64_t at = FST_SLICE_LEN(slice) - 1 - fstStateNtransLen(s) - 1 // pack size - fstStateTotalTransSize(s, version, sizes, nTrans) - (nTrans * oSizes) - oSizes; @@ -522,7 +546,9 @@ uint64_t fstStateFindInput(FstState* s, FstNode* node, uint8_t b, bool* null) { uint8_t* data = fstSliceData(slice, &dlen); uint64_t i = data[at + b]; // uint64_t i = slice->data[slice->start + at + b]; - if (i >= node->nTrans) { *null = true; } + if (i >= node->nTrans) { + *null = true; + } return i; } else { uint64_t start = node->start - fstStateNtransLen(s) - 1 // pack size @@ -539,7 +565,9 @@ uint64_t fstStateFindInput(FstState* s, FstNode* node, uint8_t b, bool* null) { return node->nTrans - i - 1; // bug } } - if (i == len) { *null = true; } + if (i == len) { + *null = true; + } fstSliceDestroy(&t); } } @@ -548,7 +576,9 @@ uint64_t fstStateFindInput(FstState* s, FstNode* node, uint8_t b, bool* null) { FstNode* fstNodeCreate(int64_t version, CompiledAddr addr, FstSlice* slice) { FstNode* n = (FstNode*)malloc(sizeof(FstNode)); - if (n == NULL) { return NULL; } + if (n == NULL) { + return NULL; + } FstState st = fstStateCreateFrom(slice, addr); @@ -614,7 +644,9 @@ void fstNodeDestroy(FstNode* node) { } FstTransitions* fstNodeTransitions(FstNode* node) { FstTransitions* t = malloc(sizeof(FstTransitions)); - if (NULL == t) { return NULL; } + if (NULL == t) { + return NULL; + } FstRange range = {.start = 0, .end = FST_NODE_LEN(node)}; t->range = range; t->node = node; @@ -721,7 +753,9 @@ bool fstBuilderNodeCompileTo(FstBuilderNode* b, FstCountingWriter* wrt, Compiled FstBuilder* fstBuilderCreate(void* w, FstType ty) { FstBuilder* b = malloc(sizeof(FstBuilder)); - if (NULL == b) { return b; } + if (NULL == b) { + return b; + } b->wrt = fstCountingWriterCreate(w); b->unfinished = fstUnFinishedNodesCreate(); @@ -735,15 +769,17 @@ FstBuilder* fstBuilderCreate(void* w, FstType ty) { taosEncodeFixedU64(&pBuf64, VERSION); fstCountingWriterWrite(b->wrt, buf64, sizeof(buf64)); - memset(buf64, 0, sizeof(buf64)); pBuf64 = buf64; + memset(buf64, 0, sizeof(buf64)); taosEncodeFixedU64(&pBuf64, ty); fstCountingWriterWrite(b->wrt, buf64, sizeof(buf64)); return b; } void fstBuilderDestroy(FstBuilder* b) { - if (b == NULL) { return; } + if (b == NULL) { + return; + } fstCountingWriterDestroy(b->wrt); fstUnFinishedNodesDestroy(b->unfinished); @@ -830,6 +866,7 @@ void fstBuilderCompileFrom(FstBuilder* b, uint64_t istate) { fstUnFinishedNodesTopLastFreeze(b->unfinished, addr); return; } + CompiledAddr fstBuilderCompile(FstBuilder* b, FstBuilderNode* bn) { if (FST_BUILDER_NODE_IS_FINAL(bn) && FST_BUILDER_NODE_TRANS_ISEMPTY(bn) && FST_BUILDER_NODE_FINALOUTPUT_ISZERO(bn)) { return EMPTY_ADDRESS; @@ -844,7 +881,9 @@ CompiledAddr fstBuilderCompile(FstBuilder* b, FstBuilderNode* bn) { fstBuilderNodeCompileTo(bn, b->wrt, b->lastAddr, startAddr); b->lastAddr = (CompiledAddr)(FST_WRITER_COUNT(b->wrt) - 1); - if (entry->state == NOTFOUND) { FST_REGISTRY_CELL_INSERT(entry->cell, b->lastAddr); } + if (entry->state == NOTFOUND) { + FST_REGISTRY_CELL_INSERT(entry->cell, b->lastAddr); + } fstRegistryEntryDestroy(entry); return b->lastAddr; @@ -887,7 +926,9 @@ FstSlice fstNodeAsSlice(FstNode* node) { FstLastTransition* fstLastTransitionCreate(uint8_t inp, Output out) { FstLastTransition* trn = malloc(sizeof(FstLastTransition)); - if (trn == NULL) { return NULL; } + if (trn == NULL) { + return NULL; + } trn->inp = inp; trn->out = out; @@ -897,7 +938,9 @@ FstLastTransition* fstLastTransitionCreate(uint8_t inp, Output out) { void fstLastTransitionDestroy(FstLastTransition* trn) { free(trn); } void fstBuilderNodeUnfinishedLastCompiled(FstBuilderNodeUnfinished* unNode, CompiledAddr addr) { FstLastTransition* trn = unNode->last; - if (trn == NULL) { return; } + if (trn == NULL) { + return; + } FstTransition t = {.inp = trn->inp, .out = trn->out, .addr = addr}; taosArrayPush(unNode->node->trans, &t); fstLastTransitionDestroy(trn); @@ -906,27 +949,35 @@ void fstBuilderNodeUnfinishedLastCompiled(FstBuilderNodeUnfinished* unNode, Comp } void fstBuilderNodeUnfinishedAddOutputPrefix(FstBuilderNodeUnfinished* unNode, Output out) { - if (FST_BUILDER_NODE_IS_FINAL(unNode->node)) { unNode->node->finalOutput += out; } + if (FST_BUILDER_NODE_IS_FINAL(unNode->node)) { + unNode->node->finalOutput += out; + } size_t sz = taosArrayGetSize(unNode->node->trans); for (size_t i = 0; i < sz; i++) { FstTransition* trn = taosArrayGet(unNode->node->trans, i); trn->out += out; } - if (unNode->last) { unNode->last->out += out; } + if (unNode->last) { + unNode->last->out += out; + } return; } Fst* fstCreate(FstSlice* slice) { int32_t slen; char* buf = fstSliceData(slice, &slen); - if (slen < 36) { return NULL; } + if (slen < 36) { + return NULL; + } uint64_t len = slen; uint64_t skip = 0; uint64_t version; taosDecodeFixedU64(buf, &version); skip += sizeof(version); - if (version == 0 || version > VERSION) { return NULL; } + if (version == 0 || version > VERSION) { + return NULL; + } uint64_t type; taosDecodeFixedU64(buf + skip, &type); @@ -949,10 +1000,14 @@ Fst* fstCreate(FstSlice* slice) { taosDecodeFixedU64(buf + len, &fstLen); // TODO(validate root addr) Fst* fst = (Fst*)calloc(1, sizeof(Fst)); - if (fst == NULL) { return NULL; } + if (fst == NULL) { + return NULL; + } fst->meta = (FstMeta*)malloc(sizeof(FstMeta)); - if (NULL == fst->meta) { goto FST_CREAT_FAILED; } + if (NULL == fst->meta) { + goto FST_CREAT_FAILED; + } fst->meta->version = version; fst->meta->rootAddr = rootAddr; @@ -983,7 +1038,7 @@ void fstDestroy(Fst* fst) { bool fstGet(Fst* fst, FstSlice* b, Output* out) { // dec lock range - pthread_mutex_lock(&fst->mtx); + // pthread_mutex_lock(&fst->mtx); FstNode* root = fstGetRoot(fst); Output tOut = 0; int32_t len; @@ -996,7 +1051,7 @@ bool fstGet(Fst* fst, FstSlice* b, Output* out) { uint8_t inp = data[i]; Output res = 0; if (false == fstNodeFindInput(root, inp, &res)) { - pthread_mutex_unlock(&fst->mtx); + // pthread_mutex_unlock(&fst->mtx); return false; } @@ -1007,7 +1062,7 @@ bool fstGet(Fst* fst, FstSlice* b, Output* out) { taosArrayPush(nodes, &root); } if (!FST_NODE_IS_FINAL(root)) { - pthread_mutex_unlock(&fst->mtx); + // pthread_mutex_unlock(&fst->mtx); return false; } else { tOut = tOut + FST_NODE_FINAL_OUTPUT(root); @@ -1018,8 +1073,8 @@ bool fstGet(Fst* fst, FstSlice* b, Output* out) { fstNodeDestroy(*node); } taosArrayDestroy(nodes); - fst->root = NULL; - pthread_mutex_unlock(&fst->mtx); + // fst->root = NULL; + // pthread_mutex_unlock(&fst->mtx); *out = tOut; return true; } @@ -1028,7 +1083,9 @@ FstStreamBuilder* fstSearch(Fst* fst, AutomationCtx* ctx) { return fstStreamBuilderCreate(fst, ctx); } StreamWithState* streamBuilderIntoStream(FstStreamBuilder* sb) { - if (sb == NULL) { return NULL; } + if (sb == NULL) { + return NULL; + } return streamWithStateCreate(sb->fst, sb->aut, sb->min, sb->max); } FstStreamWithStateBuilder* fstSearchWithState(Fst* fst, AutomationCtx* ctx) { @@ -1039,15 +1096,6 @@ FstStreamWithStateBuilder* fstSearchWithState(Fst* fst, AutomationCtx* ctx) { FstNode* fstGetRoot(Fst* fst) { CompiledAddr rAddr = fstGetRootAddr(fst); return fstGetNode(fst, rAddr); - // pthread_mutex_lock(&fst->mtx); - // if (fst->root != NULL) { - // // pthread_mutex_unlock(&fst->mtx); - // return fst->root; - //} - // CompiledAddr rAddr = fstGetRootAddr(fst); - // fst->root = fstGetNode(fst, rAddr); - //// pthread_mutex_unlock(&fst->mtx); - // return fst->root; } FstNode* fstGetNode(Fst* fst, CompiledAddr addr) { @@ -1074,14 +1122,18 @@ bool fstVerify(Fst* fst) { uint32_t len, checkSum = fst->meta->checkSum; uint8_t* data = fstSliceData(fst->data, &len); TSCKSUM initSum = 0; - if (!taosCheckChecksumWhole(data, len)) { return false; } + if (!taosCheckChecksumWhole(data, len)) { + return false; + } return true; } // data bound function FstBoundWithData* fstBoundStateCreate(FstBound type, FstSlice* data) { FstBoundWithData* b = calloc(1, sizeof(FstBoundWithData)); - if (b == NULL) { return NULL; } + if (b == NULL) { + return NULL; + } if (data != NULL) { b->data = fstSliceCopy(data, data->start, data->end); @@ -1118,7 +1170,9 @@ void fstBoundDestroy(FstBoundWithData* bound) { free(bound); } StreamWithState* streamWithStateCreate(Fst* fst, AutomationCtx* automation, FstBoundWithData* min, FstBoundWithData* max) { StreamWithState* sws = calloc(1, sizeof(StreamWithState)); - if (sws == NULL) { return NULL; } + if (sws == NULL) { + return NULL; + } sws->fst = fst; sws->aut = automation; @@ -1134,7 +1188,9 @@ StreamWithState* streamWithStateCreate(Fst* fst, AutomationCtx* automation, FstB return sws; } void streamWithStateDestroy(StreamWithState* sws) { - if (sws == NULL) { return; } + if (sws == NULL) { + return; + } taosArrayDestroy(sws->inp); taosArrayDestroyEx(sws->stack, streamStateDestroy); @@ -1200,7 +1256,9 @@ bool streamWithStateSeekMin(StreamWithState* sws, FstBoundWithData* min) { uint64_t i = 0; for (i = trans->range.start; i < trans->range.end; i++) { FstTransition trn; - if (fstNodeGetTransitionAt(node, i, &trn) && trn.inp > b) { break; } + if (fstNodeGetTransitionAt(node, i, &trn) && trn.inp > b) { + break; + } } StreamState s = {.node = node, .trans = i, .out = {.null = false, .out = out}, .autState = autState}; @@ -1248,7 +1306,9 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb while (taosArrayGetSize(sws->stack) > 0) { StreamState* p = (StreamState*)taosArrayPop(sws->stack); if (p->trans >= FST_NODE_LEN(p->node) || !automFuncs[aut->type].canMatch(aut, p->autState)) { - if (FST_NODE_ADDR(p->node) != fstGetRootAddr(sws->fst)) { taosArrayPop(sws->inp); } + if (FST_NODE_ADDR(p->node) != fstGetRootAddr(sws->fst)) { + taosArrayPop(sws->inp); + } streamStateDestroy(p); continue; } @@ -1267,7 +1327,9 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb if (FST_NODE_IS_FINAL(nextNode)) { // void *eofState = sws->aut->acceptEof(nextState); void* eofState = automFuncs[aut->type].acceptEof(aut, nextState); - if (eofState != NULL) { isMatch = automFuncs[aut->type].isMatch(aut, eofState); } + if (eofState != NULL) { + isMatch = automFuncs[aut->type].isMatch(aut, eofState); + } } StreamState s1 = {.node = p->node, .trans = p->trans + 1, .out = p->out, .autState = p->autState}; taosArrayPush(sws->stack, &s1); @@ -1277,24 +1339,26 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb size_t isz = taosArrayGetSize(sws->inp); uint8_t* buf = (uint8_t*)malloc(isz * sizeof(uint8_t)); - for (uint32_t i = 0; i < isz; i++) { buf[i] = *(uint8_t*)taosArrayGet(sws->inp, i); } + for (uint32_t i = 0; i < isz; i++) { + buf[i] = *(uint8_t*)taosArrayGet(sws->inp, i); + } FstSlice slice = fstSliceCreate(buf, taosArrayGetSize(sws->inp)); if (fstBoundWithDataExceededBy(sws->endAt, &slice)) { taosArrayDestroyEx(sws->stack, streamStateDestroy); sws->stack = (SArray*)taosArrayInit(256, sizeof(StreamState)); - free(buf); + tfree(buf); fstSliceDestroy(&slice); return NULL; } if (FST_NODE_IS_FINAL(nextNode) && isMatch) { FstOutput fOutput = {.null = false, .out = out + FST_NODE_FINAL_OUTPUT(nextNode)}; StreamWithStateResult* result = swsResultCreate(&slice, fOutput, tState); - free(buf); + tfree(buf); fstSliceDestroy(&slice); taosArrayDestroy(nodes); return result; } - free(buf); + tfree(buf); fstSliceDestroy(&slice); } for (size_t i = 0; i < taosArrayGetSize(nodes); i++) { @@ -1307,16 +1371,19 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb StreamWithStateResult* swsResultCreate(FstSlice* data, FstOutput fOut, void* state) { StreamWithStateResult* result = calloc(1, sizeof(StreamWithStateResult)); - if (result == NULL) { return NULL; } + if (result == NULL) { + return NULL; + } result->data = fstSliceCopy(data, 0, FST_SLICE_LEN(data) - 1); result->out = fOut; result->state = state; - return result; } void swsResultDestroy(StreamWithStateResult* result) { - if (NULL == result) { return; } + if (NULL == result) { + return; + } fstSliceDestroy(&result->data); startWithStateValueDestroy(result->state); @@ -1324,16 +1391,18 @@ void swsResultDestroy(StreamWithStateResult* result) { } void streamStateDestroy(void* s) { - if (NULL == s) { return; } + if (NULL == s) { + return; + } StreamState* ss = (StreamState*)s; - fstNodeDestroy(ss->node); - // free(s->autoState); } FstStreamBuilder* fstStreamBuilderCreate(Fst* fst, AutomationCtx* aut) { FstStreamBuilder* b = calloc(1, sizeof(FstStreamBuilder)); - if (NULL == b) { return NULL; } + if (NULL == b) { + return NULL; + } b->fst = fst; b->aut = aut; @@ -1349,8 +1418,9 @@ void fstStreamBuilderDestroy(FstStreamBuilder* b) { free(b); } FstStreamBuilder* fstStreamBuilderRange(FstStreamBuilder* b, FstSlice* val, RangeType type) { - if (b == NULL) { return NULL; } - + if (b == NULL) { + return NULL; + } if (type == GE) { b->min->type = Included; fstSliceDestroy(&(b->min->data)); diff --git a/source/libs/index/src/index_fst_automation.c b/source/libs/index/src/index_fst_automation.c index c6e3cee3e3..590ff294bf 100644 --- a/source/libs/index/src/index_fst_automation.c +++ b/source/libs/index/src/index_fst_automation.c @@ -17,7 +17,9 @@ StartWithStateValue* startWithStateValueCreate(StartWithStateKind kind, ValueType ty, void* val) { StartWithStateValue* nsv = calloc(1, sizeof(StartWithStateValue)); - if (nsv == NULL) { return NULL; } + if (nsv == NULL) { + return NULL; + } nsv->kind = kind; nsv->type = ty; @@ -35,7 +37,9 @@ StartWithStateValue* startWithStateValueCreate(StartWithStateKind kind, ValueTyp } void startWithStateValueDestroy(void* val) { StartWithStateValue* sv = (StartWithStateValue*)val; - if (sv == NULL) { return; } + if (sv == NULL) { + return; + } if (sv->type == FST_INT) { // @@ -48,7 +52,9 @@ void startWithStateValueDestroy(void* val) { } StartWithStateValue* startWithStateValueDump(StartWithStateValue* sv) { StartWithStateValue* nsv = calloc(1, sizeof(StartWithStateValue)); - if (nsv == NULL) { return NULL; } + if (nsv == NULL) { + return NULL; + } nsv->kind = sv->kind; nsv->type = sv->type; @@ -88,10 +94,14 @@ static bool prefixCanMatch(AutomationCtx* ctx, void* sv) { static bool prefixWillAlwaysMatch(AutomationCtx* ctx, void* state) { return true; } static void* prefixAccept(AutomationCtx* ctx, void* state, uint8_t byte) { StartWithStateValue* ssv = (StartWithStateValue*)state; - if (ssv == NULL || ctx == NULL) { return NULL; } + if (ssv == NULL || ctx == NULL) { + return NULL; + } char* data = ctx->data; - if (ssv->kind == Done) { return startWithStateValueCreate(Done, FST_INT, &ssv->val); } + if (ssv->kind == Done) { + return startWithStateValueCreate(Done, FST_INT, &ssv->val); + } if ((strlen(data) > ssv->val) && data[ssv->val] == byte) { int val = ssv->val + 1; @@ -128,7 +138,9 @@ AutomationFunc automFuncs[] = { AutomationCtx* automCtxCreate(void* data, AutomationType atype) { AutomationCtx* ctx = calloc(1, sizeof(AutomationCtx)); - if (ctx == NULL) { return NULL; } + if (ctx == NULL) { + return NULL; + } StartWithStateValue* sv = NULL; if (atype == AUTOMATION_ALWAYS) { diff --git a/source/libs/index/src/index_fst_util.c b/source/libs/index/src/index_fst_util.c index da1e177a18..f08a48c34e 100644 --- a/source/libs/index/src/index_fst_util.c +++ b/source/libs/index/src/index_fst_util.c @@ -29,18 +29,6 @@ const uint64_t VERSION = 3; const uint64_t TRANS_INDEX_THRESHOLD = 32; -// uint8_t commonInput(uint8_t idx) { -// if (idx == 0) { return -1; } -// else { -// return COMMON_INPUTS_INV[idx - 1]; -// } -//} -// -// uint8_t commonIdx(uint8_t v, uint8_t max) { -// uint8_t v = ((uint16_t)tCOMMON_INPUTS[v] + 1)%256; -// return v > max ? 0: v; -//} - uint8_t packSize(uint64_t n) { if (n < (1u << 8)) { return 1; @@ -103,9 +91,6 @@ FstSlice fstSliceCreate(uint8_t* data, uint64_t len) { FstSlice fstSliceCopy(FstSlice* s, int32_t start, int32_t end) { FstString* str = s->str; str->ref++; - // uint8_t *buf = fstSliceData(s, &alen); - // start = buf + start - (buf - s->start); - // end = buf + end - (buf - s->start); FstSlice t = {.str = str, .start = start + s->start, .end = end + s->start}; return t; @@ -130,19 +115,19 @@ FstSlice fstSliceDeepCopy(FstSlice* s, int32_t start, int32_t end) { ans.end = tlen - 1; return ans; } -bool fstSliceIsEmpty(FstSlice* s) { - return s->str == NULL || s->str->len == 0 || s->start < 0 || s->end < 0; -} +bool fstSliceIsEmpty(FstSlice* s) { return s->str == NULL || s->str->len == 0 || s->start < 0 || s->end < 0; } uint8_t* fstSliceData(FstSlice* s, int32_t* size) { FstString* str = s->str; - if (size != NULL) { *size = s->end - s->start + 1; } + if (size != NULL) { + *size = s->end - s->start + 1; + } return str->data + s->start; } void fstSliceDestroy(FstSlice* s) { FstString* str = s->str; str->ref--; - if (str->ref <= 0) { + if (str->ref == 0) { free(str->data); free(str); s->str = NULL; diff --git a/source/libs/index/src/index_tfile.c b/source/libs/index/src/index_tfile.c index 98fede4f7b..87cc48146b 100644 --- a/source/libs/index/src/index_tfile.c +++ b/source/libs/index/src/index_tfile.c @@ -13,8 +13,6 @@ p * * along with this program. If not, see . */ -//#include -//#include #include "index_tfile.h" #include "index.h" #include "index_fst.h" @@ -61,7 +59,9 @@ static void tfileGenFileFullName(char* fullname, const char* path, uint64_t s TFileCache* tfileCacheCreate(const char* path) { TFileCache* tcache = calloc(1, sizeof(TFileCache)); - if (tcache == NULL) { return NULL; } + if (tcache == NULL) { + return NULL; + } tcache->tableCache = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); tcache->capacity = 64; @@ -98,7 +98,9 @@ End: return NULL; } void tfileCacheDestroy(TFileCache* tcache) { - if (tcache == NULL) { return; } + if (tcache == NULL) { + return; + } // free table cache TFileReader** reader = taosHashIterate(tcache->tableCache, NULL); @@ -119,7 +121,9 @@ TFileReader* tfileCacheGet(TFileCache* tcache, ICacheKey* key) { int32_t sz = indexSerialCacheKey(key, buf); assert(sz < sizeof(buf)); TFileReader** reader = taosHashGet(tcache->tableCache, buf, sz); - if (reader == NULL) { return NULL; } + if (reader == NULL) { + return NULL; + } tfileReaderRef(*reader); return *reader; @@ -142,7 +146,9 @@ void tfileCachePut(TFileCache* tcache, ICacheKey* key, TFileReader* reader) { } TFileReader* tfileReaderCreate(WriterCtx* ctx) { TFileReader* reader = calloc(1, sizeof(TFileReader)); - if (reader == NULL) { return NULL; } + if (reader == NULL) { + return NULL; + } reader->ctx = ctx; @@ -169,7 +175,9 @@ TFileReader* tfileReaderCreate(WriterCtx* ctx) { return reader; } void tfileReaderDestroy(TFileReader* reader) { - if (reader == NULL) { return; } + if (reader == NULL) { + return; + } // T_REF_INC(reader); fstDestroy(reader->fst); writerCtxDestroy(reader->ctx, reader->remove); @@ -209,7 +217,9 @@ TFileWriter* tfileWriterOpen(char* path, uint64_t suid, int32_t version, const c tfileGenFileFullName(fullname, path, suid, colName, version); // indexInfo("open write file name %s", fullname); WriterCtx* wcx = writerCtxCreate(TFile, fullname, false, 1024 * 1024 * 64); - if (wcx == NULL) { return NULL; } + if (wcx == NULL) { + return NULL; + } TFileHeader tfh = {0}; tfh.suid = suid; @@ -225,7 +235,9 @@ TFileReader* tfileReaderOpen(char* path, uint64_t suid, int32_t version, const c WriterCtx* wc = writerCtxCreate(TFile, fullname, true, 1024 * 1024 * 1024); indexInfo("open read file name:%s, size: %d", wc->file.buf, wc->file.size); - if (wc == NULL) { return NULL; } + if (wc == NULL) { + return NULL; + } TFileReader* reader = tfileReaderCreate(wc); return reader; @@ -316,19 +328,25 @@ int tfileWriterPut(TFileWriter* tw, void* data, bool order) { return 0; } void tfileWriterClose(TFileWriter* tw) { - if (tw == NULL) { return; } + if (tw == NULL) { + return; + } writerCtxDestroy(tw->ctx, false); free(tw); } void tfileWriterDestroy(TFileWriter* tw) { - if (tw == NULL) { return; } + if (tw == NULL) { + return; + } writerCtxDestroy(tw->ctx, false); free(tw); } IndexTFile* indexTFileCreate(const char* path) { TFileCache* cache = tfileCacheCreate(path); - if (cache == NULL) { return NULL; } + if (cache == NULL) { + return NULL; + } IndexTFile* tfile = calloc(1, sizeof(IndexTFile)); if (tfile == NULL) { @@ -340,21 +358,27 @@ IndexTFile* indexTFileCreate(const char* path) { return tfile; } void indexTFileDestroy(IndexTFile* tfile) { - if (tfile == NULL) { return; } + if (tfile == NULL) { + return; + } tfileCacheDestroy(tfile->cache); free(tfile); } int indexTFileSearch(void* tfile, SIndexTermQuery* query, SArray* result) { int ret = -1; - if (tfile == NULL) { return ret; } + if (tfile == NULL) { + return ret; + } IndexTFile* pTfile = (IndexTFile*)tfile; SIndexTerm* term = query->term; ICacheKey key = {.suid = term->suid, .colType = term->colType, .colName = term->colName, .nColName = term->nColName}; TFileReader* reader = tfileCacheGet(pTfile->cache, &key); - if (reader == NULL) { return 0; } + if (reader == NULL) { + return 0; + } return tfileReaderSearch(reader, query, result); } @@ -373,7 +397,9 @@ static bool tfileIteratorNext(Iterate* iiter) { TFileFstIter* tIter = iiter->iter; StreamWithStateResult* rt = streamWithStateNextWith(tIter->st, NULL); - if (rt == NULL) { return false; } + if (rt == NULL) { + return false; + } int32_t sz = 0; char* ch = (char*)fstSliceData(&rt->data, &sz); @@ -383,7 +409,9 @@ static bool tfileIteratorNext(Iterate* iiter) { offset = (uint64_t)(rt->out.out); swsResultDestroy(rt); // set up iterate value - if (tfileReaderLoadTableIds(tIter->rdr, offset, iv->val) != 0) { return false; } + if (tfileReaderLoadTableIds(tIter->rdr, offset, iv->val) != 0) { + return false; + } iv->colVal = colVal; return true; @@ -394,7 +422,9 @@ static IterateValue* tifileIterateGetValue(Iterate* iter) { return &iter->val; } static TFileFstIter* tfileFstIteratorCreate(TFileReader* reader) { TFileFstIter* tIter = calloc(1, sizeof(TFileFstIter)); - if (tIter == NULL) { return NULL; } + if (tIter == NULL) { + return NULL; + } tIter->ctx = automCtxCreate(NULL, AUTOMATION_ALWAYS); tIter->fb = fstSearch(reader->fst, tIter->ctx); @@ -404,7 +434,9 @@ static TFileFstIter* tfileFstIteratorCreate(TFileReader* reader) { } Iterate* tfileIteratorCreate(TFileReader* reader) { - if (reader == NULL) { return NULL; } + if (reader == NULL) { + return NULL; + } Iterate* iter = calloc(1, sizeof(Iterate)); iter->iter = tfileFstIteratorCreate(reader); @@ -419,7 +451,9 @@ Iterate* tfileIteratorCreate(TFileReader* reader) { return iter; } void tfileIteratorDestroy(Iterate* iter) { - if (iter == NULL) { return; } + if (iter == NULL) { + return; + } IterateValue* iv = &iter->val; iterateValueDestroy(iv, true); @@ -434,7 +468,9 @@ void tfileIteratorDestroy(Iterate* iter) { } TFileReader* tfileGetReaderByCol(IndexTFile* tf, uint64_t suid, char* colName) { - if (tf == NULL) { return NULL; } + if (tf == NULL) { + return NULL; + } ICacheKey key = {.suid = suid, .colType = TSDB_DATA_TYPE_BINARY, .colName = colName, .nColName = strlen(colName)}; return tfileCacheGet(tf->cache, &key); } @@ -446,7 +482,9 @@ static int tfileUidCompare(const void* a, const void* b) { } static int tfileStrCompare(const void* a, const void* b) { int ret = strcmp((char*)a, (char*)b); - if (ret == 0) { return ret; } + if (ret == 0) { + return ret; + } return ret < 0 ? -1 : 1; } @@ -461,13 +499,17 @@ static int tfileValueCompare(const void* a, const void* b, const void* param) { TFileValue* tfileValueCreate(char* val) { TFileValue* tf = calloc(1, sizeof(TFileValue)); - if (tf == NULL) { return NULL; } + if (tf == NULL) { + return NULL; + } tf->colVal = tstrdup(val); tf->tableId = taosArrayInit(32, sizeof(uint64_t)); return tf; } int tfileValuePush(TFileValue* tf, uint64_t val) { - if (tf == NULL) { return -1; } + if (tf == NULL) { + return -1; + } taosArrayPush(tf->tableId, &val); return 0; } @@ -489,7 +531,9 @@ static int tfileWriteFstOffset(TFileWriter* tw, int32_t offset) { int32_t fstOffset = offset + sizeof(tw->header.fstOffset); tw->header.fstOffset = fstOffset; - if (sizeof(fstOffset) != tw->ctx->write(tw->ctx, (char*)&fstOffset, sizeof(fstOffset))) { return -1; } + if (sizeof(fstOffset) != tw->ctx->write(tw->ctx, (char*)&fstOffset, sizeof(fstOffset))) { + return -1; + } indexInfo("tfile write fst offset: %d", tw->ctx->size(tw->ctx)); tw->offset += sizeof(fstOffset); return 0; @@ -502,7 +546,9 @@ static int tfileWriteHeader(TFileWriter* writer) { indexInfo("tfile pre write header size: %d", writer->ctx->size(writer->ctx)); int nwrite = writer->ctx->write(writer->ctx, buf, sizeof(buf)); - if (sizeof(buf) != nwrite) { return -1; } + if (sizeof(buf) != nwrite) { + return -1; + } indexInfo("tfile after write header size: %d", writer->ctx->size(writer->ctx)); writer->offset = nwrite; @@ -556,7 +602,9 @@ static int tfileReaderLoadFst(TFileReader* reader) { static int FST_MAX_SIZE = 64 * 1024 * 1024; char* buf = calloc(1, sizeof(char) * FST_MAX_SIZE); - if (buf == NULL) { return -1; } + if (buf == NULL) { + return -1; + } WriterCtx* ctx = reader->ctx; int size = ctx->size(ctx); @@ -586,12 +634,16 @@ static int tfileReaderLoadTableIds(TFileReader* reader, int32_t offset, SArray* int32_t total = sizeof(uint64_t) * nid; char* buf = calloc(1, total); - if (buf == NULL) { return -1; } + if (buf == NULL) { + return -1; + } nread = ctx->readFrom(ctx, buf, total, offset + sizeof(nid)); assert(total == nread); - for (int32_t i = 0; i < nid; i++) { taosArrayPush(result, (uint64_t*)buf + i); } + for (int32_t i = 0; i < nid; i++) { + taosArrayPush(result, (uint64_t*)buf + i); + } free(buf); return 0; } @@ -615,13 +667,17 @@ static int tfileReaderVerify(TFileReader* reader) { } void tfileReaderRef(TFileReader* reader) { - if (reader == NULL) { return; } + if (reader == NULL) { + return; + } int ref = T_REF_INC(reader); UNUSED(ref); } void tfileReaderUnRef(TFileReader* reader) { - if (reader == NULL) { return; } + if (reader == NULL) { + return; + } int ref = T_REF_DEC(reader); if (ref == 0) { // do nothing @@ -637,11 +693,15 @@ static SArray* tfileGetFileList(const char* path) { uint32_t version; DIR* dir = opendir(path); - if (NULL == dir) { return NULL; } + if (NULL == dir) { + return NULL; + } struct dirent* entry; while ((entry = readdir(dir)) != NULL) { char* file = entry->d_name; - if (0 != tfileParseFileName(file, &suid, buf, &version)) { continue; } + if (0 != tfileParseFileName(file, &suid, buf, &version)) { + continue; + } size_t len = strlen(path) + 1 + strlen(file) + 1; char* buf = calloc(1, len); diff --git a/source/libs/index/test/CMakeLists.txt b/source/libs/index/test/CMakeLists.txt index 3957554748..665dfd7318 100644 --- a/source/libs/index/test/CMakeLists.txt +++ b/source/libs/index/test/CMakeLists.txt @@ -1,5 +1,7 @@ add_executable(indexTest "") add_executable(fstTest "") +add_executable(fstUT "") + target_sources(indexTest PRIVATE "indexTests.cc" @@ -8,6 +10,11 @@ target_sources(fstTest PRIVATE "fstTest.cc" ) + +target_sources(fstUT + PRIVATE + "fstUT.cc" +) target_include_directories ( indexTest PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/index" @@ -18,6 +25,12 @@ target_include_directories ( fstTest "${CMAKE_SOURCE_DIR}/include/libs/index" "${CMAKE_CURRENT_SOURCE_DIR}/../inc" ) + +target_include_directories ( fstUT + PUBLIC + "${CMAKE_SOURCE_DIR}/include/libs/index" + "${CMAKE_CURRENT_SOURCE_DIR}/../inc" +) target_link_libraries (indexTest os util @@ -32,6 +45,13 @@ target_link_libraries (fstTest gtest_main index ) +target_link_libraries (fstUT + os + util + common + gtest_main + index +) #add_test( diff --git a/source/libs/index/test/fstTest.cc b/source/libs/index/test/fstTest.cc index a2c0046f9a..65118a2bce 100644 --- a/source/libs/index/test/fstTest.cc +++ b/source/libs/index/test/fstTest.cc @@ -58,7 +58,9 @@ class FstReadMemory { bool init() { char* buf = (char*)calloc(1, sizeof(char) * _size); int nRead = fstCountingWriterRead(_w, (uint8_t*)buf, _size); - if (nRead <= 0) { return false; } + if (nRead <= 0) { + return false; + } _size = nRead; _s = fstSliceCreate((uint8_t*)buf, _size); _fst = fstCreate(&_s); @@ -97,7 +99,8 @@ class FstReadMemory { printf("key: %s, val: %" PRIu64 "\n", key.c_str(), (uint64_t)(rt->out.out)); swsResultDestroy(rt); } - for (size_t i = 0; i < result.size(); i++) {} + for (size_t i = 0; i < result.size(); i++) { + } std::cout << std::endl; return true; } @@ -173,7 +176,9 @@ void checkMillonWriteAndReadOfFst() { delete fw; FstReadMemory* fr = new FstReadMemory(1024 * 64 * 1024); - if (fr->init()) { printf("success to init fst read"); } + if (fr->init()) { + printf("success to init fst read"); + } Performance_fstReadRecords(fr); tfCleanup(); diff --git a/source/libs/index/test/fstUT.cc b/source/libs/index/test/fstUT.cc new file mode 100644 index 0000000000..47215693bb --- /dev/null +++ b/source/libs/index/test/fstUT.cc @@ -0,0 +1,232 @@ + +#include +#include +#include +#include +#include +#include +#include "index.h" +#include "indexInt.h" +#include "index_cache.h" +#include "index_fst.h" +#include "index_fst_counting_writer.h" +#include "index_fst_util.h" +#include "index_tfile.h" +#include "tglobal.h" +#include "tskiplist.h" +#include "tutil.h" +#include "ulog.h" + +static std::string dir = "/tmp/index"; + +static char indexlog[PATH_MAX] = {0}; +static char tindex[PATH_MAX] = {0}; +static char tindexDir[PATH_MAX] = {0}; + +static void EnvInit() { + tfInit(); + + std::string path = dir; + taosRemoveDir(path.c_str()); + taosMkDir(path.c_str()); + // init log file + snprintf(indexlog, PATH_MAX, "%s/tindex.idx", path.c_str()); + if (taosInitLog(indexlog, tsNumOfLogLines, 1) != 0) { + printf("failed to init log"); + } + // init index file + memset(tindex, 0, sizeof(tindex)); + snprintf(tindex, PATH_MAX, "%s/tindex.idx", path.c_str()); +} +static void EnvCleanup() {} +class FstWriter { + public: + FstWriter() { + _wc = writerCtxCreate(TFile, tindex, false, 64 * 1024 * 1024); + _b = fstBuilderCreate(_wc, 0); + } + bool Put(const std::string& key, uint64_t val) { + // char buf[128] = {0}; + // int len = 0; + // taosMbsToUcs4(key.c_str(), key.size(), buf, 128, &len); + // FstSlice skey = fstSliceCreate((uint8_t*)buf, len); + FstSlice skey = fstSliceCreate((uint8_t*)key.c_str(), key.size()); + bool ok = fstBuilderInsert(_b, skey, val); + + fstSliceDestroy(&skey); + return ok; + } + ~FstWriter() { + fstBuilderFinish(_b); + fstBuilderDestroy(_b); + + writerCtxDestroy(_wc, false); + } + + private: + FstBuilder* _b; + WriterCtx* _wc; +}; + +class FstReadMemory { + public: + FstReadMemory(size_t size) { + _wc = writerCtxCreate(TFile, tindex, true, 64 * 1024); + _w = fstCountingWriterCreate(_wc); + _size = size; + memset((void*)&_s, 0, sizeof(_s)); + } + bool init() { + char* buf = (char*)calloc(1, sizeof(char) * _size); + int nRead = fstCountingWriterRead(_w, (uint8_t*)buf, _size); + if (nRead <= 0) { + return false; + } + _size = nRead; + _s = fstSliceCreate((uint8_t*)buf, _size); + _fst = fstCreate(&_s); + free(buf); + return _fst != NULL; + } + bool Get(const std::string& key, uint64_t* val) { + // char buf[128] = {0}; + // int len = 0; + // taosMbsToUcs4(key.c_str(), key.size(), buf, 128, &len); + // FstSlice skey = fstSliceCreate((uint8_t*)buf, len); + + FstSlice skey = fstSliceCreate((uint8_t*)key.c_str(), key.size()); + bool ok = fstGet(_fst, &skey, val); + fstSliceDestroy(&skey); + return ok; + } + bool GetWithTimeCostUs(const std::string& key, uint64_t* val, uint64_t* elapse) { + int64_t s = taosGetTimestampUs(); + bool ok = this->Get(key, val); + int64_t e = taosGetTimestampUs(); + *elapse = e - s; + return ok; + } + // add later + bool Search(AutomationCtx* ctx, std::vector& result) { + FstStreamBuilder* sb = fstSearch(_fst, ctx); + StreamWithState* st = streamBuilderIntoStream(sb); + StreamWithStateResult* rt = NULL; + while ((rt = streamWithStateNextWith(st, NULL)) != NULL) { + // result.push_back((uint64_t)(rt->out.out)); + FstSlice* s = &rt->data; + int32_t sz = 0; + char* ch = (char*)fstSliceData(s, &sz); + std::string key(ch, sz); + printf("key: %s, val: %" PRIu64 "\n", key.c_str(), (uint64_t)(rt->out.out)); + swsResultDestroy(rt); + } + for (size_t i = 0; i < result.size(); i++) { + } + std::cout << std::endl; + return true; + } + bool SearchWithTimeCostUs(AutomationCtx* ctx, std::vector& result) { + int64_t s = taosGetTimestampUs(); + bool ok = this->Search(ctx, result); + int64_t e = taosGetTimestampUs(); + return ok; + } + + ~FstReadMemory() { + fstCountingWriterDestroy(_w); + fstDestroy(_fst); + fstSliceDestroy(&_s); + writerCtxDestroy(_wc, false); + tfCleanup(); + } + + private: + FstCountingWriter* _w; + Fst* _fst; + FstSlice _s; + WriterCtx* _wc; + size_t _size; +}; + +class FstWriterEnv : public ::testing::Test { + protected: + virtual void SetUp() { fw = new FstWriter(); } + virtual void TearDown() { delete fw; } + FstWriter* fw = NULL; +}; + +class FstReadEnv : public ::testing::Test { + protected: + virtual void SetUp() { fr = new FstReadMemory(1024); } + virtual void TearDown() { delete fr; } + FstReadMemory* fr = NULL; +}; + +class TFst { + public: + void CreateWriter() { fw = new FstWriter; } + void ReCreateWriter() { + if (fw != NULL) delete fw; + fw = new FstWriter; + } + void DestroyWriter() { + if (fw != NULL) delete fw; + } + void CreateReader() { + fr = new FstReadMemory(1024); + fr->init(); + } + void ReCreateReader() { + if (fr != NULL) delete fr; + fr = new FstReadMemory(1024); + } + void DestroyReader() { + delete fr; + fr = NULL; + } + bool Put(const std::string& k, uint64_t v) { + if (fw == NULL) { + return false; + } + return fw->Put(k, v); + } + bool Get(const std::string& k, uint64_t* v) { + if (fr == NULL) { + return false; + } + return fr->Get(k, v); + } + + private: + FstWriter* fw; + FstReadMemory* fr; +}; +class FstEnv : public ::testing::Test { + protected: + virtual void SetUp() { + EnvInit(); + fst = new TFst; + } + virtual void TearDown() { delete fst; } + TFst* fst; +}; + +TEST_F(FstEnv, writeNormal) { + fst->CreateWriter(); + std::string str("aa"); + for (int i = 0; i < 10; i++) { + str[0] = 'a' + i; + str.resize(2); + assert(fst->Put(str, i) == true); + } + // order failed + assert(fst->Put("aa", 1) == false); + + fst->DestroyWriter(); + + fst->CreateReader(); + uint64_t val; + assert(fst->Get("a", &val) == false); + assert(fst->Get("aa", &val) == true); + assert(val == 0); +}