tdataformat.c 14.4 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
slguan 已提交
15
#include "tdataformat.h"
H
TD-166  
hzcheng 已提交
16
#include "wchar.h"
H
more  
hzcheng 已提交
17

H
hzcheng 已提交
18 19 20 21 22 23 24 25 26 27
/**
 * Create a SSchema object with nCols columns
 * ASSUMPTIONS: VALID PARAMETERS
 *
 * @param nCols number of columns the schema has
 *
 * @return a STSchema object for success
 *         NULL for failure
 */
STSchema *tdNewSchema(int32_t nCols) {
H
TD-166  
hzcheng 已提交
28
  int32_t size = sizeof(STSchema) + sizeof(STColumn) * nCols;
H
hzcheng 已提交
29

H
TD-27  
hzcheng 已提交
30
  STSchema *pSchema = (STSchema *)calloc(1, size);
H
hzcheng 已提交
31
  if (pSchema == NULL) return NULL;
H
TD-166  
hzcheng 已提交
32

H
hzcheng 已提交
33
  pSchema->numOfCols = 0;
H
TD-166  
hzcheng 已提交
34 35 36
  pSchema->totalCols = nCols;
  pSchema->flen = 0;
  pSchema->tlen = 0;
H
hzcheng 已提交
37 38 39 40

  return pSchema;
}

H
hzcheng 已提交
41 42 43
/**
 * Append a column to the schema
 */
H
TD-166  
hzcheng 已提交
44 45
int tdSchemaAddCol(STSchema *pSchema, int8_t type, int16_t colId, int32_t bytes) {
  if (!isValidDataType(type, 0) || pSchema->numOfCols >= pSchema->totalCols) return -1;
H
hzcheng 已提交
46 47 48 49

  STColumn *pCol = schemaColAt(pSchema, schemaNCols(pSchema));
  colSetType(pCol, type);
  colSetColId(pCol, colId);
H
TD-166  
hzcheng 已提交
50
  if (schemaNCols(pSchema) == 0) {
H
TD-166  
hzcheng 已提交
51 52
    colSetOffset(pCol, 0);
  } else {
H
TD-166  
hzcheng 已提交
53
    STColumn *pTCol = schemaColAt(pSchema, schemaNCols(pSchema)-1);
H
TD-166  
hzcheng 已提交
54
    colSetOffset(pCol, pTCol->offset + TYPE_BYTES[pTCol->type]);
H
TD-166  
hzcheng 已提交
55
  }
H
hzcheng 已提交
56 57 58
  switch (type) {
    case TSDB_DATA_TYPE_BINARY:
    case TSDB_DATA_TYPE_NCHAR:
H
TD-166  
hzcheng 已提交
59 60
      colSetBytes(pCol, bytes); // Set as maximum bytes
      pSchema->tlen += (TYPE_BYTES[type] + sizeof(VarDataLenT) + bytes);
H
hzcheng 已提交
61 62 63
      break;
    default:
      colSetBytes(pCol, TYPE_BYTES[type]);
H
TD-166  
hzcheng 已提交
64
      pSchema->tlen += TYPE_BYTES[type];
H
hzcheng 已提交
65 66 67 68
      break;
  }

  pSchema->numOfCols++;
H
TD-166  
hzcheng 已提交
69 70 71
  pSchema->flen += TYPE_BYTES[type];

  ASSERT(pCol->offset < pSchema->flen);
H
hzcheng 已提交
72 73 74 75

  return 0;
}

H
hzcheng 已提交
76 77 78 79 80 81 82 83 84 85 86 87 88
/**
 * Duplicate the schema and return a new object
 */
STSchema *tdDupSchema(STSchema *pSchema) {
  STSchema *tSchema = tdNewSchema(schemaNCols(pSchema));
  if (tSchema == NULL) return NULL;

  int32_t size = sizeof(STSchema) + sizeof(STColumn) * schemaNCols(pSchema);
  memcpy((void *)tSchema, (void *)pSchema, size);

  return tSchema;
}

H
TD-27  
hzcheng 已提交
89 90 91 92
/**
 * Return the size of encoded schema
 */
int tdGetSchemaEncodeSize(STSchema *pSchema) {
H
TD-166  
hzcheng 已提交
93 94 95
  return T_MEMBER_SIZE(STSchema, totalCols) +
         schemaNCols(pSchema) *
             (T_MEMBER_SIZE(STColumn, type) + T_MEMBER_SIZE(STColumn, colId) + T_MEMBER_SIZE(STColumn, bytes));
H
TD-27  
hzcheng 已提交
96 97 98 99 100 101
}

/**
 * Encode a schema to dst, and return the next pointer
 */
void *tdEncodeSchema(void *dst, STSchema *pSchema) {
H
TD-166  
hzcheng 已提交
102 103 104
  ASSERT(pSchema->numOfCols == pSchema->totalCols);

  T_APPEND_MEMBER(dst, pSchema, STSchema, totalCols);
H
TD-27  
hzcheng 已提交
105 106 107 108 109 110 111 112 113 114 115 116 117 118
  for (int i = 0; i < schemaNCols(pSchema); i++) {
    STColumn *pCol = schemaColAt(pSchema, i);
    T_APPEND_MEMBER(dst, pCol, STColumn, type);
    T_APPEND_MEMBER(dst, pCol, STColumn, colId);
    T_APPEND_MEMBER(dst, pCol, STColumn, bytes);
  }

  return dst;
}

/**
 * Decode a schema from a binary.
 */
STSchema *tdDecodeSchema(void **psrc) {
H
TD-166  
hzcheng 已提交
119
  int totalCols = 0;
H
TD-27  
hzcheng 已提交
120

H
TD-166  
hzcheng 已提交
121
  T_READ_MEMBER(*psrc, int, totalCols);
H
TD-27  
hzcheng 已提交
122

H
TD-166  
hzcheng 已提交
123
  STSchema *pSchema = tdNewSchema(totalCols);
H
TD-27  
hzcheng 已提交
124
  if (pSchema == NULL) return NULL;
H
TD-166  
hzcheng 已提交
125
  for (int i = 0; i < totalCols; i++) {
H
TD-27  
hzcheng 已提交
126 127 128 129 130 131 132
    int8_t  type = 0;
    int16_t colId = 0;
    int32_t bytes = 0;
    T_READ_MEMBER(*psrc, int8_t, type);
    T_READ_MEMBER(*psrc, int16_t, colId);
    T_READ_MEMBER(*psrc, int32_t, bytes);

H
TD-166  
hzcheng 已提交
133
    tdSchemaAddCol(pSchema, type, colId, bytes);
H
TD-27  
hzcheng 已提交
134 135 136 137 138
  }

  return pSchema;
}

H
hzcheng 已提交
139 140 141
/**
 * Initialize a data row
 */
H
TD-166  
hzcheng 已提交
142
void tdInitDataRow(SDataRow row, STSchema *pSchema) { dataRowSetLen(row, TD_DATA_ROW_HEAD_SIZE + schemaFLen(pSchema)); }
H
hzcheng 已提交
143

H
TD-166  
hzcheng 已提交
144
SDataRow tdNewDataRowFromSchema(STSchema *pSchema) {
H
TD-166  
hzcheng 已提交
145
  int32_t size = dataRowMaxBytesFromSchema(pSchema);
H
hzcheng 已提交
146 147 148 149

  SDataRow row = malloc(size);
  if (row == NULL) return NULL;

H
hzcheng 已提交
150
  tdInitDataRow(row, pSchema);
H
hzcheng 已提交
151
  return row;
H
TD-166  
hzcheng 已提交
152
}
H
hzcheng 已提交
153

H
hzcheng 已提交
154 155 156 157 158 159 160 161
/**
 * Free the SDataRow object
 */
void tdFreeDataRow(SDataRow row) {
  if (row) free(row);
}

/**
H
hzcheng 已提交
162
 * Append a column value to the data row
H
TD-166  
hzcheng 已提交
163 164 165
 * @param type: column type
 * @param bytes: column bytes
 * @param offset: offset in the data row tuple, not including the data row header
H
hzcheng 已提交
166
 */
H
TD-166  
hzcheng 已提交
167
int tdAppendColVal(SDataRow row, void *value, int8_t type, int32_t bytes, int32_t offset) {
H
TD-166  
hzcheng 已提交
168
  ASSERT(value != NULL);
H
TD-166  
hzcheng 已提交
169
  int32_t toffset = offset + TD_DATA_ROW_HEAD_SIZE;
H
hzcheng 已提交
170
  char *  ptr = POINTER_SHIFT(row, dataRowLen(row));
H
TD-166  
hzcheng 已提交
171

H
TD-166  
hzcheng 已提交
172
  switch (type) {
H
TD-166  
hzcheng 已提交
173 174
    case TSDB_DATA_TYPE_BINARY:
    case TSDB_DATA_TYPE_NCHAR:
H
hzcheng 已提交
175
      *(VarDataOffsetT *)POINTER_SHIFT(row, toffset) = dataRowLen(row);
176 177
      memcpy(ptr, value, varDataTLen(value));
      dataRowLen(row) += varDataTLen(value);
H
TD-166  
hzcheng 已提交
178 179
      break;
    default:
H
hzcheng 已提交
180
      memcpy(POINTER_SHIFT(row, toffset), value, TYPE_BYTES[type]);
H
TD-166  
hzcheng 已提交
181
      break;
H
hzcheng 已提交
182
  }
H
TD-27  
hzcheng 已提交
183 184

  return 0;
H
hzcheng 已提交
185 186
}

H
hzcheng 已提交
187
SDataRow tdDataRowDup(SDataRow row) {
H
hzcheng 已提交
188
  SDataRow trow = malloc(dataRowLen(row));
H
hzcheng 已提交
189 190 191
  if (trow == NULL) return NULL;

  dataRowCpy(trow, row);
H
hzcheng 已提交
192
  return trow;
H
hzcheng 已提交
193
}
H
hzcheng 已提交
194

H
TD-166  
hzcheng 已提交
195 196 197 198
void dataColInit(SDataCol *pDataCol, STColumn *pCol, void **pBuf, int maxPoints) {
  pDataCol->type = colType(pCol);
  pDataCol->colId = colColId(pCol);
  pDataCol->bytes = colBytes(pCol);
H
TD-166  
hzcheng 已提交
199
  pDataCol->offset = colOffset(pCol) + TD_DATA_ROW_HEAD_SIZE;
H
TD-166  
hzcheng 已提交
200 201 202

  pDataCol->len = 0;
  if (pDataCol->type == TSDB_DATA_TYPE_BINARY || pDataCol->type == TSDB_DATA_TYPE_NCHAR) {
H
TD-166  
hzcheng 已提交
203
    pDataCol->spaceSize = (sizeof(VarDataLenT) + pDataCol->bytes) * maxPoints;
H
TD-166  
hzcheng 已提交
204
    pDataCol->dataOff = (VarDataOffsetT *)(*pBuf);
H
hzcheng 已提交
205 206
    pDataCol->pData = POINTER_SHIFT(*pBuf, TYPE_BYTES[pDataCol->type] * maxPoints);
    *pBuf = POINTER_SHIFT(*pBuf, pDataCol->spaceSize + TYPE_BYTES[pDataCol->type] * maxPoints);
H
TD-166  
hzcheng 已提交
207 208 209 210
  } else {
    pDataCol->spaceSize = pDataCol->bytes * maxPoints;
    pDataCol->dataOff = NULL;
    pDataCol->pData = *pBuf;
H
hzcheng 已提交
211
    *pBuf = POINTER_SHIFT(*pBuf, pDataCol->spaceSize);
H
TD-166  
hzcheng 已提交
212 213 214 215
  }

}

H
TD-166  
hzcheng 已提交
216 217 218 219 220 221 222
void dataColAppendVal(SDataCol *pCol, void *value, int numOfPoints, int maxPoints) {
  ASSERT(pCol != NULL && value != NULL);

  switch (pCol->type) {
    case TSDB_DATA_TYPE_BINARY:
    case TSDB_DATA_TYPE_NCHAR:
      // set offset
H
TD-166  
hzcheng 已提交
223
      pCol->dataOff[numOfPoints] = pCol->len;
H
TD-166  
hzcheng 已提交
224
      // Copy data
H
hzcheng 已提交
225
      memcpy(POINTER_SHIFT(pCol->pData, pCol->len), value, varDataTLen(value));
H
TD-166  
hzcheng 已提交
226
      // Update the length
H
TD-166  
hzcheng 已提交
227
      pCol->len += varDataTLen(value);
H
TD-166  
hzcheng 已提交
228 229 230
      break;
    default:
      ASSERT(pCol->len == TYPE_BYTES[pCol->type] * numOfPoints);
H
hzcheng 已提交
231
      memcpy(POINTER_SHIFT(pCol->pData, pCol->len), value, pCol->bytes);
H
TD-166  
hzcheng 已提交
232 233 234 235 236
      pCol->len += pCol->bytes;
      break;
  }
}

H
TD-166  
hzcheng 已提交
237 238 239 240 241 242 243
void dataColPopPoints(SDataCol *pCol, int pointsToPop, int numOfPoints) {
  int pointsLeft = numOfPoints - pointsToPop;

  ASSERT(pointsLeft > 0);

  if (pCol->type == TSDB_DATA_TYPE_BINARY || pCol->type == TSDB_DATA_TYPE_NCHAR) {
    ASSERT(pCol->len > 0);
H
TD-166  
hzcheng 已提交
244
    VarDataOffsetT toffset = pCol->dataOff[pointsToPop];
H
TD-166  
hzcheng 已提交
245 246
    pCol->len = pCol->len - toffset;
    ASSERT(pCol->len > 0);
H
hzcheng 已提交
247
    memmove(pCol->pData, POINTER_SHIFT(pCol->pData, toffset), pCol->len);
H
TD-166  
hzcheng 已提交
248 249 250 251
    dataColSetOffset(pCol, pointsLeft);
  } else {
    ASSERT(pCol->len == TYPE_BYTES[pCol->type] * numOfPoints);
    pCol->len = TYPE_BYTES[pCol->type] * pointsLeft;
H
hzcheng 已提交
252
    memmove(pCol->pData, POINTER_SHIFT(pCol->pData, TYPE_BYTES[pCol->type] * pointsToPop), pCol->len);
H
TD-166  
hzcheng 已提交
253 254 255
  }
}

H
TD-166  
hzcheng 已提交
256 257 258 259 260
bool isNEleNull(SDataCol *pCol, int nEle) {
  switch (pCol->type) {
    case TSDB_DATA_TYPE_BINARY:
    case TSDB_DATA_TYPE_NCHAR:
      for (int i = 0; i < nEle; i++) {
H
TD-166  
hzcheng 已提交
261
        if (!isNull(varDataVal(tdGetColDataOfRow(pCol, i)), pCol->type)) return false;
H
TD-166  
hzcheng 已提交
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
      }
      return true;
    default:
      for (int i = 0; i < nEle; i++) {
        if (!isNull(tdGetColDataOfRow(pCol, i), pCol->type)) return false;
      }
      return true;
  }
}

void dataColSetNEleNull(SDataCol *pCol, int nEle, int maxPoints) {
  char *ptr = NULL;
  switch (pCol->type) {
    case TSDB_DATA_TYPE_BINARY:
    case TSDB_DATA_TYPE_NCHAR:
H
TD-166  
hzcheng 已提交
277
      pCol->len = 0;
H
TD-166  
hzcheng 已提交
278
      for (int i = 0; i < nEle; i++) {
H
TD-166  
hzcheng 已提交
279 280 281 282 283
        pCol->dataOff[i] = pCol->len;
        ptr = (char *)pCol->pData + pCol->len;
        varDataLen(ptr) = (pCol->type == TSDB_DATA_TYPE_BINARY) ? sizeof(char) : TSDB_NCHAR_SIZE;
        setNull(ptr + sizeof(VarDataLenT), pCol->type, pCol->bytes);
        pCol->len += varDataTLen(ptr);
H
TD-166  
hzcheng 已提交
284
      }
H
TD-166  
hzcheng 已提交
285

H
TD-166  
hzcheng 已提交
286 287 288 289 290 291 292 293
      break;
    default:
      setNullN(pCol->pData, pCol->type, pCol->bytes, nEle);
      pCol->len = TYPE_BYTES[pCol->type] * nEle;
      break;
  }
}

H
TD-166  
hzcheng 已提交
294 295 296
void dataColSetOffset(SDataCol *pCol, int nEle) {
  ASSERT(((pCol->type == TSDB_DATA_TYPE_BINARY) || (pCol->type == TSDB_DATA_TYPE_NCHAR)));

H
TD-166  
hzcheng 已提交
297 298
  void * tptr = pCol->pData;
  // char *tptr = (char *)(pCol->pData);
H
TD-166  
hzcheng 已提交
299

H
TD-166  
hzcheng 已提交
300
  VarDataOffsetT offset = 0;
H
TD-166  
hzcheng 已提交
301
  for (int i = 0; i < nEle; i++) {
H
TD-166  
hzcheng 已提交
302
    pCol->dataOff[i] = offset;
H
TD-166  
hzcheng 已提交
303
    offset += varDataTLen(tptr);
H
hzcheng 已提交
304
    tptr = POINTER_SHIFT(tptr, varDataTLen(tptr));
H
TD-166  
hzcheng 已提交
305 306 307
  }
}

H
TD-166  
hzcheng 已提交
308
SDataCols *tdNewDataCols(int maxRowSize, int maxCols, int maxRows) {
H
TD-34  
hzcheng 已提交
309 310 311 312 313 314
  SDataCols *pCols = (SDataCols *)calloc(1, sizeof(SDataCols) + sizeof(SDataCol) * maxCols);
  if (pCols == NULL) return NULL;

  pCols->maxRowSize = maxRowSize;
  pCols->maxCols = maxCols;
  pCols->maxPoints = maxRows;
H
TD-166  
hzcheng 已提交
315
  pCols->bufSize = maxRowSize * maxRows;
H
TD-34  
hzcheng 已提交
316

H
TD-166  
hzcheng 已提交
317
  pCols->buf = malloc(pCols->bufSize);
H
TD-34  
hzcheng 已提交
318 319
  if (pCols->buf == NULL) {
    free(pCols);
H
TD-34  
hzcheng 已提交
320 321
    return NULL;
  }
H
TD-34  
hzcheng 已提交
322

H
TD-34  
hzcheng 已提交
323 324 325 326 327 328 329 330
  return pCols;
}

void tdInitDataCols(SDataCols *pCols, STSchema *pSchema) {
  // assert(schemaNCols(pSchema) <= pCols->numOfCols);
  tdResetDataCols(pCols);
  pCols->numOfCols = schemaNCols(pSchema);

H
TD-166  
hzcheng 已提交
331
  void *ptr = pCols->buf;
H
TD-34  
hzcheng 已提交
332
  for (int i = 0; i < schemaNCols(pSchema); i++) {
H
TD-166  
hzcheng 已提交
333
    dataColInit(pCols->cols + i, schemaColAt(pSchema, i), &ptr, pCols->maxPoints);
H
TD-166  
hzcheng 已提交
334
    ASSERT((char *)ptr - (char *)(pCols->buf) <= pCols->bufSize);
H
TD-34  
hzcheng 已提交
335
  }
H
TD-34  
hzcheng 已提交
336 337 338 339
}

void tdFreeDataCols(SDataCols *pCols) {
  if (pCols) {
H
TD-166  
hzcheng 已提交
340
    tfree(pCols->buf);
H
TD-34  
hzcheng 已提交
341 342 343 344
    free(pCols);
  }
}

H
TD-100  
hzcheng 已提交
345
SDataCols *tdDupDataCols(SDataCols *pDataCols, bool keepData) {
H
TD-166  
hzcheng 已提交
346
  SDataCols *pRet = tdNewDataCols(pDataCols->maxRowSize, pDataCols->maxCols, pDataCols->maxPoints);
H
TD-100  
hzcheng 已提交
347 348 349 350 351 352 353 354 355 356 357
  if (pRet == NULL) return NULL;

  pRet->numOfCols = pDataCols->numOfCols;
  pRet->sversion = pDataCols->sversion;
  if (keepData) pRet->numOfPoints = pDataCols->numOfPoints;

  for (int i = 0; i < pDataCols->numOfCols; i++) {
    pRet->cols[i].type = pDataCols->cols[i].type;
    pRet->cols[i].colId = pDataCols->cols[i].colId;
    pRet->cols[i].bytes = pDataCols->cols[i].bytes;
    pRet->cols[i].offset = pDataCols->cols[i].offset;
H
TD-166  
hzcheng 已提交
358 359

    pRet->cols[i].spaceSize = pDataCols->cols[i].spaceSize;
H
TD-100  
hzcheng 已提交
360
    pRet->cols[i].pData = (void *)((char *)pRet->buf + ((char *)(pDataCols->cols[i].pData) - (char *)(pDataCols->buf)));
H
TD-100  
hzcheng 已提交
361

H
TD-166  
hzcheng 已提交
362 363 364 365 366 367 368 369 370 371
    if (pRet->cols[i].type == TSDB_DATA_TYPE_BINARY || pRet->cols[i].type == TSDB_DATA_TYPE_NCHAR) {
      ASSERT(pDataCols->cols[i].dataOff != NULL);
      pRet->cols[i].dataOff =
          (int32_t *)((char *)pRet->buf + ((char *)(pDataCols->cols[i].dataOff) - (char *)(pDataCols->buf)));
    }

    if (keepData) {
      pRet->cols[i].len = pDataCols->cols[i].len;
      memcpy(pRet->cols[i].pData, pDataCols->cols[i].pData, pDataCols->cols[i].len);
      if (pRet->cols[i].type == TSDB_DATA_TYPE_BINARY || pRet->cols[i].type == TSDB_DATA_TYPE_NCHAR) {
H
TD-166  
hzcheng 已提交
372
        memcpy(pRet->cols[i].dataOff, pDataCols->cols[i].dataOff, sizeof(VarDataOffsetT) * pDataCols->maxPoints);
H
TD-166  
hzcheng 已提交
373 374
      }
    }
H
TD-100  
hzcheng 已提交
375 376 377 378 379
  }

  return pRet;
}

H
TD-34  
hzcheng 已提交
380 381
void tdResetDataCols(SDataCols *pCols) {
  pCols->numOfPoints = 0;
H
TD-34  
hzcheng 已提交
382
  for (int i = 0; i < pCols->maxCols; i++) {
H
TD-166  
hzcheng 已提交
383
    dataColReset(pCols->cols + i);
H
TD-34  
hzcheng 已提交
384 385 386
  }
}

H
TD-34  
hzcheng 已提交
387
void tdAppendDataRowToDataCol(SDataRow row, SDataCols *pCols) {
H
TD-166  
hzcheng 已提交
388 389
  ASSERT(dataColsKeyLast(pCols) < dataRowKey(row));

H
TD-34  
hzcheng 已提交
390 391
  for (int i = 0; i < pCols->numOfCols; i++) {
    SDataCol *pCol = pCols->cols + i;
H
TD-166  
hzcheng 已提交
392
    void *    value = tdGetRowDataOfCol(row, pCol->type, pCol->offset);
H
TD-166  
hzcheng 已提交
393

H
TD-166  
hzcheng 已提交
394
    dataColAppendVal(pCol, value, pCols->numOfPoints, pCols->maxPoints);
H
TD-34  
hzcheng 已提交
395
  }
H
TD-34  
hzcheng 已提交
396
  pCols->numOfPoints++;
H
TD-34  
hzcheng 已提交
397
}
H
TD-166  
hzcheng 已提交
398

H
TD-34  
hzcheng 已提交
399 400
// Pop pointsToPop points from the SDataCols
void tdPopDataColsPoints(SDataCols *pCols, int pointsToPop) {
H
TD-34  
hzcheng 已提交
401
  int pointsLeft = pCols->numOfPoints - pointsToPop;
H
TD-166  
hzcheng 已提交
402
  if (pointsLeft <= 0) {
H
TD-166  
hzcheng 已提交
403 404 405
    tdResetDataCols(pCols);
    return;
  }
H
TD-34  
hzcheng 已提交
406 407

  for (int iCol = 0; iCol < pCols->numOfCols; iCol++) {
H
TD-166  
hzcheng 已提交
408
    SDataCol *pCol = pCols->cols + iCol;
H
TD-166  
hzcheng 已提交
409
    dataColPopPoints(pCol, pointsToPop, pCols->numOfPoints);
H
TD-34  
hzcheng 已提交
410 411
  }
  pCols->numOfPoints = pointsLeft;
H
TD-34  
hzcheng 已提交
412
}
H
TD-34  
hzcheng 已提交
413

H
hzcheng 已提交
414
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge) {
H
TD-100  
hzcheng 已提交
415
  ASSERT(rowsToMerge > 0 && rowsToMerge <= source->numOfPoints);
H
TD-166  
hzcheng 已提交
416 417
  ASSERT(target->numOfPoints + rowsToMerge <= target->maxPoints);
  ASSERT(target->numOfCols == source->numOfCols);
H
TD-100  
hzcheng 已提交
418

H
TD-166  
hzcheng 已提交
419
  SDataCols *pTarget = NULL;
H
TD-100  
hzcheng 已提交
420

H
TD-166  
hzcheng 已提交
421 422 423 424 425 426
  if (dataColsKeyLast(target) < dataColsKeyFirst(source)) {  // No overlap
    for (int i = 0; i < rowsToMerge; i++) {
      for (int j = 0; j < source->numOfCols; j++) {
        dataColAppendVal(target->cols + j, tdGetColDataOfRow(source->cols + j, i), target->numOfPoints,
                         target->maxPoints);
      }
H
hzcheng 已提交
427
      target->numOfPoints++;
H
TD-166  
hzcheng 已提交
428 429 430 431 432 433 434 435 436
    }
  } else {
    pTarget = tdDupDataCols(target, true);
    if (pTarget == NULL) goto _err;

    int iter1 = 0;
    int iter2 = 0;
    tdMergeTwoDataCols(target, pTarget, &iter1, source, &iter2, pTarget->numOfPoints + rowsToMerge);
  }
H
TD-100  
hzcheng 已提交
437 438 439 440 441 442 443 444

  tdFreeDataCols(pTarget);
  return 0;

_err:
  tdFreeDataCols(pTarget);
  return -1;
}
H
TD-100  
hzcheng 已提交
445

H
TD-100  
hzcheng 已提交
446
void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, SDataCols *src2, int *iter2, int tRows) {
H
TD-166  
hzcheng 已提交
447
  // TODO: add resolve duplicate key here
H
TD-100  
hzcheng 已提交
448 449 450 451 452 453 454
  tdResetDataCols(target);

  while (target->numOfPoints < tRows) {
    if (*iter1 >= src1->numOfPoints && *iter2 >= src2->numOfPoints) break;

    TSKEY key1 = (*iter1 >= src1->numOfPoints) ? INT64_MAX : ((TSKEY *)(src1->cols[0].pData))[*iter1];
    TSKEY key2 = (*iter2 >= src2->numOfPoints) ? INT64_MAX : ((TSKEY *)(src2->cols[0].pData))[*iter2];
H
TD-100  
hzcheng 已提交
455

H
TD-100  
hzcheng 已提交
456 457 458
    if (key1 < key2) {
      for (int i = 0; i < src1->numOfCols; i++) {
        ASSERT(target->cols[i].type == src1->cols[i].type);
H
TD-166  
hzcheng 已提交
459 460
        dataColAppendVal(target->cols[i].pData, tdGetColDataOfRow(src1->cols + i, *iter1), target->numOfPoints,
                         target->maxPoints);
H
TD-100  
hzcheng 已提交
461 462
      }

H
TD-100  
hzcheng 已提交
463
      target->numOfPoints++;
H
TD-100  
hzcheng 已提交
464
      (*iter1)++;
H
TD-100  
hzcheng 已提交
465 466 467
    } else if (key1 > key2) {
      for (int i = 0; i < src2->numOfCols; i++) {
        ASSERT(target->cols[i].type == src2->cols[i].type);
H
TD-166  
hzcheng 已提交
468 469
        dataColAppendVal(target->cols[i].pData, tdGetColDataOfRow(src2->cols + i, *iter2), target->numOfPoints,
                         target->maxPoints);
H
TD-100  
hzcheng 已提交
470
      }
H
TD-100  
hzcheng 已提交
471 472

      target->numOfPoints++;
H
TD-100  
hzcheng 已提交
473
      (*iter2)++;
H
TD-100  
hzcheng 已提交
474
    } else {
H
TD-166  
hzcheng 已提交
475
      // TODO: deal with duplicate keys
H
TD-100  
hzcheng 已提交
476
      ASSERT(false);
H
TD-100  
hzcheng 已提交
477 478
    }
  }
H
TD-100  
hzcheng 已提交
479
}