tdataformat.c 26.2 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
S
common  
Shengliang Guan 已提交
15 16

#define _DEFAULT_SOURCE
S
slguan 已提交
17
#include "tdataformat.h"
S
Shengliang Guan 已提交
18
#include "tcoding.h"
L
Liu Jicong 已提交
19
#include "tdatablock.h"
S
log  
Shengliang Guan 已提交
20
#include "tlog.h"
H
more  
hzcheng 已提交
21

H
Hongze Cheng 已提交
22 23 24 25 26
struct SKVIdx {
  int32_t cid;
  int32_t offset;
};

H
Hongze Cheng 已提交
27 28 29 30 31 32 33
#pragma pack(push, 1)
typedef struct {
  int16_t nCols;
  SKVIdx  idx[];
} STSKVRow;
#pragma pack(pop)

H
Hongze Cheng 已提交
34
#define TSROW_IS_KV_ROW(r) ((r)->flags & TSROW_KV_ROW)
H
Hongze Cheng 已提交
35 36
#define SET_BIT1(p, i, v)  ((p)[(i) / 8] = (p)[(i) / 8] & (~(((uint8_t)1) << ((i) % 8))) | ((v) << ((i) % 8)))
#define SET_BIT2(p, i, v)  ((p)[(i) / 4] = (p)[(i) / 4] & (~(((uint8_t)3) << ((i) % 4))) | ((v) << ((i) % 4)))
H
Hongze Cheng 已提交
37

H
Hongze Cheng 已提交
38
// STSRow2
H
Hongze Cheng 已提交
39 40
int32_t tEncodeTSRow(SEncoder *pEncoder, const STSRow2 *pRow) {
  if (tEncodeI64(pEncoder, pRow->ts) < 0) return -1;
H
Hongze Cheng 已提交
41
  if (tEncodeU8(pEncoder, pRow->flags) < 0) return -1;
H
Hongze Cheng 已提交
42
  if (tEncodeI32v(pEncoder, pRow->sver) < 0) return -1;
H
Hongze Cheng 已提交
43 44 45 46 47 48 49 50 51 52 53 54 55

  ASSERT(pRow->flags & 0xf != 0);

  switch (pRow->flags & 0xf) {
    case TSROW_HAS_NONE:
    case TSROW_HAS_NULL:
      return 0;
    case TSROW_HAS_VAL:
      ASSERT(!TSROW_IS_KV_ROW(pRow));
    default:
      ASSERT(pRow->nData && pRow->pData);
      if (tEncodeBinary(pEncoder, pRow->pData, pRow->nData)) return -1;
      break;
H
Hongze Cheng 已提交
56
  }
H
Hongze Cheng 已提交
57

H
Hongze Cheng 已提交
58 59 60 61 62
  return 0;
}

int32_t tDecodeTSRow(SDecoder *pDecoder, STSRow2 *pRow) {
  if (tDecodeI64(pDecoder, &pRow->ts) < 0) return -1;
H
Hongze Cheng 已提交
63
  if (tDecodeU8(pDecoder, &pRow->flags) < 0) return -1;
H
Hongze Cheng 已提交
64
  if (tDecodeI32v(pDecoder, &pRow->sver) < 0) return -1;
H
Hongze Cheng 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77 78

  ASSERT(pRow->flags & 0xf != 0);

  switch (pRow->flags & 0xf) {
    case TSROW_HAS_NONE:
    case TSROW_HAS_NULL:
      pRow->nData = 0;
      pRow->pData = NULL;
      return 0;
    case TSROW_HAS_VAL:
      ASSERT(!TSROW_IS_KV_ROW(pRow));
    default:
      if (tDecodeBinary(pDecoder, &pRow->pData, &pRow->nData)) return -1;
      break;
H
Hongze Cheng 已提交
79
  }
H
Hongze Cheng 已提交
80

H
Hongze Cheng 已提交
81 82 83
  return 0;
}

H
Hongze Cheng 已提交
84 85
int32_t tTSRowGet(const STSRow2 *pRow, STSchema *pTSchema, int32_t cid, const uint8_t **ppData, uint32_t *nData,
                  int8_t *flags) {
H
Hongze Cheng 已提交
86
#if 0
H
Hongze Cheng 已提交
87 88 89 90 91 92 93 94 95 96
  if (cid == 0) {
    *ppData = (uint8_t *)&pRow->ts;
    *nData = sizeof(TSKEY);
    *flags = 0;
  } else {
    uint32_t tflags = pRow->flags & 0xf;
    *ppData = NULL;
    *nData = 0;

    switch (tflags) {
H
Hongze Cheng 已提交
97
      case TSROW_HAS_NONE:
H
Hongze Cheng 已提交
98 99
        *flags = -1;
        break;
H
Hongze Cheng 已提交
100
      case TSROW_HAS_NULL:
H
Hongze Cheng 已提交
101 102
        *flags = 1;
        break;
H
Hongze Cheng 已提交
103
      case TSROW_HAS_VAL:
H
Hongze Cheng 已提交
104 105 106
        *flags = 0;
        // find the row
        break;
H
Hongze Cheng 已提交
107
      case TSROW_HAS_NULL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
108 109 110 111 112 113 114
        // read bit map (todo)
        if (0) {
          *flags = 1;
        } else {
          *flags = -1;
        }
        break;
H
Hongze Cheng 已提交
115 116
      case TSROW_HAS_VAL | TSROW_HAS_NONE:
      case TSROW_HAS_VAL | TSROW_HAS_NULL:
H
Hongze Cheng 已提交
117 118
        // read bitmap (todo)
        if (0) {
H
Hongze Cheng 已提交
119
          if (tflags & TSROW_HAS_NONE) {
H
Hongze Cheng 已提交
120 121 122 123 124 125 126 127
            *flags = -1;
          } else {
            *flags = 1;
          }
        } else {
          // get value (todo)
        }
        break;
H
Hongze Cheng 已提交
128
      case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
129 130 131 132 133
        break;
      default:
        return -1;
    }
  }
H
Hongze Cheng 已提交
134
#endif
H
Hongze Cheng 已提交
135 136 137 138
  return 0;
}

// STSchema
H
Hongze Cheng 已提交
139 140 141 142 143 144 145
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;
  }

H
Hongze Cheng 已提交
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
  (*ppTSchema)->numOfCols = ncols;
  (*ppTSchema)->version = sver;
  (*ppTSchema)->flen = 0;
  (*ppTSchema)->vlen = 0;
  (*ppTSchema)->tlen = 0;

  for (int32_t iCol = 0; iCol < ncols; iCol++) {
    SSchema  *pColumn = &pSchema[iCol];
    STColumn *pTColumn = &((*ppTSchema)->columns[iCol]);

    pTColumn->colId = pColumn->colId;
    pTColumn->type = pColumn->type;
    pTColumn->flags = pColumn->flags;
    pTColumn->bytes = pColumn->bytes;
    pTColumn->offset = (*ppTSchema)->flen;

    // skip first column
    if (iCol) {
      (*ppTSchema)->flen += TYPE_BYTES[pColumn->type];
      if (IS_VAR_DATA_TYPE(pColumn->type)) {
        (*ppTSchema)->vlen += (pColumn->bytes + 5);
      }
    }
  }

H
Hongze Cheng 已提交
171 172 173
  return 0;
}

H
Hongze Cheng 已提交
174 175 176
void tTSchemaDestroy(STSchema *pTSchema) {
  if (pTSchema) taosMemoryFree(pTSchema);
}
H
Hongze Cheng 已提交
177

H
Hongze Cheng 已提交
178
// STSRowBuilder
H
Hongze Cheng 已提交
179
int32_t tTSRowBuilderInit(STSRowBuilder *pBuilder, int32_t sver, SSchema *pSchema, int32_t nCols) {
H
Hongze Cheng 已提交
180 181
  if (tTSchemaCreate(sver, pSchema, nCols, &pBuilder->pTSchema) < 0) return -1;

H
Hongze Cheng 已提交
182 183 184 185
  pBuilder->szBitMap1 = (nCols - 2) / 8 + 1;
  pBuilder->szBitMap2 = (nCols - 2) / 4 + 1;
  pBuilder->szKVBuf =
      sizeof(STSKVRow) + sizeof(SKVIdx) * (nCols - 1) + pBuilder->pTSchema->flen + pBuilder->pTSchema->vlen;
H
Hongze Cheng 已提交
186 187 188
  pBuilder->szTPBuf = pBuilder->szBitMap2 + pBuilder->pTSchema->flen + pBuilder->pTSchema->vlen;
  pBuilder->pKVBuf = taosMemoryMalloc(pBuilder->szKVBuf);
  if (pBuilder->pKVBuf == NULL) {
H
Hongze Cheng 已提交
189 190
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    tTSchemaDestroy(pBuilder->pTSchema);
H
Hongze Cheng 已提交
191
    return -1;
H
Hongze Cheng 已提交
192
  }
H
Hongze Cheng 已提交
193 194 195
  pBuilder->pTPBuf = taosMemoryMalloc(pBuilder->szTPBuf);
  if (pBuilder->pTPBuf == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
196 197
    taosMemoryFree(pBuilder->pKVBuf);
    tTSchemaDestroy(pBuilder->pTSchema);
H
Hongze Cheng 已提交
198
    return -1;
H
Hongze Cheng 已提交
199 200
  }

H
Hongze Cheng 已提交
201 202 203
  return 0;
}

H
Hongze Cheng 已提交
204
void tTSRowBuilderClear(STSRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
205 206 207 208
  if (pBuilder->pTPBuf) {
    taosMemoryFree(pBuilder->pTPBuf);
    pBuilder->pTPBuf = NULL;
  }
H
Hongze Cheng 已提交
209 210 211 212 213 214
  if (pBuilder->pKVBuf) {
    taosMemoryFree(pBuilder->pKVBuf);
    pBuilder->pKVBuf = NULL;
  }
  tTSchemaDestroy(pBuilder->pTSchema);
  pBuilder->pTSchema = NULL;
H
Hongze Cheng 已提交
215 216
}

H
Hongze Cheng 已提交
217
void tTSRowBuilderReset(STSRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
218
  for (int32_t iCol = pBuilder->pTSchema->numOfCols - 1; iCol >= 0; iCol--) {
H
Hongze Cheng 已提交
219 220
    STColumn *pTColumn = &pBuilder->pTSchema->columns[iCol];
    COL_CLR_SET(pTColumn->flags);
H
Hongze Cheng 已提交
221 222
  }

H
Hongze Cheng 已提交
223
  pBuilder->iCol = 0;
H
Hongze Cheng 已提交
224
  ((STSKVRow *)pBuilder->pKVBuf)->nCols = 0;
H
Hongze Cheng 已提交
225 226
  pBuilder->vlenKV = 0;
  pBuilder->vlenTP = 0;
H
Hongze Cheng 已提交
227
  pBuilder->row.flags = 0;
H
Hongze Cheng 已提交
228 229 230
}

int32_t tTSRowBuilderPut(STSRowBuilder *pBuilder, int32_t cid, const uint8_t *pData, uint32_t nData) {
H
Hongze Cheng 已提交
231 232 233
  STColumn *pTColumn = &pBuilder->pTSchema->columns[pBuilder->iCol];
  uint8_t  *p;
  int32_t   iCol;
H
Hongze Cheng 已提交
234
  STSKVRow *pTSKVRow = (STSKVRow *)pBuilder->pKVBuf;
H
Hongze Cheng 已提交
235 236 237 238 239 240

  // use interp search (todo)
  if (pTColumn->colId > cid) {
    for (iCol = pBuilder->iCol + 1; iCol < pBuilder->pTSchema->numOfCols; iCol++) {
      pTColumn = &pBuilder->pTSchema->columns[iCol];
      if (pTColumn->colId == cid) break;
H
Hongze Cheng 已提交
241
    }
H
Hongze Cheng 已提交
242 243 244 245
  } else if (pTColumn->colId < cid) {
    for (iCol = pBuilder->iCol - 1; iCol >= 0; iCol--) {
      pTColumn = &pBuilder->pTSchema->columns[iCol];
      if (pTColumn->colId == cid) break;
H
Hongze Cheng 已提交
246
    }
H
Hongze Cheng 已提交
247 248
  }

H
Hongze Cheng 已提交
249
  if (pTColumn->colId != cid || COL_IS_SET(pTColumn->flags)) {
H
Hongze Cheng 已提交
250 251 252
    return -1;
  }

H
Hongze Cheng 已提交
253 254
  pBuilder->iCol = iCol;

H
Hongze Cheng 已提交
255 256
  // set value
  if (cid == 0) {
H
Hongze Cheng 已提交
257
    ASSERT(pData && nData == sizeof(TSKEY) && iCol == 0);
H
Hongze Cheng 已提交
258
    pBuilder->row.ts = *(TSKEY *)pData;
H
Hongze Cheng 已提交
259
    pTColumn->flags |= COL_SET_VAL;
H
Hongze Cheng 已提交
260
  } else {
H
Hongze Cheng 已提交
261 262
    if (pData) {
      // set VAL
H
Hongze Cheng 已提交
263

H
Hongze Cheng 已提交
264 265 266 267 268
      pBuilder->row.flags |= TSROW_HAS_VAL;
      pTColumn->flags |= COL_SET_VAL;

      /* KV */
      if (1) {  // avoid KV at some threshold (todo)
H
Hongze Cheng 已提交
269 270
        pTSKVRow->idx[pTSKVRow->nCols].cid = cid;
        pTSKVRow->idx[pTSKVRow->nCols].offset = pBuilder->vlenKV;
H
Hongze Cheng 已提交
271

H
Hongze Cheng 已提交
272 273
        p = pBuilder->pKVBuf + sizeof(STSKVRow) + sizeof(SKVIdx) * (pBuilder->pTSchema->numOfCols - 1) +
            pBuilder->vlenKV;
H
Hongze Cheng 已提交
274 275 276 277 278 279 280 281
        if (IS_VAR_DATA_TYPE(pTColumn->type)) {
          ASSERT(nData <= pTColumn->bytes);
          pBuilder->vlenKV += tPutBinary(p, pData, nData);
        } else {
          ASSERT(nData == pTColumn->bytes);
          memcpy(p, pData, nData);
          pBuilder->vlenKV += nData;
        }
H
Hongze Cheng 已提交
282 283
      }

H
Hongze Cheng 已提交
284 285 286 287 288
      /* TUPLE */
      p = pBuilder->pTPBuf + pBuilder->szBitMap2 + pTColumn->offset;
      if (IS_VAR_DATA_TYPE(pTColumn->type)) {
        ASSERT(nData <= pTColumn->bytes);
        *(int32_t *)p = pBuilder->vlenTP;
H
Hongze Cheng 已提交
289

H
Hongze Cheng 已提交
290
        p = pBuilder->pTPBuf + pBuilder->szBitMap2 + pBuilder->pTSchema->flen + pBuilder->vlenTP;
H
Hongze Cheng 已提交
291
        pBuilder->vlenTP += tPutBinary(p, pData, nData);
H
Hongze Cheng 已提交
292
      } else {
H
Hongze Cheng 已提交
293
        ASSERT(nData == pTColumn->bytes);
H
Hongze Cheng 已提交
294 295
        memcpy(p, pData, nData);
      }
H
Hongze Cheng 已提交
296 297 298
    } else {
      // set NULL

H
Hongze Cheng 已提交
299
      pBuilder->row.flags |= TSROW_HAS_NULL;
H
Hongze Cheng 已提交
300
      pTColumn->flags |= COL_SET_NULL;
H
Hongze Cheng 已提交
301

H
Hongze Cheng 已提交
302 303
      pTSKVRow->idx[pTSKVRow->nCols].cid = cid;
      pTSKVRow->idx[pTSKVRow->nCols].offset = -1;
H
Hongze Cheng 已提交
304
    }
H
Hongze Cheng 已提交
305

H
Hongze Cheng 已提交
306
    pTSKVRow->nCols++;
H
Hongze Cheng 已提交
307 308 309 310 311
  }

  return 0;
}

H
Hongze Cheng 已提交
312 313 314 315 316 317 318 319 320 321
static FORCE_INLINE int tSKVIdxCmprFn(const void *p1, const void *p2) {
  SKVIdx *pKVIdx1 = (SKVIdx *)p1;
  SKVIdx *pKVIdx2 = (SKVIdx *)p2;
  if (pKVIdx1->cid > pKVIdx2->cid) {
    return 1;
  } else if (pKVIdx1->cid < pKVIdx2->cid) {
    return -1;
  }
  return 0;
}
H
Hongze Cheng 已提交
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
static void setBitMap(uint8_t *p, STSchema *pTSchema, uint8_t flags) {
  int32_t   bidx;
  STColumn *pTColumn;

  for (int32_t iCol = 1; iCol < pTSchema->numOfCols; iCol++) {
    pTColumn = &pTSchema->columns[iCol];
    bidx = iCol - 1;

    switch (flags) {
      case TSROW_HAS_NULL | TSROW_HAS_NONE:
        if (pTColumn->flags & COL_SET_NULL) {
          SET_BIT1(p, bidx, (uint8_t)1);
        } else {
          SET_BIT1(p, bidx, (uint8_t)0);
        }
        break;
      case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE:
        if (pTColumn->flags & COL_SET_NULL) {
          SET_BIT2(p, bidx, (uint8_t)1);
        } else if (pTColumn->flags & COL_SET_NULL) {
          SET_BIT2(p, bidx, (uint8_t)2);
        } else {
          SET_BIT2(p, bidx, (uint8_t)0);
        }
        break;
      default:
        if (pTColumn->flags & COL_SET_VAL) {
          SET_BIT1(p, bidx, (uint8_t)1);
        } else {
          SET_BIT1(p, bidx, (uint8_t)0);
        }

        break;
    }
  }
}
H
Hongze Cheng 已提交
358
int32_t tTSRowBuilderGetRow(STSRowBuilder *pBuilder, const STSRow2 **ppRow) {
H
Hongze Cheng 已提交
359 360 361
  int32_t   nDataTP, nDataKV;
  uint32_t  flags;
  STSKVRow *pTSKVRow = (STSKVRow *)pBuilder->pKVBuf;
H
Hongze Cheng 已提交
362 363

  // error not set ts
H
Hongze Cheng 已提交
364
  if (!COL_IS_SET(pBuilder->pTSchema->columns->flags)) {
H
Hongze Cheng 已提交
365 366 367
    return -1;
  }

H
Hongze Cheng 已提交
368 369
  ASSERT(pTSKVRow->nCols < pBuilder->pTSchema->numOfCols);
  if (pTSKVRow->nCols < pBuilder->pTSchema->numOfCols - 1) {
H
Hongze Cheng 已提交
370
    pBuilder->row.flags |= TSROW_HAS_NONE;
H
Hongze Cheng 已提交
371
  }
H
Hongze Cheng 已提交
372

H
Hongze Cheng 已提交
373 374 375 376 377
  ASSERT(pBuilder->row.flags & 0xf != 0);
  *(ppRow) = &pBuilder->row;
  switch (pBuilder->row.flags & 0xf) {
    case TSROW_HAS_NONE:
    case TSROW_HAS_NULL:
H
Hongze Cheng 已提交
378 379
      pBuilder->row.nData = 0;
      pBuilder->row.pData = NULL;
H
Hongze Cheng 已提交
380 381
      return 0;
    case TSROW_HAS_NULL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
382
      nDataTP = pBuilder->szBitMap1;
H
Hongze Cheng 已提交
383
      break;
H
Hongze Cheng 已提交
384
    case TSROW_HAS_VAL:
H
Hongze Cheng 已提交
385
      nDataTP = pBuilder->pTSchema->flen + pBuilder->vlenTP;
H
Hongze Cheng 已提交
386
      break;
H
Hongze Cheng 已提交
387 388
    case TSROW_HAS_VAL | TSROW_HAS_NONE:
    case TSROW_HAS_VAL | TSROW_HAS_NULL:
H
Hongze Cheng 已提交
389
      nDataTP = pBuilder->szBitMap1 + pBuilder->pTSchema->flen + pBuilder->vlenTP;
H
Hongze Cheng 已提交
390
      break;
H
Hongze Cheng 已提交
391
    case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
392
      nDataTP = pBuilder->szBitMap2 + pBuilder->pTSchema->flen + pBuilder->vlenTP;
H
Hongze Cheng 已提交
393 394
      break;
    default:
H
Hongze Cheng 已提交
395
      ASSERT(0);
H
Hongze Cheng 已提交
396 397
  }

H
Hongze Cheng 已提交
398 399
  nDataKV = sizeof(STSKVRow) + sizeof(SKVIdx) * pTSKVRow->nCols + pBuilder->vlenKV;
  pBuilder->row.sver = pBuilder->pTSchema->version;
H
Hongze Cheng 已提交
400 401 402
  if (nDataKV < nDataTP) {
    // generate KV row

H
Hongze Cheng 已提交
403
    pBuilder->row.flags |= TSROW_KV_ROW;
H
Hongze Cheng 已提交
404
    pBuilder->row.nData = nDataKV;
H
Hongze Cheng 已提交
405
    pBuilder->row.pData = pBuilder->pKVBuf;
H
Hongze Cheng 已提交
406

H
Hongze Cheng 已提交
407 408 409
    qsort(pTSKVRow->idx, pTSKVRow->nCols, sizeof(SKVIdx), tSKVIdxCmprFn);
    if (pTSKVRow->nCols < pBuilder->pTSchema->numOfCols - 1) {
      memmove(&pTSKVRow->idx[pTSKVRow->nCols], &pTSKVRow->idx[pBuilder->pTSchema->numOfCols - 1], pBuilder->vlenKV);
H
Hongze Cheng 已提交
410 411
    }
  } else {
H
Hongze Cheng 已提交
412 413 414 415
    // generate TUPLE row

    pBuilder->row.nData = nDataTP;

H
Hongze Cheng 已提交
416 417
    uint8_t *p;
    uint8_t  flags = pBuilder->row.flags & 0xf;
H
Hongze Cheng 已提交
418

H
Hongze Cheng 已提交
419 420
    if (flags == TSROW_HAS_VAL) {
      pBuilder->row.pData = pBuilder->pTPBuf + pBuilder->szBitMap2;
H
Hongze Cheng 已提交
421
    } else {
H
Hongze Cheng 已提交
422 423 424 425
      if (flags == TSROW_HAS_VAL) {
        p = pBuilder->pTPBuf;
      } else {
        p = pBuilder->pTPBuf + pBuilder->szBitMap2 - pBuilder->szBitMap1;
H
Hongze Cheng 已提交
426 427
      }

H
Hongze Cheng 已提交
428
      setBitMap(p, pBuilder->pTSchema, flags);
H
Hongze Cheng 已提交
429 430
      pBuilder->row.pData = p;
    }
H
Hongze Cheng 已提交
431 432 433 434 435
  }

  return 0;
}

H
Hongze Cheng 已提交
436
#if 1  // ====================
437
static void dataColSetNEleNull(SDataCol *pCol, int nEle);
H
Hongze Cheng 已提交
438
int         tdAllocMemForCol(SDataCol *pCol, int maxPoints) {
L
Liu Jicong 已提交
439
  int spaceNeeded = pCol->bytes * maxPoints;
S
Shengliang Guan 已提交
440
  if (IS_VAR_DATA_TYPE(pCol->type)) {
L
Liu Jicong 已提交
441
    spaceNeeded += sizeof(VarDataOffsetT) * maxPoints;
L
Liu Jicong 已提交
442
  }
C
Cary Xu 已提交
443
#ifdef TD_SUPPORT_BITMAP
C
Cary Xu 已提交
444 445 446 447
  int32_t nBitmapBytes = (int32_t)TD_BITMAP_BYTES(maxPoints);
  spaceNeeded += (int)nBitmapBytes;
  // TODO: Currently, the compression of bitmap parts is affiliated to the column data parts, thus allocate 1 more
  // TYPE_BYTES as to comprise complete TYPE_BYTES. Otherwise, invalid read/write would be triggered.
448 449
  // spaceNeeded += TYPE_BYTES[pCol->type]; // the bitmap part is append as a single part since 2022.04.03, thus remove
  // the additional space
C
Cary Xu 已提交
450
#endif
C
Cary Xu 已提交
451

S
Shengliang Guan 已提交
452
  if (pCol->spaceSize < spaceNeeded) {
wafwerar's avatar
wafwerar 已提交
453
    void *ptr = taosMemoryRealloc(pCol->pData, spaceNeeded);
S
Shengliang Guan 已提交
454 455
    if (ptr == NULL) {
      uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)spaceNeeded, strerror(errno));
L
Liu Jicong 已提交
456
      return -1;
L
Liu Jicong 已提交
457 458 459
    } else {
      pCol->pData = ptr;
      pCol->spaceSize = spaceNeeded;
460 461
    }
  }
C
Cary Xu 已提交
462
#ifdef TD_SUPPORT_BITMAP
463

C
Cary Xu 已提交
464 465 466 467
  if (IS_VAR_DATA_TYPE(pCol->type)) {
    pCol->pBitmap = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
    pCol->dataOff = POINTER_SHIFT(pCol->pBitmap, nBitmapBytes);
  } else {
C
Cary Xu 已提交
468
    pCol->pBitmap = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
L
Liu Jicong 已提交
469
  }
C
Cary Xu 已提交
470 471 472 473
#else
  if (IS_VAR_DATA_TYPE(pCol->type)) {
    pCol->dataOff = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
  }
C
Cary Xu 已提交
474
#endif
L
Liu Jicong 已提交
475
  return 0;
476 477
}

H
hzcheng 已提交
478 479 480
/**
 * Duplicate the schema and return a new object
 */
H
Hongze Cheng 已提交
481
STSchema *tdDupSchema(const STSchema *pSchema) {
S
Shengliang Guan 已提交
482
  int       tlen = sizeof(STSchema) + sizeof(STColumn) * schemaNCols(pSchema);
wafwerar's avatar
wafwerar 已提交
483
  STSchema *tSchema = (STSchema *)taosMemoryMalloc(tlen);
H
hzcheng 已提交
484 485
  if (tSchema == NULL) return NULL;

H
Hongze Cheng 已提交
486
  memcpy((void *)tSchema, (void *)pSchema, tlen);
H
hzcheng 已提交
487 488 489 490

  return tSchema;
}

H
TD-27  
hzcheng 已提交
491 492 493
/**
 * Encode a schema to dst, and return the next pointer
 */
H
TD-353  
Hongze Cheng 已提交
494 495 496 497
int tdEncodeSchema(void **buf, STSchema *pSchema) {
  int tlen = 0;
  tlen += taosEncodeFixedI32(buf, schemaVersion(pSchema));
  tlen += taosEncodeFixedI32(buf, schemaNCols(pSchema));
H
TD-166  
hzcheng 已提交
498

H
TD-27  
hzcheng 已提交
499 500
  for (int i = 0; i < schemaNCols(pSchema); i++) {
    STColumn *pCol = schemaColAt(pSchema, i);
H
TD-353  
Hongze Cheng 已提交
501
    tlen += taosEncodeFixedI8(buf, colType(pCol));
C
Cary Xu 已提交
502
    tlen += taosEncodeFixedI8(buf, colFlags(pCol));
H
TD-353  
Hongze Cheng 已提交
503
    tlen += taosEncodeFixedI16(buf, colColId(pCol));
504
    tlen += taosEncodeFixedI16(buf, colBytes(pCol));
H
TD-27  
hzcheng 已提交
505 506
  }

H
TD-353  
Hongze Cheng 已提交
507
  return tlen;
H
TD-27  
hzcheng 已提交
508 509 510 511 512
}

/**
 * Decode a schema from a binary.
 */
H
TD-353  
Hongze Cheng 已提交
513
void *tdDecodeSchema(void *buf, STSchema **pRSchema) {
S
Shengliang Guan 已提交
514 515
  int             version = 0;
  int             numOfCols = 0;
H
TD-353  
Hongze Cheng 已提交
516
  STSchemaBuilder schemaBuilder;
H
TD-27  
hzcheng 已提交
517

H
TD-353  
Hongze Cheng 已提交
518 519
  buf = taosDecodeFixedI32(buf, &version);
  buf = taosDecodeFixedI32(buf, &numOfCols);
H
TD-27  
hzcheng 已提交
520

H
Hongze Cheng 已提交
521 522
  if (tdInitTSchemaBuilder(&schemaBuilder, version) < 0) return NULL;

H
TD-353  
Hongze Cheng 已提交
523
  for (int i = 0; i < numOfCols; i++) {
524
    col_type_t  type = 0;
C
Cary Xu 已提交
525
    int8_t      flags = 0;
526 527
    col_id_t    colId = 0;
    col_bytes_t bytes = 0;
H
TD-353  
Hongze Cheng 已提交
528
    buf = taosDecodeFixedI8(buf, &type);
C
Cary Xu 已提交
529
    buf = taosDecodeFixedI8(buf, &flags);
H
TD-353  
Hongze Cheng 已提交
530
    buf = taosDecodeFixedI16(buf, &colId);
531
    buf = taosDecodeFixedI32(buf, &bytes);
C
Cary Xu 已提交
532
    if (tdAddColToSchema(&schemaBuilder, type, flags, colId, bytes) < 0) {
H
Hongze Cheng 已提交
533 534 535
      tdDestroyTSchemaBuilder(&schemaBuilder);
      return NULL;
    }
H
TD-27  
hzcheng 已提交
536 537
  }

H
TD-353  
Hongze Cheng 已提交
538
  *pRSchema = tdGetSchemaFromBuilder(&schemaBuilder);
H
Hongze Cheng 已提交
539
  tdDestroyTSchemaBuilder(&schemaBuilder);
H
TD-353  
Hongze Cheng 已提交
540
  return buf;
H
Hongze Cheng 已提交
541 542
}

C
Cary Xu 已提交
543
int tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
H
Hongze Cheng 已提交
544 545 546
  if (pBuilder == NULL) return -1;

  pBuilder->tCols = 256;
wafwerar's avatar
wafwerar 已提交
547
  pBuilder->columns = (STColumn *)taosMemoryMalloc(sizeof(STColumn) * pBuilder->tCols);
H
Hongze Cheng 已提交
548 549 550 551 552 553 554 555
  if (pBuilder->columns == NULL) return -1;

  tdResetTSchemaBuilder(pBuilder, version);
  return 0;
}

void tdDestroyTSchemaBuilder(STSchemaBuilder *pBuilder) {
  if (pBuilder) {
wafwerar's avatar
wafwerar 已提交
556
    taosMemoryFreeClear(pBuilder->columns);
H
Hongze Cheng 已提交
557 558 559
  }
}

C
Cary Xu 已提交
560
void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
H
Hongze Cheng 已提交
561 562 563
  pBuilder->nCols = 0;
  pBuilder->tlen = 0;
  pBuilder->flen = 0;
T
Tao Liu 已提交
564
  pBuilder->vlen = 0;
H
Hongze Cheng 已提交
565 566 567
  pBuilder->version = version;
}

C
Cary Xu 已提交
568
int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t flags, col_id_t colId, col_bytes_t bytes) {
569
  if (!isValidDataType(type)) return -1;
H
Hongze Cheng 已提交
570 571 572

  if (pBuilder->nCols >= pBuilder->tCols) {
    pBuilder->tCols *= 2;
wafwerar's avatar
wafwerar 已提交
573
    STColumn *columns = (STColumn *)taosMemoryRealloc(pBuilder->columns, sizeof(STColumn) * pBuilder->tCols);
T
tickduan 已提交
574 575
    if (columns == NULL) return -1;
    pBuilder->columns = columns;
H
Hongze Cheng 已提交
576 577 578 579 580
  }

  STColumn *pCol = &(pBuilder->columns[pBuilder->nCols]);
  colSetType(pCol, type);
  colSetColId(pCol, colId);
C
Cary Xu 已提交
581
  colSetFlags(pCol, flags);
H
Hongze Cheng 已提交
582 583 584
  if (pBuilder->nCols == 0) {
    colSetOffset(pCol, 0);
  } else {
S
Shengliang Guan 已提交
585
    STColumn *pTCol = &(pBuilder->columns[pBuilder->nCols - 1]);
H
Hongze Cheng 已提交
586 587 588 589 590
    colSetOffset(pCol, pTCol->offset + TYPE_BYTES[pTCol->type]);
  }

  if (IS_VAR_DATA_TYPE(type)) {
    colSetBytes(pCol, bytes);
T
Tao Liu 已提交
591 592
    pBuilder->tlen += (TYPE_BYTES[type] + bytes);
    pBuilder->vlen += bytes - sizeof(VarDataLenT);
H
Hongze Cheng 已提交
593 594 595
  } else {
    colSetBytes(pCol, TYPE_BYTES[type]);
    pBuilder->tlen += TYPE_BYTES[type];
T
Tao Liu 已提交
596
    pBuilder->vlen += TYPE_BYTES[type];
H
Hongze Cheng 已提交
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
  }

  pBuilder->nCols++;
  pBuilder->flen += TYPE_BYTES[type];

  ASSERT(pCol->offset < pBuilder->flen);

  return 0;
}

STSchema *tdGetSchemaFromBuilder(STSchemaBuilder *pBuilder) {
  if (pBuilder->nCols <= 0) return NULL;

  int tlen = sizeof(STSchema) + sizeof(STColumn) * pBuilder->nCols;

wafwerar's avatar
wafwerar 已提交
612
  STSchema *pSchema = (STSchema *)taosMemoryMalloc(tlen);
H
Hongze Cheng 已提交
613 614 615 616 617 618
  if (pSchema == NULL) return NULL;

  schemaVersion(pSchema) = pBuilder->version;
  schemaNCols(pSchema) = pBuilder->nCols;
  schemaTLen(pSchema) = pBuilder->tlen;
  schemaFLen(pSchema) = pBuilder->flen;
T
Tao Liu 已提交
619
  schemaVLen(pSchema) = pBuilder->vlen;
H
Hongze Cheng 已提交
620

C
Cary Xu 已提交
621
#ifdef TD_SUPPORT_BITMAP
C
Cary Xu 已提交
622
  schemaTLen(pSchema) += (int)TD_BITMAP_BYTES(schemaNCols(pSchema));
C
Cary Xu 已提交
623 624
#endif

H
Hongze Cheng 已提交
625 626
  memcpy(schemaColAt(pSchema, 0), pBuilder->columns, sizeof(STColumn) * pBuilder->nCols);

H
TD-27  
hzcheng 已提交
627 628 629
  return pSchema;
}

630
void dataColInit(SDataCol *pDataCol, STColumn *pCol, int maxPoints) {
H
TD-166  
hzcheng 已提交
631 632 633
  pDataCol->type = colType(pCol);
  pDataCol->colId = colColId(pCol);
  pDataCol->bytes = colBytes(pCol);
S
Shengliang Guan 已提交
634
  pDataCol->offset = colOffset(pCol) + 0;  // TD_DATA_ROW_HEAD_SIZE;
H
TD-166  
hzcheng 已提交
635 636 637

  pDataCol->len = 0;
}
C
Cary Xu 已提交
638

L
Liu Jicong 已提交
639 640 641 642 643 644
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]);
  } else {
    return POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * row);
  }
H
TD-166  
hzcheng 已提交
645 646
}

H
TD-166  
hzcheng 已提交
647
bool isNEleNull(SDataCol *pCol, int nEle) {
S
Shengliang Guan 已提交
648
  if (isAllRowsNull(pCol)) return true;
649
  for (int i = 0; i < nEle; ++i) {
L
Liu Jicong 已提交
650
    if (!isNull(tdGetColDataOfRowUnsafe(pCol, i), pCol->type)) return false;
H
TD-166  
hzcheng 已提交
651
  }
H
Hongze Cheng 已提交
652
  return true;
H
TD-166  
hzcheng 已提交
653 654
}

C
Cary Xu 已提交
655
void *dataColSetOffset(SDataCol *pCol, int nEle) {
H
TD-166  
hzcheng 已提交
656 657
  ASSERT(((pCol->type == TSDB_DATA_TYPE_BINARY) || (pCol->type == TSDB_DATA_TYPE_NCHAR)));

H
Hongze Cheng 已提交
658
  void *tptr = pCol->pData;
H
TD-166  
hzcheng 已提交
659
  // char *tptr = (char *)(pCol->pData);
H
TD-166  
hzcheng 已提交
660

H
TD-166  
hzcheng 已提交
661
  VarDataOffsetT offset = 0;
662
  for (int i = 0; i < nEle; ++i) {
H
TD-166  
hzcheng 已提交
663
    pCol->dataOff[i] = offset;
H
TD-166  
hzcheng 已提交
664
    offset += varDataTLen(tptr);
H
hzcheng 已提交
665
    tptr = POINTER_SHIFT(tptr, varDataTLen(tptr));
H
TD-166  
hzcheng 已提交
666
  }
C
Cary Xu 已提交
667
  return POINTER_SHIFT(tptr, varDataTLen(tptr));
H
TD-166  
hzcheng 已提交
668 669
}

L
Liu Jicong 已提交
670
SDataCols *tdNewDataCols(int maxCols, int maxRows) {
wafwerar's avatar
wafwerar 已提交
671
  SDataCols *pCols = (SDataCols *)taosMemoryCalloc(1, sizeof(SDataCols));
H
Haojun Liao 已提交
672
  if (pCols == NULL) {
S
Shengliang Guan 已提交
673
    uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCols), strerror(errno));
H
Haojun Liao 已提交
674 675
    return NULL;
  }
H
TD-34  
hzcheng 已提交
676

H
Hongze Cheng 已提交
677
  pCols->maxPoints = maxRows;
L
Liu Jicong 已提交
678 679 680
  pCols->maxCols = maxCols;
  pCols->numOfRows = 0;
  pCols->numOfCols = 0;
C
Cary Xu 已提交
681
  // pCols->bitmapMode = 0; // calloc already set 0
H
Hongze Cheng 已提交
682 683

  if (maxCols > 0) {
wafwerar's avatar
wafwerar 已提交
684
    pCols->cols = (SDataCol *)taosMemoryCalloc(maxCols, sizeof(SDataCol));
H
Hongze Cheng 已提交
685 686 687 688 689 690
    if (pCols->cols == NULL) {
      uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCol) * maxCols,
             strerror(errno));
      tdFreeDataCols(pCols);
      return NULL;
    }
691
#if 0  // no need as calloc used
L
Liu Jicong 已提交
692
    int i;
S
Shengliang Guan 已提交
693
    for (i = 0; i < maxCols; i++) {
L
Liu Jicong 已提交
694
      pCols->cols[i].spaceSize = 0;
L
Liu Jicong 已提交
695
      pCols->cols[i].len = 0;
L
Liu Jicong 已提交
696 697 698
      pCols->cols[i].pData = NULL;
      pCols->cols[i].dataOff = NULL;
    }
699
#endif
H
Hongze Cheng 已提交
700 701
  }

H
TD-34  
hzcheng 已提交
702 703 704
  return pCols;
}

H
Hongze Cheng 已提交
705
int tdInitDataCols(SDataCols *pCols, STSchema *pSchema) {
706 707
  int i;
  int oldMaxCols = pCols->maxCols;
L
Liu Jicong 已提交
708
  if (schemaNCols(pSchema) > oldMaxCols) {
H
Hongze Cheng 已提交
709
    pCols->maxCols = schemaNCols(pSchema);
wafwerar's avatar
wafwerar 已提交
710
    void *ptr = (SDataCol *)taosMemoryRealloc(pCols->cols, sizeof(SDataCol) * pCols->maxCols);
L
Liu Jicong 已提交
711 712
    if (ptr == NULL) return -1;
    pCols->cols = ptr;
713
    for (i = oldMaxCols; i < pCols->maxCols; ++i) {
714 715
      pCols->cols[i].pData = NULL;
      pCols->cols[i].dataOff = NULL;
716
      pCols->cols[i].pBitmap = NULL;
L
Liu Jicong 已提交
717
      pCols->cols[i].spaceSize = 0;
718
    }
L
Liu Jicong 已提交
719
  }
720 721 722
#if 0
  tdResetDataCols(pCols); // redundant loop to reset len/blen to 0, already reset in following dataColInit(...)
#endif
H
Hongze Cheng 已提交
723

724
  pCols->numOfRows = 0;
C
Cary Xu 已提交
725
  pCols->bitmapMode = 0;
H
TD-34  
hzcheng 已提交
726 727
  pCols->numOfCols = schemaNCols(pSchema);

728
  for (i = 0; i < schemaNCols(pSchema); ++i) {
729
    dataColInit(pCols->cols + i, schemaColAt(pSchema, i), pCols->maxPoints);
H
TD-34  
hzcheng 已提交
730
  }
S
Shengliang Guan 已提交
731

H
Hongze Cheng 已提交
732
  return 0;
H
TD-34  
hzcheng 已提交
733 734
}

H
Hongze Cheng 已提交
735
SDataCols *tdFreeDataCols(SDataCols *pCols) {
736
  int i;
H
TD-34  
hzcheng 已提交
737
  if (pCols) {
S
Shengliang Guan 已提交
738
    if (pCols->cols) {
739
      int maxCols = pCols->maxCols;
740
      for (i = 0; i < maxCols; ++i) {
741
        SDataCol *pCol = &pCols->cols[i];
wafwerar's avatar
wafwerar 已提交
742
        taosMemoryFreeClear(pCol->pData);
743
      }
wafwerar's avatar
wafwerar 已提交
744
      taosMemoryFree(pCols->cols);
745 746
      pCols->cols = NULL;
    }
wafwerar's avatar
wafwerar 已提交
747
    taosMemoryFree(pCols);
H
TD-34  
hzcheng 已提交
748
  }
H
Hongze Cheng 已提交
749
  return NULL;
H
TD-34  
hzcheng 已提交
750 751 752
}

void tdResetDataCols(SDataCols *pCols) {
B
Bomin Zhang 已提交
753 754
  if (pCols != NULL) {
    pCols->numOfRows = 0;
C
Cary Xu 已提交
755
    pCols->bitmapMode = 0;
756
    for (int i = 0; i < pCols->maxCols; ++i) {
B
Bomin Zhang 已提交
757 758
      dataColReset(pCols->cols + i);
    }
H
TD-34  
hzcheng 已提交
759 760
  }
}
H
Hongze Cheng 已提交
761

H
Hongze Cheng 已提交
762
SKVRow tdKVRowDup(SKVRow row) {
wafwerar's avatar
wafwerar 已提交
763
  SKVRow trow = taosMemoryMalloc(kvRowLen(row));
H
Hongze Cheng 已提交
764 765
  if (trow == NULL) return NULL;

H
Hongze Cheng 已提交
766
  kvRowCpy(trow, row);
H
Hongze Cheng 已提交
767 768 769
  return trow;
}

S
Shengliang Guan 已提交
770 771 772
static int compareColIdx(const void *a, const void *b) {
  const SColIdx *x = (const SColIdx *)a;
  const SColIdx *y = (const SColIdx *)b;
B
Bomin Zhang 已提交
773 774 775 776 777 778 779 780 781
  if (x->colId > y->colId) {
    return 1;
  }
  if (x->colId < y->colId) {
    return -1;
  }
  return 0;
}

S
Shengliang Guan 已提交
782
void tdSortKVRowByColIdx(SKVRow row) { qsort(kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), compareColIdx); }
B
Bomin Zhang 已提交
783

H
TD-90  
Hongze Cheng 已提交
784 785 786 787
int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value) {
  SColIdx *pColIdx = NULL;
  SKVRow   row = *orow;
  SKVRow   nrow = NULL;
S
Shengliang Guan 已提交
788
  void    *ptr = taosbsearch(&colId, kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), comparTagId, TD_GE);
H
TD-90  
Hongze Cheng 已提交
789

790
  if (ptr == NULL || ((SColIdx *)ptr)->colId > colId) {  // need to add a column value to the row
C
Cary Xu 已提交
791
    int diff = IS_VAR_DATA_TYPE(type) ? varDataTLen(value) : TYPE_BYTES[type];
792 793 794 795
    int nRowLen = kvRowLen(row) + sizeof(SColIdx) + diff;
    int oRowCols = kvRowNCols(row);

    ASSERT(diff > 0);
wafwerar's avatar
wafwerar 已提交
796
    nrow = taosMemoryMalloc(nRowLen);
H
TD-90  
Hongze Cheng 已提交
797 798
    if (nrow == NULL) return -1;

799 800
    kvRowSetLen(nrow, nRowLen);
    kvRowSetNCols(nrow, oRowCols + 1);
H
TD-90  
Hongze Cheng 已提交
801

802 803
    memcpy(kvRowColIdx(nrow), kvRowColIdx(row), sizeof(SColIdx) * oRowCols);
    memcpy(kvRowValues(nrow), kvRowValues(row), kvRowValLen(row));
H
TD-90  
Hongze Cheng 已提交
804

805 806 807
    pColIdx = kvRowColIdxAt(nrow, oRowCols);
    pColIdx->colId = colId;
    pColIdx->offset = kvRowValLen(row);
H
TD-90  
Hongze Cheng 已提交
808

809
    memcpy(kvRowColVal(nrow, pColIdx), value, diff);  // copy new value
H
TD-90  
Hongze Cheng 已提交
810

811
    tdSortKVRowByColIdx(nrow);
H
TD-90  
Hongze Cheng 已提交
812 813

    *orow = nrow;
wafwerar's avatar
wafwerar 已提交
814
    taosMemoryFree(row);
H
TD-90  
Hongze Cheng 已提交
815 816 817 818 819
  } else {
    ASSERT(((SColIdx *)ptr)->colId == colId);
    if (IS_VAR_DATA_TYPE(type)) {
      void *pOldVal = kvRowColVal(row, (SColIdx *)ptr);

S
Shengliang Guan 已提交
820
      if (varDataTLen(value) == varDataTLen(pOldVal)) {  // just update the column value in place
H
TD-90  
Hongze Cheng 已提交
821
        memcpy(pOldVal, value, varDataTLen(value));
822 823
      } else {  // need to reallocate the memory
        int16_t nlen = kvRowLen(row) + (varDataTLen(value) - varDataTLen(pOldVal));
H
TD-90  
Hongze Cheng 已提交
824
        ASSERT(nlen > 0);
wafwerar's avatar
wafwerar 已提交
825
        nrow = taosMemoryMalloc(nlen);
H
TD-90  
Hongze Cheng 已提交
826
        if (nrow == NULL) return -1;
H
TD-90  
Hongze Cheng 已提交
827 828 829 830

        kvRowSetLen(nrow, nlen);
        kvRowSetNCols(nrow, kvRowNCols(row));

831 832 833 834 835 836 837 838
        int zsize = sizeof(SColIdx) * kvRowNCols(row) + ((SColIdx *)ptr)->offset;
        memcpy(kvRowColIdx(nrow), kvRowColIdx(row), zsize);
        memcpy(kvRowColVal(nrow, ((SColIdx *)ptr)), value, varDataTLen(value));
        // Copy left value part
        int lsize = kvRowLen(row) - TD_KV_ROW_HEAD_SIZE - zsize - varDataTLen(pOldVal);
        if (lsize > 0) {
          memcpy(POINTER_SHIFT(nrow, TD_KV_ROW_HEAD_SIZE + zsize + varDataTLen(value)),
                 POINTER_SHIFT(row, TD_KV_ROW_HEAD_SIZE + zsize + varDataTLen(pOldVal)), lsize);
H
TD-90  
Hongze Cheng 已提交
839 840
        }

841 842 843 844 845
        for (int i = 0; i < kvRowNCols(nrow); i++) {
          pColIdx = kvRowColIdxAt(nrow, i);

          if (pColIdx->offset > ((SColIdx *)ptr)->offset) {
            pColIdx->offset = pColIdx->offset - varDataTLen(pOldVal) + varDataTLen(value);
H
TD-90  
Hongze Cheng 已提交
846 847 848 849
          }
        }

        *orow = nrow;
wafwerar's avatar
wafwerar 已提交
850
        taosMemoryFree(row);
H
TD-90  
Hongze Cheng 已提交
851 852 853 854 855 856 857
      }
    } else {
      memcpy(kvRowColVal(row, (SColIdx *)ptr), value, TYPE_BYTES[type]);
    }
  }

  return 0;
H
Hongze Cheng 已提交
858 859
}

H
TD-353  
Hongze Cheng 已提交
860
int tdEncodeKVRow(void **buf, SKVRow row) {
H
Hongze Cheng 已提交
861
  // May change the encode purpose
H
TD-353  
Hongze Cheng 已提交
862 863 864 865 866 867
  if (buf != NULL) {
    kvRowCpy(*buf, row);
    *buf = POINTER_SHIFT(*buf, kvRowLen(row));
  }

  return kvRowLen(row);
H
Hongze Cheng 已提交
868 869
}

H
Hongze Cheng 已提交
870 871
void *tdDecodeKVRow(void *buf, SKVRow *row) {
  *row = tdKVRowDup(buf);
H
TD-353  
Hongze Cheng 已提交
872
  if (*row == NULL) return NULL;
H
Hongze Cheng 已提交
873
  return POINTER_SHIFT(buf, kvRowLen(*row));
H
Hongze Cheng 已提交
874 875
}

H
Hongze Cheng 已提交
876
int tdInitKVRowBuilder(SKVRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
877 878
  pBuilder->tCols = 128;
  pBuilder->nCols = 0;
wafwerar's avatar
wafwerar 已提交
879
  pBuilder->pColIdx = (SColIdx *)taosMemoryMalloc(sizeof(SColIdx) * pBuilder->tCols);
H
Hongze Cheng 已提交
880 881 882
  if (pBuilder->pColIdx == NULL) return -1;
  pBuilder->alloc = 1024;
  pBuilder->size = 0;
wafwerar's avatar
wafwerar 已提交
883
  pBuilder->buf = taosMemoryMalloc(pBuilder->alloc);
H
Hongze Cheng 已提交
884
  if (pBuilder->buf == NULL) {
wafwerar's avatar
wafwerar 已提交
885
    taosMemoryFree(pBuilder->pColIdx);
H
Hongze Cheng 已提交
886 887 888 889 890
    return -1;
  }
  return 0;
}

H
Hongze Cheng 已提交
891
void tdDestroyKVRowBuilder(SKVRowBuilder *pBuilder) {
wafwerar's avatar
wafwerar 已提交
892 893
  taosMemoryFreeClear(pBuilder->pColIdx);
  taosMemoryFreeClear(pBuilder->buf);
H
Hongze Cheng 已提交
894 895
}

H
Hongze Cheng 已提交
896
void tdResetKVRowBuilder(SKVRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
897 898 899 900
  pBuilder->nCols = 0;
  pBuilder->size = 0;
}

H
Hongze Cheng 已提交
901
SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder) {
C
Cary Xu 已提交
902
  int tlen = sizeof(SColIdx) * pBuilder->nCols + pBuilder->size;
H
Hongze Cheng 已提交
903 904
  if (tlen == 0) return NULL;

H
Hongze Cheng 已提交
905 906
  tlen += TD_KV_ROW_HEAD_SIZE;

wafwerar's avatar
wafwerar 已提交
907
  SKVRow row = taosMemoryMalloc(tlen);
H
Hongze Cheng 已提交
908 909
  if (row == NULL) return NULL;

H
Hongze Cheng 已提交
910
  kvRowSetNCols(row, pBuilder->nCols);
H
Hongze Cheng 已提交
911
  kvRowSetLen(row, tlen);
H
Hongze Cheng 已提交
912

H
Hongze Cheng 已提交
913 914
  memcpy(kvRowColIdx(row), pBuilder->pColIdx, sizeof(SColIdx) * pBuilder->nCols);
  memcpy(kvRowValues(row), pBuilder->buf, pBuilder->size);
H
Hongze Cheng 已提交
915 916

  return row;
917
}
H
Hongze Cheng 已提交
918
#endif