tsdbDiskData.c 21.8 KB
Newer Older
H
Hongze Cheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * 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/>.
 */

#include "tsdb.h"

H
Hongze Cheng 已提交
18
typedef struct SDiskColBuilder SDiskColBuilder;
H
Hongze Cheng 已提交
19

H
Hongze Cheng 已提交
20
struct SDiskColBuilder {
H
Hongze Cheng 已提交
21 22 23 24 25 26 27 28 29 30 31 32 33
  int16_t        cid;
  int8_t         type;
  uint8_t        cmprAlg;
  uint8_t        calcSma;
  int8_t         flag;
  int32_t        nVal;
  uint8_t       *pBitMap;
  int32_t        offset;
  SCompressor   *pOffC;
  SCompressor   *pValC;
  SColumnDataAgg sma;
  uint8_t        minSet;
  uint8_t        maxSet;
H
Hongze Cheng 已提交
34
  uint8_t       *aBuf[2];
H
Hongze Cheng 已提交
35 36
};

H
Hongze Cheng 已提交
37 38 39 40 41 42 43
// SDiskData ================================================
static int32_t tDiskDataDestroy(SDiskData *pDiskData) {
  int32_t code = 0;
  pDiskData->aDiskCol = taosArrayDestroy(pDiskData->aDiskCol);
  return code;
}

H
Hongze Cheng 已提交
44
// SDiskColBuilder ================================================
H
Hongze Cheng 已提交
45 46 47 48 49 50 51 52 53
#define tDiskColBuilderCreate() \
  (SDiskColBuilder) { 0 }

static int32_t tDiskColBuilderDestroy(SDiskColBuilder *pBuilder) {
  int32_t code = 0;

  tFree(pBuilder->pBitMap);
  if (pBuilder->pOffC) tCompressorDestroy(pBuilder->pOffC);
  if (pBuilder->pValC) tCompressorDestroy(pBuilder->pValC);
H
Hongze Cheng 已提交
54 55 56
  for (int32_t iBuf = 0; iBuf < sizeof(pBuilder->aBuf) / sizeof(pBuilder->aBuf[0]); iBuf++) {
    tFree(pBuilder->aBuf[iBuf]);
  }
H
Hongze Cheng 已提交
57 58 59 60

  return code;
}

H
Hongze Cheng 已提交
61 62
static int32_t tDiskColBuilderInit(SDiskColBuilder *pBuilder, int16_t cid, int8_t type, uint8_t cmprAlg,
                                   uint8_t calcSma) {
H
Hongze Cheng 已提交
63 64
  int32_t code = 0;

H
Hongze Cheng 已提交
65 66 67
  pBuilder->cid = cid;
  pBuilder->type = type;
  pBuilder->cmprAlg = cmprAlg;
H
Hongze Cheng 已提交
68 69
  pBuilder->calcSma = IS_VAR_DATA_TYPE(type) ? 0 : calcSma;
  pBuilder->flag = 0;
H
Hongze Cheng 已提交
70 71
  pBuilder->nVal = 0;
  pBuilder->offset = 0;
H
Hongze Cheng 已提交
72 73

  if (IS_VAR_DATA_TYPE(type)) {
H
Hongze Cheng 已提交
74
    if (pBuilder->pOffC == NULL && (code = tCompressorCreate(&pBuilder->pOffC))) return code;
H
Hongze Cheng 已提交
75
    code = tCompressStart(pBuilder->pOffC, TSDB_DATA_TYPE_INT, cmprAlg);
H
Hongze Cheng 已提交
76 77 78
    if (code) return code;
  }

H
Hongze Cheng 已提交
79
  if (pBuilder->pValC == NULL && (code = tCompressorCreate(&pBuilder->pValC))) return code;
H
Hongze Cheng 已提交
80
  code = tCompressStart(pBuilder->pValC, type, cmprAlg);
H
Hongze Cheng 已提交
81 82
  if (code) return code;

H
Hongze Cheng 已提交
83 84 85 86 87 88
  if (pBuilder->calcSma) {
    pBuilder->sma = (SColumnDataAgg){.colId = cid};
    pBuilder->minSet = 0;
    pBuilder->maxSet = 0;
  }

H
Hongze Cheng 已提交
89 90 91
  return code;
}

H
Hongze Cheng 已提交
92
static int32_t tGnrtDiskCol(SDiskColBuilder *pBuilder, SDiskCol *pDiskCol) {
H
Hongze Cheng 已提交
93 94
  int32_t code = 0;

H
Hongze Cheng 已提交
95
  ASSERT(pBuilder->flag && pBuilder->flag != HAS_NONE);
H
Hongze Cheng 已提交
96

H
Hongze Cheng 已提交
97 98 99 100
  *pDiskCol = (SDiskCol){(SBlockCol){.cid = pBuilder->cid,
                                     .type = pBuilder->type,
                                     .smaOn = pBuilder->calcSma,
                                     .flag = pBuilder->flag,
H
Hongze Cheng 已提交
101
                                     .szOrigin = 0,
H
Hongze Cheng 已提交
102 103 104 105 106
                                     .szBitmap = 0,
                                     .szOffset = 0,
                                     .szValue = 0,
                                     .offset = 0},
                         .pBit = NULL, .pOff = NULL, .pVal = NULL, .agg = pBuilder->sma};
H
Hongze Cheng 已提交
107 108 109 110

  if (pBuilder->flag == HAS_NULL) return code;

  // BITMAP
H
Hongze Cheng 已提交
111
  if (pBuilder->flag != HAS_VALUE) {
H
Hongze Cheng 已提交
112 113 114 115 116 117 118
    int32_t nBit;
    if (pBuilder->flag == (HAS_VALUE | HAS_NULL | HAS_NONE)) {
      nBit = BIT2_SIZE(pBuilder->nVal);
    } else {
      nBit = BIT1_SIZE(pBuilder->nVal);
    }

H
Hongze Cheng 已提交
119 120 121 122 123 124 125 126 127
    code = tRealloc(&pBuilder->aBuf[0], nBit + COMP_OVERFLOW_BYTES);
    if (code) return code;

    code = tRealloc(&pBuilder->aBuf[1], nBit + COMP_OVERFLOW_BYTES);
    if (code) return code;

    pDiskCol->bCol.szBitmap =
        tsCompressTinyint(pBuilder->pBitMap, nBit, nBit, pBuilder->aBuf[0], nBit + COMP_OVERFLOW_BYTES,
                          pBuilder->cmprAlg, pBuilder->aBuf[1], nBit + COMP_OVERFLOW_BYTES);
H
Hongze Cheng 已提交
128
    pDiskCol->pBit = pBuilder->aBuf[0];
H
Hongze Cheng 已提交
129 130
  }

H
Hongze Cheng 已提交
131
  // OFFSET
H
Hongze Cheng 已提交
132
  if (IS_VAR_DATA_TYPE(pBuilder->type)) {
H
Hongze Cheng 已提交
133
    code = tCompressEnd(pBuilder->pOffC, &pDiskCol->pOff, &pDiskCol->bCol.szOffset, NULL);
H
Hongze Cheng 已提交
134 135 136
    if (code) return code;
  }

H
Hongze Cheng 已提交
137
  // VALUE
H
Hongze Cheng 已提交
138
  if (pBuilder->flag != (HAS_NULL | HAS_NONE)) {
H
Hongze Cheng 已提交
139
    code = tCompressEnd(pBuilder->pValC, &pDiskCol->pVal, &pDiskCol->bCol.szValue, &pDiskCol->bCol.szOrigin);
H
Hongze Cheng 已提交
140 141 142 143 144 145
    if (code) return code;
  }

  return code;
}

H
Hongze Cheng 已提交
146
static FORCE_INLINE int32_t tDiskColPutValue(SDiskColBuilder *pBuilder, SColVal *pColVal) {
H
Hongze Cheng 已提交
147 148 149
  int32_t code = 0;

  if (IS_VAR_DATA_TYPE(pColVal->type)) {
H
Hongze Cheng 已提交
150
    code = tCompress(pBuilder->pOffC, &pBuilder->offset, sizeof(int32_t));
H
Hongze Cheng 已提交
151
    if (code) return code;
H
Hongze Cheng 已提交
152
    pBuilder->offset += pColVal->value.nData;
H
Hongze Cheng 已提交
153 154

    code = tCompress(pBuilder->pValC, pColVal->value.pData, pColVal->value.nData);
H
Hongze Cheng 已提交
155
    if (code) return code;
H
Hongze Cheng 已提交
156 157
  } else {
    code = tCompress(pBuilder->pValC, &pColVal->value.val, tDataTypes[pColVal->type].bytes);
H
Hongze Cheng 已提交
158
    if (code) return code;
H
Hongze Cheng 已提交
159 160 161 162
  }

  return code;
}
H
Hongze Cheng 已提交
163 164 165 166 167 168 169 170 171 172 173 174 175
static FORCE_INLINE int32_t tDiskColAddVal00(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  pBuilder->flag = HAS_VALUE;
  return tDiskColPutValue(pBuilder, pColVal);
}
static FORCE_INLINE int32_t tDiskColAddVal01(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  pBuilder->flag = HAS_NONE;
  return 0;
}
static FORCE_INLINE int32_t tDiskColAddVal02(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  pBuilder->flag = HAS_NULL;
  return 0;
}
static FORCE_INLINE int32_t tDiskColAddVal10(SDiskColBuilder *pBuilder, SColVal *pColVal) {
H
Hongze Cheng 已提交
176 177
  int32_t code = 0;

H
Hongze Cheng 已提交
178 179 180 181 182 183 184 185 186 187 188 189 190 191
  // bit map
  int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
  code = tRealloc(&pBuilder->pBitMap, nBit);
  if (code) return code;

  memset(pBuilder->pBitMap, 0, nBit);
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);

  // value
  pBuilder->flag |= HAS_VALUE;

  SColVal cv = COL_VAL_VALUE(pColVal->cid, pColVal->type, (SValue){0});
  for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
    code = tDiskColPutValue(pBuilder, &cv);
H
Hongze Cheng 已提交
192
    if (code) return code;
H
Hongze Cheng 已提交
193 194
  }

H
Hongze Cheng 已提交
195 196 197 198 199 200 201 202 203 204 205 206 207 208
  return tDiskColPutValue(pBuilder, pColVal);
}
static FORCE_INLINE int32_t tDiskColAddVal12(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  int32_t code = 0;

  int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
  code = tRealloc(&pBuilder->pBitMap, nBit);
  if (code) return code;

  memset(pBuilder->pBitMap, 0, nBit);
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);

  pBuilder->flag |= HAS_NULL;

H
Hongze Cheng 已提交
209 210
  return code;
}
H
Hongze Cheng 已提交
211
static FORCE_INLINE int32_t tDiskColAddVal20(SDiskColBuilder *pBuilder, SColVal *pColVal) {
H
Hongze Cheng 已提交
212 213
  int32_t code = 0;

H
Hongze Cheng 已提交
214 215 216 217 218
  int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
  code = tRealloc(&pBuilder->pBitMap, nBit);
  if (code) return code;

  pBuilder->flag |= HAS_VALUE;
H
Hongze Cheng 已提交
219

H
Hongze Cheng 已提交
220 221 222 223 224 225
  memset(pBuilder->pBitMap, 0, nBit);
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);

  SColVal cv = COL_VAL_VALUE(pColVal->cid, pColVal->type, (SValue){0});
  for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
    code = tDiskColPutValue(pBuilder, &cv);
H
Hongze Cheng 已提交
226
    if (code) return code;
H
Hongze Cheng 已提交
227
  }
H
Hongze Cheng 已提交
228

H
Hongze Cheng 已提交
229 230 231 232
  return tDiskColPutValue(pBuilder, pColVal);
}
static FORCE_INLINE int32_t tDiskColAddVal21(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  int32_t code = 0;
H
Hongze Cheng 已提交
233

H
Hongze Cheng 已提交
234 235 236
  int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
  code = tRealloc(&pBuilder->pBitMap, nBit);
  if (code) return code;
H
Hongze Cheng 已提交
237

H
Hongze Cheng 已提交
238
  pBuilder->flag |= HAS_NONE;
H
Hongze Cheng 已提交
239

H
Hongze Cheng 已提交
240 241
  memset(pBuilder->pBitMap, 255, nBit);
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);
H
Hongze Cheng 已提交
242 243 244

  return code;
}
H
Hongze Cheng 已提交
245
static FORCE_INLINE int32_t tDiskColAddVal30(SDiskColBuilder *pBuilder, SColVal *pColVal) {
H
Hongze Cheng 已提交
246 247
  int32_t code = 0;

H
Hongze Cheng 已提交
248
  pBuilder->flag |= HAS_VALUE;
H
Hongze Cheng 已提交
249

H
Hongze Cheng 已提交
250 251 252
  uint8_t *pBitMap = NULL;
  code = tRealloc(&pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
  if (code) return code;
H
Hongze Cheng 已提交
253

H
Hongze Cheng 已提交
254 255 256 257
  for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
    SET_BIT2(pBitMap, iVal, GET_BIT1(pBuilder->pBitMap, iVal));
  }
  SET_BIT2(pBitMap, pBuilder->nVal, 2);
H
Hongze Cheng 已提交
258

H
Hongze Cheng 已提交
259 260
  tFree(pBuilder->pBitMap);
  pBuilder->pBitMap = pBitMap;
H
Hongze Cheng 已提交
261

H
Hongze Cheng 已提交
262 263 264 265
  SColVal cv = COL_VAL_VALUE(pColVal->cid, pColVal->type, (SValue){0});
  for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
    code = tDiskColPutValue(pBuilder, &cv);
    if (code) return code;
H
Hongze Cheng 已提交
266 267
  }

H
Hongze Cheng 已提交
268 269 270 271 272 273 274 275 276
  return tDiskColPutValue(pBuilder, pColVal);
}
static FORCE_INLINE int32_t tDiskColAddVal31(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  int32_t code = 0;

  code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
  if (code) return code;
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);

H
Hongze Cheng 已提交
277 278
  return code;
}
H
Hongze Cheng 已提交
279
static FORCE_INLINE int32_t tDiskColAddVal32(SDiskColBuilder *pBuilder, SColVal *pColVal) {
H
Hongze Cheng 已提交
280 281
  int32_t code = 0;

H
Hongze Cheng 已提交
282 283 284 285 286 287 288 289 290 291 292
  code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
  if (code) return code;
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);

  return code;
}
static FORCE_INLINE int32_t tDiskColAddVal40(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  return tDiskColPutValue(pBuilder, pColVal);
}
static FORCE_INLINE int32_t tDiskColAddVal41(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  int32_t code = 0;
H
Hongze Cheng 已提交
293

H
Hongze Cheng 已提交
294
  pBuilder->flag |= HAS_NONE;
H
Hongze Cheng 已提交
295

H
Hongze Cheng 已提交
296 297 298
  int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
  code = tRealloc(&pBuilder->pBitMap, nBit);
  if (code) return code;
H
Hongze Cheng 已提交
299

H
Hongze Cheng 已提交
300 301
  memset(pBuilder->pBitMap, 255, nBit);
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);
H
Hongze Cheng 已提交
302

H
Hongze Cheng 已提交
303 304 305 306
  return tDiskColPutValue(pBuilder, pColVal);
}
static FORCE_INLINE int32_t tDiskColAddVal42(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  int32_t code = 0;
H
Hongze Cheng 已提交
307

H
Hongze Cheng 已提交
308
  pBuilder->flag |= HAS_NULL;
H
Hongze Cheng 已提交
309

H
Hongze Cheng 已提交
310 311 312
  int32_t nBit = BIT1_SIZE(pBuilder->nVal + 1);
  code = tRealloc(&pBuilder->pBitMap, nBit);
  if (code) return code;
H
Hongze Cheng 已提交
313

H
Hongze Cheng 已提交
314 315
  memset(pBuilder->pBitMap, 255, nBit);
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);
H
Hongze Cheng 已提交
316

H
Hongze Cheng 已提交
317
  return tDiskColPutValue(pBuilder, pColVal);
H
Hongze Cheng 已提交
318
}
H
Hongze Cheng 已提交
319
static FORCE_INLINE int32_t tDiskColAddVal50(SDiskColBuilder *pBuilder, SColVal *pColVal) {
H
Hongze Cheng 已提交
320 321
  int32_t code = 0;

H
Hongze Cheng 已提交
322 323 324
  code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
  if (code) return code;
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);
H
Hongze Cheng 已提交
325

H
Hongze Cheng 已提交
326 327 328 329
  return tDiskColPutValue(pBuilder, pColVal);
}
static FORCE_INLINE int32_t tDiskColAddVal51(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  int32_t code = 0;
H
Hongze Cheng 已提交
330

H
Hongze Cheng 已提交
331 332 333
  code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
  if (code) return code;
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);
H
Hongze Cheng 已提交
334

H
Hongze Cheng 已提交
335 336 337 338 339 340 341 342 343 344 345 346 347
  return tDiskColPutValue(pBuilder, pColVal);
}
static FORCE_INLINE int32_t tDiskColAddVal52(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  int32_t code = 0;

  pBuilder->flag |= HAS_NULL;

  uint8_t *pBitMap = NULL;
  code = tRealloc(&pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
  if (code) return code;

  for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
    SET_BIT2(pBitMap, iVal, GET_BIT1(pBuilder->pBitMap, iVal) ? 2 : 0);
H
Hongze Cheng 已提交
348
  }
H
Hongze Cheng 已提交
349
  SET_BIT2(pBitMap, pBuilder->nVal, 1);
H
Hongze Cheng 已提交
350

H
Hongze Cheng 已提交
351 352 353 354
  tFree(pBuilder->pBitMap);
  pBuilder->pBitMap = pBitMap;

  return tDiskColPutValue(pBuilder, pColVal);
H
Hongze Cheng 已提交
355
}
H
Hongze Cheng 已提交
356
static FORCE_INLINE int32_t tDiskColAddVal60(SDiskColBuilder *pBuilder, SColVal *pColVal) {
H
Hongze Cheng 已提交
357 358
  int32_t code = 0;

H
Hongze Cheng 已提交
359 360 361
  code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
  if (code) return code;
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 1);
H
Hongze Cheng 已提交
362

H
Hongze Cheng 已提交
363 364 365 366
  return tDiskColPutValue(pBuilder, pColVal);
}
static FORCE_INLINE int32_t tDiskColAddVal61(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  int32_t code = 0;
H
Hongze Cheng 已提交
367

H
Hongze Cheng 已提交
368
  pBuilder->flag |= HAS_NONE;
H
Hongze Cheng 已提交
369

H
Hongze Cheng 已提交
370 371 372
  uint8_t *pBitMap = NULL;
  code = tRealloc(&pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
  if (code) return code;
H
Hongze Cheng 已提交
373

H
Hongze Cheng 已提交
374 375
  for (int32_t iVal = 0; iVal < pBuilder->nVal; iVal++) {
    SET_BIT2(pBitMap, iVal, GET_BIT1(pBuilder->pBitMap, iVal) ? 2 : 1);
H
Hongze Cheng 已提交
376
  }
H
Hongze Cheng 已提交
377
  SET_BIT2(pBitMap, pBuilder->nVal, 0);
H
Hongze Cheng 已提交
378

H
Hongze Cheng 已提交
379 380 381 382
  tFree(pBuilder->pBitMap);
  pBuilder->pBitMap = pBitMap;

  return tDiskColPutValue(pBuilder, pColVal);
H
Hongze Cheng 已提交
383
}
H
Hongze Cheng 已提交
384
static FORCE_INLINE int32_t tDiskColAddVal62(SDiskColBuilder *pBuilder, SColVal *pColVal) {
H
Hongze Cheng 已提交
385 386
  int32_t code = 0;

H
Hongze Cheng 已提交
387 388 389
  code = tRealloc(&pBuilder->pBitMap, BIT1_SIZE(pBuilder->nVal + 1));
  if (code) return code;
  SET_BIT1(pBuilder->pBitMap, pBuilder->nVal, 0);
H
Hongze Cheng 已提交
390

H
Hongze Cheng 已提交
391 392 393 394
  return tDiskColPutValue(pBuilder, pColVal);
}
static FORCE_INLINE int32_t tDiskColAddVal70(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  int32_t code = 0;
H
Hongze Cheng 已提交
395

H
Hongze Cheng 已提交
396 397 398
  code = tRealloc(&pBuilder->pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
  if (code) return code;
  SET_BIT2(pBuilder->pBitMap, pBuilder->nVal, 2);
H
Hongze Cheng 已提交
399

H
Hongze Cheng 已提交
400 401 402 403
  return tDiskColPutValue(pBuilder, pColVal);
}
static FORCE_INLINE int32_t tDiskColAddVal71(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  int32_t code = 0;
H
Hongze Cheng 已提交
404

H
Hongze Cheng 已提交
405 406 407
  code = tRealloc(&pBuilder->pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
  if (code) return code;
  SET_BIT2(pBuilder->pBitMap, pBuilder->nVal, 0);
H
Hongze Cheng 已提交
408

H
Hongze Cheng 已提交
409
  return tDiskColPutValue(pBuilder, pColVal);
H
Hongze Cheng 已提交
410
}
H
Hongze Cheng 已提交
411
static FORCE_INLINE int32_t tDiskColAddVal72(SDiskColBuilder *pBuilder, SColVal *pColVal) {
H
Hongze Cheng 已提交
412 413
  int32_t code = 0;

H
Hongze Cheng 已提交
414
  code = tRealloc(&pBuilder->pBitMap, BIT2_SIZE(pBuilder->nVal + 1));
H
Hongze Cheng 已提交
415 416
  if (code) return code;
  SET_BIT2(pBuilder->pBitMap, pBuilder->nVal, 1);
H
Hongze Cheng 已提交
417

H
Hongze Cheng 已提交
418
  return tDiskColPutValue(pBuilder, pColVal);
H
Hongze Cheng 已提交
419
}
H
Hongze Cheng 已提交
420 421 422 423 424 425 426 427 428
static int32_t (*tDiskColAddValImpl[8][3])(SDiskColBuilder *pBuilder, SColVal *pColVal) = {
    {tDiskColAddVal00, tDiskColAddVal01, tDiskColAddVal02},  // 0
    {tDiskColAddVal10, NULL, tDiskColAddVal12},              // HAS_NONE
    {tDiskColAddVal20, tDiskColAddVal21, NULL},              // HAS_NULL
    {tDiskColAddVal30, tDiskColAddVal31, tDiskColAddVal32},  // HAS_NULL|HAS_NONE
    {tDiskColAddVal40, tDiskColAddVal41, tDiskColAddVal42},  // HAS_VALUE
    {tDiskColAddVal50, tDiskColAddVal51, tDiskColAddVal52},  // HAS_VALUE|HAS_NONE
    {tDiskColAddVal60, tDiskColAddVal61, tDiskColAddVal62},  // HAS_VALUE|HAS_NULL
    {tDiskColAddVal70, tDiskColAddVal71, tDiskColAddVal72}   // HAS_VALUE|HAS_NULL|HAS_NONE
H
Hongze Cheng 已提交
429
};
H
Hongze Cheng 已提交
430
extern void (*tSmaUpdateImpl[])(SColumnDataAgg *pColAgg, SColVal *pColVal, uint8_t *minSet, uint8_t *maxSet);
H
Hongze Cheng 已提交
431 432 433
static int32_t tDiskColAddVal(SDiskColBuilder *pBuilder, SColVal *pColVal) {
  int32_t code = 0;

H
Hongze Cheng 已提交
434 435 436 437 438 439 440
  if (pBuilder->calcSma) {
    if (COL_VAL_IS_VALUE(pColVal)) {
      tSmaUpdateImpl[pBuilder->type](&pBuilder->sma, pColVal, &pBuilder->minSet, &pBuilder->maxSet);
    } else {
      pBuilder->sma.numOfNull++;
    }
  }
H
Hongze Cheng 已提交
441

H
Hongze Cheng 已提交
442 443
  if (tDiskColAddValImpl[pBuilder->flag][pColVal->flag]) {
    code = tDiskColAddValImpl[pBuilder->flag][pColVal->flag](pBuilder, pColVal);
H
Hongze Cheng 已提交
444 445
    if (code) return code;
  }
H
Hongze Cheng 已提交
446 447 448 449 450

  pBuilder->nVal++;

  return code;
}
H
Hongze Cheng 已提交
451

H
Hongze Cheng 已提交
452
// SDiskDataBuilder ================================================
H
Hongze Cheng 已提交
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
int32_t tDiskDataBuilderCreate(SDiskDataBuilder **ppBuilder) {
  int32_t code = 0;

  *ppBuilder = (SDiskDataBuilder *)taosMemoryCalloc(1, sizeof(SDiskDataBuilder));
  if (*ppBuilder == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
    return code;
  }

  return code;
}

void *tDiskDataBuilderDestroy(SDiskDataBuilder *pBuilder) {
  if (pBuilder == NULL) return NULL;

  if (pBuilder->pUidC) tCompressorDestroy(pBuilder->pUidC);
  if (pBuilder->pVerC) tCompressorDestroy(pBuilder->pVerC);
  if (pBuilder->pKeyC) tCompressorDestroy(pBuilder->pKeyC);

  if (pBuilder->aBuilder) {
    for (int32_t iBuilder = 0; iBuilder < taosArrayGetSize(pBuilder->aBuilder); iBuilder++) {
      SDiskColBuilder *pDCBuilder = (SDiskColBuilder *)taosArrayGet(pBuilder->aBuilder, iBuilder);
H
Hongze Cheng 已提交
475
      tDiskColBuilderDestroy(pDCBuilder);
H
Hongze Cheng 已提交
476 477 478 479 480 481
    }
    taosArrayDestroy(pBuilder->aBuilder);
  }
  for (int32_t iBuf = 0; iBuf < sizeof(pBuilder->aBuf) / sizeof(pBuilder->aBuf[0]); iBuf++) {
    tFree(pBuilder->aBuf[iBuf]);
  }
H
Hongze Cheng 已提交
482
  tDiskDataDestroy(&pBuilder->dd);
H
Hongze Cheng 已提交
483 484 485 486 487 488 489
  taosMemoryFree(pBuilder);

  return NULL;
}

int32_t tDiskDataBuilderInit(SDiskDataBuilder *pBuilder, STSchema *pTSchema, TABLEID *pId, uint8_t cmprAlg,
                             uint8_t calcSma) {
H
Hongze Cheng 已提交
490
  int32_t code = 0;
H
Hongze Cheng 已提交
491

H
Hongze Cheng 已提交
492 493
  ASSERT(pId->suid || pId->uid);

H
Hongze Cheng 已提交
494 495 496 497
  pBuilder->suid = pId->suid;
  pBuilder->uid = pId->uid;
  pBuilder->nRow = 0;
  pBuilder->cmprAlg = cmprAlg;
H
Hongze Cheng 已提交
498
  pBuilder->calcSma = calcSma;
H
Hongze Cheng 已提交
499 500 501 502 503 504
  pBuilder->bi = (SBlkInfo){.minUid = INT64_MAX,
                            .maxUid = INT64_MIN,
                            .minKey = TSDBKEY_MAX,
                            .maxKey = TSDBKEY_MIN,
                            .minVer = VERSION_MAX,
                            .maxVer = VERSION_MIN};
H
Hongze Cheng 已提交
505

H
Hongze Cheng 已提交
506
  if (pBuilder->pUidC == NULL && (code = tCompressorCreate(&pBuilder->pUidC))) return code;
H
Hongze Cheng 已提交
507
  code = tCompressStart(pBuilder->pUidC, TSDB_DATA_TYPE_BIGINT, cmprAlg);
H
Hongze Cheng 已提交
508 509
  if (code) return code;

H
Hongze Cheng 已提交
510
  if (pBuilder->pVerC == NULL && (code = tCompressorCreate(&pBuilder->pVerC))) return code;
H
Hongze Cheng 已提交
511
  code = tCompressStart(pBuilder->pVerC, TSDB_DATA_TYPE_BIGINT, cmprAlg);
H
Hongze Cheng 已提交
512 513
  if (code) return code;

H
Hongze Cheng 已提交
514
  if (pBuilder->pKeyC == NULL && (code = tCompressorCreate(&pBuilder->pKeyC))) return code;
H
Hongze Cheng 已提交
515
  code = tCompressStart(pBuilder->pKeyC, TSDB_DATA_TYPE_TIMESTAMP, cmprAlg);
H
Hongze Cheng 已提交
516 517
  if (code) return code;

H
Hongze Cheng 已提交
518 519 520
  if (pBuilder->aBuilder == NULL) {
    pBuilder->aBuilder = taosArrayInit(pTSchema->numOfCols - 1, sizeof(SDiskColBuilder));
    if (pBuilder->aBuilder == NULL) {
H
Hongze Cheng 已提交
521 522 523 524 525
      code = TSDB_CODE_OUT_OF_MEMORY;
      return code;
    }
  }

H
Hongze Cheng 已提交
526
  pBuilder->nBuilder = 0;
H
Hongze Cheng 已提交
527 528 529
  for (int32_t iCol = 1; iCol < pTSchema->numOfCols; iCol++) {
    STColumn *pTColumn = &pTSchema->columns[iCol];

H
Hongze Cheng 已提交
530
    if (pBuilder->nBuilder >= taosArrayGetSize(pBuilder->aBuilder)) {
H
Hongze Cheng 已提交
531
      SDiskColBuilder dc = tDiskColBuilderCreate();
H
Hongze Cheng 已提交
532
      if (taosArrayPush(pBuilder->aBuilder, &dc) == NULL) {
H
Hongze Cheng 已提交
533 534 535 536 537
        code = TSDB_CODE_OUT_OF_MEMORY;
        return code;
      }
    }

H
Hongze Cheng 已提交
538
    SDiskColBuilder *pDCBuilder = (SDiskColBuilder *)taosArrayGet(pBuilder->aBuilder, pBuilder->nBuilder);
H
Hongze Cheng 已提交
539

H
Hongze Cheng 已提交
540
    code = tDiskColBuilderInit(pDCBuilder, pTColumn->colId, pTColumn->type, cmprAlg,
H
Hongze Cheng 已提交
541
                               (calcSma && (pTColumn->flags & COL_SMA_ON)));
H
Hongze Cheng 已提交
542 543
    if (code) return code;

H
Hongze Cheng 已提交
544
    pBuilder->nBuilder++;
H
Hongze Cheng 已提交
545 546
  }

H
Hongze Cheng 已提交
547 548 549
  return code;
}

H
Hongze Cheng 已提交
550 551 552 553 554 555 556 557
int32_t tDiskDataBuilderClear(SDiskDataBuilder *pBuilder) {
  int32_t code = 0;
  pBuilder->suid = 0;
  pBuilder->uid = 0;
  return code;
}

int32_t tDiskDataAddRow(SDiskDataBuilder *pBuilder, TSDBROW *pRow, STSchema *pTSchema, TABLEID *pId) {
H
Hongze Cheng 已提交
558 559
  int32_t code = 0;

H
Hongze Cheng 已提交
560
  ASSERT(pBuilder->suid || pBuilder->uid);
H
Hongze Cheng 已提交
561
  ASSERT(pId->suid == pBuilder->suid);
H
Hongze Cheng 已提交
562

H
Hongze Cheng 已提交
563 564
  TSDBKEY key = TSDBROW_KEY(pRow);

H
Hongze Cheng 已提交
565
  // uid
H
Hongze Cheng 已提交
566
  if (pBuilder->uid && pBuilder->uid != pId->uid) {
H
Hongze Cheng 已提交
567
    ASSERT(pBuilder->suid);
H
Hongze Cheng 已提交
568 569
    for (int32_t iRow = 0; iRow < pBuilder->nRow; iRow++) {
      code = tCompress(pBuilder->pUidC, &pBuilder->uid, sizeof(int64_t));
H
Hongze Cheng 已提交
570
      if (code) return code;
H
Hongze Cheng 已提交
571
    }
H
Hongze Cheng 已提交
572
    pBuilder->uid = 0;
H
Hongze Cheng 已提交
573
  }
H
Hongze Cheng 已提交
574 575
  if (pBuilder->uid == 0) {
    code = tCompress(pBuilder->pUidC, &pId->uid, sizeof(int64_t));
H
Hongze Cheng 已提交
576
    if (code) return code;
H
Hongze Cheng 已提交
577
  }
H
Hongze Cheng 已提交
578 579
  if (pBuilder->bi.minUid > pId->uid) pBuilder->bi.minUid = pId->uid;
  if (pBuilder->bi.maxUid < pId->uid) pBuilder->bi.maxUid = pId->uid;
H
Hongze Cheng 已提交
580 581

  // version
H
Hongze Cheng 已提交
582
  code = tCompress(pBuilder->pVerC, &key.version, sizeof(int64_t));
H
Hongze Cheng 已提交
583
  if (code) return code;
H
Hongze Cheng 已提交
584 585
  if (pBuilder->bi.minVer > key.version) pBuilder->bi.minVer = key.version;
  if (pBuilder->bi.maxVer < key.version) pBuilder->bi.maxVer = key.version;
H
Hongze Cheng 已提交
586 587

  // TSKEY
H
Hongze Cheng 已提交
588
  code = tCompress(pBuilder->pKeyC, &key.ts, sizeof(int64_t));
H
Hongze Cheng 已提交
589
  if (code) return code;
H
Hongze Cheng 已提交
590 591
  if (tsdbKeyCmprFn(&pBuilder->bi.minKey, &key) > 0) pBuilder->bi.minKey = key;
  if (tsdbKeyCmprFn(&pBuilder->bi.maxKey, &key) < 0) pBuilder->bi.maxKey = key;
H
Hongze Cheng 已提交
592 593 594 595 596

  SRowIter iter = {0};
  tRowIterInit(&iter, pRow, pTSchema);

  SColVal *pColVal = tRowIterNext(&iter);
H
Hongze Cheng 已提交
597 598
  for (int32_t iBuilder = 0; iBuilder < pBuilder->nBuilder; iBuilder++) {
    SDiskColBuilder *pDCBuilder = (SDiskColBuilder *)taosArrayGet(pBuilder->aBuilder, iBuilder);
H
Hongze Cheng 已提交
599

H
Hongze Cheng 已提交
600
    while (pColVal && pColVal->cid < pDCBuilder->cid) {
H
Hongze Cheng 已提交
601 602 603
      pColVal = tRowIterNext(&iter);
    }

H
Hongze Cheng 已提交
604
    if (pColVal && pColVal->cid == pDCBuilder->cid) {
H
Hongze Cheng 已提交
605
      code = tDiskColAddVal(pDCBuilder, pColVal);
H
Hongze Cheng 已提交
606
      if (code) return code;
H
Hongze Cheng 已提交
607
      pColVal = tRowIterNext(&iter);
H
Hongze Cheng 已提交
608 609 610
    } else {
      code = tDiskColAddVal(pDCBuilder, &COL_VAL_NONE(pDCBuilder->cid, pDCBuilder->type));
      if (code) return code;
H
Hongze Cheng 已提交
611 612
    }
  }
H
Hongze Cheng 已提交
613
  pBuilder->nRow++;
H
Hongze Cheng 已提交
614 615 616

  return code;
}
H
Hongze Cheng 已提交
617

H
Hongze Cheng 已提交
618
int32_t tGnrtDiskData(SDiskDataBuilder *pBuilder, const SDiskData **ppDiskData, const SBlkInfo **ppBlkInfo) {
H
Hongze Cheng 已提交
619 620
  int32_t code = 0;

H
Hongze Cheng 已提交
621
  ASSERT(pBuilder->nRow);
H
Hongze Cheng 已提交
622

H
Hongze Cheng 已提交
623
  *ppDiskData = NULL;
H
Hongze Cheng 已提交
624
  *ppBlkInfo = NULL;
H
Hongze Cheng 已提交
625 626

  SDiskData *pDiskData = &pBuilder->dd;
H
Hongze Cheng 已提交
627 628 629 630 631 632 633 634 635 636 637 638 639 640
  // reset SDiskData
  pDiskData->hdr = (SDiskDataHdr){.delimiter = TSDB_FILE_DLMT,
                                  .fmtVer = 0,
                                  .suid = pBuilder->suid,
                                  .uid = pBuilder->uid,
                                  .szUid = 0,
                                  .szVer = 0,
                                  .szKey = 0,
                                  .szBlkCol = 0,
                                  .nRow = pBuilder->nRow,
                                  .cmprAlg = pBuilder->cmprAlg};
  pDiskData->pUid = NULL;
  pDiskData->pVer = NULL;
  pDiskData->pKey = NULL;
H
Hongze Cheng 已提交
641 642

  // UID
H
Hongze Cheng 已提交
643
  if (pBuilder->uid == 0) {
H
Hongze Cheng 已提交
644
    code = tCompressEnd(pBuilder->pUidC, &pDiskData->pUid, &pDiskData->hdr.szUid, NULL);
H
Hongze Cheng 已提交
645 646 647 648
    if (code) return code;
  }

  // VERSION
H
Hongze Cheng 已提交
649
  code = tCompressEnd(pBuilder->pVerC, &pDiskData->pVer, &pDiskData->hdr.szVer, NULL);
H
Hongze Cheng 已提交
650 651 652
  if (code) return code;

  // TSKEY
H
Hongze Cheng 已提交
653
  code = tCompressEnd(pBuilder->pKeyC, &pDiskData->pKey, &pDiskData->hdr.szKey, NULL);
H
Hongze Cheng 已提交
654 655
  if (code) return code;

H
Hongze Cheng 已提交
656 657 658 659 660 661 662 663 664 665 666
  // aDiskCol
  if (pDiskData->aDiskCol) {
    taosArrayClear(pDiskData->aDiskCol);
  } else {
    pDiskData->aDiskCol = taosArrayInit(pBuilder->nBuilder, sizeof(SDiskCol));
    if (pDiskData->aDiskCol == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
      return code;
    }
  }

H
Hongze Cheng 已提交
667
  int32_t offset = 0;
H
Hongze Cheng 已提交
668 669 670 671
  for (int32_t iBuilder = 0; iBuilder < pBuilder->nBuilder; iBuilder++) {
    SDiskColBuilder *pDCBuilder = (SDiskColBuilder *)taosArrayGet(pBuilder->aBuilder, iBuilder);

    if (pDCBuilder->flag == HAS_NONE) continue;
H
Hongze Cheng 已提交
672

H
Hongze Cheng 已提交
673
    SDiskCol dCol;
H
Hongze Cheng 已提交
674

H
Hongze Cheng 已提交
675
    code = tGnrtDiskCol(pDCBuilder, &dCol);
H
Hongze Cheng 已提交
676
    if (code) return code;
H
Hongze Cheng 已提交
677

H
Hongze Cheng 已提交
678 679
    dCol.bCol.offset = offset;
    offset = offset + dCol.bCol.szBitmap + dCol.bCol.szOffset + dCol.bCol.szValue;
H
Hongze Cheng 已提交
680

H
Hongze Cheng 已提交
681 682 683 684
    if (taosArrayPush(pDiskData->aDiskCol, &dCol) == NULL) {
      code = TSDB_CODE_OUT_OF_MEMORY;
      return code;
    }
H
Hongze Cheng 已提交
685

H
Hongze Cheng 已提交
686
    pDiskData->hdr.szBlkCol += tPutBlockCol(NULL, &dCol.bCol);
H
Hongze Cheng 已提交
687
  }
H
Hongze Cheng 已提交
688

H
Hongze Cheng 已提交
689
  *ppDiskData = pDiskData;
H
Hongze Cheng 已提交
690
  *ppBlkInfo = &pBuilder->bi;
H
Hongze Cheng 已提交
691 692
  return code;
}