tdataformat.c 27.7 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
typedef struct SKVIdx {
H
Hongze Cheng 已提交
23 24
  int32_t cid;
  int32_t offset;
H
Hongze Cheng 已提交
25
} SKVIdx;
H
Hongze Cheng 已提交
26

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 38
#define GET_BIT1(p, i)     (((p)[(i) / 8] >> ((i) % 8)) & ((uint8_t)1))
#define GET_BIT2(p, i)     (((p)[(i) / 4] >> ((i) % 4)) & ((uint8_t)3))
H
Hongze Cheng 已提交
39

H
Hongze Cheng 已提交
40
// STSRow2
H
Hongze Cheng 已提交
41 42
int32_t tPutTSRow(uint8_t *p, STSRow2 *pRow) {
  int32_t n = 0;
H
Hongze Cheng 已提交
43

H
Hongze Cheng 已提交
44 45 46 47 48
  n += tPutI64(p ? p + n : p, pRow->ts);
  n += tPutI8(p ? p + n : p, pRow->flags);
  n += tPutI32v(p ? p + n : p, pRow->sver);

  ASSERT(pRow->flags & 0xf);
H
Hongze Cheng 已提交
49 50 51 52

  switch (pRow->flags & 0xf) {
    case TSROW_HAS_NONE:
    case TSROW_HAS_NULL:
H
Hongze Cheng 已提交
53
      break;
H
Hongze Cheng 已提交
54
    default:
H
Hongze Cheng 已提交
55
      n += tPutBinary(p ? p + n : p, pRow->pData, pRow->nData);
H
Hongze Cheng 已提交
56
      break;
H
Hongze Cheng 已提交
57
  }
H
Hongze Cheng 已提交
58

H
Hongze Cheng 已提交
59
  return n;
H
Hongze Cheng 已提交
60 61
}

H
Hongze Cheng 已提交
62 63 64
int32_t tGetTSRow(uint8_t *p, STSRow2 *pRow) {
  int32_t n = 0;
  uint8_t flags;
H
Hongze Cheng 已提交
65

H
Hongze Cheng 已提交
66 67 68
  n += tGetI64(p + n, pRow ? &pRow->ts : NULL);
  n += tGetI8(p + n, pRow ? &pRow->flags : &flags);
  n += tGetI32v(p + n, pRow ? &pRow->sver : NULL);
H
Hongze Cheng 已提交
69

H
Hongze Cheng 已提交
70 71
  if (pRow) flags = pRow->flags;
  switch (flags & 0xf) {
H
Hongze Cheng 已提交
72 73
    case TSROW_HAS_NONE:
    case TSROW_HAS_NULL:
H
Hongze Cheng 已提交
74
      break;
H
Hongze Cheng 已提交
75
    default:
H
Hongze Cheng 已提交
76
      n += tGetBinary(p + n, pRow ? &pRow->pData : NULL, pRow ? &pRow->nData : NULL);
H
Hongze Cheng 已提交
77
      break;
H
Hongze Cheng 已提交
78
  }
H
Hongze Cheng 已提交
79

H
Hongze Cheng 已提交
80
  return n;
H
Hongze Cheng 已提交
81 82
}

H
Hongze Cheng 已提交
83 84 85
static FORCE_INLINE int kvRowCmprFn(const void *p1, const void *p2) {
  col_id_t cid = *(col_id_t *)p1;
  SKVIdx  *pKVIdx = (SKVIdx *)p2;
H
Hongze Cheng 已提交
86

H
Hongze Cheng 已提交
87 88 89 90 91 92 93 94 95
  if (cid < pKVIdx->cid) {
    return -1;
  } else if (cid > pKVIdx->cid) {
    return 1;
  }
  return 0;
}

int32_t tTSRowGet(const STSRow2 *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal) {
H
Hongze Cheng 已提交
96 97 98 99 100 101 102
  uint32_t       n;
  const uint8_t *p;
  uint8_t        v;
  int32_t        bidx = iCol - 1;
  STColumn      *pTColumn = &pTSchema->columns[iCol];
  STSKVRow      *pTSKVRow;
  SKVIdx        *pKVIdx;
H
Hongze Cheng 已提交
103 104 105 106 107 108

  ASSERT(pTColumn->colId != 0);

  ASSERT(pRow->flags & 0xf != 0);
  switch (pRow->flags & 0xf) {
    case TSROW_HAS_NONE:
H
Hongze Cheng 已提交
109
      // COL_VAL_SET_NONE(pColVal);
H
Hongze Cheng 已提交
110 111
      return 0;
    case TSROW_HAS_NULL:
H
Hongze Cheng 已提交
112
      // COL_VAL_SET_NULL(pColVal);
H
Hongze Cheng 已提交
113 114 115 116 117 118 119 120 121
      return 0;
  }

  if (TSROW_IS_KV_ROW(pRow)) {
    ASSERT((pRow->flags & 0xf) != TSROW_HAS_VAL);

    pTSKVRow = (STSKVRow *)pRow->pData;
    pKVIdx = bsearch(&pTColumn->colId, pTSKVRow->idx, pTSKVRow->nCols, sizeof(SKVIdx), kvRowCmprFn);
    if (pKVIdx == NULL) {
H
Hongze Cheng 已提交
122
      // COL_VAL_SET_NONE(pColVal);
H
Hongze Cheng 已提交
123
    } else if (pKVIdx->offset < 0) {
H
Hongze Cheng 已提交
124
      // COL_VAL_SET_NULL(pColVal);
H
Hongze Cheng 已提交
125 126
    } else {
      p = pRow->pData + sizeof(STSKVRow) + sizeof(SKVIdx) * pTSKVRow->nCols + pKVIdx->offset;
H
Hongze Cheng 已提交
127
      // tGetBinary(p, &p, &n); (todo)
H
Hongze Cheng 已提交
128
      // COL_VAL_SET_VAL(pColVal, p, n);
H
Hongze Cheng 已提交
129 130 131
    }
  } else {
    // get bitmap
H
Hongze Cheng 已提交
132
    p = pRow->pData;
H
Hongze Cheng 已提交
133
    switch (pRow->flags & 0xf) {
H
Hongze Cheng 已提交
134
      case TSROW_HAS_NULL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
135 136
        v = GET_BIT1(p, bidx);
        if (v == 0) {
H
Hongze Cheng 已提交
137
          // COL_VAL_SET_NONE(pColVal);
H
Hongze Cheng 已提交
138
        } else {
H
Hongze Cheng 已提交
139
          // COL_VAL_SET_NULL(pColVal);
H
Hongze Cheng 已提交
140
        }
H
Hongze Cheng 已提交
141
        return 0;
H
Hongze Cheng 已提交
142
      case TSROW_HAS_VAL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
143 144 145 146 147
        v = GET_BIT1(p, bidx);
        if (v == 1) {
          p = p + (pTSchema->numOfCols - 2) / 8 + 1;
          break;
        } else {
H
Hongze Cheng 已提交
148
          // COL_VAL_SET_NONE(pColVal);
H
Hongze Cheng 已提交
149 150
          return 0;
        }
H
Hongze Cheng 已提交
151
      case TSROW_HAS_VAL | TSROW_HAS_NULL:
H
Hongze Cheng 已提交
152 153 154 155
        v = GET_BIT1(p, bidx);
        if (v == 1) {
          p = p + (pTSchema->numOfCols - 2) / 8 + 1;
          break;
H
Hongze Cheng 已提交
156
        } else {
H
Hongze Cheng 已提交
157
          // COL_VAL_SET_NULL(pColVal);
H
Hongze Cheng 已提交
158
          return 0;
H
Hongze Cheng 已提交
159
        }
H
Hongze Cheng 已提交
160
      case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
161 162
        v = GET_BIT2(p, bidx);
        if (v == 0) {
H
Hongze Cheng 已提交
163
          // COL_VAL_SET_NONE(pColVal);
H
Hongze Cheng 已提交
164 165
          return 0;
        } else if (v == 1) {
H
Hongze Cheng 已提交
166
          // COL_VAL_SET_NULL(pColVal);
H
Hongze Cheng 已提交
167 168 169 170 171 172 173
          return 0;
        } else if (v == 2) {
          p = p + (pTSchema->numOfCols - 2) / 4 + 1;
          break;
        } else {
          ASSERT(0);
        }
H
Hongze Cheng 已提交
174
      default:
H
Hongze Cheng 已提交
175
        break;
H
Hongze Cheng 已提交
176
    }
H
Hongze Cheng 已提交
177 178 179 180

    // get real value
    p = p + pTColumn->offset;
    if (IS_VAR_DATA_TYPE(pTColumn->type)) {
H
Hongze Cheng 已提交
181
      // tGetBinary(p + pTSchema->flen + *(int32_t *)p, &p, &n); (todo)
H
Hongze Cheng 已提交
182 183 184
    } else {
      n = pTColumn->bytes;
    }
H
Hongze Cheng 已提交
185
    // COL_VAL_SET_VAL(pColVal, p, n);
H
Hongze Cheng 已提交
186
  }
H
Hongze Cheng 已提交
187

H
Hongze Cheng 已提交
188 189 190 191
  return 0;
}

// STSchema
H
Hongze Cheng 已提交
192 193 194 195 196 197 198
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 已提交
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
  (*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 已提交
224 225 226
  return 0;
}

H
Hongze Cheng 已提交
227 228 229
void tTSchemaDestroy(STSchema *pTSchema) {
  if (pTSchema) taosMemoryFree(pTSchema);
}
H
Hongze Cheng 已提交
230

H
Hongze Cheng 已提交
231
// STSRowBuilder
H
Hongze Cheng 已提交
232
int32_t tTSRowBuilderInit(STSRowBuilder *pBuilder, int32_t sver, SSchema *pSchema, int32_t nCols) {
H
Hongze Cheng 已提交
233 234
  if (tTSchemaCreate(sver, pSchema, nCols, &pBuilder->pTSchema) < 0) return -1;

H
Hongze Cheng 已提交
235 236 237 238
  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 已提交
239 240 241
  pBuilder->szTPBuf = pBuilder->szBitMap2 + pBuilder->pTSchema->flen + pBuilder->pTSchema->vlen;
  pBuilder->pKVBuf = taosMemoryMalloc(pBuilder->szKVBuf);
  if (pBuilder->pKVBuf == NULL) {
H
Hongze Cheng 已提交
242 243
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    tTSchemaDestroy(pBuilder->pTSchema);
H
Hongze Cheng 已提交
244
    return -1;
H
Hongze Cheng 已提交
245
  }
H
Hongze Cheng 已提交
246 247 248
  pBuilder->pTPBuf = taosMemoryMalloc(pBuilder->szTPBuf);
  if (pBuilder->pTPBuf == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
249 250
    taosMemoryFree(pBuilder->pKVBuf);
    tTSchemaDestroy(pBuilder->pTSchema);
H
Hongze Cheng 已提交
251
    return -1;
H
Hongze Cheng 已提交
252 253
  }

H
Hongze Cheng 已提交
254 255 256
  return 0;
}

H
Hongze Cheng 已提交
257
void tTSRowBuilderClear(STSRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
258 259 260 261
  if (pBuilder->pTPBuf) {
    taosMemoryFree(pBuilder->pTPBuf);
    pBuilder->pTPBuf = NULL;
  }
H
Hongze Cheng 已提交
262 263 264 265 266 267
  if (pBuilder->pKVBuf) {
    taosMemoryFree(pBuilder->pKVBuf);
    pBuilder->pKVBuf = NULL;
  }
  tTSchemaDestroy(pBuilder->pTSchema);
  pBuilder->pTSchema = NULL;
H
Hongze Cheng 已提交
268 269
}

H
Hongze Cheng 已提交
270
void tTSRowBuilderReset(STSRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
271
  for (int32_t iCol = pBuilder->pTSchema->numOfCols - 1; iCol >= 0; iCol--) {
H
Hongze Cheng 已提交
272 273
    STColumn *pTColumn = &pBuilder->pTSchema->columns[iCol];
    COL_CLR_SET(pTColumn->flags);
H
Hongze Cheng 已提交
274 275
  }

H
Hongze Cheng 已提交
276
  pBuilder->iCol = 0;
H
Hongze Cheng 已提交
277
  ((STSKVRow *)pBuilder->pKVBuf)->nCols = 0;
H
Hongze Cheng 已提交
278 279
  pBuilder->vlenKV = 0;
  pBuilder->vlenTP = 0;
H
Hongze Cheng 已提交
280
  pBuilder->row.flags = 0;
H
Hongze Cheng 已提交
281 282
}

H
Hongze Cheng 已提交
283
int32_t tTSRowBuilderPut(STSRowBuilder *pBuilder, int32_t cid, uint8_t *pData, uint32_t nData) {
H
Hongze Cheng 已提交
284 285 286
  STColumn *pTColumn = &pBuilder->pTSchema->columns[pBuilder->iCol];
  uint8_t  *p;
  int32_t   iCol;
H
Hongze Cheng 已提交
287
  STSKVRow *pTSKVRow = (STSKVRow *)pBuilder->pKVBuf;
H
Hongze Cheng 已提交
288 289 290 291 292 293

  // 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 已提交
294
    }
H
Hongze Cheng 已提交
295 296 297 298
  } 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 已提交
299
    }
H
Hongze Cheng 已提交
300 301
  }

H
Hongze Cheng 已提交
302
  if (pTColumn->colId != cid || COL_IS_SET(pTColumn->flags)) {
H
Hongze Cheng 已提交
303 304 305
    return -1;
  }

H
Hongze Cheng 已提交
306 307
  pBuilder->iCol = iCol;

H
Hongze Cheng 已提交
308 309
  // set value
  if (cid == 0) {
H
Hongze Cheng 已提交
310
    ASSERT(pData && nData == sizeof(TSKEY) && iCol == 0);
H
Hongze Cheng 已提交
311
    pBuilder->row.ts = *(TSKEY *)pData;
H
Hongze Cheng 已提交
312
    pTColumn->flags |= COL_SET_VAL;
H
Hongze Cheng 已提交
313
  } else {
H
Hongze Cheng 已提交
314 315
    if (pData) {
      // set VAL
H
Hongze Cheng 已提交
316

H
Hongze Cheng 已提交
317 318 319 320 321
      pBuilder->row.flags |= TSROW_HAS_VAL;
      pTColumn->flags |= COL_SET_VAL;

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

H
Hongze Cheng 已提交
325 326
        p = pBuilder->pKVBuf + sizeof(STSKVRow) + sizeof(SKVIdx) * (pBuilder->pTSchema->numOfCols - 1) +
            pBuilder->vlenKV;
H
Hongze Cheng 已提交
327 328 329 330 331 332 333 334
        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 已提交
335 336
      }

H
Hongze Cheng 已提交
337 338 339 340 341
      /* 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 已提交
342

H
Hongze Cheng 已提交
343
        p = pBuilder->pTPBuf + pBuilder->szBitMap2 + pBuilder->pTSchema->flen + pBuilder->vlenTP;
H
Hongze Cheng 已提交
344
        pBuilder->vlenTP += tPutBinary(p, pData, nData);
H
Hongze Cheng 已提交
345
      } else {
H
Hongze Cheng 已提交
346
        ASSERT(nData == pTColumn->bytes);
H
Hongze Cheng 已提交
347 348
        memcpy(p, pData, nData);
      }
H
Hongze Cheng 已提交
349 350 351
    } else {
      // set NULL

H
Hongze Cheng 已提交
352
      pBuilder->row.flags |= TSROW_HAS_NULL;
H
Hongze Cheng 已提交
353
      pTColumn->flags |= COL_SET_NULL;
H
Hongze Cheng 已提交
354

H
Hongze Cheng 已提交
355 356
      pTSKVRow->idx[pTSKVRow->nCols].cid = cid;
      pTSKVRow->idx[pTSKVRow->nCols].offset = -1;
H
Hongze Cheng 已提交
357
    }
H
Hongze Cheng 已提交
358

H
Hongze Cheng 已提交
359
    pTSKVRow->nCols++;
H
Hongze Cheng 已提交
360 361 362 363 364
  }

  return 0;
}

H
Hongze Cheng 已提交
365 366 367 368 369 370 371 372 373 374
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 已提交
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
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 已提交
411
int32_t tTSRowBuilderGetRow(STSRowBuilder *pBuilder, const STSRow2 **ppRow) {
H
Hongze Cheng 已提交
412 413 414
  int32_t   nDataTP, nDataKV;
  uint32_t  flags;
  STSKVRow *pTSKVRow = (STSKVRow *)pBuilder->pKVBuf;
H
Hongze Cheng 已提交
415 416

  // error not set ts
H
Hongze Cheng 已提交
417
  if (!COL_IS_SET(pBuilder->pTSchema->columns->flags)) {
H
Hongze Cheng 已提交
418 419 420
    return -1;
  }

H
Hongze Cheng 已提交
421 422
  ASSERT(pTSKVRow->nCols < pBuilder->pTSchema->numOfCols);
  if (pTSKVRow->nCols < pBuilder->pTSchema->numOfCols - 1) {
H
Hongze Cheng 已提交
423
    pBuilder->row.flags |= TSROW_HAS_NONE;
H
Hongze Cheng 已提交
424
  }
H
Hongze Cheng 已提交
425

H
Hongze Cheng 已提交
426 427 428 429 430
  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 已提交
431 432
      pBuilder->row.nData = 0;
      pBuilder->row.pData = NULL;
H
Hongze Cheng 已提交
433 434
      return 0;
    case TSROW_HAS_NULL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
435
      nDataTP = pBuilder->szBitMap1;
H
Hongze Cheng 已提交
436
      break;
H
Hongze Cheng 已提交
437
    case TSROW_HAS_VAL:
H
Hongze Cheng 已提交
438
      nDataTP = pBuilder->pTSchema->flen + pBuilder->vlenTP;
H
Hongze Cheng 已提交
439
      break;
H
Hongze Cheng 已提交
440 441
    case TSROW_HAS_VAL | TSROW_HAS_NONE:
    case TSROW_HAS_VAL | TSROW_HAS_NULL:
H
Hongze Cheng 已提交
442
      nDataTP = pBuilder->szBitMap1 + pBuilder->pTSchema->flen + pBuilder->vlenTP;
H
Hongze Cheng 已提交
443
      break;
H
Hongze Cheng 已提交
444
    case TSROW_HAS_VAL | TSROW_HAS_NULL | TSROW_HAS_NONE:
H
Hongze Cheng 已提交
445
      nDataTP = pBuilder->szBitMap2 + pBuilder->pTSchema->flen + pBuilder->vlenTP;
H
Hongze Cheng 已提交
446 447
      break;
    default:
H
Hongze Cheng 已提交
448
      ASSERT(0);
H
Hongze Cheng 已提交
449 450
  }

H
Hongze Cheng 已提交
451 452
  nDataKV = sizeof(STSKVRow) + sizeof(SKVIdx) * pTSKVRow->nCols + pBuilder->vlenKV;
  pBuilder->row.sver = pBuilder->pTSchema->version;
H
Hongze Cheng 已提交
453 454 455
  if (nDataKV < nDataTP) {
    // generate KV row

H
Hongze Cheng 已提交
456
    pBuilder->row.flags |= TSROW_KV_ROW;
H
Hongze Cheng 已提交
457
    pBuilder->row.nData = nDataKV;
H
Hongze Cheng 已提交
458
    pBuilder->row.pData = pBuilder->pKVBuf;
H
Hongze Cheng 已提交
459

H
Hongze Cheng 已提交
460 461 462
    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 已提交
463 464
    }
  } else {
H
Hongze Cheng 已提交
465 466 467 468
    // generate TUPLE row

    pBuilder->row.nData = nDataTP;

H
Hongze Cheng 已提交
469 470
    uint8_t *p;
    uint8_t  flags = pBuilder->row.flags & 0xf;
H
Hongze Cheng 已提交
471

H
Hongze Cheng 已提交
472 473
    if (flags == TSROW_HAS_VAL) {
      pBuilder->row.pData = pBuilder->pTPBuf + pBuilder->szBitMap2;
H
Hongze Cheng 已提交
474
    } else {
H
Hongze Cheng 已提交
475 476 477 478
      if (flags == TSROW_HAS_VAL) {
        p = pBuilder->pTPBuf;
      } else {
        p = pBuilder->pTPBuf + pBuilder->szBitMap2 - pBuilder->szBitMap1;
H
Hongze Cheng 已提交
479 480
      }

H
Hongze Cheng 已提交
481
      setBitMap(p, pBuilder->pTSchema, flags);
H
Hongze Cheng 已提交
482 483
      pBuilder->row.pData = p;
    }
H
Hongze Cheng 已提交
484 485 486 487 488
  }

  return 0;
}

H
Hongze Cheng 已提交
489
#if 1  // ====================
490
static void dataColSetNEleNull(SDataCol *pCol, int nEle);
H
Hongze Cheng 已提交
491
int         tdAllocMemForCol(SDataCol *pCol, int maxPoints) {
L
Liu Jicong 已提交
492
  int spaceNeeded = pCol->bytes * maxPoints;
S
Shengliang Guan 已提交
493
  if (IS_VAR_DATA_TYPE(pCol->type)) {
L
Liu Jicong 已提交
494
    spaceNeeded += sizeof(VarDataOffsetT) * maxPoints;
L
Liu Jicong 已提交
495
  }
C
Cary Xu 已提交
496
#ifdef TD_SUPPORT_BITMAP
C
Cary Xu 已提交
497 498 499 500
  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.
H
Hongze Cheng 已提交
501 502
  // 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 已提交
503
#endif
C
Cary Xu 已提交
504

S
Shengliang Guan 已提交
505
  if (pCol->spaceSize < spaceNeeded) {
wafwerar's avatar
wafwerar 已提交
506
    void *ptr = taosMemoryRealloc(pCol->pData, spaceNeeded);
S
Shengliang Guan 已提交
507 508
    if (ptr == NULL) {
      uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)spaceNeeded, strerror(errno));
L
Liu Jicong 已提交
509
      return -1;
L
Liu Jicong 已提交
510 511 512
    } else {
      pCol->pData = ptr;
      pCol->spaceSize = spaceNeeded;
513 514
    }
  }
C
Cary Xu 已提交
515
#ifdef TD_SUPPORT_BITMAP
516

C
Cary Xu 已提交
517 518 519 520
  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 已提交
521
    pCol->pBitmap = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
L
Liu Jicong 已提交
522
  }
C
Cary Xu 已提交
523 524 525 526
#else
  if (IS_VAR_DATA_TYPE(pCol->type)) {
    pCol->dataOff = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
  }
C
Cary Xu 已提交
527
#endif
L
Liu Jicong 已提交
528
  return 0;
529 530
}

H
hzcheng 已提交
531 532 533
/**
 * Duplicate the schema and return a new object
 */
H
Hongze Cheng 已提交
534
STSchema *tdDupSchema(const STSchema *pSchema) {
S
Shengliang Guan 已提交
535
  int       tlen = sizeof(STSchema) + sizeof(STColumn) * schemaNCols(pSchema);
wafwerar's avatar
wafwerar 已提交
536
  STSchema *tSchema = (STSchema *)taosMemoryMalloc(tlen);
H
hzcheng 已提交
537 538
  if (tSchema == NULL) return NULL;

H
Hongze Cheng 已提交
539
  memcpy((void *)tSchema, (void *)pSchema, tlen);
H
hzcheng 已提交
540 541 542 543

  return tSchema;
}

H
TD-27  
hzcheng 已提交
544 545 546
/**
 * Encode a schema to dst, and return the next pointer
 */
H
TD-353  
Hongze Cheng 已提交
547 548 549 550
int tdEncodeSchema(void **buf, STSchema *pSchema) {
  int tlen = 0;
  tlen += taosEncodeFixedI32(buf, schemaVersion(pSchema));
  tlen += taosEncodeFixedI32(buf, schemaNCols(pSchema));
H
TD-166  
hzcheng 已提交
551

H
TD-27  
hzcheng 已提交
552 553
  for (int i = 0; i < schemaNCols(pSchema); i++) {
    STColumn *pCol = schemaColAt(pSchema, i);
H
TD-353  
Hongze Cheng 已提交
554
    tlen += taosEncodeFixedI8(buf, colType(pCol));
C
Cary Xu 已提交
555
    tlen += taosEncodeFixedI8(buf, colFlags(pCol));
H
TD-353  
Hongze Cheng 已提交
556
    tlen += taosEncodeFixedI16(buf, colColId(pCol));
557
    tlen += taosEncodeFixedI16(buf, colBytes(pCol));
H
TD-27  
hzcheng 已提交
558 559
  }

H
TD-353  
Hongze Cheng 已提交
560
  return tlen;
H
TD-27  
hzcheng 已提交
561 562 563 564 565
}

/**
 * Decode a schema from a binary.
 */
H
TD-353  
Hongze Cheng 已提交
566
void *tdDecodeSchema(void *buf, STSchema **pRSchema) {
S
Shengliang Guan 已提交
567 568
  int             version = 0;
  int             numOfCols = 0;
H
TD-353  
Hongze Cheng 已提交
569
  STSchemaBuilder schemaBuilder;
H
TD-27  
hzcheng 已提交
570

H
TD-353  
Hongze Cheng 已提交
571 572
  buf = taosDecodeFixedI32(buf, &version);
  buf = taosDecodeFixedI32(buf, &numOfCols);
H
TD-27  
hzcheng 已提交
573

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

H
TD-353  
Hongze Cheng 已提交
576
  for (int i = 0; i < numOfCols; i++) {
577
    col_type_t  type = 0;
C
Cary Xu 已提交
578
    int8_t      flags = 0;
579 580
    col_id_t    colId = 0;
    col_bytes_t bytes = 0;
H
TD-353  
Hongze Cheng 已提交
581
    buf = taosDecodeFixedI8(buf, &type);
C
Cary Xu 已提交
582
    buf = taosDecodeFixedI8(buf, &flags);
H
TD-353  
Hongze Cheng 已提交
583
    buf = taosDecodeFixedI16(buf, &colId);
584
    buf = taosDecodeFixedI32(buf, &bytes);
C
Cary Xu 已提交
585
    if (tdAddColToSchema(&schemaBuilder, type, flags, colId, bytes) < 0) {
H
Hongze Cheng 已提交
586 587 588
      tdDestroyTSchemaBuilder(&schemaBuilder);
      return NULL;
    }
H
TD-27  
hzcheng 已提交
589 590
  }

H
TD-353  
Hongze Cheng 已提交
591
  *pRSchema = tdGetSchemaFromBuilder(&schemaBuilder);
H
Hongze Cheng 已提交
592
  tdDestroyTSchemaBuilder(&schemaBuilder);
H
TD-353  
Hongze Cheng 已提交
593
  return buf;
H
Hongze Cheng 已提交
594 595
}

C
Cary Xu 已提交
596
int tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
H
Hongze Cheng 已提交
597 598 599
  if (pBuilder == NULL) return -1;

  pBuilder->tCols = 256;
wafwerar's avatar
wafwerar 已提交
600
  pBuilder->columns = (STColumn *)taosMemoryMalloc(sizeof(STColumn) * pBuilder->tCols);
H
Hongze Cheng 已提交
601 602 603 604 605 606 607 608
  if (pBuilder->columns == NULL) return -1;

  tdResetTSchemaBuilder(pBuilder, version);
  return 0;
}

void tdDestroyTSchemaBuilder(STSchemaBuilder *pBuilder) {
  if (pBuilder) {
wafwerar's avatar
wafwerar 已提交
609
    taosMemoryFreeClear(pBuilder->columns);
H
Hongze Cheng 已提交
610 611 612
  }
}

C
Cary Xu 已提交
613
void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
H
Hongze Cheng 已提交
614 615 616
  pBuilder->nCols = 0;
  pBuilder->tlen = 0;
  pBuilder->flen = 0;
T
Tao Liu 已提交
617
  pBuilder->vlen = 0;
H
Hongze Cheng 已提交
618 619 620
  pBuilder->version = version;
}

C
Cary Xu 已提交
621
int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t flags, col_id_t colId, col_bytes_t bytes) {
622
  if (!isValidDataType(type)) return -1;
H
Hongze Cheng 已提交
623 624 625

  if (pBuilder->nCols >= pBuilder->tCols) {
    pBuilder->tCols *= 2;
wafwerar's avatar
wafwerar 已提交
626
    STColumn *columns = (STColumn *)taosMemoryRealloc(pBuilder->columns, sizeof(STColumn) * pBuilder->tCols);
T
tickduan 已提交
627 628
    if (columns == NULL) return -1;
    pBuilder->columns = columns;
H
Hongze Cheng 已提交
629 630 631 632 633
  }

  STColumn *pCol = &(pBuilder->columns[pBuilder->nCols]);
  colSetType(pCol, type);
  colSetColId(pCol, colId);
C
Cary Xu 已提交
634
  colSetFlags(pCol, flags);
H
Hongze Cheng 已提交
635 636 637
  if (pBuilder->nCols == 0) {
    colSetOffset(pCol, 0);
  } else {
S
Shengliang Guan 已提交
638
    STColumn *pTCol = &(pBuilder->columns[pBuilder->nCols - 1]);
H
Hongze Cheng 已提交
639 640 641 642 643
    colSetOffset(pCol, pTCol->offset + TYPE_BYTES[pTCol->type]);
  }

  if (IS_VAR_DATA_TYPE(type)) {
    colSetBytes(pCol, bytes);
T
Tao Liu 已提交
644 645
    pBuilder->tlen += (TYPE_BYTES[type] + bytes);
    pBuilder->vlen += bytes - sizeof(VarDataLenT);
H
Hongze Cheng 已提交
646 647 648
  } else {
    colSetBytes(pCol, TYPE_BYTES[type]);
    pBuilder->tlen += TYPE_BYTES[type];
T
Tao Liu 已提交
649
    pBuilder->vlen += TYPE_BYTES[type];
H
Hongze Cheng 已提交
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
  }

  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 已提交
665
  STSchema *pSchema = (STSchema *)taosMemoryMalloc(tlen);
H
Hongze Cheng 已提交
666 667 668 669 670 671
  if (pSchema == NULL) return NULL;

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

C
Cary Xu 已提交
674
#ifdef TD_SUPPORT_BITMAP
C
Cary Xu 已提交
675
  schemaTLen(pSchema) += (int)TD_BITMAP_BYTES(schemaNCols(pSchema));
C
Cary Xu 已提交
676 677
#endif

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

H
TD-27  
hzcheng 已提交
680 681 682
  return pSchema;
}

683
void dataColInit(SDataCol *pDataCol, STColumn *pCol, int maxPoints) {
H
TD-166  
hzcheng 已提交
684 685 686
  pDataCol->type = colType(pCol);
  pDataCol->colId = colColId(pCol);
  pDataCol->bytes = colBytes(pCol);
S
Shengliang Guan 已提交
687
  pDataCol->offset = colOffset(pCol) + 0;  // TD_DATA_ROW_HEAD_SIZE;
H
TD-166  
hzcheng 已提交
688 689 690

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

L
Liu Jicong 已提交
692 693 694 695 696 697
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 已提交
698 699
}

H
TD-166  
hzcheng 已提交
700
bool isNEleNull(SDataCol *pCol, int nEle) {
S
Shengliang Guan 已提交
701
  if (isAllRowsNull(pCol)) return true;
702
  for (int i = 0; i < nEle; ++i) {
L
Liu Jicong 已提交
703
    if (!isNull(tdGetColDataOfRowUnsafe(pCol, i), pCol->type)) return false;
H
TD-166  
hzcheng 已提交
704
  }
H
Hongze Cheng 已提交
705
  return true;
H
TD-166  
hzcheng 已提交
706 707
}

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

H
Hongze Cheng 已提交
711
  void *tptr = pCol->pData;
H
TD-166  
hzcheng 已提交
712
  // char *tptr = (char *)(pCol->pData);
H
TD-166  
hzcheng 已提交
713

H
TD-166  
hzcheng 已提交
714
  VarDataOffsetT offset = 0;
715
  for (int i = 0; i < nEle; ++i) {
H
TD-166  
hzcheng 已提交
716
    pCol->dataOff[i] = offset;
H
TD-166  
hzcheng 已提交
717
    offset += varDataTLen(tptr);
H
hzcheng 已提交
718
    tptr = POINTER_SHIFT(tptr, varDataTLen(tptr));
H
TD-166  
hzcheng 已提交
719
  }
C
Cary Xu 已提交
720
  return POINTER_SHIFT(tptr, varDataTLen(tptr));
H
TD-166  
hzcheng 已提交
721 722
}

L
Liu Jicong 已提交
723
SDataCols *tdNewDataCols(int maxCols, int maxRows) {
wafwerar's avatar
wafwerar 已提交
724
  SDataCols *pCols = (SDataCols *)taosMemoryCalloc(1, sizeof(SDataCols));
H
Haojun Liao 已提交
725
  if (pCols == NULL) {
S
Shengliang Guan 已提交
726
    uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCols), strerror(errno));
H
Haojun Liao 已提交
727 728
    return NULL;
  }
H
TD-34  
hzcheng 已提交
729

H
Hongze Cheng 已提交
730
  pCols->maxPoints = maxRows;
L
Liu Jicong 已提交
731 732 733
  pCols->maxCols = maxCols;
  pCols->numOfRows = 0;
  pCols->numOfCols = 0;
C
Cary Xu 已提交
734
  // pCols->bitmapMode = 0; // calloc already set 0
H
Hongze Cheng 已提交
735 736

  if (maxCols > 0) {
wafwerar's avatar
wafwerar 已提交
737
    pCols->cols = (SDataCol *)taosMemoryCalloc(maxCols, sizeof(SDataCol));
H
Hongze Cheng 已提交
738 739 740 741 742 743
    if (pCols->cols == NULL) {
      uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCol) * maxCols,
             strerror(errno));
      tdFreeDataCols(pCols);
      return NULL;
    }
744
#if 0  // no need as calloc used
L
Liu Jicong 已提交
745
    int i;
S
Shengliang Guan 已提交
746
    for (i = 0; i < maxCols; i++) {
L
Liu Jicong 已提交
747
      pCols->cols[i].spaceSize = 0;
L
Liu Jicong 已提交
748
      pCols->cols[i].len = 0;
L
Liu Jicong 已提交
749 750 751
      pCols->cols[i].pData = NULL;
      pCols->cols[i].dataOff = NULL;
    }
752
#endif
H
Hongze Cheng 已提交
753 754
  }

H
TD-34  
hzcheng 已提交
755 756 757
  return pCols;
}

H
Hongze Cheng 已提交
758
int tdInitDataCols(SDataCols *pCols, STSchema *pSchema) {
759 760
  int i;
  int oldMaxCols = pCols->maxCols;
L
Liu Jicong 已提交
761
  if (schemaNCols(pSchema) > oldMaxCols) {
H
Hongze Cheng 已提交
762
    pCols->maxCols = schemaNCols(pSchema);
wafwerar's avatar
wafwerar 已提交
763
    void *ptr = (SDataCol *)taosMemoryRealloc(pCols->cols, sizeof(SDataCol) * pCols->maxCols);
L
Liu Jicong 已提交
764 765
    if (ptr == NULL) return -1;
    pCols->cols = ptr;
766
    for (i = oldMaxCols; i < pCols->maxCols; ++i) {
767 768
      pCols->cols[i].pData = NULL;
      pCols->cols[i].dataOff = NULL;
769
      pCols->cols[i].pBitmap = NULL;
L
Liu Jicong 已提交
770
      pCols->cols[i].spaceSize = 0;
771
    }
L
Liu Jicong 已提交
772
  }
773 774 775
#if 0
  tdResetDataCols(pCols); // redundant loop to reset len/blen to 0, already reset in following dataColInit(...)
#endif
H
Hongze Cheng 已提交
776

777
  pCols->numOfRows = 0;
C
Cary Xu 已提交
778
  pCols->bitmapMode = 0;
H
TD-34  
hzcheng 已提交
779 780
  pCols->numOfCols = schemaNCols(pSchema);

781
  for (i = 0; i < schemaNCols(pSchema); ++i) {
782
    dataColInit(pCols->cols + i, schemaColAt(pSchema, i), pCols->maxPoints);
H
TD-34  
hzcheng 已提交
783
  }
S
Shengliang Guan 已提交
784

H
Hongze Cheng 已提交
785
  return 0;
H
TD-34  
hzcheng 已提交
786 787
}

H
Hongze Cheng 已提交
788
SDataCols *tdFreeDataCols(SDataCols *pCols) {
789
  int i;
H
TD-34  
hzcheng 已提交
790
  if (pCols) {
S
Shengliang Guan 已提交
791
    if (pCols->cols) {
792
      int maxCols = pCols->maxCols;
793
      for (i = 0; i < maxCols; ++i) {
794
        SDataCol *pCol = &pCols->cols[i];
wafwerar's avatar
wafwerar 已提交
795
        taosMemoryFreeClear(pCol->pData);
796
      }
wafwerar's avatar
wafwerar 已提交
797
      taosMemoryFree(pCols->cols);
798 799
      pCols->cols = NULL;
    }
wafwerar's avatar
wafwerar 已提交
800
    taosMemoryFree(pCols);
H
TD-34  
hzcheng 已提交
801
  }
H
Hongze Cheng 已提交
802
  return NULL;
H
TD-34  
hzcheng 已提交
803 804 805
}

void tdResetDataCols(SDataCols *pCols) {
B
Bomin Zhang 已提交
806 807
  if (pCols != NULL) {
    pCols->numOfRows = 0;
C
Cary Xu 已提交
808
    pCols->bitmapMode = 0;
809
    for (int i = 0; i < pCols->maxCols; ++i) {
B
Bomin Zhang 已提交
810 811
      dataColReset(pCols->cols + i);
    }
H
TD-34  
hzcheng 已提交
812 813
  }
}
H
Hongze Cheng 已提交
814

H
Hongze Cheng 已提交
815
SKVRow tdKVRowDup(SKVRow row) {
wafwerar's avatar
wafwerar 已提交
816
  SKVRow trow = taosMemoryMalloc(kvRowLen(row));
H
Hongze Cheng 已提交
817 818
  if (trow == NULL) return NULL;

H
Hongze Cheng 已提交
819
  kvRowCpy(trow, row);
H
Hongze Cheng 已提交
820 821 822
  return trow;
}

S
Shengliang Guan 已提交
823 824 825
static int compareColIdx(const void *a, const void *b) {
  const SColIdx *x = (const SColIdx *)a;
  const SColIdx *y = (const SColIdx *)b;
B
Bomin Zhang 已提交
826 827 828 829 830 831 832 833 834
  if (x->colId > y->colId) {
    return 1;
  }
  if (x->colId < y->colId) {
    return -1;
  }
  return 0;
}

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

H
TD-90  
Hongze Cheng 已提交
837 838 839 840
int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value) {
  SColIdx *pColIdx = NULL;
  SKVRow   row = *orow;
  SKVRow   nrow = NULL;
S
Shengliang Guan 已提交
841
  void    *ptr = taosbsearch(&colId, kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), comparTagId, TD_GE);
H
TD-90  
Hongze Cheng 已提交
842

843
  if (ptr == NULL || ((SColIdx *)ptr)->colId > colId) {  // need to add a column value to the row
C
Cary Xu 已提交
844
    int diff = IS_VAR_DATA_TYPE(type) ? varDataTLen(value) : TYPE_BYTES[type];
845 846 847 848
    int nRowLen = kvRowLen(row) + sizeof(SColIdx) + diff;
    int oRowCols = kvRowNCols(row);

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

852 853
    kvRowSetLen(nrow, nRowLen);
    kvRowSetNCols(nrow, oRowCols + 1);
H
TD-90  
Hongze Cheng 已提交
854

855 856
    memcpy(kvRowColIdx(nrow), kvRowColIdx(row), sizeof(SColIdx) * oRowCols);
    memcpy(kvRowValues(nrow), kvRowValues(row), kvRowValLen(row));
H
TD-90  
Hongze Cheng 已提交
857

858 859 860
    pColIdx = kvRowColIdxAt(nrow, oRowCols);
    pColIdx->colId = colId;
    pColIdx->offset = kvRowValLen(row);
H
TD-90  
Hongze Cheng 已提交
861

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

864
    tdSortKVRowByColIdx(nrow);
H
TD-90  
Hongze Cheng 已提交
865 866

    *orow = nrow;
wafwerar's avatar
wafwerar 已提交
867
    taosMemoryFree(row);
H
TD-90  
Hongze Cheng 已提交
868 869 870 871 872
  } else {
    ASSERT(((SColIdx *)ptr)->colId == colId);
    if (IS_VAR_DATA_TYPE(type)) {
      void *pOldVal = kvRowColVal(row, (SColIdx *)ptr);

S
Shengliang Guan 已提交
873
      if (varDataTLen(value) == varDataTLen(pOldVal)) {  // just update the column value in place
H
TD-90  
Hongze Cheng 已提交
874
        memcpy(pOldVal, value, varDataTLen(value));
875 876
      } else {  // need to reallocate the memory
        int16_t nlen = kvRowLen(row) + (varDataTLen(value) - varDataTLen(pOldVal));
H
TD-90  
Hongze Cheng 已提交
877
        ASSERT(nlen > 0);
wafwerar's avatar
wafwerar 已提交
878
        nrow = taosMemoryMalloc(nlen);
H
TD-90  
Hongze Cheng 已提交
879
        if (nrow == NULL) return -1;
H
TD-90  
Hongze Cheng 已提交
880 881 882 883

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

884 885 886 887 888 889 890 891
        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 已提交
892 893
        }

894 895 896 897 898
        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 已提交
899 900 901 902
          }
        }

        *orow = nrow;
wafwerar's avatar
wafwerar 已提交
903
        taosMemoryFree(row);
H
TD-90  
Hongze Cheng 已提交
904 905 906 907 908 909 910
      }
    } else {
      memcpy(kvRowColVal(row, (SColIdx *)ptr), value, TYPE_BYTES[type]);
    }
  }

  return 0;
H
Hongze Cheng 已提交
911 912
}

H
TD-353  
Hongze Cheng 已提交
913
int tdEncodeKVRow(void **buf, SKVRow row) {
H
Hongze Cheng 已提交
914
  // May change the encode purpose
H
TD-353  
Hongze Cheng 已提交
915 916 917 918 919 920
  if (buf != NULL) {
    kvRowCpy(*buf, row);
    *buf = POINTER_SHIFT(*buf, kvRowLen(row));
  }

  return kvRowLen(row);
H
Hongze Cheng 已提交
921 922
}

H
Hongze Cheng 已提交
923 924
void *tdDecodeKVRow(void *buf, SKVRow *row) {
  *row = tdKVRowDup(buf);
H
TD-353  
Hongze Cheng 已提交
925
  if (*row == NULL) return NULL;
H
Hongze Cheng 已提交
926
  return POINTER_SHIFT(buf, kvRowLen(*row));
H
Hongze Cheng 已提交
927 928
}

H
Hongze Cheng 已提交
929
int tdInitKVRowBuilder(SKVRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
930 931
  pBuilder->tCols = 128;
  pBuilder->nCols = 0;
wafwerar's avatar
wafwerar 已提交
932
  pBuilder->pColIdx = (SColIdx *)taosMemoryMalloc(sizeof(SColIdx) * pBuilder->tCols);
H
Hongze Cheng 已提交
933 934 935
  if (pBuilder->pColIdx == NULL) return -1;
  pBuilder->alloc = 1024;
  pBuilder->size = 0;
wafwerar's avatar
wafwerar 已提交
936
  pBuilder->buf = taosMemoryMalloc(pBuilder->alloc);
H
Hongze Cheng 已提交
937
  if (pBuilder->buf == NULL) {
wafwerar's avatar
wafwerar 已提交
938
    taosMemoryFree(pBuilder->pColIdx);
H
Hongze Cheng 已提交
939 940 941 942 943
    return -1;
  }
  return 0;
}

H
Hongze Cheng 已提交
944
void tdDestroyKVRowBuilder(SKVRowBuilder *pBuilder) {
wafwerar's avatar
wafwerar 已提交
945 946
  taosMemoryFreeClear(pBuilder->pColIdx);
  taosMemoryFreeClear(pBuilder->buf);
H
Hongze Cheng 已提交
947 948
}

H
Hongze Cheng 已提交
949
void tdResetKVRowBuilder(SKVRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
950 951 952 953
  pBuilder->nCols = 0;
  pBuilder->size = 0;
}

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

H
Hongze Cheng 已提交
958 959
  tlen += TD_KV_ROW_HEAD_SIZE;

wafwerar's avatar
wafwerar 已提交
960
  SKVRow row = taosMemoryMalloc(tlen);
H
Hongze Cheng 已提交
961 962
  if (row == NULL) return NULL;

H
Hongze Cheng 已提交
963
  kvRowSetNCols(row, pBuilder->nCols);
H
Hongze Cheng 已提交
964
  kvRowSetLen(row, tlen);
H
Hongze Cheng 已提交
965

H
Hongze Cheng 已提交
966 967
  memcpy(kvRowColIdx(row), pBuilder->pColIdx, sizeof(SColIdx) * pBuilder->nCols);
  memcpy(kvRowValues(row), pBuilder->buf, pBuilder->size);
H
Hongze Cheng 已提交
968 969

  return row;
970
}
H
Hongze Cheng 已提交
971
#endif