diff --git a/Jenkinsfile2 b/Jenkinsfile2 index de39f4fcecc53ce3d544d41f65a1d29761002c5b..fcc02dc3e0ed53632e0614619fe8caf823b9ed16 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -361,7 +361,7 @@ pipeline { } parallel { stage('check docs') { - agent{label " worker03 || slave215 || slave217 || slave219 || Mac_catalina "} + agent{label " slave1_47 || slave1_48 || slave1_49 || slave1_52 || worker03 || slave215 || slave217 || slave219 || Mac_catalina "} steps { check_docs() } @@ -407,7 +407,7 @@ pipeline { } } stage('linux test') { - agent{label " worker03 || slave215 || slave217 || slave219 "} + agent{label " slave1_47 || slave1_48 || slave1_49 || slave1_52 || worker03 || slave215 || slave217 || slave219 "} options { skipDefaultCheckout() } when { changeRequest() diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h index 2eda2f66cc143ddfd78f883f6c4b79547183d6e5..6855287fb2d354f52998342d368c46b3a852bf89 100644 --- a/include/common/tdataformat.h +++ b/include/common/tdataformat.h @@ -27,17 +27,17 @@ extern "C" { #endif -typedef struct SBuffer SBuffer; -typedef struct SSchema SSchema; -typedef struct STColumn STColumn; -typedef struct STSchema STSchema; -typedef struct SValue SValue; -typedef struct SColVal SColVal; -typedef struct STSRow2 STSRow2; -typedef struct STSRowBuilder STSRowBuilder; -typedef struct STagVal STagVal; -typedef struct STag STag; -typedef struct SColData SColData; +typedef struct SBuffer SBuffer; +typedef struct SSchema SSchema; +typedef struct STColumn STColumn; +typedef struct STSchema STSchema; +typedef struct SValue SValue; +typedef struct SColVal SColVal; +typedef struct SRow SRow; +typedef struct SRowIter SRowIter; +typedef struct STagVal STagVal; +typedef struct STag STag; +typedef struct SColData SColData; #define HAS_NONE ((uint8_t)0x1) #define HAS_NULL ((uint8_t)0x2) @@ -68,13 +68,10 @@ struct SBuffer { void tBufferDestroy(SBuffer *pBuffer); int32_t tBufferInit(SBuffer *pBuffer, int64_t size); int32_t tBufferPut(SBuffer *pBuffer, const void *pData, int64_t nData); +int32_t tBufferReserve(SBuffer *pBuffer, int64_t nData, void **ppData); // STSchema ================================ -int32_t tTSchemaCreate(int32_t sver, SSchema *pSchema, int32_t nCols, STSchema **ppTSchema); -void tTSchemaDestroy(STSchema *pTSchema); - -// SValue ================================ -static FORCE_INLINE int32_t tGetValue(uint8_t *p, SValue *pValue, int8_t type); +void tDestroyTSchema(STSchema *pTSchema); // SColVal ================================ #define CV_FLAG_VALUE ((int8_t)0x0) @@ -89,26 +86,14 @@ static FORCE_INLINE int32_t tGetValue(uint8_t *p, SValue *pValue, int8_t type); #define COL_VAL_IS_NULL(CV) ((CV)->flag == CV_FLAG_NULL) #define COL_VAL_IS_VALUE(CV) ((CV)->flag == CV_FLAG_VALUE) -// STSRow2 ================================ -#define TSROW_LEN(PROW, V) tGetI32v((uint8_t *)(PROW)->data, (V) ? &(V) : NULL) -#define TSROW_SVER(PROW, V) tGetI32v((PROW)->data + TSROW_LEN(PROW, NULL), (V) ? &(V) : NULL) - -int32_t tTSRowNew(STSRowBuilder *pBuilder, SArray *pArray, STSchema *pTSchema, STSRow2 **ppRow); -int32_t tTSRowClone(const STSRow2 *pRow, STSRow2 **ppRow); -void tTSRowFree(STSRow2 *pRow); -void tTSRowGet(STSRow2 *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal); -int32_t tTSRowToArray(STSRow2 *pRow, STSchema *pTSchema, SArray **ppArray); -int32_t tPutTSRow(uint8_t *p, STSRow2 *pRow); -int32_t tGetTSRow(uint8_t *p, STSRow2 **ppRow); - -// STSRowBuilder ================================ -#define tsRowBuilderInit() ((STSRowBuilder){0}) -#define tsRowBuilderClear(B) \ - do { \ - if ((B)->pBuf) { \ - taosMemoryFree((B)->pBuf); \ - } \ - } while (0) +// SRow ================================ +int32_t tRowBuild(SArray *aColVal, STSchema *pTSchema, SBuffer *pBuffer); +void tRowGet(SRow *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal); + +// SRowIter ================================ +int32_t tRowIterOpen(SRow *pRow, STSchema *pTSchema, SRowIter **ppIter); +void tRowIterClose(SRowIter **ppIter); +SColVal *tRowIterNext(SRowIter *pIter); // STag ================================ int32_t tTagNew(SArray *pArray, int32_t version, int8_t isJson, STag **ppTag); @@ -147,29 +132,17 @@ struct STSchema { int32_t numOfCols; int32_t version; int32_t flen; - int32_t vlen; int32_t tlen; STColumn columns[]; }; -#define TSROW_HAS_NONE ((uint8_t)0x1) -#define TSROW_HAS_NULL ((uint8_t)0x2U) -#define TSROW_HAS_VAL ((uint8_t)0x4U) -#define TSROW_KV_SMALL ((uint8_t)0x10U) -#define TSROW_KV_MID ((uint8_t)0x20U) -#define TSROW_KV_BIG ((uint8_t)0x40U) -#pragma pack(push, 1) -struct STSRow2 { - TSKEY ts; - uint8_t flags; - uint8_t data[]; -}; -#pragma pack(pop) - -struct STSRowBuilder { - // STSRow2 tsRow; - int32_t szBuf; - uint8_t *pBuf; +struct SRow { + uint8_t flag; + uint8_t rsv; + uint16_t sver; + uint32_t len; + TSKEY ts; + uint8_t data[]; }; struct SValue { @@ -258,37 +231,17 @@ typedef struct { int32_t nCols; schema_ver_t version; uint16_t flen; - int32_t vlen; int32_t tlen; STColumn *columns; } STSchemaBuilder; -// use 2 bits for bitmap(default: STSRow/sub block) -#define TD_VTYPE_BITS 2 -#define TD_VTYPE_PARTS 4 // PARTITIONS: 1 byte / 2 bits -#define TD_VTYPE_OPTR 3 // OPERATOR: 4 - 1, utilize to get remainder -#define TD_BITMAP_BYTES(cnt) (((cnt) + TD_VTYPE_OPTR) >> 2) - -// use 1 bit for bitmap(super block) -#define TD_VTYPE_BITS_I 1 -#define TD_VTYPE_PARTS_I 8 // PARTITIONS: 1 byte / 1 bit -#define TD_VTYPE_OPTR_I 7 // OPERATOR: 8 - 1, utilize to get remainder -#define TD_BITMAP_BYTES_I(cnt) (((cnt) + TD_VTYPE_OPTR_I) >> 3) - int32_t tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version); void tdDestroyTSchemaBuilder(STSchemaBuilder *pBuilder); void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version); int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t flags, col_id_t colId, col_bytes_t bytes); STSchema *tdGetSchemaFromBuilder(STSchemaBuilder *pBuilder); -static FORCE_INLINE int32_t tGetValue(uint8_t *p, SValue *pValue, int8_t type) { - if (IS_VAR_DATA_TYPE(type)) { - return tGetBinary(p, &pValue->pData, pValue ? &pValue->nData : NULL); - } else { - memcpy(&pValue->val, p, tDataTypes[type].bytes); - return tDataTypes[type].bytes; - } -} +STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version); #endif diff --git a/include/common/trow.h b/include/common/trow.h index 9d183c8f80d926c9f646b83f73a0cbadacbd5afe..6a71a8844ed54baa45836d16f2c3ccf9b114cc0a 100644 --- a/include/common/trow.h +++ b/include/common/trow.h @@ -55,6 +55,14 @@ typedef struct STSRow { #define TD_ROW_TP 0x0U // default #define TD_ROW_KV 0x01U +#define TD_VTYPE_PARTS 4 // PARTITIONS: 1 byte / 2 bits +#define TD_VTYPE_OPTR 3 // OPERATOR: 4 - 1, utilize to get remainder +#define TD_BITMAP_BYTES(cnt) (((cnt) + TD_VTYPE_OPTR) >> 2) + +#define TD_VTYPE_PARTS_I 8 // PARTITIONS: 1 byte / 1 bit +#define TD_VTYPE_OPTR_I 7 // OPERATOR: 8 - 1, utilize to get remainder +#define TD_BITMAP_BYTES_I(cnt) (((cnt) + TD_VTYPE_OPTR_I) >> 3) + /** * @brief value type * - for data from client input and STSRow in memory, 3 types of value none/null/norm available @@ -244,7 +252,7 @@ int32_t tdGetBitmapValTypeI(const void *pBitmap, int16_t colIdx, TDRowValT *pVal */ static FORCE_INLINE void *tdGetBitmapAddrTp(STSRow *pRow, uint32_t flen) { // The primary TS key is stored separatedly. - return POINTER_SHIFT(TD_ROW_DATA(pRow), flen - sizeof(TSKEY)); + return POINTER_SHIFT(TD_ROW_DATA(pRow), flen); // return POINTER_SHIFT(pRow->ts, flen); } diff --git a/include/libs/sync/sync.h b/include/libs/sync/sync.h index 513ba8cb3432de72911be0a56a8c5dc87c05dc60..b8a4726be0bb5dbc960416a55f66cb985a140eb1 100644 --- a/include/libs/sync/sync.h +++ b/include/libs/sync/sync.h @@ -41,6 +41,7 @@ extern "C" { #define SNAPSHOT_WAIT_MS 1000 * 30 #define SYNC_APPEND_ENTRIES_TIMEOUT_MS 10000 +#define SYNC_HEART_TIMEOUT_MS 1000 * 8 #define SYNC_MAX_BATCH_SIZE 1 #define SYNC_INDEX_BEGIN 0 diff --git a/source/client/src/clientRawBlockWrite.c b/source/client/src/clientRawBlockWrite.c index 90a2adb64743585070a4f5a2e5414c1d45648bf2..6a6a5d56d752d6ad6686e05162bb946f40902999 100644 --- a/source/client/src/clientRawBlockWrite.c +++ b/source/client/src/clientRawBlockWrite.c @@ -1275,6 +1275,7 @@ int taos_write_raw_block(TAOS* taos, int rows, char* pData, const char* tbname) nVar++; } } + fLen -= sizeof(TSKEY); int32_t extendedRowSize = rowSize + TD_ROW_HEAD_LEN - sizeof(TSKEY) + nVar * sizeof(VarDataOffsetT) + (int32_t)TD_BITMAP_BYTES(numOfCols - 1); @@ -1333,7 +1334,9 @@ int taos_write_raw_block(TAOS* taos, int rows, char* pData, const char* tbname) } } - offset += TYPE_BYTES[pColumn->type]; + if (pColumn->colId != PRIMARYKEY_TIMESTAMP_COL_ID) { + offset += TYPE_BYTES[pColumn->type]; + } } tdSRowEnd(&rb); int32_t rowLen = TD_ROW_LEN(rowData); @@ -1503,6 +1506,7 @@ static int32_t tmqWriteRawDataImpl(TAOS* taos, void* data, int32_t dataLen) { nVar++; } } + fLen -= sizeof(TSKEY); int32_t rows = rspObj.resInfo.numOfRows; int32_t extendedRowSize = rowSize + TD_ROW_HEAD_LEN - sizeof(TSKEY) + nVar * sizeof(VarDataOffsetT) + @@ -1585,8 +1589,9 @@ static int32_t tmqWriteRawDataImpl(TAOS* taos, void* data, int32_t dataLen) { tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NORM, colData, true, offset, k); } } - - offset += TYPE_BYTES[pColumn->type]; + if (pColumn->colId != PRIMARYKEY_TIMESTAMP_COL_ID) { + offset += TYPE_BYTES[pColumn->type]; + } } tdSRowEnd(&rb); int32_t rowLen = TD_ROW_LEN(rowData); @@ -1803,6 +1808,7 @@ static int32_t tmqWriteRawMetaDataImpl(TAOS* taos, void* data, int32_t dataLen) nVar++; } } + fLen -= sizeof(TSKEY); int32_t rows = rspObj.resInfo.numOfRows; int32_t extendedRowSize = rowSize + TD_ROW_HEAD_LEN - sizeof(TSKEY) + nVar * sizeof(VarDataOffsetT) + @@ -1888,8 +1894,9 @@ static int32_t tmqWriteRawMetaDataImpl(TAOS* taos, void* data, int32_t dataLen) tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NORM, colData, true, offset, k); } } - - offset += TYPE_BYTES[pColumn->type]; + if (pColumn->colId != PRIMARYKEY_TIMESTAMP_COL_ID) { + offset += TYPE_BYTES[pColumn->type]; + } } tdSRowEnd(&rb); int32_t rowLen = TD_ROW_LEN(rowData); diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 607db72ec67e81f5fee5ab40bb4a7e2383400c62..f79c39f703b4934801f77a5b7d975fab91923a8d 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -2052,6 +2052,7 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SSDataBlock* pDataB isStartKey = true; tdAppendColValToRow(&rb, PRIMARYKEY_TIMESTAMP_COL_ID, TSDB_DATA_TYPE_TIMESTAMP, TD_VTYPE_NORM, var, true, offset, k); + continue; // offset should keep 0 for next column } else if (colDataIsNull_s(pColInfoData, j)) { tdAppendColValToRow(&rb, PRIMARYKEY_TIMESTAMP_COL_ID + k, TSDB_DATA_TYPE_TIMESTAMP, TD_VTYPE_NULL, NULL, diff --git a/source/common/src/tdataformat.c b/source/common/src/tdataformat.c index 73b887342cf995a1aa564b1aa6f5bae55dac01e1..728f669fc885c4eef539a4f47cd282fd59d8a84c 100644 --- a/source/common/src/tdataformat.c +++ b/source/common/src/tdataformat.c @@ -43,606 +43,672 @@ int32_t tBufferPut(SBuffer *pBuffer, const void *pData, int64_t nData) { return code; } +int32_t tBufferReserve(SBuffer *pBuffer, int64_t nData, void **ppData) { + int32_t code = tRealloc(&pBuffer->pBuf, pBuffer->nBuf + nData); + if (code) return code; + + *ppData = pBuffer->pBuf + pBuffer->nBuf; + pBuffer->nBuf += nData; + + return code; +} + // ================================ static int32_t tGetTagVal(uint8_t *p, STagVal *pTagVal, int8_t isJson); +// SRow ======================================================================== +#define KV_FLG_LIT ((uint8_t)0x10) +#define KV_FLG_MID ((uint8_t)0x20) +#define KV_FLG_BIG ((uint8_t)0x30) + +#define ROW_BIT_NONE ((uint8_t)0x0) +#define ROW_BIT_NULL ((uint8_t)0x1) +#define ROW_BIT_VALUE ((uint8_t)0x2) + #pragma pack(push, 1) typedef struct { - int16_t nCols; - uint8_t idx[]; -} STSKVRow; + int16_t nCol; + char idx[]; // uint8_t * | uint16_t * | uint32_t * +} SKVIdx; #pragma pack(pop) -#define TSROW_IS_KV_ROW(r) ((r)->flags & TSROW_KV_ROW) - -// SValue -static FORCE_INLINE int32_t tPutValue(uint8_t *p, SValue *pValue, int8_t type) { - if (IS_VAR_DATA_TYPE(type)) { - return tPutBinary(p, pValue->pData, pValue->nData); - } else { - if (p) memcpy(p, &pValue->val, tDataTypes[type].bytes); - return tDataTypes[type].bytes; - } -} - -// STSRow2 ======================================================================== -static void setBitMap(uint8_t *pb, uint8_t v, int32_t idx, uint8_t flags) { - if (pb) { - switch (flags & 0xf) { - case TSROW_HAS_NULL | TSROW_HAS_NONE: - case TSROW_HAS_VAL | TSROW_HAS_NONE: - if (v) { - SET_BIT1(pb, idx, (uint8_t)1); - } else { - SET_BIT1(pb, idx, (uint8_t)0); - } - break; - case TSROW_HAS_VAL | TSROW_HAS_NULL: - v = v - 1; - SET_BIT1(pb, idx, v); - break; - case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE: - SET_BIT2(pb, idx, v); - break; - - default: - ASSERT(0); - } - } -} -#define SET_IDX(p, i, n, f) \ - do { \ - if ((f)&TSROW_KV_SMALL) { \ - ((uint8_t *)(p))[i] = (n); \ - } else if ((f)&TSROW_KV_MID) { \ - ((uint16_t *)(p))[i] = (n); \ - } else { \ - ((uint32_t *)(p))[i] = (n); \ - } \ +#define ROW_SET_BITMAP(PB, FLAG, IDX, VAL) \ + do { \ + if (PB) { \ + switch (FLAG) { \ + case (HAS_NULL | HAS_NONE): \ + SET_BIT1(PB, IDX, VAL); \ + break; \ + case (HAS_VALUE | HAS_NONE): \ + SET_BIT1(PB, IDX, (VAL) ? (VAL)-1 : 0); \ + break; \ + case (HAS_VALUE | HAS_NULL): \ + SET_BIT1(PB, IDX, (VAL)-1); \ + break; \ + case (HAS_VALUE | HAS_NULL | HAS_NONE): \ + SET_BIT2(PB, IDX, VAL); \ + break; \ + default: \ + ASSERT(0); \ + break; \ + } \ + } \ } while (0) -#if 0 -int32_t tTSRowNew(STSRowBuilder *pBuilder, SArray *pArray, STSchema *pTSchema, STSRow2 **ppRow) { - int32_t code = 0; -#if 0 - STColumn *pTColumn; - SColVal *pColVal; - int32_t nColVal = taosArrayGetSize(pArray); - int32_t iColVal; - - ASSERT(nColVal > 0); - - // try - uint8_t flags = 0; - uint32_t ntv = 0; - uint32_t nkv = 0; - int16_t nTag = 0; - uint32_t maxIdx = 0; - - iColVal = 0; - for (int32_t iColumn = 0; iColumn < pTSchema->numOfCols; iColumn++) { - pTColumn = &pTSchema->columns[iColumn]; - if (iColVal < nColVal) { - pColVal = (SColVal *)taosArrayGet(pArray, iColVal); - } else { - pColVal = NULL; - } - if (iColumn == 0) { - ASSERT(pColVal->cid == pTColumn->colId); - ASSERT(pTColumn->type == TSDB_DATA_TYPE_TIMESTAMP); - ASSERT(pTColumn->colId == PRIMARYKEY_TIMESTAMP_COL_ID); - - iColVal++; - } else { - if (pColVal) { - if (pColVal->cid == pTColumn->colId) { - iColVal++; +int32_t tRowBuild(SArray *aColVal, STSchema *pTSchema, SBuffer *pBuffer) { + int32_t code = 0; - if (COL_VAL_IS_NONE(pColVal)) { - flags |= TSROW_HAS_NONE; - } else if (COL_VAL_IS_NULL(pColVal)) { - flags |= TSROW_HAS_NULL; - maxIdx = nkv; - nTag++; - nkv += tPutI16v(NULL, -pTColumn->colId); + ASSERT(taosArrayGetSize(aColVal) > 0); + ASSERT(((SColVal *)aColVal->pData)[0].cid == PRIMARYKEY_TIMESTAMP_COL_ID); + ASSERT(((SColVal *)aColVal->pData)[0].type == TSDB_DATA_TYPE_TIMESTAMP); + + // scan --------------- + uint8_t flag = 0; + int32_t iColVal = 1; + const int32_t nColVal = taosArrayGetSize(aColVal); + SColVal *pColVal = (iColVal < nColVal) ? (SColVal *)taosArrayGet(aColVal, iColVal) : NULL; + int32_t iTColumn = 1; + STColumn *pTColumn = pTSchema->columns + iTColumn; + int32_t ntp = 0; + int32_t nkv = 0; + int32_t maxIdx = 0; + int32_t nIdx = 0; + while (pTColumn) { + if (pColVal) { + if (pColVal->cid == pTColumn->colId) { + ntp += TYPE_BYTES[pTColumn->type]; + if (COL_VAL_IS_VALUE(pColVal)) { // VALUE + flag |= HAS_VALUE; + maxIdx = nkv; + if (IS_VAR_DATA_TYPE(pTColumn->type)) { + ntp = ntp + tPutU32v(NULL, pColVal->value.nData) + pColVal->value.nData; + nkv = nkv + tPutI16v(NULL, pTColumn->colId) + tPutU32v(NULL, pColVal->value.nData) + pColVal->value.nData; } else { - flags |= TSROW_HAS_VAL; - maxIdx = nkv; - nTag++; - nkv += tPutI16v(NULL, pTColumn->colId); - nkv += tPutValue(NULL, &pColVal->value, pTColumn->type); - if (IS_VAR_DATA_TYPE(pTColumn->type)) { - ntv += tPutValue(NULL, &pColVal->value, pTColumn->type); - } + nkv = nkv + tPutI16v(NULL, pTColumn->colId) + pTColumn->bytes; } - } else if (pColVal->cid > pTColumn->colId) { - flags |= TSROW_HAS_NONE; + nIdx++; + } else if (COL_VAL_IS_NONE(pColVal)) { // NONE + flag |= HAS_NONE; + } else if (COL_VAL_IS_NULL(pColVal)) { // NULL + flag |= HAS_NULL; + maxIdx = nkv; + nkv += tPutI16v(NULL, -pTColumn->colId); + nIdx++; } else { ASSERT(0); } + + pTColumn = (++iTColumn < pTSchema->numOfCols) ? pTSchema->columns + iTColumn : NULL; + pColVal = (++iColVal < nColVal) ? (SColVal *)taosArrayGet(aColVal, iColVal) : NULL; + } else if (pColVal->cid > pTColumn->colId) { // NONE + flag |= HAS_NONE; + ntp += TYPE_BYTES[pTColumn->type]; + pTColumn = (++iTColumn < pTSchema->numOfCols) ? pTSchema->columns + iTColumn : NULL; } else { - flags |= TSROW_HAS_NONE; + pColVal = (++iColVal < nColVal) ? (SColVal *)taosArrayGet(aColVal, iColVal) : NULL; } + } else { // NONE + flag |= HAS_NONE; + ntp += TYPE_BYTES[pTColumn->type]; + pTColumn = (++iTColumn < pTSchema->numOfCols) ? pTSchema->columns + iTColumn : NULL; } } - ASSERT(flags); - - // decide - uint32_t nData = 0; - uint32_t nDataT = 0; - uint32_t nDataK = 0; - if (flags == TSROW_HAS_NONE || flags == TSROW_HAS_NULL) { - nData = 0; + // compare --------------- + switch (flag) { + case HAS_NONE: + case HAS_NULL: + ntp = sizeof(SRow); + break; + case HAS_VALUE: + ntp = sizeof(SRow) + ntp; + break; + case (HAS_NULL | HAS_NONE): + ntp = sizeof(SRow) + BIT1_SIZE(pTSchema->numOfCols - 1); + break; + case (HAS_VALUE | HAS_NONE): + case (HAS_VALUE | HAS_NULL): + ntp = sizeof(SRow) + BIT1_SIZE(pTSchema->numOfCols - 1) + ntp; + break; + case (HAS_VALUE | HAS_NULL | HAS_NONE): + ntp = sizeof(SRow) + BIT2_SIZE(pTSchema->numOfCols - 1) + ntp; + break; + default: + ASSERT(0); + break; + } + if (maxIdx <= UINT8_MAX) { + nkv = sizeof(SRow) + sizeof(SKVIdx) + nIdx + nkv; + flag |= KV_FLG_LIT; + } else if (maxIdx <= UINT16_MAX) { + nkv = sizeof(SRow) + sizeof(SKVIdx) + (nIdx << 1) + nkv; + flag |= KV_FLG_MID; } else { - switch (flags) { - case TSROW_HAS_VAL: - nDataT = pTSchema->flen + ntv; - break; - case TSROW_HAS_NULL | TSROW_HAS_NONE: - nDataT = BIT1_SIZE(pTSchema->numOfCols - 1); - break; - case TSROW_HAS_VAL | TSROW_HAS_NONE: - case TSROW_HAS_VAL | TSROW_HAS_NULL: - nDataT = BIT1_SIZE(pTSchema->numOfCols - 1) + pTSchema->flen + ntv; - break; - case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE: - nDataT = BIT2_SIZE(pTSchema->numOfCols - 1) + pTSchema->flen + ntv; - break; - default: - break; - ASSERT(0); - } - - uint8_t tflags = 0; - if (maxIdx <= UINT8_MAX) { - nDataK = sizeof(STSKVRow) + sizeof(uint8_t) * nTag + nkv; - tflags |= TSROW_KV_SMALL; - } else if (maxIdx <= UINT16_MAX) { - nDataK = sizeof(STSKVRow) + sizeof(uint16_t) * nTag + nkv; - tflags |= TSROW_KV_MID; - } else { - nDataK = sizeof(STSKVRow) + sizeof(uint32_t) * nTag + nkv; - tflags |= TSROW_KV_BIG; - } - - if (nDataT <= nDataK) { - nData = nDataT; - } else { - nData = nDataK; - flags |= tflags; - } + nkv = sizeof(SRow) + sizeof(SKVIdx) + (nIdx << 2) + nkv; + flag |= KV_FLG_BIG; + } + int32_t nRow; + if (nkv < ntp) { + nRow = nkv; + } else { + nRow = ntp; + flag &= ((uint8_t)0x0f); } - // alloc - if (pBuilder) { - // create from a builder - if (nData == 0) { - pBuilder->tsRow.nData = 0; - pBuilder->tsRow.pData = NULL; - } else { - if (pBuilder->szBuf < nData) { - uint8_t *p = taosMemoryRealloc(pBuilder->pBuf, nData); - if (p == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - goto _exit; - } - pBuilder->pBuf = p; - pBuilder->szBuf = nData; - } + // alloc -------------- + SRow *pRow = NULL; + code = tBufferReserve(pBuffer, nRow, (void **)&pRow); + if (code) return code; - pBuilder->tsRow.nData = nData; - pBuilder->tsRow.pData = pBuilder->pBuf; - } + // build -------------- + pColVal = (SColVal *)taosArrayGet(aColVal, 0); - *ppRow = &pBuilder->tsRow; - } else { - // create a new one - *ppRow = (STSRow2 *)taosMemoryMalloc(sizeof(STSRow2)); - if (*ppRow == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - goto _exit; - } - if (nData == 0) { - (*ppRow)->nData = 0; - (*ppRow)->pData = NULL; - } else { - (*ppRow)->nData = nData; - (*ppRow)->pData = taosMemoryMalloc(nData); - if ((*ppRow)->pData == NULL) { - taosMemoryFree(*ppRow); - code = TSDB_CODE_OUT_OF_MEMORY; - goto _exit; - } - } + pRow->flag = flag; + pRow->rsv = 0; + pRow->sver = pTSchema->version; + pRow->len = nRow; + memcpy(&pRow->ts, &pColVal->value.val, sizeof(TSKEY)); + + if (flag == HAS_NONE || flag == HAS_NULL) { + goto _exit; } - // build - (*ppRow)->flags = flags; - (*ppRow)->sver = pTSchema->version; - - pColVal = (SColVal *)taosArrayGet(pArray, 0); - (*ppRow)->ts = pColVal->value.ts; - - if ((*ppRow)->pData) { - STSKVRow *pTSKVRow = NULL; - uint8_t *pidx = NULL; - uint8_t *pkv = NULL; - uint8_t *pb = NULL; - uint8_t *pf = NULL; - uint8_t *ptv = NULL; - nkv = 0; - ntv = 0; - iColVal = 1; - - if ((flags & 0xf0) == 0) { - switch (flags & 0xf) { - case TSROW_HAS_VAL: - pf = (*ppRow)->pData; - ptv = pf + pTSchema->flen; - break; - case TSROW_HAS_NULL | TSROW_HAS_NONE: - pb = (*ppRow)->pData; - break; - case TSROW_HAS_VAL | TSROW_HAS_NONE: - case TSROW_HAS_VAL | TSROW_HAS_NULL: - pb = (*ppRow)->pData; - pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1); - ptv = pf + pTSchema->flen; - break; - case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE: - pb = (*ppRow)->pData; - pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1); - ptv = pf + pTSchema->flen; - break; - default: - ASSERT(0); - break; - } + iColVal = 1; + pColVal = (iColVal < nColVal) ? (SColVal *)taosArrayGet(aColVal, iColVal) : NULL; + iTColumn = 1; + pTColumn = pTSchema->columns + iTColumn; + if (flag & 0xf0) { // KV + SKVIdx *pIdx = (SKVIdx *)pRow->data; + int32_t iIdx = 0; + int32_t nv = 0; + uint8_t *pv = NULL; + if (flag & KV_FLG_LIT) { + pv = pIdx->idx + nIdx; + } else if (flag & KV_FLG_MID) { + pv = pIdx->idx + (nIdx << 1); } else { - pTSKVRow = (STSKVRow *)(*ppRow)->pData; - pTSKVRow->nCols = 0; - pidx = pTSKVRow->idx; - if (flags & TSROW_KV_SMALL) { - pkv = pidx + sizeof(uint8_t) * nTag; - } else if (flags & TSROW_KV_MID) { - pkv = pidx + sizeof(uint16_t) * nTag; - } else { - pkv = pidx + sizeof(uint32_t) * nTag; - } + pv = pIdx->idx + (nIdx << 2); } + pIdx->nCol = nIdx; - for (int32_t iColumn = 1; iColumn < pTSchema->numOfCols; iColumn++) { - pTColumn = &pTSchema->columns[iColumn]; - if (iColVal < nColVal) { - pColVal = (SColVal *)taosArrayGet(pArray, iColVal); - } else { - pColVal = NULL; - } - + while (pTColumn) { if (pColVal) { if (pColVal->cid == pTColumn->colId) { - iColVal++; + if (COL_VAL_IS_VALUE(pColVal)) { + if (flag & KV_FLG_LIT) { + ((uint8_t *)pIdx->idx)[iIdx] = (uint8_t)nv; + } else if (flag & KV_FLG_MID) { + ((uint16_t *)pIdx->idx)[iIdx] = (uint16_t)nv; + } else { + ((uint32_t *)pIdx->idx)[iIdx] = (uint32_t)nv; + } + iIdx++; - if (COL_VAL_IS_NONE(pColVal)) { - goto _set_none; + nv += tPutI16v(pv + nv, pTColumn->colId); + if (IS_VAR_DATA_TYPE(pTColumn->type)) { + nv += tPutU32v(pv + nv, pColVal->value.nData); + memcpy(pv + nv, pColVal->value.pData, pColVal->value.nData); + nv += pColVal->value.nData; + } else { + memcpy(pv + nv, &pColVal->value.val, pTColumn->bytes); + nv += pTColumn->bytes; + } } else if (COL_VAL_IS_NULL(pColVal)) { - goto _set_null; - } else { - goto _set_value; + if (flag & KV_FLG_LIT) { + ((uint8_t *)pIdx->idx)[iIdx] = (uint8_t)nv; + } else if (flag & KV_FLG_MID) { + ((uint16_t *)pIdx->idx)[iIdx] = (uint16_t)nv; + } else { + ((uint32_t *)pIdx->idx)[iIdx] = (uint32_t)nv; + } + iIdx++; + nv += tPutI16v(pv + nv, -pTColumn->colId); } - } else if (pColVal->cid > pTColumn->colId) { - goto _set_none; + + pTColumn = (++iTColumn < pTSchema->numOfCols) ? pTSchema->columns + iTColumn : NULL; + pColVal = (++iColVal < nColVal) ? (SColVal *)taosArrayGet(aColVal, iColVal) : NULL; + } else if (pColVal->cid > pTColumn->colId) { // NONE + pTColumn = (++iTColumn < pTSchema->numOfCols) ? pTSchema->columns + iTColumn : NULL; } else { - ASSERT(0); + pColVal = (++iColVal < nColVal) ? (SColVal *)taosArrayGet(aColVal, iColVal) : NULL; } - } else { - goto _set_none; + } else { // NONE + pTColumn = (++iTColumn < pTSchema->numOfCols) ? pTSchema->columns + iTColumn : NULL; } + } + } else { // TUPLE + uint8_t *pb = NULL; + uint8_t *pf = NULL; + uint8_t *pv = NULL; + int32_t nv = 0; - _set_none: - if ((flags & 0xf0) == 0) { - setBitMap(pb, 0, iColumn - 1, flags); - if (flags & TSROW_HAS_VAL) { // set 0 - if (IS_VAR_DATA_TYPE(pTColumn->type)) { - *(VarDataOffsetT *)(pf + pTColumn->offset) = 0; - } else { - tPutValue(pf + pTColumn->offset, &((SValue){0}), pTColumn->type); - } - } - } - continue; + switch (flag) { + case (HAS_NULL | HAS_NONE): + pb = pRow->data; + break; + case HAS_VALUE: + pf = pRow->data; + pv = pf + pTSchema->flen; + break; + case (HAS_VALUE | HAS_NONE): + case (HAS_VALUE | HAS_NULL): + pb = pRow->data; + pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1); + pv = pf + pTSchema->flen; + break; + case (HAS_VALUE | HAS_NULL | HAS_NONE): + pb = pRow->data; + pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1); + pv = pf + pTSchema->flen; + break; + default: + ASSERT(0); + break; + } - _set_null: - if ((flags & 0xf0) == 0) { - setBitMap(pb, 1, iColumn - 1, flags); - if (flags & TSROW_HAS_VAL) { // set 0 - if (IS_VAR_DATA_TYPE(pTColumn->type)) { - *(VarDataOffsetT *)(pf + pTColumn->offset) = 0; - } else { - tPutValue(pf + pTColumn->offset, &((SValue){0}), pTColumn->type); - } - } - } else { - SET_IDX(pidx, pTSKVRow->nCols, nkv, flags); - pTSKVRow->nCols++; - nkv += tPutI16v(pkv + nkv, -pTColumn->colId); - } - continue; + // build impl + while (pTColumn) { + if (pColVal) { + if (pColVal->cid == pTColumn->colId) { + if (COL_VAL_IS_VALUE(pColVal)) { // VALUE + ROW_SET_BITMAP(pb, flag, iTColumn - 1, ROW_BIT_VALUE); - _set_value: - if ((flags & 0xf0) == 0) { - setBitMap(pb, 2, iColumn - 1, flags); + if (IS_VAR_DATA_TYPE(pTColumn->type)) { + *(int32_t *)(pf + pTColumn->offset) = nv; + nv += tPutU32v(pv + nv, pColVal->value.nData); + if (pColVal->value.nData) { + memcpy(pv + nv, pColVal->value.pData, pColVal->value.nData); + nv += pColVal->value.nData; + } + } else { + memcpy(pf + pTColumn->offset, &pColVal->value.val, TYPE_BYTES[pTColumn->type]); + } + } else if (COL_VAL_IS_NONE(pColVal)) { // NONE + ROW_SET_BITMAP(pb, flag, iTColumn - 1, ROW_BIT_NONE); + if (pf) memset(pf + pTColumn->offset, 0, TYPE_BYTES[pTColumn->type]); + } else { // NULL + ROW_SET_BITMAP(pb, flag, iTColumn - 1, ROW_BIT_NULL); + if (pf) memset(pf + pTColumn->offset, 0, TYPE_BYTES[pTColumn->type]); + } - if (IS_VAR_DATA_TYPE(pTColumn->type)) { - *(VarDataOffsetT *)(pf + pTColumn->offset) = ntv; - ntv += tPutValue(ptv + ntv, &pColVal->value, pTColumn->type); + pTColumn = (++iTColumn < pTSchema->numOfCols) ? pTSchema->columns + iTColumn : NULL; + pColVal = (++iColVal < nColVal) ? (SColVal *)taosArrayGet(aColVal, iColVal) : NULL; + } else if (pColVal->cid > pTColumn->colId) { // NONE + ROW_SET_BITMAP(pb, flag, iTColumn - 1, ROW_BIT_NONE); + if (pf) memset(pf + pTColumn->offset, 0, TYPE_BYTES[pTColumn->type]); + pTColumn = (++iTColumn < pTSchema->numOfCols) ? pTSchema->columns + iTColumn : NULL; } else { - tPutValue(pf + pTColumn->offset, &pColVal->value, pTColumn->type); + pColVal = (++iColVal < nColVal) ? (SColVal *)taosArrayGet(aColVal, iColVal) : NULL; } - } else { - SET_IDX(pidx, pTSKVRow->nCols, nkv, flags); - pTSKVRow->nCols++; - nkv += tPutI16v(pkv + nkv, pColVal->cid); - nkv += tPutValue(pkv + nkv, &pColVal->value, pTColumn->type); + } else { // NONE + ROW_SET_BITMAP(pb, flag, iTColumn - 1, ROW_BIT_NONE); + if (pf) memset(pf + pTColumn->offset, 0, TYPE_BYTES[pTColumn->type]); + pTColumn = (++iTColumn < pTSchema->numOfCols) ? pTSchema->columns + iTColumn : NULL; } - continue; } } -#endif _exit: return code; } -int32_t tTSRowClone(const STSRow2 *pRow, STSRow2 **ppRow) { - int32_t code = 0; - int32_t rLen = 0; - - TSROW_LEN(pRow, rLen); - (*ppRow) = (STSRow2 *)taosMemoryMalloc(rLen); - if (*ppRow == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; - goto _exit; - } - memcpy(*ppRow, pRow, rLen); - -_exit: - return code; -} - -void tTSRowFree(STSRow2 *pRow) { - if (pRow) { - taosMemoryFree(pRow); - } -} - -void tTSRowGet(STSRow2 *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) { - uint8_t isTuple = ((pRow->flags & 0xf0) == 0) ? 1 : 0; - STColumn *pTColumn = &pTSchema->columns[iCol]; - uint8_t flags = pRow->flags & (uint8_t)0xf; - SValue value; - +void tRowGet(SRow *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) { ASSERT(iCol < pTSchema->numOfCols); - ASSERT(flags); ASSERT(pRow->sver == pTSchema->version); + STColumn *pTColumn = pTSchema->columns + iCol; + if (iCol == 0) { - value.ts = pRow->ts; - goto _return_value; + pColVal->cid = pTColumn->colId; + pColVal->type = pTColumn->type; + pColVal->flag = CV_FLAG_VALUE; + memcpy(&pColVal->value.val, &pRow->ts, sizeof(TSKEY)); + return; } - if (flags == TSROW_HAS_NONE) { - goto _return_none; - } else if (flags == TSROW_HAS_NULL) { - goto _return_null; + if (pRow->flag == HAS_NONE) { + *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type); + return; } - ASSERT(pRow->nData && pRow->pData); + if (pRow->flag == HAS_NULL) { + *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type); + return; + } - if (isTuple) { - uint8_t *pb = pRow->pData; - uint8_t *pf = NULL; + if (pRow->flag & 0xf0) { // KV Row + SKVIdx *pIdx = (SKVIdx *)pRow->data; uint8_t *pv = NULL; - uint8_t *p; - uint8_t b; - - // bit - switch (flags) { - case TSROW_HAS_VAL: - pf = pb; - break; - case TSROW_HAS_NULL | TSROW_HAS_NONE: - b = GET_BIT1(pb, iCol - 1); - if (b == 0) { - goto _return_none; - } else { - goto _return_null; - } - case TSROW_HAS_VAL | TSROW_HAS_NONE: - b = GET_BIT1(pb, iCol - 1); - if (b == 0) { - goto _return_none; - } else { - pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1); - break; - } - case TSROW_HAS_VAL | TSROW_HAS_NULL: - b = GET_BIT1(pb, iCol - 1); - if (b == 0) { - goto _return_null; - } else { - pf = pb + BIT1_SIZE(pTSchema->numOfCols - 1); - break; - } - case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE: - b = GET_BIT2(pb, iCol - 1); - if (b == 0) { - goto _return_none; - } else if (b == 1) { - goto _return_null; - } else { - pf = pb + BIT2_SIZE(pTSchema->numOfCols - 1); - break; - } - default: - ASSERT(0); - } - - ASSERT(pf); - - p = pf + pTColumn->offset; - if (IS_VAR_DATA_TYPE(pTColumn->type)) { - pv = pf + pTSchema->flen; - p = pv + *(VarDataOffsetT *)p; - } - tGetValue(p, &value, pTColumn->type); - goto _return_value; - } else { - STSKVRow *pRowK = (STSKVRow *)pRow->pData; - int16_t lidx = 0; - int16_t ridx = pRowK->nCols - 1; - uint8_t *p; - int16_t midx; - uint32_t n; - int16_t cid; - - ASSERT(pRowK->nCols > 0); - - if (pRow->flags & TSROW_KV_SMALL) { - p = pRow->pData + sizeof(STSKVRow) + sizeof(uint8_t) * pRowK->nCols; - } else if (pRow->flags & TSROW_KV_MID) { - p = pRow->pData + sizeof(STSKVRow) + sizeof(uint16_t) * pRowK->nCols; - } else if (pRow->flags & TSROW_KV_BIG) { - p = pRow->pData + sizeof(STSKVRow) + sizeof(uint32_t) * pRowK->nCols; + if (pRow->flag & KV_FLG_LIT) { + pv = pIdx->idx + pIdx->nCol; + } else if (pRow->flag & KV_FLG_MID) { + pv = pIdx->idx + (pIdx->nCol << 1); } else { - ASSERT(0); + pv = pIdx->idx + (pIdx->nCol << 2); } - while (lidx <= ridx) { - midx = (lidx + ridx) / 2; - if (pRow->flags & TSROW_KV_SMALL) { - n = ((uint8_t *)pRowK->idx)[midx]; - } else if (pRow->flags & TSROW_KV_MID) { - n = ((uint16_t *)pRowK->idx)[midx]; + int16_t lidx = 0; + int16_t ridx = pIdx->nCol - 1; + while (lidx <= ridx) { + int16_t mid = (lidx + ridx) >> 1; + uint8_t *pData = NULL; + if (pRow->flag & KV_FLG_LIT) { + pData = pv + ((uint8_t *)pIdx->idx)[mid]; + } else if (pRow->flag & KV_FLG_MID) { + pData = pv + ((uint16_t *)pIdx->idx)[mid]; } else { - n = ((uint32_t *)pRowK->idx)[midx]; + pData = pv + ((uint32_t *)pIdx->idx)[mid]; } - n += tGetI16v(p + n, &cid); + int16_t cid; + pData += tGetI16v(pData, &cid); if (TABS(cid) == pTColumn->colId) { if (cid < 0) { - goto _return_null; + *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type); } else { - n += tGetValue(p + n, &value, pTColumn->type); - goto _return_value; - } + pColVal->cid = pTColumn->colId; + pColVal->type = pTColumn->type; + pColVal->flag = CV_FLAG_VALUE; + if (IS_VAR_DATA_TYPE(pTColumn->type)) { + pData += tGetU32v(pData, &pColVal->value.nData); + if (pColVal->value.nData > 0) { + pColVal->value.pData = pData; + } else { + pColVal->value.pData = NULL; + } + } else { + memcpy(&pColVal->value.val, pData, pTColumn->bytes); + } + } return; - } else if (TABS(cid) > pTColumn->colId) { - ridx = midx - 1; + } else if (TABS(cid) < pTColumn->colId) { + lidx = mid + 1; } else { - lidx = midx + 1; + ridx = mid - 1; } } - // not found, return NONE - goto _return_none; - } + *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type); + } else { // Tuple Row + uint8_t *pf = NULL; + uint8_t *pv = NULL; + uint8_t bv = ROW_BIT_VALUE; -_return_none: - *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type); - return; + switch (pRow->flag) { + case HAS_VALUE: + pf = pRow->data; + pv = pf + pTSchema->flen; + break; + case (HAS_NULL | HAS_NONE): + bv = GET_BIT1(pRow->data, iCol - 1); + break; + case (HAS_VALUE | HAS_NONE): + bv = GET_BIT1(pRow->data, iCol - 1); + if (bv) bv++; + pf = pRow->data + BIT1_SIZE(pTSchema->numOfCols - 1); + pv = pf + pTSchema->flen; + break; + case (HAS_VALUE | HAS_NULL): + bv = GET_BIT1(pRow->data, iCol - 1); + bv++; + pf = pRow->data + BIT1_SIZE(pTSchema->numOfCols - 1); + pv = pf + pTSchema->flen; + break; + case (HAS_VALUE | HAS_NULL | HAS_NONE): + bv = GET_BIT2(pRow->data, iCol - 1); + pf = pRow->data + BIT2_SIZE(pTSchema->numOfCols - 1); + pv = pf + pTSchema->flen; + break; + default: + break; + } -_return_null: - *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type); - return; + if (bv == ROW_BIT_NONE) { + *pColVal = COL_VAL_NONE(pTColumn->colId, pTColumn->type); + return; + } else if (bv == ROW_BIT_NULL) { + *pColVal = COL_VAL_NULL(pTColumn->colId, pTColumn->type); + return; + } -_return_value: - *pColVal = COL_VAL_VALUE(pTColumn->colId, pTColumn->type, value); - return; + pColVal->cid = pTColumn->colId; + pColVal->type = pTColumn->type; + pColVal->flag = CV_FLAG_VALUE; + if (IS_VAR_DATA_TYPE(pTColumn->type)) { + uint8_t *pData = pv + *(int32_t *)(pf + pTColumn->offset); + pData += tGetU32v(pData, &pColVal->value.nData); + if (pColVal->value.nData) { + pColVal->value.pData = pData; + } else { + pColVal->value.pData = NULL; + } + } else { + memcpy(&pColVal->value.val, pv + pTColumn->offset, pTColumn->bytes); + } + } } -int32_t tTSRowToArray(STSRow2 *pRow, STSchema *pTSchema, SArray **ppArray) { - int32_t code = 0; +// SRowIter ======================================== +struct SRowIter { + SRow *pRow; + STSchema *pTSchema; + + int32_t iTColumn; + union { + struct { // kv + int32_t iCol; + SKVIdx *pIdx; + }; + struct { // tuple + uint8_t *pb; + uint8_t *pf; + }; + uint8_t *pv; + }; + SColVal cv; +}; - (*ppArray) = taosArrayInit(pTSchema->numOfCols, sizeof(SColVal)); - if (*ppArray == NULL) { - code = TSDB_CODE_OUT_OF_MEMORY; +int32_t tRowIterOpen(SRow *pRow, STSchema *pTSchema, SRowIter **ppIter) { + ASSERT(pRow->sver == pTSchema->version); + + int32_t code = 0; + + SRowIter *pIter = taosMemoryCalloc(1, sizeof(*pIter)); + if (pIter == NULL) { + code = TSDB_CODE_TDB_OUT_OF_MEMORY; goto _exit; } - for (int32_t iColumn = 0; iColumn < pTSchema->numOfCols; iColumn++) { - tTSRowGet(pRow, pTSchema, iColumn, &cv); - taosArrayPush(*ppArray, &cv); - } + pIter->pRow = pRow; + pIter->pTSchema = pTSchema; + pIter->iTColumn = 0; + + if (pRow->flag == HAS_NONE || pRow->flag == HAS_NULL) goto _exit; + if (pRow->flag & 0xf0) { + pIter->iCol = 0; + pIter->pIdx = (SKVIdx *)pRow->data; + if (pRow->flag & KV_FLG_LIT) { + pIter->pv = pIter->pIdx->idx + pIter->pIdx->nCol; + } else if (pRow->flag & KV_FLG_MID) { + pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 1); + } else { + pIter->pv = pIter->pIdx->idx + (pIter->pIdx->nCol << 2); + } + } else { + switch (pRow->flag) { + case (HAS_NULL | HAS_NONE): + pIter->pb = pRow->data; + break; + case HAS_VALUE: + pIter->pf = pRow->data; + pIter->pv = pIter->pf + pTSchema->flen; + break; + case (HAS_VALUE | HAS_NONE): + case (HAS_VALUE | HAS_NULL): + pIter->pb = pRow->data; + pIter->pf = pRow->data + BIT1_SIZE(pTSchema->numOfCols - 1); + pIter->pv = pIter->pf + pTSchema->flen; + break; + case (HAS_VALUE | HAS_NULL | HAS_NONE): + pIter->pb = pRow->data; + pIter->pf = pRow->data + BIT2_SIZE(pTSchema->numOfCols - 1); + pIter->pv = pIter->pf + pTSchema->flen; + break; + default: + ASSERT(0); + break; + } + } _exit: + if (code) { + *ppIter = NULL; + if (pIter) taosMemoryFree(pIter); + } else { + *ppIter = pIter; + } return code; } -#endif -int32_t tPutTSRow(uint8_t *p, STSRow2 *pRow) { - int32_t n = 0; - TSROW_LEN(pRow, n); - if (p) { - memcpy(p, pRow, n); +void tRowIterClose(SRowIter **ppIter) { + SRowIter *pIter = *ppIter; + if (pIter) { + taosMemoryFree(pIter); } - - return n; + *ppIter = NULL; } -int32_t tGetTSRow(uint8_t *p, STSRow2 **ppRow) { - int32_t n = 0; +SColVal *tRowIterNext(SRowIter *pIter) { + if (pIter->iTColumn >= pIter->pTSchema->numOfCols) { + return NULL; + } - *ppRow = (STSRow2 *)p; - TSROW_LEN(*ppRow, n); + STColumn *pTColumn = pIter->pTSchema->columns + pIter->iTColumn; - return n; -} + // timestamp + if (0 == pIter->iTColumn) { + pIter->cv.cid = pTColumn->colId; + pIter->cv.type = pTColumn->type; + pIter->cv.flag = CV_FLAG_VALUE; + memcpy(&pIter->cv.value.val, &pIter->pRow->ts, sizeof(TSKEY)); + goto _exit; + } -// STSchema ======================================== -int32_t tTSchemaCreate(int32_t sver, SSchema *pSchema, int32_t ncols, STSchema **ppTSchema) { - *ppTSchema = (STSchema *)taosMemoryMalloc(sizeof(STSchema) + sizeof(STColumn) * ncols); - if (*ppTSchema == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; + if (pIter->pRow->flag == HAS_NONE) { + pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type); + goto _exit; + } + + if (pIter->pRow->flag == HAS_NULL) { + pIter->cv = COL_VAL_NULL(pTColumn->type, pTColumn->colId); + goto _exit; } - (*ppTSchema)->numOfCols = ncols; - (*ppTSchema)->version = sver; - (*ppTSchema)->flen = 0; - (*ppTSchema)->vlen = 0; - (*ppTSchema)->tlen = 0; + if (pIter->pRow->flag & 0xf0) { // KV + if (pIter->iCol < pIter->pIdx->nCol) { + uint8_t *pData; - for (int32_t iCol = 0; iCol < ncols; iCol++) { - SSchema *pColumn = &pSchema[iCol]; - STColumn *pTColumn = &((*ppTSchema)->columns[iCol]); + if (pIter->pRow->flag & KV_FLG_LIT) { + pData = pIter->pv + ((uint8_t *)pIter->pIdx->idx)[pIter->iCol]; + } else if (pIter->pRow->flag & KV_FLG_MID) { + pData = pIter->pv + ((uint16_t *)pIter->pIdx->idx)[pIter->iCol]; + } else { + pData = pIter->pv + ((uint32_t *)pIter->pIdx->idx)[pIter->iCol]; + } + + int16_t cid; + pData += tGetI16v(pData, &cid); - pTColumn->colId = pColumn->colId; - pTColumn->type = pColumn->type; - pTColumn->flags = pColumn->flags; - pTColumn->bytes = pColumn->bytes; - pTColumn->offset = (*ppTSchema)->flen; + if (TABS(cid) == pTColumn->colId) { + if (cid < 0) { + pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type); + } else { + pIter->cv.cid = pTColumn->colId; + pIter->cv.type = pTColumn->type; + pIter->cv.flag = CV_FLAG_VALUE; - // skip first column - if (iCol) { - (*ppTSchema)->flen += TYPE_BYTES[pColumn->type]; - if (IS_VAR_DATA_TYPE(pColumn->type)) { - (*ppTSchema)->vlen += (pColumn->bytes + 5); + if (IS_VAR_DATA_TYPE(pTColumn->type)) { + pData += tGetU32v(pData, &pIter->cv.value.nData); + if (pIter->cv.value.nData > 0) { + pIter->cv.value.pData = pData; + } else { + pIter->cv.value.pData = NULL; + } + } else { + memcpy(&pIter->cv.value.val, pData, pTColumn->bytes); + } + } + + pIter->iCol++; + goto _exit; + } else if (TABS(cid) > pTColumn->colId) { + pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type); + goto _exit; + } else { + ASSERT(0); } + } else { + pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type); + goto _exit; } + } else { // Tuple + uint8_t bv = ROW_BIT_VALUE; + if (pIter->pb) { + switch (pIter->pRow->flag) { + case (HAS_NULL | HAS_NONE): + bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1); + break; + case (HAS_VALUE | HAS_NONE): + bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1); + if (bv) bv++; + break; + case (HAS_VALUE | HAS_NULL): + bv = GET_BIT1(pIter->pb, pIter->iTColumn - 1) + 1; + break; + case (HAS_VALUE | HAS_NULL | HAS_NONE): + bv = GET_BIT2(pIter->pb, pIter->iTColumn - 1); + break; + default: + ASSERT(0); + break; + } + + if (bv == ROW_BIT_NONE) { + pIter->cv = COL_VAL_NONE(pTColumn->colId, pTColumn->type); + goto _exit; + } else if (bv == ROW_BIT_NULL) { + pIter->cv = COL_VAL_NULL(pTColumn->colId, pTColumn->type); + goto _exit; + } + } + + pIter->cv.cid = pTColumn->colId; + pIter->cv.type = pTColumn->type; + pIter->cv.flag = CV_FLAG_VALUE; + if (IS_VAR_DATA_TYPE(pTColumn->type)) { + uint8_t *pData = pIter->pv + *(int32_t *)(pIter->pf + pTColumn->offset); + pData += tGetU32v(pData, &pIter->cv.value.nData); + if (pIter->cv.value.nData > 0) { + pIter->cv.value.pData = pData; + } else { + pIter->cv.value.pData = NULL; + } + } else { + memcpy(&pIter->cv.value.val, pIter->pv + pTColumn->offset, pTColumn->bytes); + } + goto _exit; } - return 0; +_exit: + pIter->iTColumn++; + return &pIter->cv; } -void tTSchemaDestroy(STSchema *pTSchema) { - if (pTSchema) taosMemoryFree(pTSchema); -} +// STSchema ======================================== // STag ======================================== static int tTagValCmprFn(const void *p1, const void *p2) { @@ -1042,7 +1108,6 @@ void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) { pBuilder->nCols = 0; pBuilder->tlen = 0; pBuilder->flen = 0; - pBuilder->vlen = 0; pBuilder->version = version; } @@ -1061,24 +1126,21 @@ int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t flags, c pCol->colId = colId; pCol->flags = flags; if (pBuilder->nCols == 0) { - pCol->offset = 0; + pCol->offset = -1; } else { - STColumn *pTCol = &(pBuilder->columns[pBuilder->nCols - 1]); - pCol->offset = pTCol->offset + TYPE_BYTES[pTCol->type]; + pCol->offset = pBuilder->flen; + pBuilder->flen += TYPE_BYTES[type]; } if (IS_VAR_DATA_TYPE(type)) { pCol->bytes = bytes; pBuilder->tlen += (TYPE_BYTES[type] + bytes); - pBuilder->vlen += bytes - sizeof(VarDataLenT); } else { pCol->bytes = TYPE_BYTES[type]; pBuilder->tlen += TYPE_BYTES[type]; - pBuilder->vlen += TYPE_BYTES[type]; } pBuilder->nCols++; - pBuilder->flen += TYPE_BYTES[type]; ASSERT(pCol->offset < pBuilder->flen); @@ -1097,7 +1159,6 @@ STSchema *tdGetSchemaFromBuilder(STSchemaBuilder *pBuilder) { pSchema->numOfCols = pBuilder->nCols; pSchema->tlen = pBuilder->tlen; pSchema->flen = pBuilder->flen; - pSchema->vlen = pBuilder->vlen; #ifdef TD_SUPPORT_BITMAP pSchema->tlen += (int)TD_BITMAP_BYTES(pSchema->numOfCols); @@ -1110,6 +1171,43 @@ STSchema *tdGetSchemaFromBuilder(STSchemaBuilder *pBuilder) { #endif +STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) { + STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols); + if (pTSchema == NULL) return NULL; + + pTSchema->numOfCols = numOfCols; + pTSchema->version = version; + + // timestamp column + ASSERT(aSchema[0].type == TSDB_DATA_TYPE_TIMESTAMP); + ASSERT(aSchema[0].colId == PRIMARYKEY_TIMESTAMP_COL_ID); + pTSchema->columns[0].colId = aSchema[0].colId; + pTSchema->columns[0].type = aSchema[0].type; + pTSchema->columns[0].flags = aSchema[0].flags; + pTSchema->columns[0].bytes = aSchema[0].bytes; + pTSchema->columns[0].offset = -1; + + // other columns + for (int32_t iCol = 1; iCol < numOfCols; iCol++) { + SSchema *pSchema = &aSchema[iCol]; + STColumn *pTColumn = &pTSchema->columns[iCol]; + + pTColumn->colId = pSchema->colId; + pTColumn->type = pSchema->type; + pTColumn->flags = pSchema->flags; + pTColumn->bytes = pSchema->bytes; + pTColumn->offset = pTSchema->flen; + + pTSchema->flen += TYPE_BYTES[pTColumn->type]; + } + + return pTSchema; +} + +void tDestroyTSchema(STSchema *pTSchema) { + if (pTSchema) taosMemoryFree(pTSchema); +} + // SColData ======================================== void tColDataDestroy(void *ph) { SColData *pColData = (SColData *)ph; @@ -1496,7 +1594,7 @@ static FORCE_INLINE void tColDataGetValue4(SColData *pColData, int32_t iVal, SCo } value.pData = pColData->pData + pColData->aOffset[iVal]; } else { - tGetValue(pColData->pData + tDataTypes[pColData->type].bytes * iVal, &value, pColData->type); + memcpy(&value.val, pColData->pData + tDataTypes[pColData->type].bytes * iVal, tDataTypes[pColData->type].bytes); } *pColVal = COL_VAL_VALUE(pColData->cid, pColData->type, value); } diff --git a/source/common/src/trow.c b/source/common/src/trow.c index 653cd34b3717d9cf870fad2676519864c7fe5a6e..52ebd7f879f5b4cc6a675d01de2300b6ed24f412 100644 --- a/source/common/src/trow.c +++ b/source/common/src/trow.c @@ -192,7 +192,7 @@ bool tdSTpRowGetVal(STSRow *pRow, col_id_t colId, col_type_t colType, int32_t fl return true; } void *pBitmap = tdGetBitmapAddrTp(pRow, flen); - tdGetTpRowValOfCol(pVal, pRow, pBitmap, colType, offset - sizeof(TSKEY), colIdx); + tdGetTpRowValOfCol(pVal, pRow, pBitmap, colType, offset, colIdx); return true; } @@ -217,7 +217,7 @@ bool tdSTSRowIterFetch(STSRowIter *pIter, col_id_t colId, col_type_t colType, SC return false; } } - tdSTSRowIterGetTpVal(pIter, pCol->type, pCol->offset - sizeof(TSKEY), pVal); + tdSTSRowIterGetTpVal(pIter, pCol->type, pCol->offset, pVal); ++pIter->colIdx; } else if (TD_IS_KV_ROW(pIter->pRow)) { return tdSTSRowIterGetKvVal(pIter, colId, &pIter->kvIdx, pVal); @@ -244,7 +244,7 @@ bool tdSTSRowIterNext(STSRowIter *pIter, SCellVal *pVal) { } if (TD_IS_TP_ROW(pIter->pRow)) { - tdSTSRowIterGetTpVal(pIter, pCol->type, pCol->offset - sizeof(TSKEY), pVal); + tdSTSRowIterGetTpVal(pIter, pCol->type, pCol->offset, pVal); } else if (TD_IS_KV_ROW(pIter->pRow)) { tdSTSRowIterGetKvVal(pIter, pCol->colId, &pIter->kvIdx, pVal); } else { @@ -469,7 +469,7 @@ bool tdSTSRowGetVal(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCell #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); + tdGetTpRowValOfCol(pVal, pRow, pIter->pBitmap, pCol->type, pCol->offset, 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); @@ -757,11 +757,10 @@ int32_t tdAppendColValToKvRow(SRowBuilder *pBuilder, TDRowValT valType, const vo 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)) { + if (colIdx < 1) { terrno = TSDB_CODE_INVALID_PARA; return terrno; } - offset -= sizeof(TSKEY); --colIdx; #ifdef TD_SUPPORT_BITMAP @@ -853,7 +852,7 @@ int32_t tdSRowResetBuf(SRowBuilder *pBuilder, void *pBuf) { 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; + len = TD_ROW_HEAD_LEN + pBuilder->flen + pBuilder->nBitmaps; TD_ROW_SET_LEN(pBuilder->pBuf, len); TD_ROW_SET_SVER(pBuilder->pBuf, pBuilder->sver); break; diff --git a/source/common/src/ttypes.c b/source/common/src/ttypes.c index 8c5d44b8d58f00281784c9103eee5c9d6d8c6901..7b5d0a8805ed77ac580d5c4c2f02d699338012f7 100644 --- a/source/common/src/ttypes.c +++ b/source/common/src/ttypes.c @@ -61,7 +61,7 @@ tDataTypeDescriptor tDataTypes[TSDB_DATA_TYPE_MAX] = { static float floatMin = -FLT_MAX, floatMax = FLT_MAX; static double doubleMin = -DBL_MAX, doubleMax = DBL_MAX; -FORCE_INLINE void *getDataMin(int32_t type, void* value) { +FORCE_INLINE void *getDataMin(int32_t type, void *value) { switch (type) { case TSDB_DATA_TYPE_FLOAT: *(float *)value = floatMin; @@ -77,7 +77,7 @@ FORCE_INLINE void *getDataMin(int32_t type, void* value) { return value; } -FORCE_INLINE void *getDataMax(int32_t type, void* value) { +FORCE_INLINE void *getDataMax(int32_t type, void *value) { switch (type) { case TSDB_DATA_TYPE_FLOAT: *(float *)value = floatMax; diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c index 16fe6c1b91f8a7788ad4a48993b337fe6bc7b160..ceb452c5519c168611fb432443bbdf0be6c52937 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c @@ -196,7 +196,7 @@ SArray *mmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_SYNC_PRE_SNAPSHOT, mmPutMsgToSyncQueue, 1) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_SYNC_PRE_SNAPSHOT_REPLY, mmPutMsgToSyncQueue, 1) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_SYNC_HEARTBEAT, mmPutMsgToSyncCtrlQueue, 1) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_SYNC_HEARTBEAT_REPLY, mmPutMsgToSyncCtrlQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_SYNC_HEARTBEAT_REPLY, mmPutMsgToSyncQueue, 1) == NULL) goto _OVER; code = 0; diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index e15d7ac3dfa122f4204a4cd8301920ba1fba2cd1..743beb7f823376f5f517564c0ffbfeef32c50f1f 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -464,7 +464,7 @@ SArray *vmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_SYNC_PRE_SNAPSHOT_REPLY, vmPutMsgToSyncQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_SYNC_HEARTBEAT, vmPutMsgToSyncCtrlQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_SYNC_HEARTBEAT_REPLY, vmPutMsgToSyncCtrlQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_SYNC_HEARTBEAT_REPLY, vmPutMsgToSyncQueue, 0) == NULL) goto _OVER; code = 0; diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h index c6e2842c321b1025445c4070f94fe3d6e9a05ae5..d335e84c4c4c653e533b3f19b0a174f7eefa0f34 100644 --- a/source/dnode/vnode/src/inc/tsdb.h +++ b/source/dnode/vnode/src/inc/tsdb.h @@ -56,7 +56,7 @@ typedef struct SDataFWriter SDataFWriter; typedef struct SDataFReader SDataFReader; typedef struct SDelFWriter SDelFWriter; typedef struct SDelFReader SDelFReader; -typedef struct SRowIter SRowIter; +typedef struct STSDBRowIter STSDBRowIter; typedef struct STsdbFS STsdbFS; typedef struct SRowMerger SRowMerger; typedef struct STsdbReadSnap STsdbReadSnap; @@ -111,9 +111,9 @@ static FORCE_INLINE int64_t tsdbLogicToFileSize(int64_t lSize, int32_t szPage) { void tsdbRowGetColVal(TSDBROW *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal); // int32_t tPutTSDBRow(uint8_t *p, TSDBROW *pRow); int32_t tsdbRowCmprFn(const void *p1, const void *p2); -// SRowIter -void tRowIterInit(SRowIter *pIter, TSDBROW *pRow, STSchema *pTSchema); -SColVal *tRowIterNext(SRowIter *pIter); +// STSDBRowIter +void tsdbRowIterInit(STSDBRowIter *pIter, TSDBROW *pRow, STSchema *pTSchema); +SColVal *tsdbRowIterNext(STSDBRowIter *pIter); // SRowMerger int32_t tRowMergerInit2(SRowMerger *pMerger, STSchema *pResTSchema, TSDBROW *pRow, STSchema *pTSchema); int32_t tRowMergerAdd(SRowMerger *pMerger, TSDBROW *pRow, STSchema *pTSchema); @@ -562,7 +562,7 @@ struct SDFileSet { SSttFile *aSttF[TSDB_MAX_STT_TRIGGER]; }; -struct SRowIter { +struct STSDBRowIter { TSDBROW *pRow; STSchema *pTSchema; SColVal colVal; diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit.c b/source/dnode/vnode/src/tsdb/tsdbCommit.c index 65a46331aa8d4bd62f29f4e0c6c068ef4f95a6cd..cf9ae30ff07e3e17bacc9ae71ea5f222b5c16827 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCommit.c +++ b/source/dnode/vnode/src/tsdb/tsdbCommit.c @@ -341,7 +341,7 @@ int32_t tsdbUpdateTableSchema(SMeta *pMeta, int64_t suid, int64_t uid, SSkmInfo pSkmInfo->suid = suid; pSkmInfo->uid = uid; - tTSchemaDestroy(pSkmInfo->pTSchema); + tDestroyTSchema(pSkmInfo->pTSchema); code = metaGetTbTSchemaEx(pMeta, suid, uid, -1, &pSkmInfo->pTSchema); TSDB_CHECK_CODE(code, lino, _exit); @@ -365,7 +365,7 @@ static int32_t tsdbCommitterUpdateRowSchema(SCommitter *pCommitter, int64_t suid pCommitter->skmRow.suid = suid; pCommitter->skmRow.uid = uid; - tTSchemaDestroy(pCommitter->skmRow.pTSchema); + tDestroyTSchema(pCommitter->skmRow.pTSchema); code = metaGetTbTSchemaEx(pCommitter->pTsdb->pVnode->pMeta, suid, uid, sver, &pCommitter->skmRow.pTSchema); TSDB_CHECK_CODE(code, lino, _exit); @@ -498,7 +498,7 @@ static int32_t tsdbCommitFileDataStart(SCommitter *pCommitter) { #if 0 ASSERT(pCommitter->minKey <= pCommitter->nextKey && pCommitter->maxKey >= pCommitter->nextKey); #endif - + pCommitter->nextKey = TSKEY_MAX; // Reader @@ -623,7 +623,8 @@ int32_t tsdbWriteDataBlock(SDataFWriter *pWriter, SBlockData *pBlockData, SMapDa _exit: if (code) { - tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, + tstrerror(code)); } return code; } @@ -666,7 +667,8 @@ int32_t tsdbWriteSttBlock(SDataFWriter *pWriter, SBlockData *pBlockData, SArray _exit: if (code) { - tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, + tstrerror(code)); } return code; } @@ -706,7 +708,8 @@ static int32_t tsdbCommitSttBlk(SDataFWriter *pWriter, SDiskDataBuilder *pBuilde _exit: if (code) { - tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, tstrerror(code)); + tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pWriter->pTsdb->pVnode), __func__, lino, + tstrerror(code)); } return code; } @@ -919,8 +922,8 @@ static void tsdbCommitDataEnd(SCommitter *pCommitter) { #else tBlockDataDestroy(&pCommitter->dWriter.bDatal, 1); #endif - tTSchemaDestroy(pCommitter->skmTable.pTSchema); - tTSchemaDestroy(pCommitter->skmRow.pTSchema); + tDestroyTSchema(pCommitter->skmTable.pTSchema); + tDestroyTSchema(pCommitter->skmRow.pTSchema); } static int32_t tsdbCommitData(SCommitter *pCommitter) { diff --git a/source/dnode/vnode/src/tsdb/tsdbDiskData.c b/source/dnode/vnode/src/tsdb/tsdbDiskData.c index 9f59707ddc469a3aff34a0f8817393773a63de11..b46a00363817666cdff7bc7756ff204483787c36 100644 --- a/source/dnode/vnode/src/tsdb/tsdbDiskData.c +++ b/source/dnode/vnode/src/tsdb/tsdbDiskData.c @@ -595,21 +595,21 @@ int32_t tDiskDataAddRow(SDiskDataBuilder *pBuilder, TSDBROW *pRow, STSchema *pTS if (pBuilder->bi.minKey > kRow.ts) pBuilder->bi.minKey = kRow.ts; if (pBuilder->bi.maxKey < kRow.ts) pBuilder->bi.maxKey = kRow.ts; - SRowIter iter = {0}; - tRowIterInit(&iter, pRow, pTSchema); + STSDBRowIter iter = {0}; + tsdbRowIterInit(&iter, pRow, pTSchema); - SColVal *pColVal = tRowIterNext(&iter); + SColVal *pColVal = tsdbRowIterNext(&iter); for (int32_t iBuilder = 0; iBuilder < pBuilder->nBuilder; iBuilder++) { SDiskColBuilder *pDCBuilder = (SDiskColBuilder *)taosArrayGet(pBuilder->aBuilder, iBuilder); while (pColVal && pColVal->cid < pDCBuilder->cid) { - pColVal = tRowIterNext(&iter); + pColVal = tsdbRowIterNext(&iter); } if (pColVal && pColVal->cid == pDCBuilder->cid) { code = tDiskColAddVal(pDCBuilder, pColVal); if (code) return code; - pColVal = tRowIterNext(&iter); + pColVal = tsdbRowIterNext(&iter); } else { code = tDiskColAddVal(pDCBuilder, &COL_VAL_NONE(pDCBuilder->cid, pDCBuilder->type)); if (code) return code; diff --git a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c index ec89bed17a8c9ee002d751ee0c43bb5c0f5170e2..f4bdeeb387842d1a959f7269608a6f29f6decf28 100644 --- a/source/dnode/vnode/src/tsdb/tsdbSnapshot.c +++ b/source/dnode/vnode/src/tsdb/tsdbSnapshot.c @@ -555,7 +555,7 @@ int32_t tsdbSnapReaderClose(STsdbSnapReader** ppReader) { } tBlockDataDestroy(&pReader->bData, 1); - tTSchemaDestroy(pReader->skmTable.pTSchema); + tDestroyTSchema(pReader->skmTable.pTSchema); // del if (pReader->pDelFReader) tsdbDelFReaderClose(&pReader->pDelFReader); @@ -1416,7 +1416,7 @@ int32_t tsdbSnapWriterClose(STsdbSnapWriter** ppWriter, int8_t rollback) { taosArrayDestroy(pWriter->dReader.aBlockIdx); tBlockDataDestroy(&pWriter->bData, 1); - tTSchemaDestroy(pWriter->skmTable.pTSchema); + tDestroyTSchema(pWriter->skmTable.pTSchema); for (int32_t iBuf = 0; iBuf < sizeof(pWriter->aBuf) / sizeof(uint8_t*); iBuf++) { tFree(pWriter->aBuf[iBuf]); diff --git a/source/dnode/vnode/src/tsdb/tsdbUtil.c b/source/dnode/vnode/src/tsdb/tsdbUtil.c index b0cf09662c9e4ffccb663fd1689fcd16668cf05b..599428564788afeb1c962965f95c4fc35cde8a4a 100644 --- a/source/dnode/vnode/src/tsdb/tsdbUtil.c +++ b/source/dnode/vnode/src/tsdb/tsdbUtil.c @@ -579,8 +579,8 @@ int32_t tsdbRowCmprFn(const void *p1, const void *p2) { return tsdbKeyCmprFn(&TSDBROW_KEY((TSDBROW *)p1), &TSDBROW_KEY((TSDBROW *)p2)); } -// SRowIter ====================================================== -void tRowIterInit(SRowIter *pIter, TSDBROW *pRow, STSchema *pTSchema) { +// STSDBRowIter ====================================================== +void tsdbRowIterInit(STSDBRowIter *pIter, TSDBROW *pRow, STSchema *pTSchema) { pIter->pRow = pRow; if (pRow->type == 0) { ASSERT(pTSchema); @@ -594,7 +594,7 @@ void tRowIterInit(SRowIter *pIter, TSDBROW *pRow, STSchema *pTSchema) { } } -SColVal *tRowIterNext(SRowIter *pIter) { +SColVal *tsdbRowIterNext(STSDBRowIter *pIter) { if (pIter->pRow->type == 0) { if (pIter->i < pIter->pTSchema->numOfCols) { tTSRowGetVal(pIter->pRow->pTSRow, pIter->pTSchema, pIter->i, &pIter->colVal); @@ -1084,11 +1084,11 @@ static int32_t tBlockDataAppendTPRow(SBlockData *pBlockData, STSRow *pRow, STSch cv.flag = CV_FLAG_VALUE; if (IS_VAR_DATA_TYPE(pTColumn->type)) { - void *pData = (char *)pRow + *(int32_t *)(pRow->data + pTColumn->offset - sizeof(TSKEY)); + void *pData = (char *)pRow + *(int32_t *)(pRow->data + pTColumn->offset); cv.value.nData = varDataLen(pData); cv.value.pData = varDataVal(pData); } else { - memcpy(&cv.value.val, pRow->data + pTColumn->offset - sizeof(TSKEY), pTColumn->bytes); + memcpy(&cv.value.val, pRow->data + pTColumn->offset, pTColumn->bytes); } code = tColDataAppendValue(pColData, &cv); @@ -1106,11 +1106,11 @@ static int32_t tBlockDataAppendTPRow(SBlockData *pBlockData, STSRow *pRow, STSch cv.flag = CV_FLAG_VALUE; if (IS_VAR_DATA_TYPE(pTColumn->type)) { - void *pData = (char *)pRow + *(int32_t *)(pRow->data + pTColumn->offset - sizeof(TSKEY)); + void *pData = (char *)pRow + *(int32_t *)(pRow->data + pTColumn->offset); cv.value.nData = varDataLen(pData); cv.value.pData = varDataVal(pData); } else { - memcpy(&cv.value.val, pRow->data + pTColumn->offset - sizeof(TSKEY), pTColumn->bytes); + memcpy(&cv.value.val, pRow->data + pTColumn->offset, pTColumn->bytes); } code = tColDataAppendValue(pColData, &cv); diff --git a/source/libs/parser/src/parInsertStmt.c b/source/libs/parser/src/parInsertStmt.c index 9a5f349d8fe1f9da5bd2290832b3d5ab61cb7688..a6ce71211a3f36dc5d2ab46b2740fa94e00343ed 100644 --- a/source/libs/parser/src/parInsertStmt.c +++ b/source/libs/parser/src/parInsertStmt.c @@ -47,6 +47,7 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen) { STableDataBlocks* pDataBlock = (STableDataBlocks*)pBlock; SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen}; + int32_t code = TSDB_CODE_SUCCESS; SParsedDataColInfo* tags = (SParsedDataColInfo*)boundTags; if (NULL == tags) { return TSDB_CODE_QRY_APP_ERROR; @@ -59,10 +60,10 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch SArray* tagName = taosArrayInit(8, TSDB_COL_NAME_LEN); if (!tagName) { - return buildInvalidOperationMsg(&pBuf, "out of memory"); + code = buildInvalidOperationMsg(&pBuf, "out of memory"); + goto end; } - int32_t code = TSDB_CODE_SUCCESS; SSchema* pSchema = getTableTagSchema(pDataBlock->pTableMeta); bool isJson = false; @@ -77,6 +78,10 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch int32_t colLen = pTagSchema->bytes; if (IS_VAR_DATA_TYPE(pTagSchema->type)) { colLen = bind[c].length[0]; + if ((colLen + VARSTR_HEADER_SIZE) > pTagSchema->bytes) { + code = buildInvalidOperationMsg(&pBuf, "tag length is too big"); + goto end; + } } taosArrayPush(tagName, pTagSchema->name); if (pTagSchema->type == TSDB_DATA_TYPE_JSON) { diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c index bc09163753d91e883d4e0f176bb97733cfca2c33..5f8120171f10a7c00a4d5237606902de4dca9ab4 100644 --- a/source/libs/parser/src/parInsertUtil.c +++ b/source/libs/parser/src/parInsertUtil.c @@ -139,8 +139,8 @@ void insSetBoundColumnInfo(SParsedDataColInfo* pColList, SSchema* pSchema, col_i if (i > 0) { pColList->cols[i].offset = pColList->cols[i - 1].offset + pSchema[i - 1].bytes; pColList->cols[i].toffset = pColList->flen; + pColList->flen += TYPE_BYTES[type]; } - pColList->flen += TYPE_BYTES[type]; switch (type) { case TSDB_DATA_TYPE_BINARY: pColList->allNullLen += (VARSTR_HEADER_SIZE + CHAR_BYTES); diff --git a/source/libs/qworker/src/qworker.c b/source/libs/qworker/src/qworker.c index 4caa266d8acbda5ce5f511267202ca3930916c9b..aad9a52126541dc4132eb18d5740366433fe29cf 100644 --- a/source/libs/qworker/src/qworker.c +++ b/source/libs/qworker/src/qworker.c @@ -743,7 +743,7 @@ int32_t qwProcessCQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg) { } QW_LOCK(QW_WRITE, &ctx->lock); - if (queryStop || code || 0 == atomic_load_8((int8_t *)&ctx->queryContinue)) { + if ((queryStop && (0 == atomic_load_8((int8_t *)&ctx->queryContinue))) || code || 0 == atomic_load_8((int8_t *)&ctx->queryContinue)) { // Note: query is not running anymore QW_SET_PHASE(ctx, 0); QW_UNLOCK(QW_WRITE, &ctx->lock); diff --git a/source/libs/sync/inc/syncInt.h b/source/libs/sync/inc/syncInt.h index 57f52c7d88204793975c1c78222fdb58424a7fad..1e72b4eb261ff1f7137df85ccddb0af8fe17e030 100644 --- a/source/libs/sync/inc/syncInt.h +++ b/source/libs/sync/inc/syncInt.h @@ -232,6 +232,7 @@ int32_t syncNodeSendMsgById(const SRaftId* destRaftId, SSyncNode* pSyncNode, S int32_t syncNodeSendMsgByInfo(const SNodeInfo* nodeInfo, SSyncNode* pSyncNode, SRpcMsg* pMsg); SyncIndex syncMinMatchIndex(SSyncNode* pSyncNode); int32_t syncCacheEntry(SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry, LRUHandle** h); +bool syncNodeHeartbeatTimeout(SSyncNode* pSyncNode); // raft state change -------------- void syncNodeUpdateTerm(SSyncNode* pSyncNode, SyncTerm term); diff --git a/source/libs/sync/inc/syncMessage.h b/source/libs/sync/inc/syncMessage.h index 92e7b555a44e5fda4d1012913dcc906f8d876f3c..acaf499cbbfa90a81814a4ceb8e0e3d8d546b784 100644 --- a/source/libs/sync/inc/syncMessage.h +++ b/source/libs/sync/inc/syncMessage.h @@ -137,6 +137,7 @@ typedef struct SyncHeartbeatReply { SyncTerm term; SyncTerm privateTerm; int64_t startTime; + int64_t timeStamp; } SyncHeartbeatReply; typedef struct SyncPreSnapshot { diff --git a/source/libs/sync/src/syncIndexMgr.c b/source/libs/sync/src/syncIndexMgr.c index ca5e531528afd76fbbb68e61cbe3224e337b89a6..830e50fc4fe04938b6787d0e7150d460d368d376 100644 --- a/source/libs/sync/src/syncIndexMgr.c +++ b/source/libs/sync/src/syncIndexMgr.c @@ -50,9 +50,10 @@ void syncIndexMgrClear(SSyncIndexMgr *pSyncIndexMgr) { memset(pSyncIndexMgr->privateTerm, 0, sizeof(pSyncIndexMgr->privateTerm)); // int64_t timeNow = taosGetMonotonicMs(); + int64_t timeNow = taosGetTimestampMs(); for (int i = 0; i < pSyncIndexMgr->replicaNum; ++i) { pSyncIndexMgr->startTimeArr[i] = 0; - pSyncIndexMgr->recvTimeArr[i] = 0; + pSyncIndexMgr->recvTimeArr[i] = timeNow; } /* @@ -147,7 +148,7 @@ int64_t syncIndexMgrGetRecvTime(SSyncIndexMgr *pSyncIndexMgr, const SRaftId *pRa return recvTime; } } - ASSERT(0); + return -1; } diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c index 88b8ba7e2531bd386fdd224ef1651c5992a6dc7d..d9f6753daccfd07e04f6b6120c7f12d6866fc129 100644 --- a/source/libs/sync/src/syncMain.c +++ b/source/libs/sync/src/syncMain.c @@ -639,6 +639,14 @@ int32_t syncNodePropose(SSyncNode* pSyncNode, SRpcMsg* pMsg, bool isWeak) { return -1; } + // heartbeat timeout + if (syncNodeHeartbeatTimeout(pSyncNode)) { + terrno = TSDB_CODE_SYN_PROPOSE_NOT_READY; + sNError(pSyncNode, "failed to sync propose since hearbeat timeout, type:%s, last:%" PRId64 ", cmt:%" PRId64, + TMSG_INFO(pMsg->msgType), syncNodeGetLastIndex(pSyncNode), pSyncNode->commitIndex); + return -1; + } + // optimized one replica if (syncNodeIsOptimizedOneReplica(pSyncNode, pMsg)) { SyncIndex retIndex; @@ -2086,6 +2094,29 @@ int32_t syncCacheEntry(SSyncLogStore* pLogStore, SSyncRaftEntry* pEntry, LRUHand return code; } +bool syncNodeHeartbeatTimeout(SSyncNode* pSyncNode) { + if (pSyncNode->replicaNum == 1) { + return false; + } + + int32_t toCount = 0; + int64_t tsNow = taosGetTimestampMs(); + for (int32_t i = 0; i < pSyncNode->peersNum; ++i) { + int64_t recvTime = syncIndexMgrGetRecvTime(pSyncNode->pMatchIndex, &(pSyncNode->peersId[i])); + if (recvTime == 0 || recvTime == -1) { + continue; + } + + if (tsNow - recvTime > SYNC_HEART_TIMEOUT_MS) { + toCount++; + } + } + + bool b = (toCount >= pSyncNode->quorum ? true : false); + + return b; +} + static int32_t syncNodeAppendNoop(SSyncNode* ths) { int32_t ret = 0; @@ -2127,6 +2158,7 @@ int32_t syncNodeOnHeartbeat(SSyncNode* ths, const SRpcMsg* pRpcMsg) { pMsgReply->srcId = ths->myRaftId; pMsgReply->term = ths->pRaftStore->currentTerm; pMsgReply->privateTerm = 8864; // magic number + pMsgReply->timeStamp = taosGetTimestampMs(); if (pMsg->term == ths->pRaftStore->currentTerm && ths->state != TAOS_SYNC_STATE_LEADER) { syncNodeResetElectTimer(ths); @@ -2191,7 +2223,7 @@ int32_t syncNodeOnHeartbeatReply(SSyncNode* ths, const SRpcMsg* pRpcMsg) { syncLogRecvHeartbeatReply(ths, pMsg, ""); // update last reply time, make decision whether the other node is alive or not - syncIndexMgrSetRecvTime(ths->pMatchIndex, &pMsg->destId, pMsg->startTime); + syncIndexMgrSetRecvTime(ths->pMatchIndex, &pMsg->srcId, pMsg->timeStamp); return 0; } diff --git a/source/libs/sync/src/syncUtil.c b/source/libs/sync/src/syncUtil.c index da6f8a52d92499abf4b21d0a5582f9dfb391ad21..4c847862865fbd4be754a9a108924a7967fe2f17 100644 --- a/source/libs/sync/src/syncUtil.c +++ b/source/libs/sync/src/syncUtil.c @@ -424,8 +424,8 @@ void syncLogRecvHeartbeatReply(SSyncNode* pSyncNode, const SyncHeartbeatReply* p char host[64]; uint16_t port; syncUtilU642Addr(pMsg->srcId.addr, host, sizeof(host), &port); - sNTrace(pSyncNode, "recv sync-heartbeat-reply from %s:%d {term:%" PRId64 ", pterm:%" PRId64 "}, %s", host, port, - pMsg->term, pMsg->privateTerm, s); + sNTrace(pSyncNode, "recv sync-heartbeat-reply from %s:%d {term:%" PRId64 ", ts:%" PRId64 "}, %s", host, port, + pMsg->term, pMsg->timeStamp, s); } void syncLogSendSyncPreSnapshot(SSyncNode* pSyncNode, const SyncPreSnapshot* pMsg, const char* s) {