From b6593d9ae9b9a6ba7f8925f56991967fa66a9422 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 9 May 2022 05:06:55 +0000 Subject: [PATCH 1/8] refact: tsdb --- source/dnode/vnode/src/tsdb/tsdbMemTable2.c | 139 ++++++++++++++------ 1 file changed, 100 insertions(+), 39 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c index 952ccfda9c..e162d519ac 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c +++ b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c @@ -22,15 +22,16 @@ typedef struct SMemSkipListNode SMemSkipListNode; typedef struct SMemSkipListCurosr SMemSkipListCurosr; struct SMemTable { - STsdb *pTsdb; - TSKEY minKey; - TSKEY maxKey; - int64_t minVer; - int64_t maxVer; - int64_t nRows; - int32_t nHash; - int32_t nBucket; - SMemData **pBuckets; + STsdb *pTsdb; + TSKEY minKey; + TSKEY maxKey; + int64_t minVer; + int64_t maxVer; + int64_t nRows; + int32_t nHash; + int32_t nBucket; + SMemData **pBuckets; + SMemSkipListCurosr *pSlc; }; struct SMemSkipListNode { @@ -60,9 +61,15 @@ struct SMemData { struct SMemSkipListCurosr { SMemSkipList *pSl; - SMemSkipListNode *pNodeC; + SMemSkipListNode *forwards[]; }; +typedef struct { + int64_t version; + uint32_t szRow; + const STSRow *pRow; +} STsdbRow; + #define HASH_BUCKET(SUID, UID, NBUCKET) (TABS((SUID) + (UID)) % (NBUCKET)) #define SL_NODE_SIZE(l) (sizeof(SMemSkipListNode) + sizeof(SMemSkipListNode *) * (l)*2) @@ -76,7 +83,13 @@ struct SMemSkipListCurosr { #define SL_HEAD_NODE_FORWARD(n, l) SL_NODE_FORWARD(n, l) #define SL_TAIL_NODE_BACKWARD(n, l) SL_NODE_FORWARD(n, l) -static int8_t tsdbMemSkipListRandLevel(SMemSkipList *pSl); +static int8_t tsdbMemSkipListRandLevel(SMemSkipList *pSl); +static int32_t tsdbEncodeRow(SEncoder *pEncoder, const STsdbRow *pRow); +static int32_t tsdbDecodeRow(SDecoder *pDecoder, STsdbRow *pRow); +static int32_t tsdbMemSkipListCursorCreate(int8_t maxLevel, SMemSkipListCurosr **ppSlc); +static void tsdbMemSkipListCursorDestroy(SMemSkipListCurosr *pSlc); +static void tsdbMemSkipListCursorInit(SMemSkipListCurosr *pSlc, SMemSkipList *pSl); +static void tsdbMemSkipListCursorPut(SMemSkipListCurosr *pSlc, SMemSkipListNode *pNode); // SMemTable int32_t tsdbMemTableCreate2(STsdb *pTsdb, SMemTable **ppMemTb) { @@ -102,6 +115,11 @@ int32_t tsdbMemTableCreate2(STsdb *pTsdb, SMemTable **ppMemTb) { taosMemoryFree(pMemTb); return -1; } + if (tsdbMemSkipListCursorCreate(pTsdb->pVnode->config.tsdbCfg.slLevel, &pMemTb->pSlc) < 0) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + taosMemoryFree(pMemTb->pBuckets); + taosMemoryFree(pMemTb); + } *ppMemTb = pMemTb; return 0; @@ -110,6 +128,7 @@ int32_t tsdbMemTableCreate2(STsdb *pTsdb, SMemTable **ppMemTb) { int32_t tsdbMemTableDestroy2(STsdb *pTsdb, SMemTable *pMemTb) { if (pMemTb) { // loop to destroy the contents (todo) + tsdbMemSkipListCursorDestroy(pMemTb->pSlc); taosMemoryFree(pMemTb->pBuckets); taosMemoryFree(pMemTb); } @@ -177,52 +196,47 @@ int32_t tsdbInsertData2(SMemTable *pMemTb, int64_t version, const SVSubmitBlk *p } // do insert data to SMemData - SMemSkipListCurosr slc = {0}; - const STSRow *pRow; - uint32_t szRow; - SDecoder decoder = {0}; + STsdbRow tRow = {.version = version}; + SEncoder ec = {0}; + SDecoder dc = {0}; - tDecoderInit(&decoder, pSubmitBlk->pData, pSubmitBlk->nData); + tDecoderInit(&dc, pSubmitBlk->pData, pSubmitBlk->nData); + tsdbMemSkipListCursorInit(pMemTb->pSlc, &pMemData->sl); for (;;) { - if (tDecodeIsEnd(&decoder)) break; + if (tDecodeIsEnd(&dc)) break; - if (tDecodeBinary(&decoder, (const uint8_t **)&pRow, &szRow) < 0) { + if (tDecodeBinary(&dc, (const uint8_t **)&tRow.pRow, &tRow.szRow) < 0) { terrno = TSDB_CODE_INVALID_MSG; return -1; } - // check the row (todo) - - // // move the cursor to position to write (todo) - // int32_t c; - // tsdbMemSkipListCursorMoveTo(&slc, pTSRow, version, &c); - // ASSERT(c); + // move cursor // encode row - int8_t level = tsdbMemSkipListRandLevel(&pMemData->sl); - int32_t tsize = SL_NODE_SIZE(level) + sizeof(version) + (0 /*todo*/); - SMemSkipListNode *pNode = vnodeBufPoolMalloc(pPool, tsize); + int8_t level = tsdbMemSkipListRandLevel(&pMemData->sl); + int32_t tsize; + int32_t ret; + tEncodeSize(tsdbEncodeRow, &tRow, tsize, ret); + SMemSkipListNode *pNode = vnodeBufPoolMalloc(pPool, tsize + SL_NODE_SIZE(level)); if (pNode == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } pNode->level = level; + tEncoderInit(&ec, (uint8_t *)SL_NODE_DATA(pNode), tsize); + ret = tsdbEncodeRow(&ec, &tRow); + ASSERT(ret == 0); + tEncoderClear(&ec); - // uint8_t *pData = SL_NODE_DATA(pSlNode); - // *(int64_t *)pData = version; - // pData += sizeof(version); - // memcpy(pData, pt, p - pt); - - // // insert row - // tsdbMemSkipListCursorPut(&slc, pSlNode); + // put the node + tsdbMemSkipListCursorPut(pMemTb->pSlc, pNode); // update status - if (pRow->ts < pMemData->minKey) pMemData->minKey = pRow->ts; - if (pRow->ts > pMemData->maxKey) pMemData->maxKey = pRow->ts; + if (tRow.pRow->ts < pMemData->minKey) pMemData->minKey = tRow.pRow->ts; + if (tRow.pRow->ts > pMemData->maxKey) pMemData->maxKey = tRow.pRow->ts; } - tDecoderClear(&decoder); - // tsdbMemSkipListCursorClose(&slc); + tDecoderClear(&dc); // update status if (pMemData->minVer == -1) pMemData->minVer = version; @@ -236,7 +250,7 @@ int32_t tsdbInsertData2(SMemTable *pMemTb, int64_t version, const SVSubmitBlk *p return 0; } -static int8_t tsdbMemSkipListRandLevel(SMemSkipList *pSl) { +static FORCE_INLINE int8_t tsdbMemSkipListRandLevel(SMemSkipList *pSl) { int8_t level = 1; int8_t tlevel; const uint32_t factor = 4; @@ -249,4 +263,51 @@ static int8_t tsdbMemSkipListRandLevel(SMemSkipList *pSl) { } return level; +} + +static FORCE_INLINE int32_t tsdbEncodeRow(SEncoder *pEncoder, const STsdbRow *pRow) { + if (tEncodeI64(pEncoder, pRow->version) < 0) return -1; + if (tEncodeBinary(pEncoder, (const uint8_t *)pRow->pRow, pRow->szRow) < 0) return -1; + return 0; +} + +static FORCE_INLINE int32_t tsdbDecodeRow(SDecoder *pDecoder, STsdbRow *pRow) { + if (tDecodeI64(pDecoder, &pRow->version) < 0) return -1; + if (tDecodeBinary(pDecoder, (const uint8_t **)&pRow->pRow, &pRow->szRow) < 0) return -1; + return 0; +} + +static int32_t tsdbMemSkipListCursorCreate(int8_t maxLevel, SMemSkipListCurosr **ppSlc) { + *ppSlc = (SMemSkipListCurosr *)taosMemoryCalloc(1, sizeof(**ppSlc) + sizeof(SMemSkipListNode *) * maxLevel); + if (*ppSlc == NULL) { + return -1; + } + return 0; +} + +static void tsdbMemSkipListCursorDestroy(SMemSkipListCurosr *pSlc) { taosMemoryFree(pSlc); } + +static void tsdbMemSkipListCursorInit(SMemSkipListCurosr *pSlc, SMemSkipList *pSl) { + SMemSkipListNode *pHead = SL_HEAD_NODE(pSl); + pSlc->pSl = pSl; + for (int8_t iLevel = 0; iLevel < pSl->maxLevel; iLevel++) { + pSlc->forwards[iLevel] = pHead; + } +} + +static void tsdbMemSkipListCursorPut(SMemSkipListCurosr *pSlc, SMemSkipListNode *pNode) { + SMemSkipList *pSl = pSlc->pSl; + SMemSkipListNode *pNodeNext; + + for (int8_t iLevel = 0; iLevel < pNode->level; iLevel++) { + // todo + + ASSERT(0); + } + + if (pSl->level < pNode->level) { + pSl->level = pNode->level; + } + + pSl->size += 1; } \ No newline at end of file From 9a035fdb1dbab8257c769097006df8b679bd05f2 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 9 May 2022 05:40:25 +0000 Subject: [PATCH 2/8] refact tsdb --- include/util/tskiplist2.h | 70 -------- source/dnode/vnode/src/tsdb/tsdbMemTable2.c | 42 ++++- source/util/src/tskiplist2.c | 175 -------------------- 3 files changed, 38 insertions(+), 249 deletions(-) delete mode 100644 include/util/tskiplist2.h delete mode 100644 source/util/src/tskiplist2.c diff --git a/include/util/tskiplist2.h b/include/util/tskiplist2.h deleted file mode 100644 index 83e6ad0868..0000000000 --- a/include/util/tskiplist2.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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_UTIL_SKIPLIST2_H_ -#define _TD_UTIL_SKIPLIST2_H_ - -#include "os.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SL_MAX_LEVEL 15 - -typedef struct SSkipList2 SSkipList2; -typedef struct SSLCursor SSLCursor; -typedef struct SSLCfg SSLCfg; -typedef struct SSLNode SSLNode; - -typedef int32_t (*tslCmprFn)(const void *pKey1, int32_t nKey1, const void *pKey2, int32_t nKey2); - -// SSkipList2 -int32_t slOpen(const SSLCfg *pCfg, SSkipList2 **ppSl); -int32_t slClose(SSkipList2 *pSl); -int32_t slClear(SSkipList2 *pSl); - -// SSLCursor -int32_t slcOpen(SSkipList2 *pSl, SSLCursor *pSlc); -int32_t slcClose(SSLCursor *pSlc); -int32_t slcMoveTo(SSLCursor *pSlc, const void *pKey, int32_t nKey); -int32_t slcMoveToNext(SSLCursor *pSlc); -int32_t slcMoveToPrev(SSLCursor *pSlc); -int32_t slcMoveToFirst(SSLCursor *pSlc); -int32_t slcMoveToLast(SSLCursor *pSlc); -int32_t slcPut(SSLCursor *pSlc, const void *pKey, int32_t nKey, const void *pData, int32_t nData); -int32_t slcGet(SSLCursor *pSlc, const void **ppKey, int32_t *nKey, const void **ppData, int32_t *nData); -int32_t slcDrop(SSLCursor *pSlc); - -// struct -struct SSLCfg { - int8_t maxLevel; - int32_t nKey; - int32_t nData; - tslCmprFn cmprFn; - void *pPool; - void *(*xMalloc)(void *, int32_t size); - void (*xFree)(void *, void *); -}; - -struct SSLCursor { - SSkipList2 *pSl; - SSLNode **forwards[SL_MAX_LEVEL]; -}; - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_UTIL_SKIPLIST2_H_*/ \ No newline at end of file diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c index e162d519ac..e8e7260514 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c +++ b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c @@ -61,7 +61,7 @@ struct SMemData { struct SMemSkipListCurosr { SMemSkipList *pSl; - SMemSkipListNode *forwards[]; + SMemSkipListNode *pNodeC; }; typedef struct { @@ -70,6 +70,8 @@ typedef struct { const STSRow *pRow; } STsdbRow; +#define SL_MAX_LEVEL 15 + #define HASH_BUCKET(SUID, UID, NBUCKET) (TABS((SUID) + (UID)) % (NBUCKET)) #define SL_NODE_SIZE(l) (sizeof(SMemSkipListNode) + sizeof(SMemSkipListNode *) * (l)*2) @@ -90,6 +92,9 @@ static int32_t tsdbMemSkipListCursorCreate(int8_t maxLevel, SMemSkipListCurosr * static void tsdbMemSkipListCursorDestroy(SMemSkipListCurosr *pSlc); static void tsdbMemSkipListCursorInit(SMemSkipListCurosr *pSlc, SMemSkipList *pSl); static void tsdbMemSkipListCursorPut(SMemSkipListCurosr *pSlc, SMemSkipListNode *pNode); +static int32_t tsdbMemSkipListCursorMoveTo(SMemSkipListCurosr *pSlc, int64_t version, TSKEY ts, int32_t flags); +static int32_t tsdbMemSkipListCursorMoveToNext(SMemSkipListCurosr *pSlc); +static int32_t tsdbMemSkipListCursorMoveToPrev(SMemSkipListCurosr *pSlc); // SMemTable int32_t tsdbMemTableCreate2(STsdb *pTsdb, SMemTable **ppMemTb) { @@ -211,6 +216,7 @@ int32_t tsdbInsertData2(SMemTable *pMemTb, int64_t version, const SVSubmitBlk *p } // move cursor + tsdbMemSkipListCursorMoveTo(pMemTb->pSlc, version, tRow.pRow->ts, 0); // encode row int8_t level = tsdbMemSkipListRandLevel(&pMemData->sl); @@ -290,9 +296,9 @@ static void tsdbMemSkipListCursorDestroy(SMemSkipListCurosr *pSlc) { taosMemoryF static void tsdbMemSkipListCursorInit(SMemSkipListCurosr *pSlc, SMemSkipList *pSl) { SMemSkipListNode *pHead = SL_HEAD_NODE(pSl); pSlc->pSl = pSl; - for (int8_t iLevel = 0; iLevel < pSl->maxLevel; iLevel++) { - pSlc->forwards[iLevel] = pHead; - } + // for (int8_t iLevel = 0; iLevel < pSl->maxLevel; iLevel++) { + // pSlc->forwards[iLevel] = pHead; + // } } static void tsdbMemSkipListCursorPut(SMemSkipListCurosr *pSlc, SMemSkipListNode *pNode) { @@ -310,4 +316,32 @@ static void tsdbMemSkipListCursorPut(SMemSkipListCurosr *pSlc, SMemSkipListNode } pSl->size += 1; +} + +static int32_t tsdbMemSkipListCursorMoveTo(SMemSkipListCurosr *pSlc, int64_t version, TSKEY ts, int32_t flags) { + SMemSkipListNode **pForwards = NULL; + SMemSkipList *pSl = pSlc->pSl; + int8_t maxLevel = pSl->maxLevel; + SMemSkipListNode *pHead = SL_HEAD_NODE(pSl); + SMemSkipListNode *pTail = SL_TAIL_NODE(pSl); + + for (int8_t iLevel = 0; iLevel < maxLevel; iLevel++) { + pForwards[iLevel] = pHead; + } + + for (int8_t iLevel = maxLevel - 1; iLevel >= 0; iLevel--) { + if (iLevel < pSl->level) { + } + } + return 0; +} + +static int32_t tsdbMemSkipListCursorMoveToNext(SMemSkipListCurosr *pSlc) { + // TODO + return 0; +} + +static int32_t tsdbMemSkipListCursorMoveToPrev(SMemSkipListCurosr *pSlc) { + // TODO + return 0; } \ No newline at end of file diff --git a/source/util/src/tskiplist2.c b/source/util/src/tskiplist2.c deleted file mode 100644 index 77f5ed5051..0000000000 --- a/source/util/src/tskiplist2.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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 "tskiplist2.h" - -struct SSLNode { - int8_t level; - SSLNode *forwards[]; -}; - -struct SSkipList2 { - int8_t level; - uint32_t seed; - int32_t size; - const SSLCfg *pCfg; - SSLNode *pHead[]; -}; - -static void *slMalloc(void *pPool, int32_t size); -static void slFree(void *pPool, void *p); -static int32_t slCmprFn(const void *pKey, int32_t nKey, const void *pData, int32_t nData); - -const SSLCfg slDefaultCfg = {.maxLevel = SL_MAX_LEVEL, - .nKey = -1, - .nData = -1, - .cmprFn = slCmprFn, - .pPool = NULL, - .xMalloc = slMalloc, - .xFree = slFree}; - -int32_t slOpen(const SSLCfg *pCfg, SSkipList2 **ppSl) { - SSkipList2 *pSl = NULL; - int32_t size; - - *ppSl = NULL; - if (pCfg == NULL) pCfg = &slDefaultCfg; - - // check config (TODO) - - // malloc handle - size = sizeof(*pSl) + sizeof(SSLNode *) * pCfg->maxLevel * 2; - pSl = pCfg->xMalloc(pCfg->pPool, size); - if (pSl == NULL) { - return -1; - } - - pSl->level = 0; - pSl->seed = taosRand(); - pSl->size = 0; - pSl->pCfg = pCfg; - - // init an empty skiplist - for (int32_t i = 0; i < pCfg->maxLevel * 2; i++) { - pSl->pHead[i] = NULL; - } - - *ppSl = pSl; - return 0; -} - -int32_t slClose(SSkipList2 *pSl) { - if (pSl) { - slClear(pSl); - if (pSl->pCfg->xFree) { - pSl->pCfg->xFree(pSl->pCfg->pPool, pSl); - } - } - - return 0; -} - -int32_t slClear(SSkipList2 *pSl) { - // loop to clear sl - for (;;) { - // (TODO) - } - - // init sl (TODO) - - return 0; -} - -int32_t slcOpen(SSkipList2 *pSl, SSLCursor *pSlc) { - pSlc->pSl = pSl; - - for (int i = 0; i < SL_MAX_LEVEL; i++) { - if (i < pSl->pCfg->maxLevel) { - } else { - pSlc->forwards[i] = NULL; - } - } - - // TODO - return 0; -} - -int32_t slcClose(SSLCursor *pSlc) { - // TODO - return 0; -} - -int32_t slcMoveTo(SSLCursor *pSlc, const void *pKey, int32_t nKey) { - // TODO - return 0; -} - -int32_t slcMoveToNext(SSLCursor *pSlc) { - // TODO - return 0; -} - -int32_t slcMoveToPrev(SSLCursor *pSlc) { - // TODO - return 0; -} - -int32_t slcMoveToFirst(SSLCursor *pSlc) { - // TODO - return 0; -} - -int32_t slcMoveToLast(SSLCursor *pSlc) { - // TODO - return 0; -} - -int32_t slcPut(SSLCursor *pSlc, const void *pKey, int32_t nKey, const void *pData, int32_t nData) { - // TODO - return 0; -} - -int32_t slcGet(SSLCursor *pSlc, const void **ppKey, int32_t *nKey, const void **ppData, int32_t *nData) { - // TODO - return 0; -} - -int32_t slcDrop(SSLCursor *pSlc) { - // TODO - return 0; -} - -static FORCE_INLINE void *slMalloc(void *pPool, int32_t size) { return taosMemoryMalloc(size); } - -static FORCE_INLINE void slFree(void *pPool, void *p) { taosMemoryFree(p); } - -static int32_t slCmprFn(const void *pKey1, int32_t nKey1, const void *pKey2, int32_t nKey2) { - ASSERT(nKey1 >= 0 && nKey2 >= 0); - - int32_t nKey = nKey1 > nKey2 ? nKey2 : nKey1; - int32_t c; - - c = memcmp(pKey1, pKey2, nKey); - if (c == 0) { - if (nKey1 > nKey2) { - c = 1; - } else if (nKey1 < nKey2) { - c = -1; - } - } - - return c; -} \ No newline at end of file From fba58c763f573a03242efbf4994bf98cc2526a2f Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 9 May 2022 06:29:43 +0000 Subject: [PATCH 3/8] refact TSDB --- source/dnode/vnode/src/tsdb/tsdbMemTable2.c | 60 ++++++++++++--------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c index e8e7260514..bfd79f7965 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c +++ b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c @@ -95,6 +95,7 @@ static void tsdbMemSkipListCursorPut(SMemSkipListCurosr *pSlc, SMemSkipListNo static int32_t tsdbMemSkipListCursorMoveTo(SMemSkipListCurosr *pSlc, int64_t version, TSKEY ts, int32_t flags); static int32_t tsdbMemSkipListCursorMoveToNext(SMemSkipListCurosr *pSlc); static int32_t tsdbMemSkipListCursorMoveToPrev(SMemSkipListCurosr *pSlc); +static SMemSkipListNode *tsdbMemSkipListNodeCreate(SVBufPool *pPool, SMemSkipList *pSl, const STsdbRow *pTRow); // SMemTable int32_t tsdbMemTableCreate2(STsdb *pTsdb, SMemTable **ppMemTb) { @@ -201,15 +202,18 @@ int32_t tsdbInsertData2(SMemTable *pMemTb, int64_t version, const SVSubmitBlk *p } // do insert data to SMemData - STsdbRow tRow = {.version = version}; - SEncoder ec = {0}; - SDecoder dc = {0}; + SMemSkipListNode *forwards[SL_MAX_LEVEL]; + SMemSkipListNode *pNode; + STsdbRow tRow = {.version = version}; + SEncoder ec = {0}; + SDecoder dc = {0}; tDecoderInit(&dc, pSubmitBlk->pData, pSubmitBlk->nData); tsdbMemSkipListCursorInit(pMemTb->pSlc, &pMemData->sl); for (;;) { if (tDecodeIsEnd(&dc)) break; + // decode row if (tDecodeBinary(&dc, (const uint8_t **)&tRow.pRow, &tRow.szRow) < 0) { terrno = TSDB_CODE_INVALID_MSG; return -1; @@ -219,22 +223,12 @@ int32_t tsdbInsertData2(SMemTable *pMemTb, int64_t version, const SVSubmitBlk *p tsdbMemSkipListCursorMoveTo(pMemTb->pSlc, version, tRow.pRow->ts, 0); // encode row - int8_t level = tsdbMemSkipListRandLevel(&pMemData->sl); - int32_t tsize; - int32_t ret; - tEncodeSize(tsdbEncodeRow, &tRow, tsize, ret); - SMemSkipListNode *pNode = vnodeBufPoolMalloc(pPool, tsize + SL_NODE_SIZE(level)); + pNode = tsdbMemSkipListNodeCreate(pPool, &pMemData->sl, &tRow); if (pNode == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } - pNode->level = level; - tEncoderInit(&ec, (uint8_t *)SL_NODE_DATA(pNode), tsize); - ret = tsdbEncodeRow(&ec, &tRow); - ASSERT(ret == 0); - tEncoderClear(&ec); - // put the node tsdbMemSkipListCursorPut(pMemTb->pSlc, pNode); @@ -258,14 +252,11 @@ int32_t tsdbInsertData2(SMemTable *pMemTb, int64_t version, const SVSubmitBlk *p static FORCE_INLINE int8_t tsdbMemSkipListRandLevel(SMemSkipList *pSl) { int8_t level = 1; - int8_t tlevel; + int8_t tlevel = TMIN(pSl->maxLevel, pSl->level + 1); const uint32_t factor = 4; - if (pSl->size) { - tlevel = TMIN(pSl->maxLevel, pSl->level + 1); - while ((taosRandR(&pSl->seed) % factor) == 0 && level < tlevel) { - level++; - } + while ((taosRandR(&pSl->seed) % factor) == 0 && level < tlevel) { + level++; } return level; @@ -325,14 +316,12 @@ static int32_t tsdbMemSkipListCursorMoveTo(SMemSkipListCurosr *pSlc, int64_t ver SMemSkipListNode *pHead = SL_HEAD_NODE(pSl); SMemSkipListNode *pTail = SL_TAIL_NODE(pSl); - for (int8_t iLevel = 0; iLevel < maxLevel; iLevel++) { - pForwards[iLevel] = pHead; - } - - for (int8_t iLevel = maxLevel - 1; iLevel >= 0; iLevel--) { - if (iLevel < pSl->level) { + if (pSl->size == 0) { + for (int8_t iLevel = 0; iLevel < pSl->maxLevel; iLevel++) { + pForwards[iLevel] = pHead; } } + return 0; } @@ -344,4 +333,23 @@ static int32_t tsdbMemSkipListCursorMoveToNext(SMemSkipListCurosr *pSlc) { static int32_t tsdbMemSkipListCursorMoveToPrev(SMemSkipListCurosr *pSlc) { // TODO return 0; +} + +static SMemSkipListNode *tsdbMemSkipListNodeCreate(SVBufPool *pPool, SMemSkipList *pSl, const STsdbRow *pTRow) { + int32_t tsize; + int32_t ret; + int8_t level = tsdbMemSkipListRandLevel(pSl); + SMemSkipListNode *pNode = NULL; + SEncoder ec = {0}; + + tEncodeSize(tsdbEncodeRow, pTRow, tsize, ret); + pNode = vnodeBufPoolMalloc(pPool, tsize + SL_NODE_SIZE(level)); + if (pNode) { + pNode->level = level; + tEncoderInit(&ec, (uint8_t *)SL_NODE_DATA(pNode), tsize); + tsdbEncodeRow(&ec, pTRow); + tEncoderClear(&ec); + } + + return pNode; } \ No newline at end of file From ede0d49163a8d06722381627ae6bfe7479bac5f4 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 9 May 2022 06:30:45 +0000 Subject: [PATCH 4/8] more refact --- source/dnode/vnode/src/tsdb/tsdbMemTable2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c index bfd79f7965..2dff0f14e1 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c +++ b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c @@ -204,13 +204,14 @@ int32_t tsdbInsertData2(SMemTable *pMemTb, int64_t version, const SVSubmitBlk *p // do insert data to SMemData SMemSkipListNode *forwards[SL_MAX_LEVEL]; SMemSkipListNode *pNode; + int32_t iRow; STsdbRow tRow = {.version = version}; SEncoder ec = {0}; SDecoder dc = {0}; tDecoderInit(&dc, pSubmitBlk->pData, pSubmitBlk->nData); tsdbMemSkipListCursorInit(pMemTb->pSlc, &pMemData->sl); - for (;;) { + for (iRow = 0;; iRow++) { if (tDecodeIsEnd(&dc)) break; // decode row From 37c122f0a76506d638217a937bd8de31534a1d27 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 9 May 2022 07:03:46 +0000 Subject: [PATCH 5/8] refact --- source/dnode/vnode/src/tsdb/tsdbMemTable2.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c index 2dff0f14e1..e9dc98d102 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c +++ b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c @@ -326,6 +326,16 @@ static int32_t tsdbMemSkipListCursorMoveTo(SMemSkipListCurosr *pSlc, int64_t ver return 0; } +static int32_t tsdbMemSkipListCursorMoveToFirst(SMemSkipListCurosr *pSlc) { + // TODO + return 0; +} + +static int32_t tsdbMemSkipListCursorMoveToLast(SMemSkipListCurosr *pSlc) { + // TODO + return 0; +} + static int32_t tsdbMemSkipListCursorMoveToNext(SMemSkipListCurosr *pSlc) { // TODO return 0; From db998d29b6091009aa5657ffe711c500ab631c44 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 9 May 2022 09:43:15 +0000 Subject: [PATCH 6/8] refact: tdata --- include/common/tdata.h | 45 ++ include/common/tdataformat.h | 410 +----------------- include/common/trow.h | 76 +--- source/common/src/tdata.c | 14 + source/common/src/tdataformat.c | 450 -------------------- source/dnode/vnode/src/tsdb/tsdbCommit.c | 58 +-- source/dnode/vnode/src/tsdb/tsdbMemTable2.c | 32 +- 7 files changed, 96 insertions(+), 989 deletions(-) create mode 100644 include/common/tdata.h create mode 100644 source/common/src/tdata.c diff --git a/include/common/tdata.h b/include/common/tdata.h new file mode 100644 index 0000000000..9c4d33ed02 --- /dev/null +++ b/include/common/tdata.h @@ -0,0 +1,45 @@ +/* + * 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_TDATA_H_ +#define _TD_TDATA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "os.h" + +typedef struct STaosData TDATA, tdata_t; + +typedef enum { + TAOS_META_STABLE_DATA = 0, // super table meta + TAOS_META_TABLE_DATA, // non-super table meta + TAOS_TS_ROW_DATA, // row time-series data + TAOS_TS_COL_DATA, // col time-series data + TAOS_DATA_MAX +} ETaosDataT; + +struct STaosData { + ETaosDataT type; + uint32_t nPayload; + uint8_t *pPayload; +}; + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_TDATA_H_*/ \ No newline at end of file diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h index e94be797b9..1f3b787538 100644 --- a/include/common/tdataformat.h +++ b/include/common/tdataformat.h @@ -150,29 +150,6 @@ int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t flags, STSchema *tdGetSchemaFromBuilder(STSchemaBuilder *pBuilder); // ----------------- Semantic timestamp key definition -#ifdef TD_2_0 - -typedef uint64_t TKEY; - -#define TKEY_INVALID UINT64_MAX -#define TKEY_NULL TKEY_INVALID -#define TKEY_NEGATIVE_FLAG (((TKEY)1) << 63) -#define TKEY_DELETE_FLAG (((TKEY)1) << 62) -#define TKEY_VALUE_FILTER (~(TKEY_NEGATIVE_FLAG | TKEY_DELETE_FLAG)) - -#define TKEY_IS_NEGATIVE(tkey) (((tkey)&TKEY_NEGATIVE_FLAG) != 0) -#define TKEY_IS_DELETED(tkey) (((tkey)&TKEY_DELETE_FLAG) != 0) -#define tdSetTKEYDeleted(tkey) ((tkey) | TKEY_DELETE_FLAG) -#define tdGetTKEY(key) (((TKEY)TABS(key)) | (TKEY_NEGATIVE_FLAG & (TKEY)(key))) -#define tdGetKey(tkey) (((TSKEY)((tkey)&TKEY_VALUE_FILTER)) * (TKEY_IS_NEGATIVE(tkey) ? -1 : 1)) - -#define MIN_TS_KEY ((TSKEY)0x8000000000000001) -#define MAX_TS_KEY ((TSKEY)0x3fffffffffffffff) - -#define TD_TO_TKEY(key) tdGetTKEY(((key) < MIN_TS_KEY) ? MIN_TS_KEY : (((key) > MAX_TS_KEY) ? MAX_TS_KEY : key)) - -#else - // typedef uint64_t TKEY; #define TKEY TSKEY @@ -192,8 +169,6 @@ typedef uint64_t TKEY; #define TD_TO_TKEY(key) tdGetTKEY(((key) < MIN_TS_KEY) ? MIN_TS_KEY : (((key) > MAX_TS_KEY) ? MAX_TS_KEY : key)) -#endif - static FORCE_INLINE TKEY keyToTkey(TSKEY key) { TSKEY lkey = key; if (key > MAX_TS_KEY) { @@ -218,157 +193,6 @@ static FORCE_INLINE int32_t tkeyComparFn(const void *tkey1, const void *tkey2) { } } -#if 0 -// ----------------- Data row structure - -/* A data row, the format is like below: - * |<------------------------------------------------ len ---------------------------------->| - * |<-- Head -->|<--------- flen -------------->| | - * +---------------------+---------------------------------+---------------------------------+ - * | uint16_t | int16_t | | | - * +----------+----------+---------------------------------+---------------------------------+ - * | len | sversion | First part | Second part | - * +----------+----------+---------------------------------+---------------------------------+ - * - * NOTE: timestamp in this row structure is TKEY instead of TSKEY - */ -typedef void *SDataRow; - -#define TD_DATA_ROW_HEAD_SIZE (sizeof(uint16_t) + sizeof(int16_t)) - -#define dataRowLen(r) (*(TDRowLenT *)(r)) // 0~65535 -#define dataRowEnd(r) POINTER_SHIFT(r, dataRowLen(r)) -#define dataRowVersion(r) (*(int16_t *)POINTER_SHIFT(r, sizeof(int16_t))) -#define dataRowTuple(r) POINTER_SHIFT(r, TD_DATA_ROW_HEAD_SIZE) -#define dataRowTKey(r) (*(TKEY *)(dataRowTuple(r))) -#define dataRowKey(r) tdGetKey(dataRowTKey(r)) -#define dataRowSetLen(r, l) (dataRowLen(r) = (l)) -#define dataRowSetVersion(r, v) (dataRowVersion(r) = (v)) -#define dataRowCpy(dst, r) memcpy((dst), (r), dataRowLen(r)) -#define dataRowMaxBytesFromSchema(s) (schemaTLen(s) + TD_DATA_ROW_HEAD_SIZE) -#define dataRowDeleted(r) TKEY_IS_DELETED(dataRowTKey(r)) - -SDataRow tdNewDataRowFromSchema(STSchema *pSchema); -void tdFreeDataRow(SDataRow row); -void tdInitDataRow(SDataRow row, STSchema *pSchema); -SDataRow tdDataRowDup(SDataRow row); - -// offset here not include dataRow header length -static FORCE_INLINE int32_t tdAppendDataColVal(SDataRow row, const void *value, bool isCopyVarData, int8_t type, - int32_t offset) { - assert(value != NULL); - int32_t toffset = offset + TD_DATA_ROW_HEAD_SIZE; - - if (IS_VAR_DATA_TYPE(type)) { - *(VarDataOffsetT *)POINTER_SHIFT(row, toffset) = dataRowLen(row); - if (isCopyVarData) { - memcpy(POINTER_SHIFT(row, dataRowLen(row)), value, varDataTLen(value)); - } - dataRowLen(row) += varDataTLen(value); - } else { - if (offset == 0) { - assert(type == TSDB_DATA_TYPE_TIMESTAMP); - TKEY tvalue = tdGetTKEY(*(TSKEY *)value); - memcpy(POINTER_SHIFT(row, toffset), (const void *)(&tvalue), TYPE_BYTES[type]); - } else { - memcpy(POINTER_SHIFT(row, toffset), value, TYPE_BYTES[type]); - } - } - - return 0; -} - -// offset here not include dataRow header length -static FORCE_INLINE int32_t tdAppendColVal(SDataRow row, const void *value, int8_t type, int32_t offset) { - return tdAppendDataColVal(row, value, true, type, offset); -} - -// NOTE: offset here including the header size -static FORCE_INLINE void *tdGetRowDataOfCol(SDataRow row, int8_t type, int32_t offset) { - if (IS_VAR_DATA_TYPE(type)) { - return POINTER_SHIFT(row, *(VarDataOffsetT *)POINTER_SHIFT(row, offset)); - } else { - return POINTER_SHIFT(row, offset); - } -} - -static FORCE_INLINE void *tdGetPtrToCol(SDataRow row, STSchema *pSchema, int32_t idx) { - return POINTER_SHIFT(row, TD_DATA_ROW_HEAD_SIZE + pSchema->columns[idx].offset); -} - -static FORCE_INLINE void *tdGetColOfRowBySchema(SDataRow row, STSchema *pSchema, int32_t idx) { - int16_t offset = TD_DATA_ROW_HEAD_SIZE + pSchema->columns[idx].offset; - int8_t type = pSchema->columns[idx].type; - - return tdGetRowDataOfCol(row, type, offset); -} - -static FORCE_INLINE bool tdIsColOfRowNullBySchema(SDataRow row, STSchema *pSchema, int32_t idx) { - int16_t offset = TD_DATA_ROW_HEAD_SIZE + pSchema->columns[idx].offset; - int8_t type = pSchema->columns[idx].type; - - return isNull(tdGetRowDataOfCol(row, type, offset), type); -} - -static FORCE_INLINE void tdSetColOfRowNullBySchema(SDataRow row, STSchema *pSchema, int32_t idx) { - int16_t offset = TD_DATA_ROW_HEAD_SIZE + pSchema->columns[idx].offset; - int8_t type = pSchema->columns[idx].type; - int16_t bytes = pSchema->columns[idx].bytes; - - setNull(tdGetRowDataOfCol(row, type, offset), type, bytes); -} - -static FORCE_INLINE void tdCopyColOfRowBySchema(SDataRow dst, STSchema *pDstSchema, int32_t dstIdx, SDataRow src, - STSchema *pSrcSchema, int32_t srcIdx) { - int8_t type = pDstSchema->columns[dstIdx].type; - assert(type == pSrcSchema->columns[srcIdx].type); - void *pData = tdGetPtrToCol(dst, pDstSchema, dstIdx); - void *value = tdGetPtrToCol(src, pSrcSchema, srcIdx); - - switch (type) { - case TSDB_DATA_TYPE_BINARY: - case TSDB_DATA_TYPE_NCHAR: - *(VarDataOffsetT *)pData = *(VarDataOffsetT *)value; - pData = POINTER_SHIFT(dst, *(VarDataOffsetT *)pData); - value = POINTER_SHIFT(src, *(VarDataOffsetT *)value); - memcpy(pData, value, varDataTLen(value)); - break; - case TSDB_DATA_TYPE_NULL: - case TSDB_DATA_TYPE_BOOL: - case TSDB_DATA_TYPE_TINYINT: - case TSDB_DATA_TYPE_UTINYINT: - *(uint8_t *)pData = *(uint8_t *)value; - break; - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_USMALLINT: - *(uint16_t *)pData = *(uint16_t *)value; - break; - case TSDB_DATA_TYPE_INT: - case TSDB_DATA_TYPE_UINT: - *(uint32_t *)pData = *(uint32_t *)value; - break; - case TSDB_DATA_TYPE_BIGINT: - case TSDB_DATA_TYPE_UBIGINT: - *(uint64_t *)pData = *(uint64_t *)value; - break; - case TSDB_DATA_TYPE_FLOAT: - SET_FLOAT_PTR(pData, value); - break; - case TSDB_DATA_TYPE_DOUBLE: - SET_DOUBLE_PTR(pData, value); - break; - case TSDB_DATA_TYPE_TIMESTAMP: - if (pSrcSchema->columns[srcIdx].colId == PRIMARYKEY_TIMESTAMP_COL_ID) { - *(TSKEY *)pData = tdGetKey(*(TKEY *)value); - } else { - *(TSKEY *)pData = *(TSKEY *)value; - } - break; - default: - memcpy(pData, value, pSrcSchema->columns[srcIdx].bytes); - } -} -#endif // ----------------- Data column structure // SDataCol arrangement: data => bitmap => dataOffset typedef struct SDataCol { @@ -398,29 +222,6 @@ void *dataColSetOffset(SDataCol *pCol, int32_t nEle); bool isNEleNull(SDataCol *pCol, int32_t nEle); -#if 0 -// Get the data pointer from a column-wised data -static FORCE_INLINE const void *tdGetColDataOfRow(SDataCol *pCol, int32_t row) { - if (isAllRowsNull(pCol)) { - return getNullValue(pCol->type); - } - if (IS_VAR_DATA_TYPE(pCol->type)) { - return POINTER_SHIFT(pCol->pData, pCol->dataOff[row]); - } else { - return POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * row); - } -} - -static FORCE_INLINE int32_t dataColGetNEleLen(SDataCol *pDataCol, int32_t rows) { - assert(rows > 0); - - if (IS_VAR_DATA_TYPE(pDataCol->type)) { - return pDataCol->dataOff[rows - 1] + varDataTLen(tdGetColDataOfRow(pDataCol, rows - 1)); - } else { - return TYPE_BYTES[pDataCol->type] * rows; - } -} -#endif typedef struct { col_id_t maxCols; // max number of columns col_id_t numOfCols; // Total number of cols @@ -479,7 +280,8 @@ void tdResetDataCols(SDataCols *pCols); int32_t tdInitDataCols(SDataCols *pCols, STSchema *pSchema); SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData); SDataCols *tdFreeDataCols(SDataCols *pCols); -int32_t tdMergeDataCols(SDataCols *target, SDataCols *source, int32_t rowsToMerge, int32_t *pOffset, bool update, TDRowVerT maxVer); +int32_t tdMergeDataCols(SDataCols *target, SDataCols *source, int32_t rowsToMerge, int32_t *pOffset, bool update, + TDRowVerT maxVer); // ----------------- K-V data row structure /* |<-------------------------------------- len -------------------------------------------->| @@ -542,54 +344,6 @@ static FORCE_INLINE void *tdGetKVRowIdxOfCol(SKVRow row, int16_t colId) { return taosbsearch(&colId, kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), comparTagId, TD_EQ); } -#if 0 -// offset here not include kvRow header length -static FORCE_INLINE int32_t tdAppendKvColVal(SKVRow row, const void *value, bool isCopyValData, int16_t colId, int8_t type, - int32_t offset) { - assert(value != NULL); - int32_t toffset = offset + TD_KV_ROW_HEAD_SIZE; - SColIdx *pColIdx = (SColIdx *)POINTER_SHIFT(row, toffset); - char * ptr = (char *)POINTER_SHIFT(row, kvRowLen(row)); - - pColIdx->colId = colId; - pColIdx->offset = kvRowLen(row); // offset of pColIdx including the TD_KV_ROW_HEAD_SIZE - - if (IS_VAR_DATA_TYPE(type)) { - if (isCopyValData) { - memcpy(ptr, value, varDataTLen(value)); - } - kvRowLen(row) += varDataTLen(value); - } else { - if (offset == 0) { - assert(type == TSDB_DATA_TYPE_TIMESTAMP); - TKEY tvalue = tdGetTKEY(*(TSKEY *)value); - memcpy(ptr, (void *)(&tvalue), TYPE_BYTES[type]); - } else { - memcpy(ptr, value, TYPE_BYTES[type]); - } - kvRowLen(row) += TYPE_BYTES[type]; - } - - return 0; -} -// NOTE: offset here including the header size -static FORCE_INLINE void *tdGetKvRowDataOfCol(void *row, int32_t offset) { return POINTER_SHIFT(row, offset); } - -static FORCE_INLINE void *tdGetKVRowValOfColEx(SKVRow row, int16_t colId, int32_t *nIdx) { - while (*nIdx < kvRowNCols(row)) { - SColIdx *pColIdx = kvRowColIdxAt(row, *nIdx); - if (pColIdx->colId == colId) { - ++(*nIdx); - return tdGetKvRowDataOfCol(row, pColIdx->offset); - } else if (pColIdx->colId > colId) { - return NULL; - } else { - ++(*nIdx); - } - } - return NULL; -} -#endif // ----------------- K-V data row builder typedef struct { int16_t tCols; @@ -632,166 +386,6 @@ static FORCE_INLINE int32_t tdAddColToKVRow(SKVRowBuilder *pBuilder, col_id_t co return 0; } -#if 0 -// ----------------- SMemRow appended with tuple row structure -/* - * |---------|------------------------------------------------- len ---------------------------------->| - * |<-------- Head ------>|<--------- flen -------------->| | - * |---------+---------------------+---------------------------------+---------------------------------+ - * | uint8_t | uint16_t | int16_t | | | - * |---------+----------+----------+---------------------------------+---------------------------------+ - * | flag | len | sversion | First part | Second part | - * +---------+----------+----------+---------------------------------+---------------------------------+ - * - * NOTE: timestamp in this row structure is TKEY instead of TSKEY - */ - -// ----------------- SMemRow appended with extended K-V data row structure -/* |--------------------|------------------------------------------------ len ---------------------------------->| - * |<------------- Head ------------>|<--------- flen -------------->| | - * |--------------------+----------+--------------------------------------------+---------------------------------+ - * | uint8_t | int16_t | uint16_t | int16_t | | | - * |---------+----------+----------+----------+---------------------------------+---------------------------------+ - * | flag | sversion | len | ncols | cols index | data part | - * |---------+----------+----------+----------+---------------------------------+---------------------------------+ - */ - -typedef void *SMemRow; - -#define TD_MEM_ROW_TYPE_SIZE sizeof(uint8_t) -#define TD_MEM_ROW_KV_VER_SIZE sizeof(int16_t) -#define TD_MEM_ROW_KV_TYPE_VER_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_MEM_ROW_KV_VER_SIZE) -#define TD_MEM_ROW_DATA_HEAD_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_DATA_ROW_HEAD_SIZE) -#define TD_MEM_ROW_KV_HEAD_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_MEM_ROW_KV_VER_SIZE + TD_KV_ROW_HEAD_SIZE) - -#define SMEM_ROW_DATA 0x0U // SDataRow -#define SMEM_ROW_KV 0x01U // SKVRow - -#define KVRatioConvert (0.9f) - -#define memRowType(r) ((*(uint8_t *)(r)) & 0x01) - -#define memRowSetType(r, t) ((*(uint8_t *)(r)) = (t)) // set the total byte in case of dirty memory -#define isDataRowT(t) (SMEM_ROW_DATA == (((uint8_t)(t)) & 0x01)) -#define isDataRow(r) (SMEM_ROW_DATA == memRowType(r)) -#define isKvRowT(t) (SMEM_ROW_KV == (((uint8_t)(t)) & 0x01)) -#define isKvRow(r) (SMEM_ROW_KV == memRowType(r)) -#define isUtilizeKVRow(k, d) ((k) < ((d)*KVRatioConvert)) - -#define memRowDataBody(r) POINTER_SHIFT(r, TD_MEM_ROW_TYPE_SIZE) // section after flag -#define memRowKvBody(r) \ - POINTER_SHIFT(r, TD_MEM_ROW_KV_TYPE_VER_SIZE) // section after flag + sversion as to reuse SKVRow - -#define memRowDataLen(r) (*(TDRowLenT *)memRowDataBody(r)) // 0~65535 -#define memRowKvLen(r) (*(TDRowLenT *)memRowKvBody(r)) // 0~65535 - -#define memRowDataTLen(r) \ - ((TDRowLenT)(memRowDataLen(r) + TD_MEM_ROW_TYPE_SIZE)) // using uint32_t/int32_t to store the TLen - -#define memRowKvTLen(r) ((TDRowLenT)(memRowKvLen(r) + TD_MEM_ROW_KV_TYPE_VER_SIZE)) - -#define memRowLen(r) (isDataRow(r) ? memRowDataLen(r) : memRowKvLen(r)) -#define memRowTLen(r) (isDataRow(r) ? memRowDataTLen(r) : memRowKvTLen(r)) // using uint32_t/int32_t to store the TLen - -static FORCE_INLINE char *memRowEnd(SMemRow row) { - if (isDataRow(row)) { - return (char *)dataRowEnd(memRowDataBody(row)); - } else { - return (char *)kvRowEnd(memRowKvBody(row)); - } -} - -#define memRowDataVersion(r) dataRowVersion(memRowDataBody(r)) -#define memRowKvVersion(r) (*(int16_t *)POINTER_SHIFT(r, TD_MEM_ROW_TYPE_SIZE)) -#define memRowVersion(r) (isDataRow(r) ? memRowDataVersion(r) : memRowKvVersion(r)) // schema version -#define memRowSetKvVersion(r, v) (memRowKvVersion(r) = (v)) -#define memRowTuple(r) (isDataRow(r) ? dataRowTuple(memRowDataBody(r)) : kvRowValues(memRowKvBody(r))) - -#define memRowTKey(r) (isDataRow(r) ? dataRowTKey(memRowDataBody(r)) : kvRowTKey(memRowKvBody(r))) -#define memRowKey(r) (isDataRow(r) ? dataRowKey(memRowDataBody(r)) : kvRowKey(memRowKvBody(r))) -#define memRowKeys(r) (isDataRow(r) ? dataRowTuple(memRowDataBody(r)) : kvRowKeys(memRowKvBody(r))) -#define memRowSetTKey(r, k) \ - do { \ - if (isDataRow(r)) { \ - dataRowTKey(memRowDataBody(r)) = (k); \ - } else { \ - kvRowTKey(memRowKvBody(r)) = (k); \ - } \ - } while (0) - -#define memRowSetLen(r, l) (isDataRow(r) ? memRowDataLen(r) = (l) : memRowKvLen(r) = (l)) -#define memRowSetVersion(r, v) (isDataRow(r) ? dataRowSetVersion(memRowDataBody(r), v) : memRowSetKvVersion(r, v)) -#define memRowCpy(dst, r) memcpy((dst), (r), memRowTLen(r)) -#define memRowMaxBytesFromSchema(s) (schemaTLen(s) + TD_MEM_ROW_DATA_HEAD_SIZE) -#define memRowDeleted(r) TKEY_IS_DELETED(memRowTKey(r)) - -SMemRow tdMemRowDup(SMemRow row); -void tdAppendMemRowToDataCol(SMemRow row, STSchema *pSchema, SDataCols *pCols, bool forceSetNull); - -// NOTE: offset here including the header size -static FORCE_INLINE void *tdGetMemRowDataOfCol(void *row, int16_t colId, int8_t colType, uint16_t offset) { - if (isDataRow(row)) { - return tdGetRowDataOfCol(memRowDataBody(row), colType, offset); - } else { - return tdGetKVRowValOfCol(memRowKvBody(row), colId); - } -} - -/** - * NOTE: - * 1. Applicable to scan columns one by one - * 2. offset here including the header size - */ -static FORCE_INLINE void *tdGetMemRowDataOfColEx(void *row, int16_t colId, int8_t colType, int32_t offset, - int32_t *kvNIdx) { - if (isDataRow(row)) { - return tdGetRowDataOfCol(memRowDataBody(row), colType, offset); - } else { - return tdGetKVRowValOfColEx(memRowKvBody(row), colId, kvNIdx); - } -} - -static FORCE_INLINE int32_t tdAppendMemRowColVal(SMemRow row, const void *value, bool isCopyVarData, int16_t colId, - int8_t type, int32_t offset) { - if (isDataRow(row)) { - tdAppendDataColVal(memRowDataBody(row), value, isCopyVarData, type, offset); - } else { - tdAppendKvColVal(memRowKvBody(row), value, isCopyVarData, colId, type, offset); - } - return 0; -} - -// make sure schema->flen appended for SDataRow -static FORCE_INLINE int32_t tdGetColAppendLen(uint8_t rowType, const void *value, int8_t colType) { - int32_t len = 0; - if (IS_VAR_DATA_TYPE(colType)) { - len += varDataTLen(value); - if (rowType == SMEM_ROW_KV) { - len += sizeof(SColIdx); - } - } else { - if (rowType == SMEM_ROW_KV) { - len += TYPE_BYTES[colType]; - len += sizeof(SColIdx); - } - } - return len; -} - -typedef struct { - int16_t colId; - uint8_t colType; - char * colVal; -} SColInfo; - -static FORCE_INLINE void setSColInfo(SColInfo *colInfo, int16_t colId, uint8_t colType, char *colVal) { - colInfo->colId = colId; - colInfo->colType = colType; - colInfo->colVal = colVal; -} - -SMemRow mergeTwoMemRows(void *buffer, SMemRow row1, SMemRow row2, STSchema *pSchema1, STSchema *pSchema2); -#endif #ifdef __cplusplus } diff --git a/include/common/trow.h b/include/common/trow.h index 0d34c6e49f..ebce0b085d 100644 --- a/include/common/trow.h +++ b/include/common/trow.h @@ -165,15 +165,15 @@ typedef struct { #define TD_ROW_HEAD_LEN (sizeof(STSRow)) #define TD_ROW_NCOLS_LEN (sizeof(col_id_t)) -#define TD_ROW_INFO(r) ((r)->info) -#define TD_ROW_TYPE(r) ((r)->type) -#define TD_ROW_DELETE(r) ((r)->del) -#define TD_ROW_ENDIAN(r) ((r)->endian) -#define TD_ROW_SVER(r) ((r)->sver) -#define TD_ROW_NCOLS(r) ((r)->data) // only valid for SKvRow -#define TD_ROW_DATA(r) ((r)->data) -#define TD_ROW_LEN(r) ((r)->len) -#define TD_ROW_KEY(r) ((r)->ts) +#define TD_ROW_INFO(r) ((r)->info) +#define TD_ROW_TYPE(r) ((r)->type) +#define TD_ROW_DELETE(r) ((r)->del) +#define TD_ROW_ENDIAN(r) ((r)->endian) +#define TD_ROW_SVER(r) ((r)->sver) +#define TD_ROW_NCOLS(r) ((r)->data) // only valid for SKvRow +#define TD_ROW_DATA(r) ((r)->data) +#define TD_ROW_LEN(r) ((r)->len) +#define TD_ROW_KEY(r) ((r)->ts) // #define TD_ROW_VER(r) ((r)->ver) #define TD_ROW_KEY_ADDR(r) (r) @@ -1410,64 +1410,6 @@ static void tdSRowPrint(STSRow *row, STSchema *pSchema, const char *tag) { } printf("\n"); } -#ifdef TROW_ORIGIN_HZ -typedef struct { - uint32_t nRows; - char rows[]; -} STSRowBatch; - -static void tdSRowPrint(STSRow *row) { - printf("type:%d, del:%d, sver:%d\n", row->type, row->del, row->sver); - printf("isDeleted:%s, isTpRow:%s, isKvRow:%s\n", TD_BOOL_STR(TD_ROW_IS_DELETED(row)), TD_BOOL_STR(TD_IS_TP_ROW(row)), - TD_BOOL_STR(TD_IS_KV_ROW(row))); -} - -typedef enum { - /// tuple row builder - TD_TP_ROW_BUILDER = 0, - /// kv row builder - TD_KV_ROW_BUILDER, - /// self-determined row builder - TD_SD_ROW_BUILDER -} ERowBbuilderT; - -typedef struct { - /// row builder type - ERowBbuilderT type; - /// buffer writer - SBufferWriter bw; - /// target row - STSRow *pRow; -} STSRowBuilder; - -typedef struct { - STSchema *pSchema; - STSRow *pRow; -} STSRowReader; - -typedef struct { - uint32_t it; - STSRowBatch *pRowBatch; -} STSRowBatchIter; - -// STSRowBuilder -#define trbInit(rt, allocator, endian, target, size) \ - { .type = (rt), .bw = tbufInitWriter(allocator, endian), .pRow = (target) } -void trbSetRowInfo(STSRowBuilder *pRB, bool del, uint16_t sver); -void trbSetRowVersion(STSRowBuilder *pRB, uint64_t ver); -void trbSetRowTS(STSRowBuilder *pRB, TSKEY ts); -int32_t trbWriteCol(STSRowBuilder *pRB, void *pData, col_id_t cid); - -// STSRowReader -#define tRowReaderInit(schema, row) \ - { .schema = (schema), .row = (row) } -int32_t tRowReaderRead(STSRowReader *pRowReader, col_id_t cid, void *target, uint64_t size); - -// STSRowBatchIter -#define tRowBatchIterInit(pRB) \ - { .it = 0, .pRowBatch = (pRB) } -const STSRow *tRowBatchIterNext(STSRowBatchIter *pRowBatchIter); -#endif #ifdef __cplusplus } diff --git a/source/common/src/tdata.c b/source/common/src/tdata.c new file mode 100644 index 0000000000..6dea4a4e57 --- /dev/null +++ b/source/common/src/tdata.c @@ -0,0 +1,14 @@ +/* + * 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 . + */ \ No newline at end of file diff --git a/source/common/src/tdataformat.c b/source/common/src/tdataformat.c index e659b9ec04..5d893fe398 100644 --- a/source/common/src/tdataformat.c +++ b/source/common/src/tdataformat.c @@ -129,50 +129,6 @@ void *tdDecodeSchema(void *buf, STSchema **pRSchema) { return buf; } -#if 0 -int32_t tEncodeSTColumn(SCoder *pEncoder, const STColumn *pCol) { - if (tEncodeI16(pEncoder, pCol->colId) < 0) return -1; - if (tEncodeI8(pEncoder, pCol->type) < 0) return -1; - if (tEncodeI8(pEncoder, pCol->sma) < 0) return -1; - if (tEncodeI32(pEncoder, pCol->bytes) < 0) return -1; - if (tEncodeI32(pEncoder, pCol->offset) < 0) return -1; - return pEncoder->pos; -} - -int32_t tDecodeSTColumn(SCoder *pDecoder, STColumn *pCol) { - if (tDecodeI16(pDecoder, &pCol->colId) < 0) return -1; - if (tDecodeI8(pDecoder, &pCol->type) < 0) return -1; - if (tDecodeI8(pDecoder, &pCol->sma) < 0) return -1; - if (tDecodeI32(pDecoder, &pCol->bytes) < 0) return -1; - if (tDecodeI32(pDecoder, &pCol->offset) < 0) return -1; - return 0; -} - -int32_t tEncodeSchema(SCoder *pEncoder, const STSchema *pSchema) { - if (tEncodeI32(pEncoder, pSchema->numOfCols) < 0) return -1; - if (tEncodeI16(pEncoder, pSchema->version) < 0) return -1; - if (tEncodeU16(pEncoder, pSchema->flen) < 0) return -1; - if (tEncodeI32(pEncoder, pSchema->vlen) < 0) return -1; - if (tEncodeI32(pEncoder, pSchema->tlen) < 0) return -1; - - for (int32_t i = 0; i < schemaNCols(pSchema); i++) { - const STColumn *pCol = schemaColAt(pSchema, i); - if (tEncodeSTColumn(pEncoder, pCol) < 0) return -1; - } - return 0; -} - -int32_t tDecodeSchema(SCoder *pDecoder, STSchema *pSchema) { - if (tDecodeI32(pDecoder, &pSchema->numOfCols) < 0) return -1; - if (tDecodeI16(pDecoder, &pSchema->version) < 0) return -1; - if (tDecodeU16(pDecoder, &pSchema->flen) < 0) return -1; - if (tDecodeI32(pDecoder, &pSchema->vlen) < 0) return -1; - if (tDecodeI32(pDecoder, &pSchema->tlen) < 0) return -1; - - return 0; -} -#endif - int tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) { if (pBuilder == NULL) return -1; @@ -260,49 +216,6 @@ STSchema *tdGetSchemaFromBuilder(STSchemaBuilder *pBuilder) { return pSchema; } -#if 0 -/** - * Initialize a data row - */ -void tdInitDataRow(SDataRow row, STSchema *pSchema) { - dataRowSetLen(row, TD_DATA_ROW_HEAD_SIZE + schemaFLen(pSchema)); - dataRowSetVersion(row, schemaVersion(pSchema)); -} - -SDataRow tdNewDataRowFromSchema(STSchema *pSchema) { - int32_t size = dataRowMaxBytesFromSchema(pSchema); - - SDataRow row = taosMemoryMalloc(size); - if (row == NULL) return NULL; - - tdInitDataRow(row, pSchema); - return row; -} - -/** - * Free the SDataRow object - */ -void tdFreeDataRow(SDataRow row) { - if (row) taosMemoryFree(row); -} - -SDataRow tdDataRowDup(SDataRow row) { - SDataRow trow = taosMemoryMalloc(dataRowLen(row)); - if (trow == NULL) return NULL; - - dataRowCpy(trow, row); - return trow; -} - -SMemRow tdMemRowDup(SMemRow row) { - SMemRow trow = taosMemoryMalloc(memRowTLen(row)); - if (trow == NULL) return NULL; - - memRowCpy(trow, row); - return trow; -} -#endif - void dataColInit(SDataCol *pDataCol, STColumn *pCol, int maxPoints) { pDataCol->type = colType(pCol); pDataCol->colId = colColId(pCol); @@ -312,39 +225,6 @@ void dataColInit(SDataCol *pDataCol, STColumn *pCol, int maxPoints) { pDataCol->len = 0; } -#if 0 -// value from timestamp should be TKEY here instead of TSKEY -int dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxPoints) { - ASSERT(pCol != NULL && value != NULL); - - if (isAllRowsNull(pCol)) { - if (isNull(value, pCol->type)) { - // all null value yet, just return - return 0; - } - - if (tdAllocMemForCol(pCol, maxPoints) < 0) return -1; - if (numOfRows > 0) { - // Find the first not null value, fill all previouse values as NULL - dataColSetNEleNull(pCol, numOfRows); - } - } - - if (IS_VAR_DATA_TYPE(pCol->type)) { - // set offset - pCol->dataOff[numOfRows] = pCol->len; - // Copy data - memcpy(POINTER_SHIFT(pCol->pData, pCol->len), value, varDataTLen(value)); - // Update the length - pCol->len += varDataTLen(value); - } else { - ASSERT(pCol->len == TYPE_BYTES[pCol->type] * numOfRows); - memcpy(POINTER_SHIFT(pCol->pData, pCol->len), value, pCol->bytes); - pCol->len += pCol->bytes; - } - return 0; -} -#endif static FORCE_INLINE const void *tdGetColDataOfRowUnsafe(SDataCol *pCol, int row) { if (IS_VAR_DATA_TYPE(pCol->type)) { return POINTER_SHIFT(pCol->pData, pCol->dataOff[row]); @@ -361,31 +241,6 @@ bool isNEleNull(SDataCol *pCol, int nEle) { return true; } -#if 0 -static FORCE_INLINE void dataColSetNullAt(SDataCol *pCol, int index) { - if (IS_VAR_DATA_TYPE(pCol->type)) { - pCol->dataOff[index] = pCol->len; - char *ptr = POINTER_SHIFT(pCol->pData, pCol->len); - setVardataNull(ptr, pCol->type); - pCol->len += varDataTLen(ptr); - } else { - setNull(POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * index), pCol->type, pCol->bytes); - pCol->len += TYPE_BYTES[pCol->type]; - } -} - -static void dataColSetNEleNull(SDataCol *pCol, int nEle, int8_t bitmapMode) { - if (IS_VAR_DATA_TYPE(pCol->type)) { - pCol->len = 0; - for (int i = 0; i < nEle; ++i) { - dataColSetNullAt(pCol, i); - } - } else { - setNullN(pCol->pData, pCol->type, pCol->bytes, nEle); - pCol->len = TYPE_BYTES[pCol->type] * nEle; - } -} -#endif void *dataColSetOffset(SDataCol *pCol, int nEle) { ASSERT(((pCol->type == TSDB_DATA_TYPE_BINARY) || (pCol->type == TSDB_DATA_TYPE_NCHAR))); @@ -483,42 +338,6 @@ SDataCols *tdFreeDataCols(SDataCols *pCols) { return NULL; } -#if 0 -SDataCols *tdDupDataCols(SDataCols *pDataCols, bool keepData) { - SDataCols *pRet = tdNewDataCols(pDataCols->maxCols, pDataCols->maxPoints); - if (pRet == NULL) return NULL; - - pRet->numOfCols = pDataCols->numOfCols; - pRet->sversion = pDataCols->sversion; - if (keepData) pRet->numOfRows = pDataCols->numOfRows; - - for (int i = 0; i < pDataCols->numOfCols; i++) { - pRet->cols[i].type = pDataCols->cols[i].type; - pRet->cols[i].bitmap = pDataCols->cols[i].bitmap; - pRet->cols[i].colId = pDataCols->cols[i].colId; - pRet->cols[i].bytes = pDataCols->cols[i].bytes; - pRet->cols[i].offset = pDataCols->cols[i].offset; - - if (keepData) { - if (pDataCols->cols[i].len > 0) { - if (tdAllocMemForCol(&pRet->cols[i], pRet->maxPoints) < 0) { - tdFreeDataCols(pRet); - return NULL; - } - pRet->cols[i].len = pDataCols->cols[i].len; - memcpy(pRet->cols[i].pData, pDataCols->cols[i].pData, pDataCols->cols[i].len); - if (IS_VAR_DATA_TYPE(pRet->cols[i].type)) { - int dataOffSize = sizeof(VarDataOffsetT) * pDataCols->maxPoints; - memcpy(pRet->cols[i].dataOff, pDataCols->cols[i].dataOff, dataOffSize); - } - } - } - } - - return pRet; -} -#endif - void tdResetDataCols(SDataCols *pCols) { if (pCols != NULL) { pCols->numOfRows = 0; @@ -528,180 +347,6 @@ void tdResetDataCols(SDataCols *pCols) { } } } -#if 0 -static void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols, bool forceSetNull) { - ASSERT(pCols->numOfRows == 0 || dataColsKeyLast(pCols) < dataRowKey(row)); - - int rcol = 0; - int dcol = 0; - - while (dcol < pCols->numOfCols) { - bool setCol = 0; - SDataCol *pDataCol = &(pCols->cols[dcol]); - if (rcol >= schemaNCols(pSchema)) { - dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints); - dcol++; - continue; - } - - STColumn *pRowCol = schemaColAt(pSchema, rcol); - if (pRowCol->colId == pDataCol->colId) { - void *value = tdGetRowDataOfCol(row, pRowCol->type, pRowCol->offset + TD_DATA_ROW_HEAD_SIZE); - if(!isNull(value, pDataCol->type)) setCol = 1; - dataColAppendVal(pDataCol, value, pCols->numOfRows, pCols->maxPoints); - dcol++; - rcol++; - } else if (pRowCol->colId < pDataCol->colId) { - rcol++; - } else { - if(forceSetNull || setCol) { - dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints); - } - dcol++; - } - } - pCols->numOfRows++; -} - -static void tdAppendKVRowToDataCol(SKVRow row, STSchema *pSchema, SDataCols *pCols, bool forceSetNull) { - ASSERT(pCols->numOfRows == 0 || dataColsKeyLast(pCols) < kvRowKey(row)); - - int rcol = 0; - int dcol = 0; - - int nRowCols = kvRowNCols(row); - - while (dcol < pCols->numOfCols) { - bool setCol = 0; - SDataCol *pDataCol = &(pCols->cols[dcol]); - if (rcol >= nRowCols || rcol >= schemaNCols(pSchema)) { - dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints); - ++dcol; - continue; - } - - SColIdx *colIdx = kvRowColIdxAt(row, rcol); - - if (colIdx->colId == pDataCol->colId) { - void *value = tdGetKvRowDataOfCol(row, colIdx->offset); - if(!isNull(value, pDataCol->type)) setCol = 1; - dataColAppendVal(pDataCol, value, pCols->numOfRows, pCols->maxPoints); - ++dcol; - ++rcol; - } else if (colIdx->colId < pDataCol->colId) { - ++rcol; - } else { - if(forceSetNull || setCol) { - dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints); - } - ++dcol; - } - } - pCols->numOfRows++; -} - -void tdAppendMemRowToDataCol(SMemRow row, STSchema *pSchema, SDataCols *pCols, bool forceSetNull) { - if (isDataRow(row)) { - tdAppendDataRowToDataCol(memRowDataBody(row), pSchema, pCols, forceSetNull); - } else if (isKvRow(row)) { - tdAppendKVRowToDataCol(memRowKvBody(row), pSchema, pCols, forceSetNull); - } else { - ASSERT(0); - } -} - -int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset, bool forceSetNull) { - ASSERT(rowsToMerge > 0 && rowsToMerge <= source->numOfRows); - ASSERT(target->numOfCols == source->numOfCols); - int offset = 0; - - if (pOffset == NULL) { - pOffset = &offset; - } - - SDataCols *pTarget = NULL; - - if ((target->numOfRows == 0) || (dataColsKeyLast(target) < dataColsKeyAtRow(source, *pOffset))) { // No overlap - ASSERT(target->numOfRows + rowsToMerge <= target->maxPoints); - for (int i = 0; i < rowsToMerge; i++) { - for (int j = 0; j < source->numOfCols; j++) { - if (source->cols[j].len > 0 || target->cols[j].len > 0) { - dataColAppendVal(target->cols + j, tdGetColDataOfRow(source->cols + j, i + (*pOffset)), target->numOfRows, - target->maxPoints); - } - } - target->numOfRows++; - } - (*pOffset) += rowsToMerge; - } else { - pTarget = tdDupDataCols(target, true); - if (pTarget == NULL) goto _err; - - int iter1 = 0; - tdMergeTwoDataCols(target, pTarget, &iter1, pTarget->numOfRows, source, pOffset, source->numOfRows, - pTarget->numOfRows + rowsToMerge, forceSetNull); - } - - tdFreeDataCols(pTarget); - return 0; - -_err: - tdFreeDataCols(pTarget); - return -1; -} - -// src2 data has more priority than src1 -static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, int limit1, SDataCols *src2, int *iter2, - int limit2, int tRows, bool forceSetNull) { - tdResetDataCols(target); - ASSERT(limit1 <= src1->numOfRows && limit2 <= src2->numOfRows); - - while (target->numOfRows < tRows) { - if (*iter1 >= limit1 && *iter2 >= limit2) break; - - TSKEY key1 = (*iter1 >= limit1) ? INT64_MAX : dataColsKeyAt(src1, *iter1); - TKEY tkey1 = (*iter1 >= limit1) ? TKEY_NULL : dataColsTKeyAt(src1, *iter1); - TSKEY key2 = (*iter2 >= limit2) ? INT64_MAX : dataColsKeyAt(src2, *iter2); - TKEY tkey2 = (*iter2 >= limit2) ? TKEY_NULL : dataColsTKeyAt(src2, *iter2); - - ASSERT(tkey1 == TKEY_NULL || (!TKEY_IS_DELETED(tkey1))); - - if (key1 < key2) { - for (int i = 0; i < src1->numOfCols; i++) { - ASSERT(target->cols[i].type == src1->cols[i].type); - if (src1->cols[i].len > 0 || target->cols[i].len > 0) { - dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src1->cols + i, *iter1), target->numOfRows, - target->maxPoints); - } - } - - target->numOfRows++; - (*iter1)++; - } else if (key1 >= key2) { - if ((key1 > key2) || (key1 == key2 && !TKEY_IS_DELETED(tkey2))) { - for (int i = 0; i < src2->numOfCols; i++) { - ASSERT(target->cols[i].type == src2->cols[i].type); - if (src2->cols[i].len > 0 && !isNull(src2->cols[i].pData, src2->cols[i].type)) { - dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src2->cols + i, *iter2), target->numOfRows, - target->maxPoints); - } else if(!forceSetNull && key1 == key2 && src1->cols[i].len > 0) { - dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src1->cols + i, *iter1), target->numOfRows, - target->maxPoints); - } else if(target->cols[i].len > 0) { - dataColSetNullAt(&target->cols[i], target->numOfRows); - } - } - target->numOfRows++; - } - - (*iter2)++; - if (key1 == key2) (*iter1)++; - } - - ASSERT(target->numOfRows <= target->maxPoints); - } -} -#endif SKVRow tdKVRowDup(SKVRow row) { SKVRow trow = taosMemoryMalloc(kvRowLen(row)); @@ -859,98 +504,3 @@ SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder) { return row; } -#if 0 -SMemRow mergeTwoMemRows(void *buffer, SMemRow row1, SMemRow row2, STSchema *pSchema1, STSchema *pSchema2) { -#if 0 - ASSERT(memRowKey(row1) == memRowKey(row2)); - ASSERT(schemaVersion(pSchema1) == memRowVersion(row1)); - ASSERT(schemaVersion(pSchema2) == memRowVersion(row2)); - ASSERT(schemaVersion(pSchema1) >= schemaVersion(pSchema2)); -#endif - - SArray *stashRow = taosArrayInit(pSchema1->numOfCols, sizeof(SColInfo)); - if (stashRow == NULL) { - return NULL; - } - - SMemRow pRow = buffer; - SDataRow dataRow = memRowDataBody(pRow); - memRowSetType(pRow, SMEM_ROW_DATA); - dataRowSetVersion(dataRow, schemaVersion(pSchema1)); // use latest schema version - dataRowSetLen(dataRow, (TDRowLenT)(TD_DATA_ROW_HEAD_SIZE + pSchema1->flen)); - - TDRowLenT dataLen = 0, kvLen = TD_MEM_ROW_KV_HEAD_SIZE; - - int32_t i = 0; // row1 - int32_t j = 0; // row2 - int32_t nCols1 = schemaNCols(pSchema1); - int32_t nCols2 = schemaNCols(pSchema2); - SColInfo colInfo = {0}; - int32_t kvIdx1 = 0, kvIdx2 = 0; - - while (i < nCols1) { - STColumn *pCol = schemaColAt(pSchema1, i); - void * val1 = tdGetMemRowDataOfColEx(row1, pCol->colId, pCol->type, TD_DATA_ROW_HEAD_SIZE + pCol->offset, &kvIdx1); - // if val1 != NULL, use val1; - if (val1 != NULL && !isNull(val1, pCol->type)) { - tdAppendColVal(dataRow, val1, pCol->type, pCol->offset); - kvLen += tdGetColAppendLen(SMEM_ROW_KV, val1, pCol->type); - setSColInfo(&colInfo, pCol->colId, pCol->type, val1); - taosArrayPush(stashRow, &colInfo); - ++i; // next col - continue; - } - - void *val2 = NULL; - while (j < nCols2) { - STColumn *tCol = schemaColAt(pSchema2, j); - if (tCol->colId < pCol->colId) { - ++j; - continue; - } - if (tCol->colId == pCol->colId) { - val2 = tdGetMemRowDataOfColEx(row2, tCol->colId, tCol->type, TD_DATA_ROW_HEAD_SIZE + tCol->offset, &kvIdx2); - } else if (tCol->colId > pCol->colId) { - // set NULL - } - break; - } // end of while(jtype); - } - tdAppendColVal(dataRow, val2, pCol->type, pCol->offset); - if (!isNull(val2, pCol->type)) { - kvLen += tdGetColAppendLen(SMEM_ROW_KV, val2, pCol->type); - setSColInfo(&colInfo, pCol->colId, pCol->type, val2); - taosArrayPush(stashRow, &colInfo); - } - - ++i; // next col - } - - dataLen = memRowTLen(pRow); - - if (kvLen < dataLen) { - // scan stashRow and generate SKVRow - memset(buffer, 0, sizeof(dataLen)); - SMemRow tRow = buffer; - memRowSetType(tRow, SMEM_ROW_KV); - SKVRow kvRow = (SKVRow)memRowKvBody(tRow); - int16_t nKvNCols = (int16_t) taosArrayGetSize(stashRow); - kvRowSetLen(kvRow, (TDRowLenT)(TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * nKvNCols)); - kvRowSetNCols(kvRow, nKvNCols); - memRowSetKvVersion(tRow, pSchema1->version); - - int32_t toffset = 0; - int16_t k; - for (k = 0; k < nKvNCols; ++k) { - SColInfo *pColInfo = taosArrayGet(stashRow, k); - tdAppendKvColVal(kvRow, pColInfo->colVal, true, pColInfo->colId, pColInfo->colType, toffset); - toffset += sizeof(SColIdx); - } - ASSERT(kvLen == memRowTLen(tRow)); - } - taosArrayDestroy(stashRow); - return buffer; -} -#endif diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit.c b/source/dnode/vnode/src/tsdb/tsdbCommit.c index 6c0df33d05..1315963090 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCommit.c +++ b/source/dnode/vnode/src/tsdb/tsdbCommit.c @@ -211,7 +211,7 @@ int tsdbCommit(STsdb *pRepo) { void tsdbGetRtnSnap(STsdb *pRepo, SRtn *pRtn) { STsdbKeepCfg *pCfg = REPO_KEEP_CFG(pRepo); - TSKEY minKey, midKey, maxKey, now; + TSKEY minKey, midKey, maxKey, now; now = taosGetTimestamp(pCfg->precision); minKey = now - pCfg->keep2 * tsTickPerDay[pCfg->precision]; @@ -1386,34 +1386,7 @@ static void tsdbLoadAndMergeFromCache(SDataCols *pDataCols, int *iter, SCommitIt tSkipListIterNext(pCommitIter->pIter); } else { -#if 0 - if (update != TD_ROW_OVERWRITE_UPDATE) { - // copy disk data - for (int i = 0; i < pDataCols->numOfCols; ++i) { - // TODO: dataColAppendVal may fail - SCellVal sVal = {0}; - if (tdGetColDataOfRow(&sVal, pDataCols->cols + i, *iter, pDataCols->bitmapMode) < 0) { - TASSERT(0); - } - tdAppendValToDataCol(pTarget->cols + i, sVal.valType, sVal.val, pTarget->numOfRows, pTarget->maxPoints, pTarget->bitmapMode); - } - - if (update == TD_ROW_DISCARD_UPDATE) pTarget->numOfRows++; - } - if (update != TD_ROW_DISCARD_UPDATE) { - // copy mem data - if (pSchema == NULL || schemaVersion(pSchema) != TD_ROW_SVER(row)) { - pSchema = tsdbGetTableSchemaImpl(pCommitIter->pTable, false, false, TD_ROW_SVER(row)); - ASSERT(pSchema != NULL); - } - - tdAppendSTSRowToDataCol(row, pSchema, pTarget, update == TD_ROW_OVERWRITE_UPDATE); - } - ++(*iter); - tSkipListIterNext(pCommitIter->pIter); -#endif - - if(lastKey != key1) { + if (lastKey != key1) { lastKey = key1; ++pTarget->numOfRows; } @@ -1484,29 +1457,4 @@ static bool tsdbCanAddSubBlock(SCommitH *pCommith, SBlock *pBlock, SMergeInfo *p } return false; -} - -// int tsdbApplyRtn(STsdbRepo *pRepo) { -// SRtn rtn; -// SFSIter fsiter; -// STsdbFS * pfs = REPO_FS(pRepo); -// SDFileSet *pSet; - -// // Get retention snapshot -// tsdbGetRtnSnap(pRepo, &rtn); - -// tsdbFSIterInit(&fsiter, pfs, TSDB_FS_ITER_FORWARD); -// while ((pSet = tsdbFSIterNext(&fsiter))) { -// if (pSet->fid < rtn.minFid) { -// tsdbInfo("vgId:%d FSET %d at level %d disk id %d expires, remove it", REPO_ID(pRepo), pSet->fid, -// TSDB_FSET_LEVEL(pSet), TSDB_FSET_ID(pSet)); -// continue; -// } - -// if (tsdbApplyRtnOnFSet(pRepo, pSet, &rtn) < 0) { -// return -1; -// } -// } - -// return 0; -// } +} \ No newline at end of file diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c index e9dc98d102..3168ff53f6 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMemTable2.c +++ b/source/dnode/vnode/src/tsdb/tsdbMemTable2.c @@ -21,6 +21,8 @@ typedef struct SMemSkipList SMemSkipList; typedef struct SMemSkipListNode SMemSkipListNode; typedef struct SMemSkipListCurosr SMemSkipListCurosr; +#define SL_MAX_LEVEL 5 + struct SMemTable { STsdb *pTsdb; TSKEY minKey; @@ -61,7 +63,7 @@ struct SMemData { struct SMemSkipListCurosr { SMemSkipList *pSl; - SMemSkipListNode *pNodeC; + SMemSkipListNode *pNodes[SL_MAX_LEVEL]; }; typedef struct { @@ -70,8 +72,6 @@ typedef struct { const STSRow *pRow; } STsdbRow; -#define SL_MAX_LEVEL 15 - #define HASH_BUCKET(SUID, UID, NBUCKET) (TABS((SUID) + (UID)) % (NBUCKET)) #define SL_NODE_SIZE(l) (sizeof(SMemSkipListNode) + sizeof(SMemSkipListNode *) * (l)*2) @@ -93,6 +93,8 @@ static void tsdbMemSkipListCursorDestroy(SMemSkipListCurosr *pSlc); static void tsdbMemSkipListCursorInit(SMemSkipListCurosr *pSlc, SMemSkipList *pSl); static void tsdbMemSkipListCursorPut(SMemSkipListCurosr *pSlc, SMemSkipListNode *pNode); static int32_t tsdbMemSkipListCursorMoveTo(SMemSkipListCurosr *pSlc, int64_t version, TSKEY ts, int32_t flags); +static void tsdbMemSkipListCursorMoveToFirst(SMemSkipListCurosr *pSlc); +static void tsdbMemSkipListCursorMoveToLast(SMemSkipListCurosr *pSlc); static int32_t tsdbMemSkipListCursorMoveToNext(SMemSkipListCurosr *pSlc); static int32_t tsdbMemSkipListCursorMoveToPrev(SMemSkipListCurosr *pSlc); static SMemSkipListNode *tsdbMemSkipListNodeCreate(SVBufPool *pPool, SMemSkipList *pSl, const STsdbRow *pTRow); @@ -326,14 +328,26 @@ static int32_t tsdbMemSkipListCursorMoveTo(SMemSkipListCurosr *pSlc, int64_t ver return 0; } -static int32_t tsdbMemSkipListCursorMoveToFirst(SMemSkipListCurosr *pSlc) { - // TODO - return 0; +static void tsdbMemSkipListCursorMoveToFirst(SMemSkipListCurosr *pSlc) { + SMemSkipList *pSl = pSlc->pSl; + SMemSkipListNode *pHead = SL_HEAD_NODE(pSl); + + for (int8_t iLevel = 0; iLevel < pSl->maxLevel; iLevel++) { + pSlc->pNodes[iLevel] = pHead; + } + + tsdbMemSkipListCursorMoveToNext(pSlc); } -static int32_t tsdbMemSkipListCursorMoveToLast(SMemSkipListCurosr *pSlc) { - // TODO - return 0; +static void tsdbMemSkipListCursorMoveToLast(SMemSkipListCurosr *pSlc) { + SMemSkipList *pSl = pSlc->pSl; + SMemSkipListNode *pTail = SL_TAIL_NODE(pSl); + + for (int8_t iLevel = 0; iLevel < pSl->maxLevel; iLevel++) { + pSlc->pNodes[iLevel] = pTail; + } + + tsdbMemSkipListCursorMoveToPrev(pSlc); } static int32_t tsdbMemSkipListCursorMoveToNext(SMemSkipListCurosr *pSlc) { From 76a9ef186efde3a66cd194abef6f558a1bd48bac Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Mon, 9 May 2022 13:10:16 +0000 Subject: [PATCH 7/8] refact row apis --- include/common/trow.h | 1159 ++------------------------------------ source/common/src/trow.c | 934 ++++++++++++++++++++++++++++++ 2 files changed, 975 insertions(+), 1118 deletions(-) diff --git a/include/common/trow.h b/include/common/trow.h index ebce0b085d..eed15689c0 100644 --- a/include/common/trow.h +++ b/include/common/trow.h @@ -95,8 +95,6 @@ static FORCE_INLINE bool tdValIsNull(TDRowValT valType, const void *val, int32_t #endif } -typedef void *SRow; - typedef struct { TDRowValT valType; void *val; @@ -228,24 +226,19 @@ static FORCE_INLINE void *tdKVRowColVal(STSRow *pRow, SKvRowIdx *pIdx) { return void tdMergeBitmap(uint8_t *srcBitmap, int32_t nBits, uint8_t *dstBitmap); static FORCE_INLINE void tdRowCopy(void *dst, STSRow *row) { memcpy(dst, row, TD_ROW_LEN(row)); } -static FORCE_INLINE int32_t tdSetBitmapValTypeI(void *pBitmap, int16_t colIdx, TDRowValT valType); static FORCE_INLINE int32_t tdSetBitmapValTypeII(void *pBitmap, int16_t colIdx, TDRowValT valType); static FORCE_INLINE int32_t tdSetBitmapValType(void *pBitmap, int16_t colIdx, TDRowValT valType, int8_t bitmapMode); int32_t tdSetBitmapValTypeN(void *pBitmap, int16_t nEle, TDRowValT valType, int8_t bitmapMode); -static FORCE_INLINE int32_t tdGetBitmapValTypeI(const void *pBitmap, int16_t colIdx, TDRowValT *pValType); -static FORCE_INLINE int32_t tdGetBitmapValTypeII(const void *pBitmap, int16_t colIdx, TDRowValT *pValType); static FORCE_INLINE int32_t tdGetBitmapValType(const void *pBitmap, int16_t colIdx, TDRowValT *pValType, int8_t bitmapMode); -static FORCE_INLINE bool tdIsBitmapValTypeNorm(const void *pBitmap, int16_t idx, int8_t bitmapMode); bool tdIsBitmapBlkNorm(const void *pBitmap, int32_t numOfBits, int8_t bitmapMode); int32_t tdAppendValToDataCol(SDataCol *pCol, TDRowValT valType, const void *val, int32_t numOfRows, int32_t maxPoints, int8_t bitmapMode, bool isMerge); -static FORCE_INLINE int32_t tdAppendColValToTpRow(SRowBuilder *pBuilder, TDRowValT valType, const void *val, - bool isCopyVarData, int8_t colType, int16_t colIdx, int32_t offset); -static FORCE_INLINE int32_t tdAppendColValToKvRow(SRowBuilder *pBuilder, TDRowValT valType, const void *val, - bool isCopyVarData, int8_t colType, int16_t colIdx, int32_t offset, - col_id_t colId); -int32_t tdAppendSTSRowToDataCol(STSRow *pRow, STSchema *pSchema, SDataCols *pCols, bool isMerge); +int32_t tdAppendSTSRowToDataCol(STSRow *pRow, STSchema *pSchema, SDataCols *pCols, bool isMerge); + +int32_t tdGetBitmapValTypeII(const void *pBitmap, int16_t colIdx, TDRowValT *pValType); +int32_t tdSetBitmapValTypeI(void *pBitmap, int16_t colIdx, TDRowValT valType); +int32_t tdGetBitmapValTypeI(const void *pBitmap, int16_t colIdx, TDRowValT *pValType); /** * @brief @@ -264,257 +257,11 @@ static FORCE_INLINE void *tdGetBitmapAddrKv(STSRow *pRow, col_id_t nKvCols) { // The primary TS key is stored separatedly and is Norm value, thus should minus 1 firstly return POINTER_SHIFT(TD_ROW_COL_IDX(pRow), (--nKvCols) * sizeof(SKvRowIdx)); } -static FORCE_INLINE void *tdGetBitmapAddr(STSRow *pRow, uint8_t rowType, uint32_t flen, col_id_t nKvCols) { -#ifdef TD_SUPPORT_BITMAP - switch (rowType) { - case TD_ROW_TP: - return tdGetBitmapAddrTp(pRow, flen); - case TD_ROW_KV: - return tdGetBitmapAddrKv(pRow, nKvCols); - default: - break; - } -#endif - return NULL; -} - -static FORCE_INLINE int32_t tdSetBitmapValType(void *pBitmap, int16_t colIdx, TDRowValT valType, int8_t bitmapMode) { - switch (bitmapMode) { - case 0: - tdSetBitmapValTypeII(pBitmap, colIdx, valType); - break; - case -1: - case 1: - tdSetBitmapValTypeI(pBitmap, colIdx, valType); - break; - default: - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return TSDB_CODE_FAILED; - } - return TSDB_CODE_SUCCESS; -} - -/** - * @brief Use 2 bits at default - * - * @param pBitmap - * @param colIdx The relative index of colId, may have minus value as parameter. - * @param valType - * @return FORCE_INLINE - */ -static FORCE_INLINE int32_t tdSetBitmapValTypeII(void *pBitmap, int16_t colIdx, TDRowValT valType) { - if (!pBitmap || colIdx < 0) { - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - int16_t nBytes = colIdx / TD_VTYPE_PARTS; - int16_t nOffset = colIdx & TD_VTYPE_OPTR; - char *pDestByte = (char *)POINTER_SHIFT(pBitmap, nBytes); - // use literal value directly and not use formula to simplify the codes - switch (nOffset) { - case 0: - *pDestByte = ((*pDestByte) & 0x3F) | (valType << 6); - // set the value and clear other partitions for offset 0 - // *pDestByte |= (valType << 6); - break; - case 1: - *pDestByte = ((*pDestByte) & 0xCF) | (valType << 4); - // *pDestByte |= (valType << 4); - break; - case 2: - *pDestByte = ((*pDestByte) & 0xF3) | (valType << 2); - // *pDestByte |= (valType << 2); - break; - case 3: - *pDestByte = ((*pDestByte) & 0xFC) | valType; - // *pDestByte |= (valType); - break; - default: - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - return TSDB_CODE_SUCCESS; -} - -static FORCE_INLINE bool tdIsBitmapValTypeNorm(const void *pBitmap, int16_t idx, int8_t bitmapMode) { - TDRowValT valType = 0; - tdGetBitmapValType(pBitmap, idx, &valType, bitmapMode); - if (tdValTypeIsNorm(valType)) { - return true; - } - return false; -} - -static FORCE_INLINE int32_t tdGetBitmapValType(const void *pBitmap, int16_t colIdx, TDRowValT *pValType, - int8_t bitmapMode) { - switch (bitmapMode) { - case 0: - tdGetBitmapValTypeII(pBitmap, colIdx, pValType); - break; - case -1: - case 1: - tdGetBitmapValTypeI(pBitmap, colIdx, pValType); - break; - default: - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return TSDB_CODE_FAILED; - } - return TSDB_CODE_SUCCESS; -} - -/** - * @brief Use 2 bits at default - * - * @param pBitmap - * @param colIdx The relative index of colId, may have minus value as parameter. - * @param pValType - * @return FORCE_INLINE - */ -static FORCE_INLINE int32_t tdGetBitmapValTypeII(const void *pBitmap, int16_t colIdx, TDRowValT *pValType) { - if (!pBitmap || colIdx < 0) { - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - int16_t nBytes = colIdx / TD_VTYPE_PARTS; - int16_t nOffset = colIdx & TD_VTYPE_OPTR; - char *pDestByte = (char *)POINTER_SHIFT(pBitmap, nBytes); - // use literal value directly and not use formula to simplify the codes - switch (nOffset) { - case 0: - *pValType = (((*pDestByte) & 0xC0) >> 6); - break; - case 1: - *pValType = (((*pDestByte) & 0x30) >> 4); - break; - case 2: - *pValType = (((*pDestByte) & 0x0C) >> 2); - break; - case 3: - *pValType = ((*pDestByte) & 0x03); - break; - default: - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - return TSDB_CODE_SUCCESS; -} - -/** - * @brief - * - * @param pBitmap - * @param colIdx The relative index of colId, may have minus value as parameter. - * @param valType - * @return FORCE_INLINE - */ -static FORCE_INLINE int32_t tdSetBitmapValTypeI(void *pBitmap, int16_t colIdx, TDRowValT valType) { - if (!pBitmap || colIdx < 0) { - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - int16_t nBytes = colIdx / TD_VTYPE_PARTS_I; - int16_t nOffset = colIdx & TD_VTYPE_OPTR_I; - char *pDestByte = (char *)POINTER_SHIFT(pBitmap, nBytes); - // use literal value directly and not use formula to simplify the codes - switch (nOffset) { - case 0: - *pDestByte = ((*pDestByte) & 0x7F) | (valType << 7); - // set the value and clear other partitions for offset 0 - // *pDestByte |= (valType << 7); - break; - case 1: - *pDestByte = ((*pDestByte) & 0xBF) | (valType << 6); - // *pDestByte |= (valType << 6); - break; - case 2: - *pDestByte = ((*pDestByte) & 0xDF) | (valType << 5); - // *pDestByte |= (valType << 5); - break; - case 3: - *pDestByte = ((*pDestByte) & 0xEF) | (valType << 4); - // *pDestByte |= (valType << 4); - break; - case 4: - *pDestByte = ((*pDestByte) & 0xF7) | (valType << 3); - // *pDestByte |= (valType << 3); - break; - case 5: - *pDestByte = ((*pDestByte) & 0xFB) | (valType << 2); - // *pDestByte |= (valType << 2); - break; - case 6: - *pDestByte = ((*pDestByte) & 0xFD) | (valType << 1); - // *pDestByte |= (valType << 1); - break; - case 7: - *pDestByte = ((*pDestByte) & 0xFE) | valType; - // *pDestByte |= (valType); - break; - default: - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - return TSDB_CODE_SUCCESS; -} - -/** - * @brief - * - * @param pBitmap - * @param colIdx The relative index of colId, may have minus value as parameter. - * @param pValType - * @return FORCE_INLINE - */ -static FORCE_INLINE int32_t tdGetBitmapValTypeI(const void *pBitmap, int16_t colIdx, TDRowValT *pValType) { - if (!pBitmap || colIdx < 0) { - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - int16_t nBytes = colIdx / TD_VTYPE_PARTS_I; - int16_t nOffset = colIdx & TD_VTYPE_OPTR_I; - char *pDestByte = (char *)POINTER_SHIFT(pBitmap, nBytes); - // use literal value directly and not use formula to simplify the codes - switch (nOffset) { - case 0: - *pValType = (((*pDestByte) & 0x80) >> 7); - break; - case 1: - *pValType = (((*pDestByte) & 0x40) >> 6); - break; - case 2: - *pValType = (((*pDestByte) & 0x20) >> 5); - break; - case 3: - *pValType = (((*pDestByte) & 0x10) >> 4); - break; - case 4: - *pValType = (((*pDestByte) & 0x08) >> 3); - break; - case 5: - *pValType = (((*pDestByte) & 0x04) >> 2); - break; - case 6: - *pValType = (((*pDestByte) & 0x02) >> 1); - break; - case 7: - *pValType = ((*pDestByte) & 0x01); - break; - default: - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - return TSDB_CODE_SUCCESS; -} +void *tdGetBitmapAddr(STSRow *pRow, uint8_t rowType, uint32_t flen, col_id_t nKvCols); +int32_t tdSetBitmapValType(void *pBitmap, int16_t colIdx, TDRowValT valType, int8_t bitmapMode); +int32_t tdSetBitmapValTypeII(void *pBitmap, int16_t colIdx, TDRowValT valType); +bool tdIsBitmapValTypeNorm(const void *pBitmap, int16_t idx, int8_t bitmapMode); +int32_t tdGetBitmapValType(const void *pBitmap, int16_t colIdx, TDRowValT *pValType, int8_t bitmapMode); // ----------------- Tuple row structure(STpRow) /* @@ -539,482 +286,28 @@ static FORCE_INLINE int32_t tdGetBitmapValTypeI(const void *pBitmap, int16_t col * */ -/** - * @brief - * - * @param pBuilder - * @param sver schema version - * @return FORCE_INLINE - */ static FORCE_INLINE void tdSRowInit(SRowBuilder *pBuilder, int16_t sver) { pBuilder->rowType = TD_ROW_TP; // default STpRow pBuilder->sver = sver; } - -/** - * @brief Not recommended to use - * - * @param pBuilder - * @param rowType - * @return FORCE_INLINE - */ -static FORCE_INLINE void tdSRowSetRowType(SRowBuilder *pBuilder, int8_t rowType) { pBuilder->rowType = rowType; } - -/** - * @brief - * - * @param pBuilder - * @param nCols - * @param nBoundCols use -1 if not available - * @param flen - * @return FORCE_INLINE - */ -static FORCE_INLINE int32_t tdSRowSetInfo(SRowBuilder *pBuilder, int32_t nCols, int32_t nBoundCols, int32_t flen) { - pBuilder->flen = flen; - pBuilder->nCols = nCols; - pBuilder->nBoundCols = nBoundCols; - if (pBuilder->flen <= 0 || pBuilder->nCols <= 0) { - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } -#ifdef TD_SUPPORT_BITMAP - // the primary TS key is stored separatedly - pBuilder->nBitmaps = (int16_t)TD_BITMAP_BYTES(pBuilder->nCols - 1); - if (nBoundCols > 0) { - pBuilder->nBoundBitmaps = (int16_t)TD_BITMAP_BYTES(pBuilder->nBoundCols - 1); - } else { - pBuilder->nBoundBitmaps = 0; - } -#else - pBuilder->nBitmaps = 0; - pBuilder->nBoundBitmaps = 0; -#endif - return TSDB_CODE_SUCCESS; -} - -/** - * @brief - * - * @param pBuilder - * @param nCols - * @param nBoundCols use -1 if not available - * @param flen - * @return FORCE_INLINE - */ -static FORCE_INLINE int32_t tdSRowSetTpInfo(SRowBuilder *pBuilder, int32_t nCols, int32_t flen) { - pBuilder->flen = flen; - pBuilder->nCols = nCols; - if (pBuilder->flen <= 0 || pBuilder->nCols <= 0) { - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } -#ifdef TD_SUPPORT_BITMAP - // the primary TS key is stored separatedly - pBuilder->nBitmaps = (int16_t)TD_BITMAP_BYTES(pBuilder->nCols - 1); -#else - pBuilder->nBitmaps = 0; - pBuilder->nBoundBitmaps = 0; -#endif - return TSDB_CODE_SUCCESS; -} - -/** - * @brief To judge row type: STpRow/SKvRow - * - * @param pBuilder - * @param nCols - * @param nBoundCols - * @param flen - * @param allNullLen use -1 if not available - * @param boundNullLen use -1 if not available - * @return FORCE_INLINE - */ -static FORCE_INLINE int32_t tdSRowSetExtendedInfo(SRowBuilder *pBuilder, int32_t nCols, int32_t nBoundCols, - int32_t flen, int32_t allNullLen, int32_t boundNullLen) { - if ((boundNullLen > 0) && (allNullLen > 0) && (nBoundCols > 0)) { - uint32_t tpLen = allNullLen; - uint32_t kvLen = sizeof(col_id_t) + sizeof(SKvRowIdx) * nBoundCols + boundNullLen; - if (isSelectKVRow(kvLen, tpLen)) { - pBuilder->rowType = TD_ROW_KV; - } else { - pBuilder->rowType = TD_ROW_TP; - } - - } else { - pBuilder->rowType = TD_ROW_TP; - } - - pBuilder->flen = flen; - pBuilder->nCols = nCols; - pBuilder->nBoundCols = nBoundCols; - if (pBuilder->flen <= 0 || pBuilder->nCols <= 0) { - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } -#ifdef TD_SUPPORT_BITMAP - // the primary TS key is stored separatedly - pBuilder->nBitmaps = (col_id_t)TD_BITMAP_BYTES(pBuilder->nCols - 1); - if (nBoundCols > 0) { - pBuilder->nBoundBitmaps = (col_id_t)TD_BITMAP_BYTES(pBuilder->nBoundCols - 1); - } else { - pBuilder->nBoundBitmaps = 0; - } -#else - pBuilder->nBitmaps = 0; - pBuilder->nBoundBitmaps = 0; -#endif - return TSDB_CODE_SUCCESS; -} - -/** - * @brief The invoker is responsible for memory alloc/dealloc. - * - * @param pBuilder - * @param pBuf Output buffer of STSRow - */ -static int32_t tdSRowResetBuf(SRowBuilder *pBuilder, void *pBuf) { - pBuilder->pBuf = (STSRow *)pBuf; - if (!pBuilder->pBuf) { - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - - TD_ROW_SET_INFO(pBuilder->pBuf, 0); - TD_ROW_SET_TYPE(pBuilder->pBuf, pBuilder->rowType); - - TASSERT(pBuilder->nBitmaps > 0 && pBuilder->flen > 0); - - uint32_t len = 0; - switch (pBuilder->rowType) { - case TD_ROW_TP: -#ifdef TD_SUPPORT_BITMAP - pBuilder->pBitmap = tdGetBitmapAddrTp(pBuilder->pBuf, pBuilder->flen); - memset(pBuilder->pBitmap, TD_VTYPE_NONE_BYTE_II, pBuilder->nBitmaps); -#endif - // the primary TS key is stored separatedly - len = TD_ROW_HEAD_LEN + pBuilder->flen - sizeof(TSKEY) + pBuilder->nBitmaps; - TD_ROW_SET_LEN(pBuilder->pBuf, len); - TD_ROW_SET_SVER(pBuilder->pBuf, pBuilder->sver); - break; - case TD_ROW_KV: -#ifdef TD_SUPPORT_BITMAP - pBuilder->pBitmap = tdGetBitmapAddrKv(pBuilder->pBuf, pBuilder->nBoundCols); - memset(pBuilder->pBitmap, TD_VTYPE_NONE_BYTE_II, pBuilder->nBoundBitmaps); -#endif - len = TD_ROW_HEAD_LEN + TD_ROW_NCOLS_LEN + (pBuilder->nBoundCols - 1) * sizeof(SKvRowIdx) + - pBuilder->nBoundBitmaps; // add - TD_ROW_SET_LEN(pBuilder->pBuf, len); - TD_ROW_SET_SVER(pBuilder->pBuf, pBuilder->sver); - TD_ROW_SET_NCOLS(pBuilder->pBuf, pBuilder->nBoundCols); - break; - default: - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - - return TSDB_CODE_SUCCESS; -} - -/** - * @brief The invoker is responsible for memory alloc/dealloc. - * - * @param pBuilder - * @param pBuf Output buffer of STSRow - */ -static int32_t tdSRowGetBuf(SRowBuilder *pBuilder, void *pBuf) { - pBuilder->pBuf = (STSRow *)pBuf; - if (!pBuilder->pBuf) { - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - - TASSERT(pBuilder->nBitmaps > 0 && pBuilder->flen > 0); - - uint32_t len = 0; - switch (pBuilder->rowType) { - case TD_ROW_TP: -#ifdef TD_SUPPORT_BITMAP - pBuilder->pBitmap = tdGetBitmapAddrTp(pBuilder->pBuf, pBuilder->flen); -#endif - break; - case TD_ROW_KV: -#ifdef TD_SUPPORT_BITMAP - pBuilder->pBitmap = tdGetBitmapAddrKv(pBuilder->pBuf, pBuilder->nBoundCols); -#endif - break; - default: - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - return TSDB_CODE_SUCCESS; -} - -/** - * @brief 由调用方管理存储空间的分配及释放,一次输入多个参数 - * - * @param pBuilder - * @param pBuf - * @param allNullLen - * @param boundNullLen - * @param nCols - * @param nBoundCols - * @param flen - * @return FORCE_INLINE - */ -static FORCE_INLINE int32_t tdSRowInitEx(SRowBuilder *pBuilder, void *pBuf, uint32_t allNullLen, uint32_t boundNullLen, - int32_t nCols, int32_t nBoundCols, int32_t flen) { - if (tdSRowSetExtendedInfo(pBuilder, allNullLen, boundNullLen, nCols, nBoundCols, flen) < 0) { - return terrno; - } - return tdSRowResetBuf(pBuilder, pBuf); -} - -/** - * @brief - * - * @param pBuilder - */ -static FORCE_INLINE void tdSRowReset(SRowBuilder *pBuilder) { - pBuilder->rowType = TD_ROW_TP; - pBuilder->pBuf = NULL; - pBuilder->nBoundCols = -1; - pBuilder->nCols = -1; - pBuilder->flen = -1; - pBuilder->pBitmap = NULL; -} - -// internal func -static FORCE_INLINE int32_t tdAppendColValToTpRow(SRowBuilder *pBuilder, TDRowValT valType, const void *val, - bool isCopyVarData, int8_t colType, int16_t colIdx, int32_t offset) { - if ((offset < (int32_t)sizeof(TSKEY)) || (colIdx < 1)) { - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - offset -= sizeof(TSKEY); - --colIdx; - -#ifdef TD_SUPPORT_BITMAP - if (tdSetBitmapValType(pBuilder->pBitmap, colIdx, valType, 0) != TSDB_CODE_SUCCESS) { - return terrno; - } -#endif - - STSRow *row = pBuilder->pBuf; - - // 1. No need to set flen part for Null/None, just use bitmap. When upsert for the same primary TS key, the bitmap - // should be updated simultaneously if Norm val overwrite Null/None cols. - // 2. When consume STSRow in memory by taos client/tq, the output of Null/None cols should both be Null. - if (tdValIsNorm(valType, val, colType)) { - // TODO: The layout of new data types imported since 3.0 like blob/medium blob is the same with binary/nchar. - if (IS_VAR_DATA_TYPE(colType)) { - // ts key stored in STSRow.ts - *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(row), offset) = TD_ROW_LEN(row); - if (isCopyVarData) { - memcpy(POINTER_SHIFT(row, TD_ROW_LEN(row)), val, varDataTLen(val)); - } - TD_ROW_LEN(row) += varDataTLen(val); - } else { - memcpy(POINTER_SHIFT(TD_ROW_DATA(row), offset), val, TYPE_BYTES[colType]); - } - } -#ifdef TD_SUPPORT_BACK2 - // NULL/None value - else { - // TODO: Null value for new data types imported since 3.0 need to be defined. - const void *nullVal = getNullValue(colType); - if (IS_VAR_DATA_TYPE(colType)) { - // ts key stored in STSRow.ts - *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(row), offset) = TD_ROW_LEN(row); - - if (isCopyVarData) { - memcpy(POINTER_SHIFT(row, TD_ROW_LEN(row)), nullVal, varDataTLen(nullVal)); - } - TD_ROW_LEN(row) += varDataTLen(nullVal); - } else { - memcpy(POINTER_SHIFT(TD_ROW_DATA(row), offset), nullVal, TYPE_BYTES[colType]); - } - } -#endif - - return 0; -} - -// internal func -static FORCE_INLINE int32_t tdAppendColValToKvRow(SRowBuilder *pBuilder, TDRowValT valType, const void *val, - bool isCopyVarData, int8_t colType, int16_t colIdx, int32_t offset, - col_id_t colId) { - if ((offset < (int32_t)sizeof(SKvRowIdx)) || (colIdx < 1)) { - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; - } - offset -= sizeof(SKvRowIdx); - --colIdx; - -#ifdef TD_SUPPORT_BITMAP - if (tdSetBitmapValType(pBuilder->pBitmap, colIdx, valType, 0) != TSDB_CODE_SUCCESS) { - return terrno; - } -#endif - - STSRow *row = pBuilder->pBuf; - // No need to store None/Null values. - if (tdValIsNorm(valType, val, colType)) { - // ts key stored in STSRow.ts - SKvRowIdx *pColIdx = (SKvRowIdx *)POINTER_SHIFT(TD_ROW_COL_IDX(row), offset); - char *ptr = (char *)POINTER_SHIFT(row, TD_ROW_LEN(row)); - pColIdx->colId = colId; - pColIdx->offset = TD_ROW_LEN(row); // the offset include the TD_ROW_HEAD_LEN - - if (IS_VAR_DATA_TYPE(colType)) { - if (isCopyVarData) { - memcpy(ptr, val, varDataTLen(val)); - } - TD_ROW_LEN(row) += varDataTLen(val); - } else { - memcpy(ptr, val, TYPE_BYTES[colType]); - TD_ROW_LEN(row) += TYPE_BYTES[colType]; - } - } -#ifdef TD_SUPPORT_BACK2 - // NULL/None value - else { - SKvRowIdx *pColIdx = (SKvRowIdx *)POINTER_SHIFT(TD_ROW_COL_IDX(row), offset); - char *ptr = (char *)POINTER_SHIFT(row, TD_ROW_LEN(row)); - pColIdx->colId = colId; - pColIdx->offset = TD_ROW_LEN(row); // the offset include the TD_ROW_HEAD_LEN - const void *nullVal = getNullValue(colType); - - if (IS_VAR_DATA_TYPE(colType)) { - if (isCopyVarData) { - memcpy(ptr, nullVal, varDataTLen(nullVal)); - } - TD_ROW_LEN(row) += varDataTLen(nullVal); - } else { - memcpy(ptr, nullVal, TYPE_BYTES[colType]); - TD_ROW_LEN(row) += TYPE_BYTES[colType]; - } - } -#endif - - return 0; -} - -/** - * @brief exposed func - * - * @param pBuilder - * @param colId start from PRIMARYKEY_TIMESTAMP_COL_ID - * @param colType - * @param valType - * @param val - * @param isCopyVarData - * @param offset - * @param colIdx sorted column index, start from 0 - * @return FORCE_INLINE - */ -static FORCE_INLINE int32_t tdAppendColValToRow(SRowBuilder *pBuilder, col_id_t colId, int8_t colType, - TDRowValT valType, const void *val, bool isCopyVarData, int32_t offset, - col_id_t colIdx) { - STSRow *pRow = pBuilder->pBuf; - if (!val) { -#ifdef TD_SUPPORT_BITMAP - if (tdValTypeIsNorm(valType)) { - terrno = TSDB_CODE_INVALID_PTR; - return terrno; - } -#else - TASSERT(0); - terrno = TSDB_CODE_INVALID_PARA; - return terrno; -#endif - } - // TS KEY is stored in STSRow.ts and not included in STSRow.data field. - if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) { - TD_ROW_KEY(pRow) = *(TSKEY *)val; - // The primary TS key is Norm all the time, thus its valType is not stored in bitmap. - return TSDB_CODE_SUCCESS; - } - // TODO: We can avoid the type judegement by FP, but would prevent the inline scheme. - if (TD_IS_TP_ROW(pRow)) { - tdAppendColValToTpRow(pBuilder, valType, val, isCopyVarData, colType, colIdx, offset); - } else { - tdAppendColValToKvRow(pBuilder, valType, val, isCopyVarData, colType, colIdx, offset, colId); - } - return TSDB_CODE_SUCCESS; -} - -// internal -static FORCE_INLINE int32_t tdGetTpRowValOfCol(SCellVal *output, STSRow *pRow, void *pBitmap, int8_t colType, - int32_t offset, int16_t colIdx) { -#ifdef TD_SUPPORT_BITMAP - if (tdGetBitmapValType(pBitmap, colIdx, &output->valType, 0) != TSDB_CODE_SUCCESS) { - output->valType = TD_VTYPE_NONE; - return terrno; - } - if (tdValTypeIsNorm(output->valType)) { - if (IS_VAR_DATA_TYPE(colType)) { - output->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset)); - } else { - output->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset); - } - } -#else - if (IS_VAR_DATA_TYPE(colType)) { - output->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset)); - } else { - output->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset); - } - output->valType = isNull(output->val, colType) ? TD_VTYPE_NULL : TD_VTYPE_NORM; -#endif - return TSDB_CODE_SUCCESS; -} - -static FORCE_INLINE int32_t compareKvRowColId(const void *key1, const void *key2) { - if (*(int16_t *)key1 > ((SColIdx *)key2)->colId) { - return 1; - } else if (*(int16_t *)key1 < ((SColIdx *)key2)->colId) { - return -1; - } else { - return 0; - } -} -// internal -static FORCE_INLINE int32_t tdGetKvRowValOfCol(SCellVal *output, STSRow *pRow, void *pBitmap, int32_t offset, - int16_t colIdx) { -#ifdef TD_SUPPORT_BITMAP - TASSERT(colIdx < tdRowGetNCols(pRow) - 1); - if (tdGetBitmapValType(pBitmap, colIdx, &output->valType, 0) != TSDB_CODE_SUCCESS) { - output->valType = TD_VTYPE_NONE; - return terrno; - } - if (tdValTypeIsNorm(output->valType)) { - if (offset < 0) { - terrno = TSDB_CODE_INVALID_PARA; - output->valType = TD_VTYPE_NONE; - return terrno; - } - output->val = POINTER_SHIFT(pRow, offset); - } -#else - TASSERT(0); - if (offset < 0) { - terrno = TSDB_CODE_INVALID_PARA; - output->valType = TD_VTYPE_NONE; - return terrno; - } - output->val = POINTER_SHIFT(pRow, offset); - output->valType = isNull(output->val, colType) ? TD_VTYPE_NULL : TD_VTYPE_NORM; -#endif - return TSDB_CODE_SUCCESS; -} +int32_t tdSRowSetInfo(SRowBuilder *pBuilder, int32_t nCols, int32_t nBoundCols, int32_t flen); +int32_t tdSRowSetTpInfo(SRowBuilder *pBuilder, int32_t nCols, int32_t flen); +int32_t tdSRowSetExtendedInfo(SRowBuilder *pBuilder, int32_t nCols, int32_t nBoundCols, int32_t flen, + int32_t allNullLen, int32_t boundNullLen); +int32_t tdSRowResetBuf(SRowBuilder *pBuilder, void *pBuf); +int32_t tdSRowGetBuf(SRowBuilder *pBuilder, void *pBuf); +int32_t tdSRowInitEx(SRowBuilder *pBuilder, void *pBuf, uint32_t allNullLen, uint32_t boundNullLen, int32_t nCols, + int32_t nBoundCols, int32_t flen); +void tdSRowReset(SRowBuilder *pBuilder); +int32_t tdAppendColValToTpRow(SRowBuilder *pBuilder, TDRowValT valType, const void *val, bool isCopyVarData, + int8_t colType, int16_t colIdx, int32_t offset); +int32_t tdAppendColValToKvRow(SRowBuilder *pBuilder, TDRowValT valType, const void *val, bool isCopyVarData, + int8_t colType, int16_t colIdx, int32_t offset, col_id_t colId); +int32_t tdAppendColValToRow(SRowBuilder *pBuilder, col_id_t colId, int8_t colType, TDRowValT valType, const void *val, + bool isCopyVarData, int32_t offset, col_id_t colIdx); +int32_t tdGetTpRowValOfCol(SCellVal *output, STSRow *pRow, void *pBitmap, int8_t colType, int32_t offset, + int16_t colIdx); +int32_t tdGetKvRowValOfCol(SCellVal *output, STSRow *pRow, void *pBitmap, int32_t offset, int16_t colIdx); typedef struct { STSchema *pSchema; @@ -1026,390 +319,20 @@ typedef struct { col_id_t kvIdx; // [0, nKvCols) } STSRowIter; -static FORCE_INLINE void tdSTSRowIterReset(STSRowIter *pIter, STSRow *pRow) { - pIter->pRow = pRow; - pIter->pBitmap = tdGetBitmapAddr(pRow, pRow->type, pIter->pSchema->flen, tdRowGetNCols(pRow)); - pIter->offset = 0; - pIter->colIdx = PRIMARYKEY_TIMESTAMP_COL_ID; - pIter->kvIdx = 0; -} - -static FORCE_INLINE void tdSTSRowIterInit(STSRowIter *pIter, STSchema *pSchema) { - pIter->pSchema = pSchema; - pIter->maxColId = pSchema->columns[pSchema->numOfCols - 1].colId; -} - -static int32_t tdCompareColId(const void *arg1, const void *arg2) { - int32_t colId = *(int32_t *)arg1; - STColumn *pCol = (STColumn *)arg2; - - if (colId < pCol->colId) { - return -1; - } else if (colId == pCol->colId) { - return 0; - } else { - return 1; - } -} - -/** - * @brief STSRow method to get value of specified colId/colType by bsearch - * - * @param pIter - * @param colId Start from PRIMARYKEY_TIMESTAMP_COL_ID(1) - * @param colType - * @param pVal - * @return true Not reach end and pVal is set(None/Null/Norm). - * @return false Reach end and pVal not set. - */ -static FORCE_INLINE bool tdSTSRowGetVal(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal) { - if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) { - pVal->val = &pIter->pRow->ts; - pVal->valType = TD_VTYPE_NORM; - return true; - } - - STSRow *pRow = pIter->pRow; - int16_t colIdx = -1; - if (TD_IS_TP_ROW(pRow)) { - STSchema *pSchema = pIter->pSchema; - STColumn *pCol = - (STColumn *)taosbsearch(&colId, pSchema->columns, pSchema->numOfCols, sizeof(STColumn), tdCompareColId, TD_EQ); - if (!pCol) { - pVal->valType = TD_VTYPE_NONE; - if (COL_REACH_END(colId, pIter->maxColId)) return false; - return true; - } -#ifdef TD_SUPPORT_BITMAP - colIdx = POINTER_DISTANCE(pCol, pSchema->columns) / sizeof(STColumn); -#endif - tdGetTpRowValOfCol(pVal, pRow, pIter->pBitmap, pCol->type, pCol->offset - sizeof(TSKEY), colIdx - 1); - } else if (TD_IS_KV_ROW(pRow)) { - SKvRowIdx *pIdx = (SKvRowIdx *)taosbsearch(&colId, TD_ROW_COL_IDX(pRow), tdRowGetNCols(pRow), sizeof(SKvRowIdx), - compareKvRowColId, TD_EQ); -#ifdef TD_SUPPORT_BITMAP - if (pIdx) { - colIdx = POINTER_DISTANCE(TD_ROW_COL_IDX(pRow), pIdx) / sizeof(SKvRowIdx); - } -#endif - tdGetKvRowValOfCol(pVal, pRow, pIter->pBitmap, pIdx ? pIdx->offset : -1, colIdx); - } else { - if (COL_REACH_END(colId, pIter->maxColId)) return false; - pVal->valType = TD_VTYPE_NONE; - } - - return true; -} - -// internal -static FORCE_INLINE bool tdGetTpRowDataOfCol(STSRowIter *pIter, col_type_t colType, int32_t offset, SCellVal *pVal) { - STSRow *pRow = pIter->pRow; - if (IS_VAR_DATA_TYPE(colType)) { - pVal->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset)); - } else { - pVal->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset); - } - -#ifdef TD_SUPPORT_BITMAP - if (tdGetBitmapValType(pIter->pBitmap, pIter->colIdx - 1, &pVal->valType, 0) != TSDB_CODE_SUCCESS) { - pVal->valType = TD_VTYPE_NONE; - } -#else - pVal->valType = isNull(pVal->val, colType) ? TD_VTYPE_NULL : TD_VTYPE_NORM; -#endif - - return true; -} - -// internal -static FORCE_INLINE bool tdGetKvRowValOfColEx(STSRowIter *pIter, col_id_t colId, col_type_t colType, col_id_t *nIdx, - SCellVal *pVal) { - STSRow *pRow = pIter->pRow; - SKvRowIdx *pKvIdx = NULL; - bool colFound = false; - col_id_t kvNCols = tdRowGetNCols(pRow) - 1; - while (*nIdx < kvNCols) { - pKvIdx = (SKvRowIdx *)POINTER_SHIFT(TD_ROW_COL_IDX(pRow), *nIdx * sizeof(SKvRowIdx)); - if (pKvIdx->colId == colId) { - ++(*nIdx); - pVal->val = POINTER_SHIFT(pRow, pKvIdx->offset); - colFound = true; - break; - } else if (pKvIdx->colId > colId) { - pVal->valType = TD_VTYPE_NONE; - return true; - } else { - ++(*nIdx); - } - } - - if (!colFound) { - if (colId <= pIter->maxColId) { - pVal->valType = TD_VTYPE_NONE; - return true; - } else { - return false; - } - } - -#ifdef TD_SUPPORT_BITMAP - int16_t colIdx = -1; - if (pKvIdx) colIdx = POINTER_DISTANCE(TD_ROW_COL_IDX(pRow), pKvIdx) / sizeof(SKvRowIdx); - if (tdGetBitmapValType(pIter->pBitmap, colIdx, &pVal->valType, 0) != TSDB_CODE_SUCCESS) { - pVal->valType = TD_VTYPE_NONE; - } -#else - pVal->valType = isNull(pVal->val, colType) ? TD_VTYPE_NULL : TD_VTYPE_NORM; -#endif - - return true; -} - -/** - * @brief STSRow Iter to get value from colId 1 to maxColId ascendingly - * - * @param pIter - * @param pVal - * @param colId - * @param colType - * @param pVal output - * @return true Not reach end and pVal is set(None/Null/Norm). - * @return false Reach end of row and pVal not set. - */ -static FORCE_INLINE bool tdSTSRowIterNext(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal) { - if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) { - pVal->val = &pIter->pRow->ts; - pVal->valType = TD_VTYPE_NORM; - return true; - } - - if (TD_IS_TP_ROW(pIter->pRow)) { - STColumn *pCol = NULL; - STSchema *pSchema = pIter->pSchema; - while (pIter->colIdx < pSchema->numOfCols) { - pCol = &pSchema->columns[pIter->colIdx]; // 1st column of schema is primary TS key - if (colId == pCol->colId) { - break; - } else if (pCol->colId < colId) { - ++pIter->colIdx; - continue; - } else { - return false; - } - } - tdGetTpRowDataOfCol(pIter, pCol->type, pCol->offset - sizeof(TSKEY), pVal); - ++pIter->colIdx; - } else if (TD_IS_KV_ROW(pIter->pRow)) { - return tdGetKvRowValOfColEx(pIter, colId, colType, &pIter->kvIdx, pVal); - } else { - pVal->valType = TD_VTYPE_NONE; - terrno = TSDB_CODE_INVALID_PARA; - if (COL_REACH_END(colId, pIter->maxColId)) return false; - } - return true; -} - +void tdSTSRowIterReset(STSRowIter *pIter, STSRow *pRow); +void tdSTSRowIterInit(STSRowIter *pIter, STSchema *pSchema); +bool tdSTSRowGetVal(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal); +bool tdGetTpRowDataOfCol(STSRowIter *pIter, col_type_t colType, int32_t offset, SCellVal *pVal); +bool tdGetKvRowValOfColEx(STSRowIter *pIter, col_id_t colId, col_type_t colType, col_id_t *nIdx, SCellVal *pVal); +bool tdSTSRowIterNext(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal); STSRow *mergeTwoRows(void *buffer, STSRow *row1, STSRow *row2, STSchema *pSchema1, STSchema *pSchema2); - -// Get the data pointer from a column-wised data -static FORCE_INLINE int32_t tdGetColDataOfRow(SCellVal *pVal, SDataCol *pCol, int32_t row, int8_t bitmapMode) { - if (isAllRowsNone(pCol)) { - pVal->valType = TD_VTYPE_NULL; -#ifdef TD_SUPPORT_READ2 - pVal->val = (void *)getNullValue(pCol->type); -#else - pVal->val = NULL; -#endif - return TSDB_CODE_SUCCESS; - } - - if (TD_COL_ROWS_NORM(pCol)) { - pVal->valType = TD_VTYPE_NORM; - } else if (tdGetBitmapValType(pCol->pBitmap, row, &(pVal->valType), bitmapMode) < 0) { - return terrno; - } - - if (tdValTypeIsNorm(pVal->valType)) { - if (IS_VAR_DATA_TYPE(pCol->type)) { - pVal->val = POINTER_SHIFT(pCol->pData, pCol->dataOff[row]); - } else { - pVal->val = POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * row); - } - } else { - pVal->valType = TD_VTYPE_NULL; -#ifdef TD_SUPPORT_READ2 - pVal->val = (void *)getNullValue(pCol->type); -#else - pVal->val = NULL; -#endif - } - return TSDB_CODE_SUCCESS; -} - -/** - * @brief - * - * @param pRow - * @param colId - * @param colType - * @param flen - * @param offset - * @param colIdx start from 0 - * @param pVal - * @return FORCE_INLINE - */ -static FORCE_INLINE bool tdSTpRowGetVal(STSRow *pRow, col_id_t colId, col_type_t colType, int32_t flen, uint32_t offset, - col_id_t colIdx, SCellVal *pVal) { - if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) { - tdRowSetVal(pVal, TD_VTYPE_NORM, TD_ROW_KEY_ADDR(pRow)); - return true; - } - void *pBitmap = tdGetBitmapAddrTp(pRow, flen); - tdGetTpRowValOfCol(pVal, pRow, pBitmap, colType, offset - sizeof(TSKEY), colIdx); - return true; -} - -/** - * @brief - * - * @param pRow - * @param colId - * @param offset - * @param colIdx start from 0 - * @param pVal - * @return FORCE_INLINE - */ -static FORCE_INLINE bool tdSKvRowGetVal(STSRow *pRow, col_id_t colId, uint32_t offset, col_id_t colIdx, - SCellVal *pVal) { - if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) { - tdRowSetVal(pVal, TD_VTYPE_NORM, TD_ROW_KEY_ADDR(pRow)); - return true; - } - void *pBitmap = tdGetBitmapAddrKv(pRow, tdRowGetNCols(pRow)); - tdGetKvRowValOfCol(pVal, pRow, pBitmap, offset, colIdx); - return true; -} - -static FORCE_INLINE int32_t dataColGetNEleLen(SDataCol *pDataCol, int32_t rows, int8_t bitmapMode) { - ASSERT(rows > 0); - int32_t result = 0; - - if (IS_VAR_DATA_TYPE(pDataCol->type)) { - result += pDataCol->dataOff[rows - 1]; - SCellVal val = {0}; - if (tdGetColDataOfRow(&val, pDataCol, rows - 1, bitmapMode) < 0) { - TASSERT(0); - } - - // Currently, count the varDataTLen in of Null/None cols considering back compatibility test for 2.4 - result += varDataTLen(val.val); - // TODO: later on, don't save Null/None for VarDataT for 3.0 - // if (tdValTypeIsNorm(val.valType)) { - // result += varDataTLen(val.val); - // } - } else { - result += TYPE_BYTES[pDataCol->type] * rows; - } - - ASSERT(pDataCol->len == result); - - return result; -} - -static void tdSCellValPrint(SCellVal *pVal, int8_t colType) { - if (tdValTypeIsNull(pVal->valType)) { - printf("NULL "); - return; - } else if (tdValTypeIsNone(pVal->valType)) { - printf("NONE "); - return; - } - switch (colType) { - case TSDB_DATA_TYPE_BOOL: - printf("%s ", (*(int8_t *)pVal->val) == 0 ? "false" : "true"); - break; - case TSDB_DATA_TYPE_TINYINT: - printf("%" PRIi8 " ", *(int8_t *)pVal->val); - break; - case TSDB_DATA_TYPE_SMALLINT: - printf("%" PRIi16 " ", *(int16_t *)pVal->val); - break; - case TSDB_DATA_TYPE_INT: - printf("%" PRIi32 " ", *(int32_t *)pVal->val); - break; - case TSDB_DATA_TYPE_BIGINT: - printf("%" PRIi64 " ", *(int64_t *)pVal->val); - break; - case TSDB_DATA_TYPE_FLOAT: - printf("%f ", *(float *)pVal->val); - break; - case TSDB_DATA_TYPE_DOUBLE: - printf("%lf ", *(double *)pVal->val); - break; - case TSDB_DATA_TYPE_VARCHAR: - printf("VARCHAR "); - break; - case TSDB_DATA_TYPE_TIMESTAMP: - printf("%" PRIi64 " ", *(int64_t *)pVal->val); - break; - case TSDB_DATA_TYPE_NCHAR: - printf("NCHAR "); - break; - case TSDB_DATA_TYPE_UTINYINT: - printf("%" PRIu8 " ", *(uint8_t *)pVal->val); - break; - case TSDB_DATA_TYPE_USMALLINT: - printf("%" PRIu16 " ", *(uint16_t *)pVal->val); - break; - case TSDB_DATA_TYPE_UINT: - printf("%" PRIu32 " ", *(uint32_t *)pVal->val); - break; - case TSDB_DATA_TYPE_UBIGINT: - printf("%" PRIu64 " ", *(uint64_t *)pVal->val); - break; - case TSDB_DATA_TYPE_JSON: - printf("JSON "); - break; - case TSDB_DATA_TYPE_VARBINARY: - printf("VARBIN "); - break; - case TSDB_DATA_TYPE_DECIMAL: - printf("DECIMAL "); - break; - case TSDB_DATA_TYPE_BLOB: - printf("BLOB "); - break; - case TSDB_DATA_TYPE_MEDIUMBLOB: - printf("MedBLOB "); - break; - // case TSDB_DATA_TYPE_BINARY: - // printf("BINARY "); - // break; - case TSDB_DATA_TYPE_MAX: - printf("UNDEF "); - break; - default: - printf("UNDEF "); - break; - } -} - -static void tdSRowPrint(STSRow *row, STSchema *pSchema, const char *tag) { - STSRowIter iter = {0}; - tdSTSRowIterInit(&iter, pSchema); - tdSTSRowIterReset(&iter, row); - printf("%s >>>", tag); - for (int i = 0; i < pSchema->numOfCols; ++i) { - STColumn *stCol = pSchema->columns + i; - SCellVal sVal = {255, NULL}; - if (!tdSTSRowIterNext(&iter, stCol->colId, stCol->type, &sVal)) { - break; - } - ASSERT(sVal.valType == 0 || sVal.valType == 1 || sVal.valType == 2); - tdSCellValPrint(&sVal, stCol->type); - } - printf("\n"); -} +int32_t tdGetColDataOfRow(SCellVal *pVal, SDataCol *pCol, int32_t row, int8_t bitmapMode); +bool tdSTpRowGetVal(STSRow *pRow, col_id_t colId, col_type_t colType, int32_t flen, uint32_t offset, col_id_t colIdx, + SCellVal *pVal); +bool tdSKvRowGetVal(STSRow *pRow, col_id_t colId, uint32_t offset, col_id_t colIdx, SCellVal *pVal); +int32_t dataColGetNEleLen(SDataCol *pDataCol, int32_t rows, int8_t bitmapMode); +void tdSCellValPrint(SCellVal *pVal, int8_t colType); +void tdSRowPrint(STSRow *row, STSchema *pSchema, const char *tag); #ifdef __cplusplus } diff --git a/source/common/src/trow.c b/source/common/src/trow.c index 50e51a40dd..44bcd72a33 100644 --- a/source/common/src/trow.c +++ b/source/common/src/trow.c @@ -33,6 +33,7 @@ const uint8_t tdVTypeByte[2][3] = {{ // declaration static uint8_t tdGetBitmapByte(uint8_t byte); +static int32_t tdCompareColId(const void *arg1, const void *arg2); // static void dataColSetNEleNull(SDataCol *pCol, int nEle); @@ -916,4 +917,937 @@ SDataCols *tdDupDataCols(SDataCols *pDataCols, bool keepData) { } return pRet; +} + +void tdSRowPrint(STSRow *row, STSchema *pSchema, const char *tag) { + STSRowIter iter = {0}; + tdSTSRowIterInit(&iter, pSchema); + tdSTSRowIterReset(&iter, row); + printf("%s >>>", tag); + for (int i = 0; i < pSchema->numOfCols; ++i) { + STColumn *stCol = pSchema->columns + i; + SCellVal sVal = {255, NULL}; + if (!tdSTSRowIterNext(&iter, stCol->colId, stCol->type, &sVal)) { + break; + } + ASSERT(sVal.valType == 0 || sVal.valType == 1 || sVal.valType == 2); + tdSCellValPrint(&sVal, stCol->type); + } + printf("\n"); +} + +void tdSCellValPrint(SCellVal *pVal, int8_t colType) { + if (tdValTypeIsNull(pVal->valType)) { + printf("NULL "); + return; + } else if (tdValTypeIsNone(pVal->valType)) { + printf("NONE "); + return; + } + switch (colType) { + case TSDB_DATA_TYPE_BOOL: + printf("%s ", (*(int8_t *)pVal->val) == 0 ? "false" : "true"); + break; + case TSDB_DATA_TYPE_TINYINT: + printf("%" PRIi8 " ", *(int8_t *)pVal->val); + break; + case TSDB_DATA_TYPE_SMALLINT: + printf("%" PRIi16 " ", *(int16_t *)pVal->val); + break; + case TSDB_DATA_TYPE_INT: + printf("%" PRIi32 " ", *(int32_t *)pVal->val); + break; + case TSDB_DATA_TYPE_BIGINT: + printf("%" PRIi64 " ", *(int64_t *)pVal->val); + break; + case TSDB_DATA_TYPE_FLOAT: + printf("%f ", *(float *)pVal->val); + break; + case TSDB_DATA_TYPE_DOUBLE: + printf("%lf ", *(double *)pVal->val); + break; + case TSDB_DATA_TYPE_VARCHAR: + printf("VARCHAR "); + break; + case TSDB_DATA_TYPE_TIMESTAMP: + printf("%" PRIi64 " ", *(int64_t *)pVal->val); + break; + case TSDB_DATA_TYPE_NCHAR: + printf("NCHAR "); + break; + case TSDB_DATA_TYPE_UTINYINT: + printf("%" PRIu8 " ", *(uint8_t *)pVal->val); + break; + case TSDB_DATA_TYPE_USMALLINT: + printf("%" PRIu16 " ", *(uint16_t *)pVal->val); + break; + case TSDB_DATA_TYPE_UINT: + printf("%" PRIu32 " ", *(uint32_t *)pVal->val); + break; + case TSDB_DATA_TYPE_UBIGINT: + printf("%" PRIu64 " ", *(uint64_t *)pVal->val); + break; + case TSDB_DATA_TYPE_JSON: + printf("JSON "); + break; + case TSDB_DATA_TYPE_VARBINARY: + printf("VARBIN "); + break; + case TSDB_DATA_TYPE_DECIMAL: + printf("DECIMAL "); + break; + case TSDB_DATA_TYPE_BLOB: + printf("BLOB "); + break; + case TSDB_DATA_TYPE_MEDIUMBLOB: + printf("MedBLOB "); + break; + // case TSDB_DATA_TYPE_BINARY: + // printf("BINARY "); + // break; + case TSDB_DATA_TYPE_MAX: + printf("UNDEF "); + break; + default: + printf("UNDEF "); + break; + } +} + +int32_t dataColGetNEleLen(SDataCol *pDataCol, int32_t rows, int8_t bitmapMode) { + ASSERT(rows > 0); + int32_t result = 0; + + if (IS_VAR_DATA_TYPE(pDataCol->type)) { + result += pDataCol->dataOff[rows - 1]; + SCellVal val = {0}; + if (tdGetColDataOfRow(&val, pDataCol, rows - 1, bitmapMode) < 0) { + TASSERT(0); + } + + // Currently, count the varDataTLen in of Null/None cols considering back compatibility test for 2.4 + result += varDataTLen(val.val); + // TODO: later on, don't save Null/None for VarDataT for 3.0 + // if (tdValTypeIsNorm(val.valType)) { + // result += varDataTLen(val.val); + // } + } else { + result += TYPE_BYTES[pDataCol->type] * rows; + } + + ASSERT(pDataCol->len == result); + + return result; +} + +bool tdSKvRowGetVal(STSRow *pRow, col_id_t colId, uint32_t offset, col_id_t colIdx, SCellVal *pVal) { + if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) { + tdRowSetVal(pVal, TD_VTYPE_NORM, TD_ROW_KEY_ADDR(pRow)); + return true; + } + void *pBitmap = tdGetBitmapAddrKv(pRow, tdRowGetNCols(pRow)); + tdGetKvRowValOfCol(pVal, pRow, pBitmap, offset, colIdx); + return true; +} + +bool tdSTpRowGetVal(STSRow *pRow, col_id_t colId, col_type_t colType, int32_t flen, uint32_t offset, col_id_t colIdx, + SCellVal *pVal) { + if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) { + tdRowSetVal(pVal, TD_VTYPE_NORM, TD_ROW_KEY_ADDR(pRow)); + return true; + } + void *pBitmap = tdGetBitmapAddrTp(pRow, flen); + tdGetTpRowValOfCol(pVal, pRow, pBitmap, colType, offset - sizeof(TSKEY), colIdx); + return true; +} + +int32_t tdGetColDataOfRow(SCellVal *pVal, SDataCol *pCol, int32_t row, int8_t bitmapMode) { + if (isAllRowsNone(pCol)) { + pVal->valType = TD_VTYPE_NULL; +#ifdef TD_SUPPORT_READ2 + pVal->val = (void *)getNullValue(pCol->type); +#else + pVal->val = NULL; +#endif + return TSDB_CODE_SUCCESS; + } + + if (TD_COL_ROWS_NORM(pCol)) { + pVal->valType = TD_VTYPE_NORM; + } else if (tdGetBitmapValType(pCol->pBitmap, row, &(pVal->valType), bitmapMode) < 0) { + return terrno; + } + + if (tdValTypeIsNorm(pVal->valType)) { + if (IS_VAR_DATA_TYPE(pCol->type)) { + pVal->val = POINTER_SHIFT(pCol->pData, pCol->dataOff[row]); + } else { + pVal->val = POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * row); + } + } else { + pVal->valType = TD_VTYPE_NULL; +#ifdef TD_SUPPORT_READ2 + pVal->val = (void *)getNullValue(pCol->type); +#else + pVal->val = NULL; +#endif + } + return TSDB_CODE_SUCCESS; +} + +bool tdSTSRowIterNext(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal) { + if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) { + pVal->val = &pIter->pRow->ts; + pVal->valType = TD_VTYPE_NORM; + return true; + } + + if (TD_IS_TP_ROW(pIter->pRow)) { + STColumn *pCol = NULL; + STSchema *pSchema = pIter->pSchema; + while (pIter->colIdx < pSchema->numOfCols) { + pCol = &pSchema->columns[pIter->colIdx]; // 1st column of schema is primary TS key + if (colId == pCol->colId) { + break; + } else if (pCol->colId < colId) { + ++pIter->colIdx; + continue; + } else { + return false; + } + } + tdGetTpRowDataOfCol(pIter, pCol->type, pCol->offset - sizeof(TSKEY), pVal); + ++pIter->colIdx; + } else if (TD_IS_KV_ROW(pIter->pRow)) { + return tdGetKvRowValOfColEx(pIter, colId, colType, &pIter->kvIdx, pVal); + } else { + pVal->valType = TD_VTYPE_NONE; + terrno = TSDB_CODE_INVALID_PARA; + if (COL_REACH_END(colId, pIter->maxColId)) return false; + } + return true; +} + +bool tdGetKvRowValOfColEx(STSRowIter *pIter, col_id_t colId, col_type_t colType, col_id_t *nIdx, SCellVal *pVal) { + STSRow *pRow = pIter->pRow; + SKvRowIdx *pKvIdx = NULL; + bool colFound = false; + col_id_t kvNCols = tdRowGetNCols(pRow) - 1; + while (*nIdx < kvNCols) { + pKvIdx = (SKvRowIdx *)POINTER_SHIFT(TD_ROW_COL_IDX(pRow), *nIdx * sizeof(SKvRowIdx)); + if (pKvIdx->colId == colId) { + ++(*nIdx); + pVal->val = POINTER_SHIFT(pRow, pKvIdx->offset); + colFound = true; + break; + } else if (pKvIdx->colId > colId) { + pVal->valType = TD_VTYPE_NONE; + return true; + } else { + ++(*nIdx); + } + } + + if (!colFound) { + if (colId <= pIter->maxColId) { + pVal->valType = TD_VTYPE_NONE; + return true; + } else { + return false; + } + } + +#ifdef TD_SUPPORT_BITMAP + int16_t colIdx = -1; + if (pKvIdx) colIdx = POINTER_DISTANCE(TD_ROW_COL_IDX(pRow), pKvIdx) / sizeof(SKvRowIdx); + if (tdGetBitmapValType(pIter->pBitmap, colIdx, &pVal->valType, 0) != TSDB_CODE_SUCCESS) { + pVal->valType = TD_VTYPE_NONE; + } +#else + pVal->valType = isNull(pVal->val, colType) ? TD_VTYPE_NULL : TD_VTYPE_NORM; +#endif + + return true; +} + +bool tdGetTpRowDataOfCol(STSRowIter *pIter, col_type_t colType, int32_t offset, SCellVal *pVal) { + STSRow *pRow = pIter->pRow; + if (IS_VAR_DATA_TYPE(colType)) { + pVal->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset)); + } else { + pVal->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset); + } + +#ifdef TD_SUPPORT_BITMAP + if (tdGetBitmapValType(pIter->pBitmap, pIter->colIdx - 1, &pVal->valType, 0) != TSDB_CODE_SUCCESS) { + pVal->valType = TD_VTYPE_NONE; + } +#else + pVal->valType = isNull(pVal->val, colType) ? TD_VTYPE_NULL : TD_VTYPE_NORM; +#endif + + return true; +} + +static FORCE_INLINE int32_t compareKvRowColId(const void *key1, const void *key2) { + if (*(int16_t *)key1 > ((SColIdx *)key2)->colId) { + return 1; + } else if (*(int16_t *)key1 < ((SColIdx *)key2)->colId) { + return -1; + } else { + return 0; + } +} + +bool tdSTSRowGetVal(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCellVal *pVal) { + if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) { + pVal->val = &pIter->pRow->ts; + pVal->valType = TD_VTYPE_NORM; + return true; + } + + STSRow *pRow = pIter->pRow; + int16_t colIdx = -1; + if (TD_IS_TP_ROW(pRow)) { + STSchema *pSchema = pIter->pSchema; + STColumn *pCol = + (STColumn *)taosbsearch(&colId, pSchema->columns, pSchema->numOfCols, sizeof(STColumn), tdCompareColId, TD_EQ); + if (!pCol) { + pVal->valType = TD_VTYPE_NONE; + if (COL_REACH_END(colId, pIter->maxColId)) return false; + return true; + } +#ifdef TD_SUPPORT_BITMAP + colIdx = POINTER_DISTANCE(pCol, pSchema->columns) / sizeof(STColumn); +#endif + tdGetTpRowValOfCol(pVal, pRow, pIter->pBitmap, pCol->type, pCol->offset - sizeof(TSKEY), colIdx - 1); + } else if (TD_IS_KV_ROW(pRow)) { + SKvRowIdx *pIdx = (SKvRowIdx *)taosbsearch(&colId, TD_ROW_COL_IDX(pRow), tdRowGetNCols(pRow), sizeof(SKvRowIdx), + compareKvRowColId, TD_EQ); +#ifdef TD_SUPPORT_BITMAP + if (pIdx) { + colIdx = POINTER_DISTANCE(TD_ROW_COL_IDX(pRow), pIdx) / sizeof(SKvRowIdx); + } +#endif + tdGetKvRowValOfCol(pVal, pRow, pIter->pBitmap, pIdx ? pIdx->offset : -1, colIdx); + } else { + if (COL_REACH_END(colId, pIter->maxColId)) return false; + pVal->valType = TD_VTYPE_NONE; + } + + return true; +} + +static int32_t tdCompareColId(const void *arg1, const void *arg2) { + int32_t colId = *(int32_t *)arg1; + STColumn *pCol = (STColumn *)arg2; + + if (colId < pCol->colId) { + return -1; + } else if (colId == pCol->colId) { + return 0; + } else { + return 1; + } +} + +int32_t tdGetBitmapValTypeII(const void *pBitmap, int16_t colIdx, TDRowValT *pValType) { + if (!pBitmap || colIdx < 0) { + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + int16_t nBytes = colIdx / TD_VTYPE_PARTS; + int16_t nOffset = colIdx & TD_VTYPE_OPTR; + char *pDestByte = (char *)POINTER_SHIFT(pBitmap, nBytes); + // use literal value directly and not use formula to simplify the codes + switch (nOffset) { + case 0: + *pValType = (((*pDestByte) & 0xC0) >> 6); + break; + case 1: + *pValType = (((*pDestByte) & 0x30) >> 4); + break; + case 2: + *pValType = (((*pDestByte) & 0x0C) >> 2); + break; + case 3: + *pValType = ((*pDestByte) & 0x03); + break; + default: + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + return TSDB_CODE_SUCCESS; +} + +int32_t tdGetBitmapValTypeI(const void *pBitmap, int16_t colIdx, TDRowValT *pValType) { + if (!pBitmap || colIdx < 0) { + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + int16_t nBytes = colIdx / TD_VTYPE_PARTS_I; + int16_t nOffset = colIdx & TD_VTYPE_OPTR_I; + char *pDestByte = (char *)POINTER_SHIFT(pBitmap, nBytes); + // use literal value directly and not use formula to simplify the codes + switch (nOffset) { + case 0: + *pValType = (((*pDestByte) & 0x80) >> 7); + break; + case 1: + *pValType = (((*pDestByte) & 0x40) >> 6); + break; + case 2: + *pValType = (((*pDestByte) & 0x20) >> 5); + break; + case 3: + *pValType = (((*pDestByte) & 0x10) >> 4); + break; + case 4: + *pValType = (((*pDestByte) & 0x08) >> 3); + break; + case 5: + *pValType = (((*pDestByte) & 0x04) >> 2); + break; + case 6: + *pValType = (((*pDestByte) & 0x02) >> 1); + break; + case 7: + *pValType = ((*pDestByte) & 0x01); + break; + default: + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + return TSDB_CODE_SUCCESS; +} + +int32_t tdSetBitmapValTypeI(void *pBitmap, int16_t colIdx, TDRowValT valType) { + if (!pBitmap || colIdx < 0) { + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + int16_t nBytes = colIdx / TD_VTYPE_PARTS_I; + int16_t nOffset = colIdx & TD_VTYPE_OPTR_I; + char *pDestByte = (char *)POINTER_SHIFT(pBitmap, nBytes); + // use literal value directly and not use formula to simplify the codes + switch (nOffset) { + case 0: + *pDestByte = ((*pDestByte) & 0x7F) | (valType << 7); + // set the value and clear other partitions for offset 0 + // *pDestByte |= (valType << 7); + break; + case 1: + *pDestByte = ((*pDestByte) & 0xBF) | (valType << 6); + // *pDestByte |= (valType << 6); + break; + case 2: + *pDestByte = ((*pDestByte) & 0xDF) | (valType << 5); + // *pDestByte |= (valType << 5); + break; + case 3: + *pDestByte = ((*pDestByte) & 0xEF) | (valType << 4); + // *pDestByte |= (valType << 4); + break; + case 4: + *pDestByte = ((*pDestByte) & 0xF7) | (valType << 3); + // *pDestByte |= (valType << 3); + break; + case 5: + *pDestByte = ((*pDestByte) & 0xFB) | (valType << 2); + // *pDestByte |= (valType << 2); + break; + case 6: + *pDestByte = ((*pDestByte) & 0xFD) | (valType << 1); + // *pDestByte |= (valType << 1); + break; + case 7: + *pDestByte = ((*pDestByte) & 0xFE) | valType; + // *pDestByte |= (valType); + break; + default: + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + return TSDB_CODE_SUCCESS; +} + +int32_t tdGetKvRowValOfCol(SCellVal *output, STSRow *pRow, void *pBitmap, int32_t offset, int16_t colIdx) { +#ifdef TD_SUPPORT_BITMAP + TASSERT(colIdx < tdRowGetNCols(pRow) - 1); + if (tdGetBitmapValType(pBitmap, colIdx, &output->valType, 0) != TSDB_CODE_SUCCESS) { + output->valType = TD_VTYPE_NONE; + return terrno; + } + if (tdValTypeIsNorm(output->valType)) { + if (offset < 0) { + terrno = TSDB_CODE_INVALID_PARA; + output->valType = TD_VTYPE_NONE; + return terrno; + } + output->val = POINTER_SHIFT(pRow, offset); + } +#else + TASSERT(0); + if (offset < 0) { + terrno = TSDB_CODE_INVALID_PARA; + output->valType = TD_VTYPE_NONE; + return terrno; + } + output->val = POINTER_SHIFT(pRow, offset); + output->valType = isNull(output->val, colType) ? TD_VTYPE_NULL : TD_VTYPE_NORM; +#endif + return TSDB_CODE_SUCCESS; +} + +int32_t tdGetTpRowValOfCol(SCellVal *output, STSRow *pRow, void *pBitmap, int8_t colType, int32_t offset, + int16_t colIdx) { +#ifdef TD_SUPPORT_BITMAP + if (tdGetBitmapValType(pBitmap, colIdx, &output->valType, 0) != TSDB_CODE_SUCCESS) { + output->valType = TD_VTYPE_NONE; + return terrno; + } + if (tdValTypeIsNorm(output->valType)) { + if (IS_VAR_DATA_TYPE(colType)) { + output->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset)); + } else { + output->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset); + } + } +#else + if (IS_VAR_DATA_TYPE(colType)) { + output->val = POINTER_SHIFT(pRow, *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(pRow), offset)); + } else { + output->val = POINTER_SHIFT(TD_ROW_DATA(pRow), offset); + } + output->valType = isNull(output->val, colType) ? TD_VTYPE_NULL : TD_VTYPE_NORM; +#endif + return TSDB_CODE_SUCCESS; +} + +int32_t tdAppendColValToRow(SRowBuilder *pBuilder, col_id_t colId, int8_t colType, TDRowValT valType, const void *val, + bool isCopyVarData, int32_t offset, col_id_t colIdx) { + STSRow *pRow = pBuilder->pBuf; + if (!val) { +#ifdef TD_SUPPORT_BITMAP + if (tdValTypeIsNorm(valType)) { + terrno = TSDB_CODE_INVALID_PTR; + return terrno; + } +#else + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; +#endif + } + // TS KEY is stored in STSRow.ts and not included in STSRow.data field. + if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) { + TD_ROW_KEY(pRow) = *(TSKEY *)val; + // The primary TS key is Norm all the time, thus its valType is not stored in bitmap. + return TSDB_CODE_SUCCESS; + } + // TODO: We can avoid the type judegement by FP, but would prevent the inline scheme. + if (TD_IS_TP_ROW(pRow)) { + tdAppendColValToTpRow(pBuilder, valType, val, isCopyVarData, colType, colIdx, offset); + } else { + tdAppendColValToKvRow(pBuilder, valType, val, isCopyVarData, colType, colIdx, offset, colId); + } + return TSDB_CODE_SUCCESS; +} + +int32_t tdAppendColValToKvRow(SRowBuilder *pBuilder, TDRowValT valType, const void *val, bool isCopyVarData, + int8_t colType, int16_t colIdx, int32_t offset, col_id_t colId) { + if ((offset < (int32_t)sizeof(SKvRowIdx)) || (colIdx < 1)) { + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + offset -= sizeof(SKvRowIdx); + --colIdx; + +#ifdef TD_SUPPORT_BITMAP + if (tdSetBitmapValType(pBuilder->pBitmap, colIdx, valType, 0) != TSDB_CODE_SUCCESS) { + return terrno; + } +#endif + + STSRow *row = pBuilder->pBuf; + // No need to store None/Null values. + if (tdValIsNorm(valType, val, colType)) { + // ts key stored in STSRow.ts + SKvRowIdx *pColIdx = (SKvRowIdx *)POINTER_SHIFT(TD_ROW_COL_IDX(row), offset); + char *ptr = (char *)POINTER_SHIFT(row, TD_ROW_LEN(row)); + pColIdx->colId = colId; + pColIdx->offset = TD_ROW_LEN(row); // the offset include the TD_ROW_HEAD_LEN + + if (IS_VAR_DATA_TYPE(colType)) { + if (isCopyVarData) { + memcpy(ptr, val, varDataTLen(val)); + } + TD_ROW_LEN(row) += varDataTLen(val); + } else { + memcpy(ptr, val, TYPE_BYTES[colType]); + TD_ROW_LEN(row) += TYPE_BYTES[colType]; + } + } +#ifdef TD_SUPPORT_BACK2 + // NULL/None value + else { + SKvRowIdx *pColIdx = (SKvRowIdx *)POINTER_SHIFT(TD_ROW_COL_IDX(row), offset); + char *ptr = (char *)POINTER_SHIFT(row, TD_ROW_LEN(row)); + pColIdx->colId = colId; + pColIdx->offset = TD_ROW_LEN(row); // the offset include the TD_ROW_HEAD_LEN + const void *nullVal = getNullValue(colType); + + if (IS_VAR_DATA_TYPE(colType)) { + if (isCopyVarData) { + memcpy(ptr, nullVal, varDataTLen(nullVal)); + } + TD_ROW_LEN(row) += varDataTLen(nullVal); + } else { + memcpy(ptr, nullVal, TYPE_BYTES[colType]); + TD_ROW_LEN(row) += TYPE_BYTES[colType]; + } + } +#endif + + return 0; +} + +int32_t tdAppendColValToTpRow(SRowBuilder *pBuilder, TDRowValT valType, const void *val, bool isCopyVarData, + int8_t colType, int16_t colIdx, int32_t offset) { + if ((offset < (int32_t)sizeof(TSKEY)) || (colIdx < 1)) { + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + offset -= sizeof(TSKEY); + --colIdx; + +#ifdef TD_SUPPORT_BITMAP + if (tdSetBitmapValType(pBuilder->pBitmap, colIdx, valType, 0) != TSDB_CODE_SUCCESS) { + return terrno; + } +#endif + + STSRow *row = pBuilder->pBuf; + + // 1. No need to set flen part for Null/None, just use bitmap. When upsert for the same primary TS key, the bitmap + // should be updated simultaneously if Norm val overwrite Null/None cols. + // 2. When consume STSRow in memory by taos client/tq, the output of Null/None cols should both be Null. + if (tdValIsNorm(valType, val, colType)) { + // TODO: The layout of new data types imported since 3.0 like blob/medium blob is the same with binary/nchar. + if (IS_VAR_DATA_TYPE(colType)) { + // ts key stored in STSRow.ts + *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(row), offset) = TD_ROW_LEN(row); + if (isCopyVarData) { + memcpy(POINTER_SHIFT(row, TD_ROW_LEN(row)), val, varDataTLen(val)); + } + TD_ROW_LEN(row) += varDataTLen(val); + } else { + memcpy(POINTER_SHIFT(TD_ROW_DATA(row), offset), val, TYPE_BYTES[colType]); + } + } +#ifdef TD_SUPPORT_BACK2 + // NULL/None value + else { + // TODO: Null value for new data types imported since 3.0 need to be defined. + const void *nullVal = getNullValue(colType); + if (IS_VAR_DATA_TYPE(colType)) { + // ts key stored in STSRow.ts + *(VarDataOffsetT *)POINTER_SHIFT(TD_ROW_DATA(row), offset) = TD_ROW_LEN(row); + + if (isCopyVarData) { + memcpy(POINTER_SHIFT(row, TD_ROW_LEN(row)), nullVal, varDataTLen(nullVal)); + } + TD_ROW_LEN(row) += varDataTLen(nullVal); + } else { + memcpy(POINTER_SHIFT(TD_ROW_DATA(row), offset), nullVal, TYPE_BYTES[colType]); + } + } +#endif + + return 0; +} + +int32_t tdSRowSetExtendedInfo(SRowBuilder *pBuilder, int32_t nCols, int32_t nBoundCols, int32_t flen, + int32_t allNullLen, int32_t boundNullLen) { + if ((boundNullLen > 0) && (allNullLen > 0) && (nBoundCols > 0)) { + uint32_t tpLen = allNullLen; + uint32_t kvLen = sizeof(col_id_t) + sizeof(SKvRowIdx) * nBoundCols + boundNullLen; + if (isSelectKVRow(kvLen, tpLen)) { + pBuilder->rowType = TD_ROW_KV; + } else { + pBuilder->rowType = TD_ROW_TP; + } + + } else { + pBuilder->rowType = TD_ROW_TP; + } + + pBuilder->flen = flen; + pBuilder->nCols = nCols; + pBuilder->nBoundCols = nBoundCols; + if (pBuilder->flen <= 0 || pBuilder->nCols <= 0) { + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } +#ifdef TD_SUPPORT_BITMAP + // the primary TS key is stored separatedly + pBuilder->nBitmaps = (col_id_t)TD_BITMAP_BYTES(pBuilder->nCols - 1); + if (nBoundCols > 0) { + pBuilder->nBoundBitmaps = (col_id_t)TD_BITMAP_BYTES(pBuilder->nBoundCols - 1); + } else { + pBuilder->nBoundBitmaps = 0; + } +#else + pBuilder->nBitmaps = 0; + pBuilder->nBoundBitmaps = 0; +#endif + return TSDB_CODE_SUCCESS; +} + +int32_t tdSRowResetBuf(SRowBuilder *pBuilder, void *pBuf) { + pBuilder->pBuf = (STSRow *)pBuf; + if (!pBuilder->pBuf) { + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + TD_ROW_SET_INFO(pBuilder->pBuf, 0); + TD_ROW_SET_TYPE(pBuilder->pBuf, pBuilder->rowType); + + TASSERT(pBuilder->nBitmaps > 0 && pBuilder->flen > 0); + + uint32_t len = 0; + switch (pBuilder->rowType) { + case TD_ROW_TP: +#ifdef TD_SUPPORT_BITMAP + pBuilder->pBitmap = tdGetBitmapAddrTp(pBuilder->pBuf, pBuilder->flen); + memset(pBuilder->pBitmap, TD_VTYPE_NONE_BYTE_II, pBuilder->nBitmaps); +#endif + // the primary TS key is stored separatedly + len = TD_ROW_HEAD_LEN + pBuilder->flen - sizeof(TSKEY) + pBuilder->nBitmaps; + TD_ROW_SET_LEN(pBuilder->pBuf, len); + TD_ROW_SET_SVER(pBuilder->pBuf, pBuilder->sver); + break; + case TD_ROW_KV: +#ifdef TD_SUPPORT_BITMAP + pBuilder->pBitmap = tdGetBitmapAddrKv(pBuilder->pBuf, pBuilder->nBoundCols); + memset(pBuilder->pBitmap, TD_VTYPE_NONE_BYTE_II, pBuilder->nBoundBitmaps); +#endif + len = TD_ROW_HEAD_LEN + TD_ROW_NCOLS_LEN + (pBuilder->nBoundCols - 1) * sizeof(SKvRowIdx) + + pBuilder->nBoundBitmaps; // add + TD_ROW_SET_LEN(pBuilder->pBuf, len); + TD_ROW_SET_SVER(pBuilder->pBuf, pBuilder->sver); + TD_ROW_SET_NCOLS(pBuilder->pBuf, pBuilder->nBoundCols); + break; + default: + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t tdSRowGetBuf(SRowBuilder *pBuilder, void *pBuf) { + pBuilder->pBuf = (STSRow *)pBuf; + if (!pBuilder->pBuf) { + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + TASSERT(pBuilder->nBitmaps > 0 && pBuilder->flen > 0); + + uint32_t len = 0; + switch (pBuilder->rowType) { + case TD_ROW_TP: +#ifdef TD_SUPPORT_BITMAP + pBuilder->pBitmap = tdGetBitmapAddrTp(pBuilder->pBuf, pBuilder->flen); +#endif + break; + case TD_ROW_KV: +#ifdef TD_SUPPORT_BITMAP + pBuilder->pBitmap = tdGetBitmapAddrKv(pBuilder->pBuf, pBuilder->nBoundCols); +#endif + break; + default: + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + return TSDB_CODE_SUCCESS; +} + +int32_t tdSRowInitEx(SRowBuilder *pBuilder, void *pBuf, uint32_t allNullLen, uint32_t boundNullLen, int32_t nCols, + int32_t nBoundCols, int32_t flen) { + if (tdSRowSetExtendedInfo(pBuilder, allNullLen, boundNullLen, nCols, nBoundCols, flen) < 0) { + return terrno; + } + return tdSRowResetBuf(pBuilder, pBuf); +} + +void tdSRowReset(SRowBuilder *pBuilder) { + pBuilder->rowType = TD_ROW_TP; + pBuilder->pBuf = NULL; + pBuilder->nBoundCols = -1; + pBuilder->nCols = -1; + pBuilder->flen = -1; + pBuilder->pBitmap = NULL; +} + +int32_t tdSRowSetTpInfo(SRowBuilder *pBuilder, int32_t nCols, int32_t flen) { + pBuilder->flen = flen; + pBuilder->nCols = nCols; + if (pBuilder->flen <= 0 || pBuilder->nCols <= 0) { + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } +#ifdef TD_SUPPORT_BITMAP + // the primary TS key is stored separatedly + pBuilder->nBitmaps = (int16_t)TD_BITMAP_BYTES(pBuilder->nCols - 1); +#else + pBuilder->nBitmaps = 0; + pBuilder->nBoundBitmaps = 0; +#endif + return TSDB_CODE_SUCCESS; +} + +int32_t tdSRowSetInfo(SRowBuilder *pBuilder, int32_t nCols, int32_t nBoundCols, int32_t flen) { + pBuilder->flen = flen; + pBuilder->nCols = nCols; + pBuilder->nBoundCols = nBoundCols; + if (pBuilder->flen <= 0 || pBuilder->nCols <= 0) { + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } +#ifdef TD_SUPPORT_BITMAP + // the primary TS key is stored separatedly + pBuilder->nBitmaps = (int16_t)TD_BITMAP_BYTES(pBuilder->nCols - 1); + if (nBoundCols > 0) { + pBuilder->nBoundBitmaps = (int16_t)TD_BITMAP_BYTES(pBuilder->nBoundCols - 1); + } else { + pBuilder->nBoundBitmaps = 0; + } +#else + pBuilder->nBitmaps = 0; + pBuilder->nBoundBitmaps = 0; +#endif + return TSDB_CODE_SUCCESS; +} + +int32_t tdGetBitmapValType(const void *pBitmap, int16_t colIdx, TDRowValT *pValType, int8_t bitmapMode) { + switch (bitmapMode) { + case 0: + tdGetBitmapValTypeII(pBitmap, colIdx, pValType); + break; + case -1: + case 1: + tdGetBitmapValTypeI(pBitmap, colIdx, pValType); + break; + default: + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return TSDB_CODE_FAILED; + } + return TSDB_CODE_SUCCESS; +} + +bool tdIsBitmapValTypeNorm(const void *pBitmap, int16_t idx, int8_t bitmapMode) { + TDRowValT valType = 0; + tdGetBitmapValType(pBitmap, idx, &valType, bitmapMode); + if (tdValTypeIsNorm(valType)) { + return true; + } + return false; +} + +int32_t tdSetBitmapValTypeII(void *pBitmap, int16_t colIdx, TDRowValT valType) { + if (!pBitmap || colIdx < 0) { + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + int16_t nBytes = colIdx / TD_VTYPE_PARTS; + int16_t nOffset = colIdx & TD_VTYPE_OPTR; + char *pDestByte = (char *)POINTER_SHIFT(pBitmap, nBytes); + // use literal value directly and not use formula to simplify the codes + switch (nOffset) { + case 0: + *pDestByte = ((*pDestByte) & 0x3F) | (valType << 6); + // set the value and clear other partitions for offset 0 + // *pDestByte |= (valType << 6); + break; + case 1: + *pDestByte = ((*pDestByte) & 0xCF) | (valType << 4); + // *pDestByte |= (valType << 4); + break; + case 2: + *pDestByte = ((*pDestByte) & 0xF3) | (valType << 2); + // *pDestByte |= (valType << 2); + break; + case 3: + *pDestByte = ((*pDestByte) & 0xFC) | valType; + // *pDestByte |= (valType); + break; + default: + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + return TSDB_CODE_SUCCESS; +} + +int32_t tdSetBitmapValType(void *pBitmap, int16_t colIdx, TDRowValT valType, int8_t bitmapMode) { + switch (bitmapMode) { + case 0: + tdSetBitmapValTypeII(pBitmap, colIdx, valType); + break; + case -1: + case 1: + tdSetBitmapValTypeI(pBitmap, colIdx, valType); + break; + default: + TASSERT(0); + terrno = TSDB_CODE_INVALID_PARA; + return TSDB_CODE_FAILED; + } + return TSDB_CODE_SUCCESS; +} + +void *tdGetBitmapAddr(STSRow *pRow, uint8_t rowType, uint32_t flen, col_id_t nKvCols) { +#ifdef TD_SUPPORT_BITMAP + switch (rowType) { + case TD_ROW_TP: + return tdGetBitmapAddrTp(pRow, flen); + case TD_ROW_KV: + return tdGetBitmapAddrKv(pRow, nKvCols); + default: + break; + } +#endif + return NULL; +} + +void tdSTSRowIterReset(STSRowIter *pIter, STSRow *pRow) { + pIter->pRow = pRow; + pIter->pBitmap = tdGetBitmapAddr(pRow, pRow->type, pIter->pSchema->flen, tdRowGetNCols(pRow)); + pIter->offset = 0; + pIter->colIdx = PRIMARYKEY_TIMESTAMP_COL_ID; + pIter->kvIdx = 0; +} + +void tdSTSRowIterInit(STSRowIter *pIter, STSchema *pSchema) { + pIter->pSchema = pSchema; + pIter->maxColId = pSchema->columns[pSchema->numOfCols - 1].colId; } \ No newline at end of file From 60efd600b8acce556ca5c3488bd384608afc5955 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Tue, 10 May 2022 01:57:08 +0000 Subject: [PATCH 8/8] refact --- include/common/trow.h | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/include/common/trow.h b/include/common/trow.h index eed15689c0..4031946ee8 100644 --- a/include/common/trow.h +++ b/include/common/trow.h @@ -30,6 +30,22 @@ extern "C" { #endif +typedef struct { + TSKEY ts; + union { + uint32_t info; + struct { + uint16_t type : 2; + uint16_t del : 1; + uint16_t endian : 1; + uint16_t reserve : 12; + uint16_t sver; + }; + }; + uint32_t len; + char data[]; +} STSRow; + // Target of tdataformat.h: // 1. Row related definition in dataformat.h of 2.0 could be replaced with tdataformat.h of 3.0. // 2. The basic definition in dataformat.h is shared with tdataformat.h of 3.0. @@ -117,31 +133,6 @@ typedef struct { SKvRowIdx cidx[]; } SKvRow; -typedef struct { - /// timestamp - TSKEY ts; - union { - /// union field for encode and decode - uint32_t info; - struct { - /// row type - uint16_t type : 2; - /// is delete row(0 not delete, 1 delete) - uint16_t del : 1; - /// endian(0 little endian, 1 big endian) - uint16_t endian : 1; - /// reserved for back compatibility - uint16_t reserve : 12; - /// row schema version - uint16_t sver; - }; - }; - /// row total length - uint32_t len; - /// the inline data, maybe a tuple or a k-v tuple - char data[]; -} STSRow; - typedef struct { // basic info int8_t rowType;