tdataformat.c 15.0 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

22
static void dataColSetNEleNull(SDataCol *pCol, int nEle);
C
Cary Xu 已提交
23
#if 0
H
TD-1438  
Hongze Cheng 已提交
24
static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, int limit1, SDataCols *src2, int *iter2,
25
                               int limit2, int tRows, bool forceSetNull);
C
Cary Xu 已提交
26
#endif
L
Liu Jicong 已提交
27
int tdAllocMemForCol(SDataCol *pCol, int maxPoints) {
L
Liu Jicong 已提交
28
  int spaceNeeded = pCol->bytes * maxPoints;
S
Shengliang Guan 已提交
29
  if (IS_VAR_DATA_TYPE(pCol->type)) {
L
Liu Jicong 已提交
30
    spaceNeeded += sizeof(VarDataOffsetT) * maxPoints;
L
Liu Jicong 已提交
31
  }
C
Cary Xu 已提交
32
#ifdef TD_SUPPORT_BITMAP
C
Cary Xu 已提交
33 34 35 36
  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.
37 38
  // 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 已提交
39
#endif
C
Cary Xu 已提交
40

S
Shengliang Guan 已提交
41
  if (pCol->spaceSize < spaceNeeded) {
wafwerar's avatar
wafwerar 已提交
42
    void *ptr = taosMemoryRealloc(pCol->pData, spaceNeeded);
S
Shengliang Guan 已提交
43 44
    if (ptr == NULL) {
      uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)spaceNeeded, strerror(errno));
L
Liu Jicong 已提交
45
      return -1;
L
Liu Jicong 已提交
46 47 48
    } else {
      pCol->pData = ptr;
      pCol->spaceSize = spaceNeeded;
49 50
    }
  }
C
Cary Xu 已提交
51
#ifdef TD_SUPPORT_BITMAP
52

C
Cary Xu 已提交
53 54 55 56
  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 已提交
57
    pCol->pBitmap = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
L
Liu Jicong 已提交
58
  }
C
Cary Xu 已提交
59 60 61 62
#else
  if (IS_VAR_DATA_TYPE(pCol->type)) {
    pCol->dataOff = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
  }
C
Cary Xu 已提交
63
#endif
L
Liu Jicong 已提交
64
  return 0;
65 66
}

H
hzcheng 已提交
67 68 69
/**
 * Duplicate the schema and return a new object
 */
H
Hongze Cheng 已提交
70
STSchema *tdDupSchema(const STSchema *pSchema) {
S
Shengliang Guan 已提交
71
  int       tlen = sizeof(STSchema) + sizeof(STColumn) * schemaNCols(pSchema);
wafwerar's avatar
wafwerar 已提交
72
  STSchema *tSchema = (STSchema *)taosMemoryMalloc(tlen);
H
hzcheng 已提交
73 74
  if (tSchema == NULL) return NULL;

H
Hongze Cheng 已提交
75
  memcpy((void *)tSchema, (void *)pSchema, tlen);
H
hzcheng 已提交
76 77 78 79

  return tSchema;
}

H
TD-27  
hzcheng 已提交
80 81 82
/**
 * Encode a schema to dst, and return the next pointer
 */
H
TD-353  
Hongze Cheng 已提交
83 84 85 86
int tdEncodeSchema(void **buf, STSchema *pSchema) {
  int tlen = 0;
  tlen += taosEncodeFixedI32(buf, schemaVersion(pSchema));
  tlen += taosEncodeFixedI32(buf, schemaNCols(pSchema));
H
TD-166  
hzcheng 已提交
87

H
TD-27  
hzcheng 已提交
88 89
  for (int i = 0; i < schemaNCols(pSchema); i++) {
    STColumn *pCol = schemaColAt(pSchema, i);
H
TD-353  
Hongze Cheng 已提交
90
    tlen += taosEncodeFixedI8(buf, colType(pCol));
C
Cary Xu 已提交
91
    tlen += taosEncodeFixedI8(buf, colFlags(pCol));
H
TD-353  
Hongze Cheng 已提交
92
    tlen += taosEncodeFixedI16(buf, colColId(pCol));
93
    tlen += taosEncodeFixedI16(buf, colBytes(pCol));
H
TD-27  
hzcheng 已提交
94 95
  }

H
TD-353  
Hongze Cheng 已提交
96
  return tlen;
H
TD-27  
hzcheng 已提交
97 98 99 100 101
}

/**
 * Decode a schema from a binary.
 */
H
TD-353  
Hongze Cheng 已提交
102
void *tdDecodeSchema(void *buf, STSchema **pRSchema) {
S
Shengliang Guan 已提交
103 104
  int             version = 0;
  int             numOfCols = 0;
H
TD-353  
Hongze Cheng 已提交
105
  STSchemaBuilder schemaBuilder;
H
TD-27  
hzcheng 已提交
106

H
TD-353  
Hongze Cheng 已提交
107 108
  buf = taosDecodeFixedI32(buf, &version);
  buf = taosDecodeFixedI32(buf, &numOfCols);
H
TD-27  
hzcheng 已提交
109

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

H
TD-353  
Hongze Cheng 已提交
112
  for (int i = 0; i < numOfCols; i++) {
113
    col_type_t  type = 0;
C
Cary Xu 已提交
114
    int8_t      flags = 0;
115 116
    col_id_t    colId = 0;
    col_bytes_t bytes = 0;
H
TD-353  
Hongze Cheng 已提交
117
    buf = taosDecodeFixedI8(buf, &type);
C
Cary Xu 已提交
118
    buf = taosDecodeFixedI8(buf, &flags);
H
TD-353  
Hongze Cheng 已提交
119
    buf = taosDecodeFixedI16(buf, &colId);
120
    buf = taosDecodeFixedI32(buf, &bytes);
C
Cary Xu 已提交
121
    if (tdAddColToSchema(&schemaBuilder, type, flags, colId, bytes) < 0) {
H
Hongze Cheng 已提交
122 123 124
      tdDestroyTSchemaBuilder(&schemaBuilder);
      return NULL;
    }
H
TD-27  
hzcheng 已提交
125 126
  }

H
TD-353  
Hongze Cheng 已提交
127
  *pRSchema = tdGetSchemaFromBuilder(&schemaBuilder);
H
Hongze Cheng 已提交
128
  tdDestroyTSchemaBuilder(&schemaBuilder);
H
TD-353  
Hongze Cheng 已提交
129
  return buf;
H
Hongze Cheng 已提交
130 131
}

C
Cary Xu 已提交
132
int tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
H
Hongze Cheng 已提交
133 134 135
  if (pBuilder == NULL) return -1;

  pBuilder->tCols = 256;
wafwerar's avatar
wafwerar 已提交
136
  pBuilder->columns = (STColumn *)taosMemoryMalloc(sizeof(STColumn) * pBuilder->tCols);
H
Hongze Cheng 已提交
137 138 139 140 141 142 143 144
  if (pBuilder->columns == NULL) return -1;

  tdResetTSchemaBuilder(pBuilder, version);
  return 0;
}

void tdDestroyTSchemaBuilder(STSchemaBuilder *pBuilder) {
  if (pBuilder) {
wafwerar's avatar
wafwerar 已提交
145
    taosMemoryFreeClear(pBuilder->columns);
H
Hongze Cheng 已提交
146 147 148
  }
}

C
Cary Xu 已提交
149
void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version) {
H
Hongze Cheng 已提交
150 151 152
  pBuilder->nCols = 0;
  pBuilder->tlen = 0;
  pBuilder->flen = 0;
T
Tao Liu 已提交
153
  pBuilder->vlen = 0;
H
Hongze Cheng 已提交
154 155 156
  pBuilder->version = version;
}

C
Cary Xu 已提交
157
int32_t tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int8_t flags, col_id_t colId, col_bytes_t bytes) {
158
  if (!isValidDataType(type)) return -1;
H
Hongze Cheng 已提交
159 160 161

  if (pBuilder->nCols >= pBuilder->tCols) {
    pBuilder->tCols *= 2;
wafwerar's avatar
wafwerar 已提交
162
    STColumn *columns = (STColumn *)taosMemoryRealloc(pBuilder->columns, sizeof(STColumn) * pBuilder->tCols);
T
tickduan 已提交
163 164
    if (columns == NULL) return -1;
    pBuilder->columns = columns;
H
Hongze Cheng 已提交
165 166 167 168 169
  }

  STColumn *pCol = &(pBuilder->columns[pBuilder->nCols]);
  colSetType(pCol, type);
  colSetColId(pCol, colId);
C
Cary Xu 已提交
170
  colSetFlags(pCol, flags);
H
Hongze Cheng 已提交
171 172 173
  if (pBuilder->nCols == 0) {
    colSetOffset(pCol, 0);
  } else {
S
Shengliang Guan 已提交
174
    STColumn *pTCol = &(pBuilder->columns[pBuilder->nCols - 1]);
H
Hongze Cheng 已提交
175 176 177 178 179
    colSetOffset(pCol, pTCol->offset + TYPE_BYTES[pTCol->type]);
  }

  if (IS_VAR_DATA_TYPE(type)) {
    colSetBytes(pCol, bytes);
T
Tao Liu 已提交
180 181
    pBuilder->tlen += (TYPE_BYTES[type] + bytes);
    pBuilder->vlen += bytes - sizeof(VarDataLenT);
H
Hongze Cheng 已提交
182 183 184
  } else {
    colSetBytes(pCol, TYPE_BYTES[type]);
    pBuilder->tlen += TYPE_BYTES[type];
T
Tao Liu 已提交
185
    pBuilder->vlen += TYPE_BYTES[type];
H
Hongze Cheng 已提交
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
  }

  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 已提交
201
  STSchema *pSchema = (STSchema *)taosMemoryMalloc(tlen);
H
Hongze Cheng 已提交
202 203 204 205 206 207
  if (pSchema == NULL) return NULL;

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

C
Cary Xu 已提交
210
#ifdef TD_SUPPORT_BITMAP
C
Cary Xu 已提交
211
  schemaTLen(pSchema) += (int)TD_BITMAP_BYTES(schemaNCols(pSchema));
C
Cary Xu 已提交
212 213
#endif

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

H
TD-27  
hzcheng 已提交
216 217 218
  return pSchema;
}

219
void dataColInit(SDataCol *pDataCol, STColumn *pCol, int maxPoints) {
H
TD-166  
hzcheng 已提交
220 221 222
  pDataCol->type = colType(pCol);
  pDataCol->colId = colColId(pCol);
  pDataCol->bytes = colBytes(pCol);
S
Shengliang Guan 已提交
223
  pDataCol->offset = colOffset(pCol) + 0;  // TD_DATA_ROW_HEAD_SIZE;
H
TD-166  
hzcheng 已提交
224 225 226

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

L
Liu Jicong 已提交
228 229 230 231 232 233
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 已提交
234 235
}

H
TD-166  
hzcheng 已提交
236
bool isNEleNull(SDataCol *pCol, int nEle) {
S
Shengliang Guan 已提交
237
  if (isAllRowsNull(pCol)) return true;
238
  for (int i = 0; i < nEle; ++i) {
L
Liu Jicong 已提交
239
    if (!isNull(tdGetColDataOfRowUnsafe(pCol, i), pCol->type)) return false;
H
TD-166  
hzcheng 已提交
240
  }
H
Hongze Cheng 已提交
241
  return true;
H
TD-166  
hzcheng 已提交
242 243
}

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

H
Hongze Cheng 已提交
247
  void *tptr = pCol->pData;
H
TD-166  
hzcheng 已提交
248
  // char *tptr = (char *)(pCol->pData);
H
TD-166  
hzcheng 已提交
249

H
TD-166  
hzcheng 已提交
250
  VarDataOffsetT offset = 0;
251
  for (int i = 0; i < nEle; ++i) {
H
TD-166  
hzcheng 已提交
252
    pCol->dataOff[i] = offset;
H
TD-166  
hzcheng 已提交
253
    offset += varDataTLen(tptr);
H
hzcheng 已提交
254
    tptr = POINTER_SHIFT(tptr, varDataTLen(tptr));
H
TD-166  
hzcheng 已提交
255
  }
C
Cary Xu 已提交
256
  return POINTER_SHIFT(tptr, varDataTLen(tptr));
H
TD-166  
hzcheng 已提交
257 258
}

L
Liu Jicong 已提交
259
SDataCols *tdNewDataCols(int maxCols, int maxRows) {
wafwerar's avatar
wafwerar 已提交
260
  SDataCols *pCols = (SDataCols *)taosMemoryCalloc(1, sizeof(SDataCols));
H
Haojun Liao 已提交
261
  if (pCols == NULL) {
S
Shengliang Guan 已提交
262
    uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCols), strerror(errno));
H
Haojun Liao 已提交
263 264
    return NULL;
  }
H
TD-34  
hzcheng 已提交
265

H
Hongze Cheng 已提交
266
  pCols->maxPoints = maxRows;
L
Liu Jicong 已提交
267 268 269
  pCols->maxCols = maxCols;
  pCols->numOfRows = 0;
  pCols->numOfCols = 0;
C
Cary Xu 已提交
270
  // pCols->bitmapMode = 0; // calloc already set 0
H
Hongze Cheng 已提交
271 272

  if (maxCols > 0) {
wafwerar's avatar
wafwerar 已提交
273
    pCols->cols = (SDataCol *)taosMemoryCalloc(maxCols, sizeof(SDataCol));
H
Hongze Cheng 已提交
274 275 276 277 278 279
    if (pCols->cols == NULL) {
      uDebug("malloc failure, size:%" PRId64 " failed, reason:%s", (int64_t)sizeof(SDataCol) * maxCols,
             strerror(errno));
      tdFreeDataCols(pCols);
      return NULL;
    }
280
#if 0  // no need as calloc used
L
Liu Jicong 已提交
281
    int i;
S
Shengliang Guan 已提交
282
    for (i = 0; i < maxCols; i++) {
L
Liu Jicong 已提交
283
      pCols->cols[i].spaceSize = 0;
L
Liu Jicong 已提交
284
      pCols->cols[i].len = 0;
L
Liu Jicong 已提交
285 286 287
      pCols->cols[i].pData = NULL;
      pCols->cols[i].dataOff = NULL;
    }
288
#endif
H
Hongze Cheng 已提交
289 290
  }

H
TD-34  
hzcheng 已提交
291 292 293
  return pCols;
}

H
Hongze Cheng 已提交
294
int tdInitDataCols(SDataCols *pCols, STSchema *pSchema) {
295 296
  int i;
  int oldMaxCols = pCols->maxCols;
L
Liu Jicong 已提交
297
  if (schemaNCols(pSchema) > oldMaxCols) {
H
Hongze Cheng 已提交
298
    pCols->maxCols = schemaNCols(pSchema);
wafwerar's avatar
wafwerar 已提交
299
    void *ptr = (SDataCol *)taosMemoryRealloc(pCols->cols, sizeof(SDataCol) * pCols->maxCols);
L
Liu Jicong 已提交
300 301
    if (ptr == NULL) return -1;
    pCols->cols = ptr;
302
    for (i = oldMaxCols; i < pCols->maxCols; ++i) {
303 304
      pCols->cols[i].pData = NULL;
      pCols->cols[i].dataOff = NULL;
305
      pCols->cols[i].pBitmap = NULL;
L
Liu Jicong 已提交
306
      pCols->cols[i].spaceSize = 0;
307
    }
L
Liu Jicong 已提交
308
  }
309 310 311
#if 0
  tdResetDataCols(pCols); // redundant loop to reset len/blen to 0, already reset in following dataColInit(...)
#endif
H
Hongze Cheng 已提交
312

313
  pCols->numOfRows = 0;
C
Cary Xu 已提交
314
  pCols->bitmapMode = 0;
H
TD-34  
hzcheng 已提交
315 316
  pCols->numOfCols = schemaNCols(pSchema);

317
  for (i = 0; i < schemaNCols(pSchema); ++i) {
318
    dataColInit(pCols->cols + i, schemaColAt(pSchema, i), pCols->maxPoints);
H
TD-34  
hzcheng 已提交
319
  }
S
Shengliang Guan 已提交
320

H
Hongze Cheng 已提交
321
  return 0;
H
TD-34  
hzcheng 已提交
322 323
}

H
Hongze Cheng 已提交
324
SDataCols *tdFreeDataCols(SDataCols *pCols) {
325
  int i;
H
TD-34  
hzcheng 已提交
326
  if (pCols) {
S
Shengliang Guan 已提交
327
    if (pCols->cols) {
328
      int maxCols = pCols->maxCols;
329
      for (i = 0; i < maxCols; ++i) {
330
        SDataCol *pCol = &pCols->cols[i];
wafwerar's avatar
wafwerar 已提交
331
        taosMemoryFreeClear(pCol->pData);
332
      }
wafwerar's avatar
wafwerar 已提交
333
      taosMemoryFree(pCols->cols);
334 335
      pCols->cols = NULL;
    }
wafwerar's avatar
wafwerar 已提交
336
    taosMemoryFree(pCols);
H
TD-34  
hzcheng 已提交
337
  }
H
Hongze Cheng 已提交
338
  return NULL;
H
TD-34  
hzcheng 已提交
339 340 341
}

void tdResetDataCols(SDataCols *pCols) {
B
Bomin Zhang 已提交
342 343
  if (pCols != NULL) {
    pCols->numOfRows = 0;
C
Cary Xu 已提交
344
    pCols->bitmapMode = 0;
345
    for (int i = 0; i < pCols->maxCols; ++i) {
B
Bomin Zhang 已提交
346 347
      dataColReset(pCols->cols + i);
    }
H
TD-34  
hzcheng 已提交
348 349
  }
}
H
Hongze Cheng 已提交
350

H
Hongze Cheng 已提交
351
SKVRow tdKVRowDup(SKVRow row) {
wafwerar's avatar
wafwerar 已提交
352
  SKVRow trow = taosMemoryMalloc(kvRowLen(row));
H
Hongze Cheng 已提交
353 354
  if (trow == NULL) return NULL;

H
Hongze Cheng 已提交
355
  kvRowCpy(trow, row);
H
Hongze Cheng 已提交
356 357 358
  return trow;
}

S
Shengliang Guan 已提交
359 360 361
static int compareColIdx(const void *a, const void *b) {
  const SColIdx *x = (const SColIdx *)a;
  const SColIdx *y = (const SColIdx *)b;
B
Bomin Zhang 已提交
362 363 364 365 366 367 368 369 370
  if (x->colId > y->colId) {
    return 1;
  }
  if (x->colId < y->colId) {
    return -1;
  }
  return 0;
}

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

H
TD-90  
Hongze Cheng 已提交
373 374 375 376
int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value) {
  SColIdx *pColIdx = NULL;
  SKVRow   row = *orow;
  SKVRow   nrow = NULL;
S
Shengliang Guan 已提交
377
  void    *ptr = taosbsearch(&colId, kvRowColIdx(row), kvRowNCols(row), sizeof(SColIdx), comparTagId, TD_GE);
H
TD-90  
Hongze Cheng 已提交
378

379
  if (ptr == NULL || ((SColIdx *)ptr)->colId > colId) {  // need to add a column value to the row
C
Cary Xu 已提交
380
    int diff = IS_VAR_DATA_TYPE(type) ? varDataTLen(value) : TYPE_BYTES[type];
381 382 383 384
    int nRowLen = kvRowLen(row) + sizeof(SColIdx) + diff;
    int oRowCols = kvRowNCols(row);

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

388 389
    kvRowSetLen(nrow, nRowLen);
    kvRowSetNCols(nrow, oRowCols + 1);
H
TD-90  
Hongze Cheng 已提交
390

391 392
    memcpy(kvRowColIdx(nrow), kvRowColIdx(row), sizeof(SColIdx) * oRowCols);
    memcpy(kvRowValues(nrow), kvRowValues(row), kvRowValLen(row));
H
TD-90  
Hongze Cheng 已提交
393

394 395 396
    pColIdx = kvRowColIdxAt(nrow, oRowCols);
    pColIdx->colId = colId;
    pColIdx->offset = kvRowValLen(row);
H
TD-90  
Hongze Cheng 已提交
397

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

400
    tdSortKVRowByColIdx(nrow);
H
TD-90  
Hongze Cheng 已提交
401 402

    *orow = nrow;
wafwerar's avatar
wafwerar 已提交
403
    taosMemoryFree(row);
H
TD-90  
Hongze Cheng 已提交
404 405 406 407 408
  } else {
    ASSERT(((SColIdx *)ptr)->colId == colId);
    if (IS_VAR_DATA_TYPE(type)) {
      void *pOldVal = kvRowColVal(row, (SColIdx *)ptr);

S
Shengliang Guan 已提交
409
      if (varDataTLen(value) == varDataTLen(pOldVal)) {  // just update the column value in place
H
TD-90  
Hongze Cheng 已提交
410
        memcpy(pOldVal, value, varDataTLen(value));
411 412
      } else {  // need to reallocate the memory
        int16_t nlen = kvRowLen(row) + (varDataTLen(value) - varDataTLen(pOldVal));
H
TD-90  
Hongze Cheng 已提交
413
        ASSERT(nlen > 0);
wafwerar's avatar
wafwerar 已提交
414
        nrow = taosMemoryMalloc(nlen);
H
TD-90  
Hongze Cheng 已提交
415
        if (nrow == NULL) return -1;
H
TD-90  
Hongze Cheng 已提交
416 417 418 419

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

420 421 422 423 424 425 426 427
        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 已提交
428 429
        }

430 431 432 433 434
        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 已提交
435 436 437 438
          }
        }

        *orow = nrow;
wafwerar's avatar
wafwerar 已提交
439
        taosMemoryFree(row);
H
TD-90  
Hongze Cheng 已提交
440 441 442 443 444 445 446
      }
    } else {
      memcpy(kvRowColVal(row, (SColIdx *)ptr), value, TYPE_BYTES[type]);
    }
  }

  return 0;
H
Hongze Cheng 已提交
447 448
}

H
TD-353  
Hongze Cheng 已提交
449
int tdEncodeKVRow(void **buf, SKVRow row) {
H
Hongze Cheng 已提交
450
  // May change the encode purpose
H
TD-353  
Hongze Cheng 已提交
451 452 453 454 455 456
  if (buf != NULL) {
    kvRowCpy(*buf, row);
    *buf = POINTER_SHIFT(*buf, kvRowLen(row));
  }

  return kvRowLen(row);
H
Hongze Cheng 已提交
457 458
}

H
Hongze Cheng 已提交
459 460
void *tdDecodeKVRow(void *buf, SKVRow *row) {
  *row = tdKVRowDup(buf);
H
TD-353  
Hongze Cheng 已提交
461
  if (*row == NULL) return NULL;
H
Hongze Cheng 已提交
462
  return POINTER_SHIFT(buf, kvRowLen(*row));
H
Hongze Cheng 已提交
463 464
}

H
Hongze Cheng 已提交
465
int tdInitKVRowBuilder(SKVRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
466 467
  pBuilder->tCols = 128;
  pBuilder->nCols = 0;
wafwerar's avatar
wafwerar 已提交
468
  pBuilder->pColIdx = (SColIdx *)taosMemoryMalloc(sizeof(SColIdx) * pBuilder->tCols);
H
Hongze Cheng 已提交
469 470 471
  if (pBuilder->pColIdx == NULL) return -1;
  pBuilder->alloc = 1024;
  pBuilder->size = 0;
wafwerar's avatar
wafwerar 已提交
472
  pBuilder->buf = taosMemoryMalloc(pBuilder->alloc);
H
Hongze Cheng 已提交
473
  if (pBuilder->buf == NULL) {
wafwerar's avatar
wafwerar 已提交
474
    taosMemoryFree(pBuilder->pColIdx);
H
Hongze Cheng 已提交
475 476 477 478 479
    return -1;
  }
  return 0;
}

H
Hongze Cheng 已提交
480
void tdDestroyKVRowBuilder(SKVRowBuilder *pBuilder) {
wafwerar's avatar
wafwerar 已提交
481 482
  taosMemoryFreeClear(pBuilder->pColIdx);
  taosMemoryFreeClear(pBuilder->buf);
H
Hongze Cheng 已提交
483 484
}

H
Hongze Cheng 已提交
485
void tdResetKVRowBuilder(SKVRowBuilder *pBuilder) {
H
Hongze Cheng 已提交
486 487 488 489
  pBuilder->nCols = 0;
  pBuilder->size = 0;
}

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

H
Hongze Cheng 已提交
494 495
  tlen += TD_KV_ROW_HEAD_SIZE;

wafwerar's avatar
wafwerar 已提交
496
  SKVRow row = taosMemoryMalloc(tlen);
H
Hongze Cheng 已提交
497 498
  if (row == NULL) return NULL;

H
Hongze Cheng 已提交
499
  kvRowSetNCols(row, pBuilder->nCols);
H
Hongze Cheng 已提交
500
  kvRowSetLen(row, tlen);
H
Hongze Cheng 已提交
501

H
Hongze Cheng 已提交
502 503
  memcpy(kvRowColIdx(row), pBuilder->pColIdx, sizeof(SColIdx) * pBuilder->nCols);
  memcpy(kvRowValues(row), pBuilder->buf, pBuilder->size);
H
Hongze Cheng 已提交
504 505

  return row;
506
}