diff --git a/src/common/inc/tdataformat.h b/src/common/inc/tdataformat.h index a9350769a183cf806a2dbe9bfc01e94225ff4fa3..74f636e3f7b73df6f1d8a0a6bc05ce4446017e36 100644 --- a/src/common/inc/tdataformat.h +++ b/src/common/inc/tdataformat.h @@ -267,6 +267,22 @@ static FORCE_INLINE void *tdGetKVRowDataOfCol(SKVDataRow row, int16_t colId) { return kvDataRowColVal(row, (SColIdx *)ret); } +// ----------------- K-V data row builder +typedef struct { + int16_t tCols; + int16_t nCols; + SColIdx *pColIdx; + int16_t alloc; + int16_t size; + void * buf; +} SKVDataRowBuilder; + +int tdInitKVDataRowBuilder(SKVDataRowBuilder *pBuilder); +void tdDestroyKVDataRowBuilder(SKVDataRowBuilder *pBuilder); +void tdResetKVDataRowBuilder(SKVDataRowBuilder *pBuilder); +SKVDataRow tdGetKVDataRowFromBuilder(SKVDataRowBuilder *pBuilder); +int tdAddColToKVDataRow(SKVDataRowBuilder *pBuilder, int16_t colId, int8_t type, void *value); + // ----------------- Tag row structure /* A tag row, the format is like below: diff --git a/src/common/src/tdataformat.c b/src/common/src/tdataformat.c index 3429970e7346ad35bf5280c4263e438f2ac116cf..2658d8f2808cf8012ee93c46032dc1272c8abef4 100644 --- a/src/common/src/tdataformat.c +++ b/src/common/src/tdataformat.c @@ -679,4 +679,72 @@ void *tdEncodeKVDataRow(void *buf, SKVDataRow row) { void *tdDecodeKVDataRow(void *buf, SKVDataRow *row) { *row = tdKVDataRowDup(buf); return POINTER_SHIFT(buf, kvDataRowLen(*row)); +} + +int tdInitKVDataRowBuilder(SKVDataRowBuilder *pBuilder) { + pBuilder->tCols = 128; + pBuilder->nCols = 0; + pBuilder->pColIdx = (SColIdx *)malloc(sizeof(SColIdx) * pBuilder->tCols); + if (pBuilder->pColIdx == NULL) return -1; + pBuilder->alloc = 1024; + pBuilder->size = 0; + pBuilder->buf = malloc(pBuilder->alloc); + if (pBuilder->buf == NULL) { + free(pBuilder->pColIdx); + return -1; + } + return 0; +} + +void tdDestroyKVDataRowBuilder(SKVDataRowBuilder *pBuilder) { + tfree(pBuilder->pColIdx); + tfree(pBuilder->buf); +} + +void tdResetKVDataRowBuilder(SKVDataRowBuilder *pBuilder) { + pBuilder->nCols = 0; + pBuilder->size = 0; +} + +SKVDataRow tdGetKVDataRowFromBuilder(SKVDataRowBuilder *pBuilder) { + int tlen = sizeof(SColIdx) * pBuilder->nCols + pBuilder->size; + if (tlen == 0) return NULL; + + SKVDataRow row = malloc(TD_KV_DATA_ROW_HEAD_SIZE + tlen); + if (row == NULL) return NULL; + + kvDataRowSetNCols(row, pBuilder->nCols); + kvDataRowSetLen(row, TD_KV_DATA_ROW_HEAD_SIZE + tlen); + + memcpy(kvDataRowColIdx(row), pBuilder->pColIdx, sizeof(SColIdx) * pBuilder->nCols); + memcpy(kvDataRowValues(row), pBuilder->buf, pBuilder->size); + + return row; +} + +int tdAddColToKVDataRow(SKVDataRowBuilder *pBuilder, int16_t colId, int8_t type, void *value) { + ASSERT(pBuilder->nCols == 0 || colId > pBuilder->pColIdx[pBuilder->nCols - 1].colId); + + if (pBuilder->nCols >= pBuilder->tCols) { + pBuilder->tCols *= 2; + pBuilder->pColIdx = realloc(pBuilder->pColIdx, sizeof(SColIdx) * pBuilder->tCols); + if (pBuilder->pColIdx == NULL) return -1; + } + + pBuilder->pColIdx[pBuilder->nCols].colId = colId; + pBuilder->pColIdx[pBuilder->nCols].offset = pBuilder->size; + + pBuilder->nCols++; + + int tlen = IS_VAR_DATA_TYPE(type) ? varDataTLen(value) : TYPE_BYTES[type]; + if (tlen > pBuilder->alloc - pBuilder->size) { + pBuilder->alloc *= 2; + pBuilder->buf = realloc(pBuilder->buf, pBuilder->alloc); + if (pBuilder->buf == NULL) return -1; + } + + memcpy(POINTER_SHIFT(pBuilder->buf, pBuilder->size), value, tlen); + pBuilder->size += tlen; + + return 0; } \ No newline at end of file