• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #5124

16 Sep 2026 01:31AM UTC coverage: 72.781% (-0.5%) from 73.303%
#5124

push

travis-ci

jbjia
test(coverage): sync from gitlab

308307 of 423608 relevant lines covered (72.78%)

65361367.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

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

16
#include "tsdbDataFileRW.h"
17
#include "meta.h"
18

19
// SDataFileReader =============================================
20
struct SDataFileReader {
21
  SDataFileReaderConfig config[1];
22

23
  SBuffer  local[10];
24
  SBuffer *buffers;
25

26
  struct {
27
    bool headFooterLoaded;
28
    bool tombFooterLoaded;
29
    bool brinBlkLoaded;
30
    bool tombBlkLoaded;
31
  } ctx[1];
32

33
  STsdbFD *fd[TSDB_FTYPE_MAX];
34

35
  SHeadFooter   headFooter[1];
36
  STombFooter   tombFooter[1];
37
  TBrinBlkArray brinBlkArray[1];
38
  TTombBlkArray tombBlkArray[1];
39
};
40

41
static int32_t tsdbDataFileReadHeadFooter(SDataFileReader *reader) {
3,614,733 ✔
42
  if (reader->ctx->headFooterLoaded) {
3,614,733 ✔
43
    return 0;
×
44
  }
45

46
  int32_t code = 0;
3,614,733 ✔
47
  int32_t lino = 0;
3,614,733 ✔
48

49
  int32_t ftype = TSDB_FTYPE_HEAD;
3,614,406 ✔
50
  if (reader->fd[ftype]) {
3,614,406 ✔
51
    SEncryptData *pEncryptData = &(reader->config->tsdb->pVnode->config.tsdbCfg.encryptData);
2,758,078 ✔
52

53
#if 1
54
    TAOS_CHECK_GOTO(tsdbReadFile(reader->fd[ftype], reader->config->files[ftype].file.size - sizeof(SHeadFooter),
2,758,078 ✔
55
                                 (uint8_t *)reader->headFooter, sizeof(SHeadFooter), 0, pEncryptData),
56
                    &lino, _exit);
57
#else
58
    int64_t size = reader->config->files[ftype].file.size;
59
    for (; size > TSDB_FHDR_SIZE; size--) {
60
      code = tsdbReadFile(reader->fd[ftype], size - sizeof(SHeadFooter), (uint8_t *)reader->headFooter,
61
                          sizeof(SHeadFooter), 0, encryptAlgorithm, encryptKey);
62
      if (code) continue;
63
      if (reader->headFooter->brinBlkPtr->offset + reader->headFooter->brinBlkPtr->size + sizeof(SHeadFooter) == size) {
64
        break;
65
      }
66
    }
67
    if (size <= TSDB_FHDR_SIZE) {
68
      TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
69
    }
70
#endif
71
  }
72

73
  reader->ctx->headFooterLoaded = true;
3,614,433 ✔
74

75
_exit:
3,614,433 ✔
76
  if (code) {
3,614,256 ✔
77
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, lino,
×
78
              tstrerror(code));
79
  }
80
  return code;
3,614,256 ✔
81
}
82

83
static int32_t tsdbDataFileReadTombFooter(SDataFileReader *reader) {
896,263 ✔
84
  if (reader->ctx->tombFooterLoaded) {
896,263 ✔
85
    return 0;
×
86
  }
87

88
  int32_t code = 0;
896,263 ✔
89
  int32_t lino = 0;
896,263 ✔
90

91
  int32_t ftype = TSDB_FTYPE_TOMB;
896,263 ✔
92
  if (reader->fd[ftype]) {
896,263 ✔
93
    SEncryptData *pEncryptData = &(reader->config->tsdb->pVnode->config.tsdbCfg.encryptData);
865,328 ✔
94

95
    TAOS_CHECK_GOTO(tsdbReadFile(reader->fd[ftype], reader->config->files[ftype].file.size - sizeof(STombFooter),
865,328 ✔
96
                                 (uint8_t *)reader->tombFooter, sizeof(STombFooter), 0, pEncryptData),
97
                    &lino, _exit);
98
  }
99
  reader->ctx->tombFooterLoaded = true;
896,263 ✔
100

101
_exit:
896,263 ✔
102
  if (code) {
896,263 ✔
103
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, lino,
×
104
              tstrerror(code));
105
  }
106
  return code;
896,263 ✔
107
}
108

109
int32_t tsdbDataFileReaderOpen(const char *fname[], const SDataFileReaderConfig *config, SDataFileReader **reader) {
3,668,930 ✔
110
  int32_t code = 0;
3,668,930 ✔
111
  int32_t lino = 0;
3,668,930 ✔
112

113
  if ((*reader = taosMemoryCalloc(1, sizeof(**reader))) == NULL) {
3,668,930 ✔
114
    TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
115
  }
116

117
  for (int32_t i = 0; i < ARRAY_SIZE(reader[0]->local); i++) {
40,340,485 ✔
118
    tBufferInit(reader[0]->local + i);
36,672,254 ✔
119
  }
120

121
  reader[0]->config[0] = config[0];
3,668,231 ✔
122
  reader[0]->buffers = config->buffers;
3,668,231 ✔
123
  if (reader[0]->buffers == NULL) {
3,668,231 ✔
124
    reader[0]->buffers = reader[0]->local;
3,584,328 ✔
125
  }
126

127
  if (fname) {
3,668,231 ✔
128
    for (int32_t i = 0; i < TSDB_FTYPE_MAX; ++i) {
17,771,982 ✔
129
      if (fname[i]) {
14,217,458 ✔
130
        int32_t lcn = config->files[i].file.lcn;
8,998,239 ✔
131
        TAOS_CHECK_GOTO(tsdbOpenFile(fname[i], config->tsdb, TD_FILE_READ, &reader[0]->fd[i], lcn), &lino, _exit);
8,998,239 ✔
132
      }
133
    }
134
  } else {
135
    for (int32_t i = 0; i < TSDB_FTYPE_MAX; ++i) {
587,271 ✔
136
      if (config->files[i].exist) {
472,812 ✔
137
        char fname1[TSDB_FILENAME_LEN];
224,477 ✔
138
        tsdbTFileName(config->tsdb, &config->files[i].file, fname1);
224,477 ✔
139
        int32_t lcn = config->files[i].file.lcn;
224,477 ✔
140
        TAOS_CHECK_GOTO(tsdbOpenFile(fname1, config->tsdb, TD_FILE_READ, &reader[0]->fd[i], lcn), &lino, _exit);
224,477 ✔
141
      }
142
    }
143
  }
144

145
_exit:
3,668,983 ✔
146
  if (code) {
3,673,355 ✔
147
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(config->tsdb->pVnode), __func__, __FILE__, lino,
×
148
              tstrerror(code));
149
  }
150
  return code;
3,673,355 ✔
151
}
152

153
void tsdbDataFileReaderClose(SDataFileReader **reader) {
18,326,380 ✔
154
  if (reader[0] == NULL) {
18,326,380 ✔
155
    return;
14,594,185 ✔
156
  }
157

158
  TARRAY2_DESTROY(reader[0]->tombBlkArray, NULL);
3,665,820 ✔
159
  TARRAY2_DESTROY(reader[0]->brinBlkArray, NULL);
3,665,820 ✔
160

161
  for (int32_t i = 0; i < TSDB_FTYPE_MAX; ++i) {
18,356,863 ✔
162
    if (reader[0]->fd[i]) {
14,686,860 ✔
163
      tsdbCloseFile(&reader[0]->fd[i]);
9,222,288 ✔
164
    }
165
  }
166

167
  for (int32_t i = 0; i < ARRAY_SIZE(reader[0]->local); ++i) {
40,383,263 ✔
168
    tBufferDestroy(reader[0]->local + i);
36,714,145 ✔
169
  }
170

171
  taosMemoryFree(reader[0]);
3,669,118 ✔
172
  reader[0] = NULL;
3,670,346 ✔
173
}
174

175
int32_t tsdbDataFileReadBrinBlk(SDataFileReader *reader, const TBrinBlkArray **brinBlkArray) {
3,616,653 ✔
176
  int32_t code = 0;
3,616,653 ✔
177
  int32_t lino = 0;
3,616,653 ✔
178
  void   *data = NULL;
3,616,830 ✔
179

180
  if (!reader->ctx->brinBlkLoaded) {
3,616,830 ✔
181
    TAOS_CHECK_GOTO(tsdbDataFileReadHeadFooter(reader), &lino, _exit);
3,619,458 ✔
182

183
    if (reader->headFooter->brinBlkPtr->size > 0) {
3,614,583 ✔
184
      data = taosMemoryMalloc(reader->headFooter->brinBlkPtr->size);
2,758,459 ✔
185
      if (data == NULL) {
2,755,627 ✔
186
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
187
      }
188

189
      SEncryptData *pEncryptData = &(reader->config->tsdb->pVnode->config.tsdbCfg.encryptData);
2,755,627 ✔
190

191
      TAOS_CHECK_GOTO(tsdbReadFile(reader->fd[TSDB_FTYPE_HEAD], reader->headFooter->brinBlkPtr->offset, data,
2,755,627 ✔
192
                                   reader->headFooter->brinBlkPtr->size, 0, pEncryptData),
193
                      &lino, _exit);
194

195
      int32_t size = reader->headFooter->brinBlkPtr->size / sizeof(SBrinBlk);
2,759,875 ✔
196
      TARRAY2_INIT_EX(reader->brinBlkArray, size, size, data);
2,759,875 ✔
197
    } else {
198
      TARRAY2_INIT(reader->brinBlkArray);
856,124 ✔
199
    }
200

201
    reader->ctx->brinBlkLoaded = true;
3,615,999 ✔
202
  }
203
  brinBlkArray[0] = reader->brinBlkArray;
3,613,371 ✔
204

205
_exit:
3,613,371 ✔
206
  if (code) {
3,613,725 ✔
207
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, lino,
×
208
              tstrerror(code));
209
    taosMemoryFree(data);
×
210
  }
211
  return code;
3,613,725 ✔
212
}
213

214
int32_t tsdbDataFileReadBrinBlock(SDataFileReader *reader, const SBrinBlk *brinBlk, SBrinBlock *brinBlock) {
2,102,057 ✔
215
  int32_t code = 0;
2,102,057 ✔
216
  int32_t lino = 0;
2,102,057 ✔
217

218
  if (brinBlk->numOfPKs > TD_MAX_PK_COLS) {
2,102,057 ✔
219
    tsdbError("vgId:%d %s failed at %s:%d since brin block numOfPKs %d exceeds max %d (file corrupted)",
4,027 ✔
220
              TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, __LINE__, (int)brinBlk->numOfPKs,
221
              (int)TD_MAX_PK_COLS);
222
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
223
  }
224

225
  SBuffer *buffer = reader->buffers + 0;
2,098,030 ✔
226
  SBuffer *assist = reader->buffers + 1;
2,098,030 ✔
227

228
  SEncryptData *pEncryptData = &(reader->config->tsdb->pVnode->config.tsdbCfg.encryptData);
2,098,030 ✔
229

230
  // load data
231
  tBufferClear(buffer);
×
232
  TAOS_CHECK_GOTO(tsdbReadFileToBuffer(reader->fd[TSDB_FTYPE_HEAD], brinBlk->dp->offset, brinBlk->dp->size, buffer, 0,
2,098,030 ✔
233
                                       pEncryptData),
234
                  &lino, _exit);
235

236
  // decode brin block
237
  SBufferReader br = BUFFER_READER_INITIALIZER(0, buffer);
2,104,358 ✔
238
  tBrinBlockClear(brinBlock);
2,104,358 ✔
239
  brinBlock->numOfPKs = brinBlk->numOfPKs;
2,104,712 ✔
240
  brinBlock->numOfRecords = brinBlk->numRec;
2,104,712 ✔
241
  for (int32_t i = 0; i < 10; i++) {  // int64_t
23,151,461 ✔
242

243
    SCompressInfo cinfo = {
21,046,218 ✔
244
        .cmprAlg = brinBlk->cmprAlg,
21,046,218 ✔
245
        .dataType = TSDB_DATA_TYPE_BIGINT,
246
        .compressedSize = brinBlk->size[i],
21,046,218 ✔
247
        .originalSize = brinBlk->numRec * sizeof(int64_t),
21,046,218 ✔
248
    };
249
    TAOS_CHECK_GOTO(tDecompressDataToBuffer(BR_PTR(&br), &cinfo, brinBlock->buffers + i, assist), &lino, _exit);
21,046,218 ✔
250
    br.offset += brinBlk->size[i];
21,045,333 ✔
251
  }
252

253
  for (int32_t i = 10; i < 15; i++) {  // int32_t
12,630,192 ✔
254
    SCompressInfo cinfo = {
10,523,887 ✔
255
        .cmprAlg = brinBlk->cmprAlg,
10,524,064 ✔
256
        .dataType = TSDB_DATA_TYPE_INT,
257
        .compressedSize = brinBlk->size[i],
10,524,064 ✔
258
        .originalSize = brinBlk->numRec * sizeof(int32_t),
10,524,064 ✔
259
    };
260
    TAOS_CHECK_GOTO(tDecompressDataToBuffer(BR_PTR(&br), &cinfo, brinBlock->buffers + i, assist), &lino, _exit);
10,524,064 ✔
261
    br.offset += brinBlk->size[i];
10,524,595 ✔
262
  }
263

264
  // primary keys
265
  if (brinBlk->numOfPKs > 0) {  // decode the primary keys
2,106,305 ✔
266
    SValueColumnCompressInfo firstInfos[TD_MAX_PK_COLS];
1,031 ✔
267
    SValueColumnCompressInfo lastInfos[TD_MAX_PK_COLS];
1,031 ✔
268

269
    for (int32_t i = 0; i < brinBlk->numOfPKs; i++) {
2,062 ✔
270
      TAOS_CHECK_GOTO(tValueColumnCompressInfoDecode(&br, firstInfos + i), &lino, _exit);
1,031 ✔
271
    }
272
    for (int32_t i = 0; i < brinBlk->numOfPKs; i++) {
2,062 ✔
273
      TAOS_CHECK_GOTO(tValueColumnCompressInfoDecode(&br, lastInfos + i), &lino, _exit);
1,031 ✔
274
    }
275

276
    for (int32_t i = 0; i < brinBlk->numOfPKs; i++) {
2,062 ✔
277
      SValueColumnCompressInfo *info = firstInfos + i;
1,031 ✔
278

279
      TAOS_CHECK_GOTO(tValueColumnDecompress(BR_PTR(&br), info, brinBlock->firstKeyPKs + i, assist), &lino, _exit);
1,031 ✔
280
      br.offset += (info->offsetCompressedSize + info->dataCompressedSize);
1,031 ✔
281
    }
282

283
    for (int32_t i = 0; i < brinBlk->numOfPKs; i++) {
2,062 ✔
284
      SValueColumnCompressInfo *info = lastInfos + i;
1,031 ✔
285

286
      TAOS_CHECK_GOTO(tValueColumnDecompress(BR_PTR(&br), info, brinBlock->lastKeyPKs + i, assist), &lino, _exit);
1,031 ✔
287
      br.offset += (info->offsetCompressedSize + info->dataCompressedSize);
1,031 ✔
288
    }
289
  }
290

291
  if (br.offset != br.buffer->size) {
2,104,889 ✔
292
    tsdbError("vgId:%d %s failed at %s:%d since brin block size mismatch, expected: %u, actual: %u, fname:%s",
×
293
              TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, lino, br.buffer->size, br.offset,
294
              reader->fd[TSDB_FTYPE_HEAD]->path);
295
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
296
  }
297

298
_exit:
2,105,597 ✔
299
  if (code) {
2,104,889 ✔
300
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, lino,
×
301
              tstrerror(code));
302
  }
303
  return code;
2,104,889 ✔
304
}
305

306
extern int32_t tBlockDataDecompress(SBufferReader *br, SBlockData *blockData, SBuffer *assist);
307

308
int32_t tsdbDataFileReadBlockData(SDataFileReader *reader, const SBrinRecord *record, SBlockData *bData) {
598,946 ✔
309
  int32_t code = 0;
598,946 ✔
310
  int32_t lino = 0;
598,946 ✔
311
  int32_t fid = reader->config->files[TSDB_FTYPE_DATA].file.fid;
598,946 ✔
312

313
  SBuffer *buffer = reader->buffers + 0;
598,946 ✔
314
  SBuffer *assist = reader->buffers + 1;
598,946 ✔
315

316
  SEncryptData *pEncryptData = &(reader->config->tsdb->pVnode->config.tsdbCfg.encryptData);
598,946 ✔
317

318
  // load data
319
  tBufferClear(buffer);
×
320
  TAOS_CHECK_GOTO(tsdbReadFileToBuffer(reader->fd[TSDB_FTYPE_DATA], record->blockOffset, record->blockSize, buffer, 0,
598,946 ✔
321
                                       pEncryptData),
322
                  &lino, _exit);
323

324
  // decompress
325
  SBufferReader br = BUFFER_READER_INITIALIZER(0, buffer);
598,946 ✔
326
  TAOS_CHECK_GOTO(tBlockDataDecompress(&br, bData, assist), &lino, _exit);
598,946 ✔
327

328
  if (br.offset != buffer->size) {
598,946 ✔
329
    tsdbError("vgId:%d %s failed at %s:%d since block data size mismatch, expected: %u, actual: %u, fname:%s",
×
330
              TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, __LINE__, buffer->size, br.offset,
331
              reader->fd[TSDB_FTYPE_DATA]->path);
332
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
333
  }
334

335
_exit:
598,946 ✔
336
  if (code) {
598,946 ✔
337
    tsdbError("vgId:%d %s fid %d failed at %s:%d since %s", TD_VID(reader->config->tsdb->pVnode), __func__, fid,
×
338
              __FILE__, lino, tstrerror(code));
339
  }
340
  return code;
598,946 ✔
341
}
342

343
int32_t tsdbDataFileReadBlockDataByColumn(SDataFileReader *reader, const SBrinRecord *record, SBlockData *bData,
4,067,292 ✔
344
                                          STSchema *pTSchema, int16_t cids[], int32_t ncid) {
345
  int32_t code = 0;
4,067,292 ✔
346
  int32_t lino = 0;
4,067,292 ✔
347
  int32_t fid = reader->config->files[TSDB_FTYPE_DATA].file.fid;
4,067,115 ✔
348

349
  SDiskDataHdr hdr;
4,067,115 ✔
350
  SBuffer     *buffer0 = reader->buffers + 0;
4,067,369 ✔
351
  SBuffer     *buffer1 = reader->buffers + 1;
4,067,369 ✔
352
  SBuffer     *assist = reader->buffers + 2;
4,067,369 ✔
353

354
  SEncryptData *pEncryptData = &(reader->config->tsdb->pVnode->config.tsdbCfg.encryptData);
4,067,369 ✔
355

356
  // load key part
357
  tBufferClear(buffer0);
×
358
  TAOS_CHECK_GOTO(tsdbReadFileToBuffer(reader->fd[TSDB_FTYPE_DATA], record->blockOffset, record->blockKeySize, buffer0,
4,067,369 ✔
359
                                       0, pEncryptData),
360
                  &lino, _exit);
361

362
  // SDiskDataHdr
363
  SBufferReader br = BUFFER_READER_INITIALIZER(0, buffer0);
4,068,777 ✔
364
  TAOS_CHECK_GOTO(tGetDiskDataHdr(&br, &hdr), &lino, _exit);
4,068,777 ✔
365

366
  if (hdr.delimiter != TSDB_FILE_DLMT) {
4,068,531 ✔
367
    tsdbError("vgId:%d %s failed at %s:%d since disk data header delimiter is invalid, fname:%s",
×
368
              TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, __LINE__, reader->fd[TSDB_FTYPE_DATA]->path);
369
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
370
  }
371

372
  tBlockDataReset(bData);
4,068,531 ✔
373
  bData->suid = hdr.suid;
4,068,885 ✔
374
  bData->uid = hdr.uid;
4,068,885 ✔
375
  bData->nRow = hdr.nRow;
4,068,885 ✔
376

377
  // Key part
378
  TAOS_CHECK_GOTO(tBlockDataDecompressKeyPart(&hdr, &br, bData, assist), &lino, _exit);
4,068,885 ✔
379
  if (br.offset != buffer0->size) {
4,068,177 ✔
380
    tsdbError("vgId:%d %s failed at %s:%d since key part size mismatch, expected: %u, actual: %u, fname:%s",
×
381
              TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, __LINE__, buffer0->size, br.offset,
382
              reader->fd[TSDB_FTYPE_DATA]->path);
383
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
384
  }
385

386
  int extraColIdx = -1;
4,068,177 ✔
387
  for (int i = 0; i < ncid; i++) {
4,072,233 ✔
388
    if (tBlockDataGetColData(bData, cids[i]) == NULL) {
3,617,492 ✔
389
      extraColIdx = i;
3,613,082 ✔
390
      break;
3,613,082 ✔
391
    }
392
  }
393

394
  if (extraColIdx < 0) {
4,067,823 ✔
395
    goto _exit;
455,095 ✔
396
  }
397

398
  // load SBlockCol part
399
  tBufferClear(buffer0);
×
400
  TAOS_CHECK_GOTO(tsdbReadFileToBuffer(reader->fd[TSDB_FTYPE_DATA], record->blockOffset + record->blockKeySize,
3,612,728 ✔
401
                                       hdr.szBlkCol, buffer0, 0, pEncryptData),
402
                  &lino, _exit);
403

404
  // calc szHint
405
  int64_t szHint = 0;
3,612,905 ✔
406
  int     extraCols = 1;
3,612,905 ✔
407
  for (int i = extraColIdx + 1; i < ncid; ++i) {
3,612,905 ✔
408
    if (tBlockDataGetColData(bData, cids[i]) == NULL) {
1,816,865 ✔
409
      ++extraCols;
1,817,042 ✔
410
      break;
1,817,042 ✔
411
    }
412
  }
413

414
  if (extraCols >= 2) {
3,613,082 ✔
415
    br = BUFFER_READER_INITIALIZER(0, buffer0);
1,817,573 ✔
416

417
    SBlockCol blockCol = {.cid = 0};
1,817,573 ✔
418
    for (int32_t i = extraColIdx; i < ncid; ++i) {
1,817,573 ✔
419
      int16_t extraColCid = cids[i];
1,815,626 ✔
420

421
      while (extraColCid > blockCol.cid) {
5,767,709 ✔
422
        if (br.offset >= buffer0->size) {
3,949,782 ✔
423
          blockCol.cid = INT16_MAX;
×
424
          break;
×
425
        }
426

427
        TAOS_CHECK_GOTO(tGetBlockCol(&br, &blockCol, hdr.fmtVer, hdr.cmprAlg), &lino, _exit);
3,949,782 ✔
428
      }
429

430
      if (extraColCid == blockCol.cid || blockCol.cid == INT16_MAX) {
1,817,927 ✔
431
        extraColIdx = i;
1,817,927 ✔
432
        break;
1,817,927 ✔
433
      }
434
    }
435

436
    if (blockCol.cid > 0 && blockCol.cid < INT16_MAX /*&& blockCol->flag == HAS_VALUE*/) {
1,819,874 ✔
437
      int64_t   offset = blockCol.offset;
1,818,104 ✔
438
      SBlockCol lastNonNoneBlockCol = {.cid = 0};
1,818,104 ✔
439

440
      for (int32_t i = extraColIdx; i < ncid; ++i) {
8,778,193 ✔
441
        int16_t extraColCid = cids[i];
6,961,328 ✔
442

443
        while (extraColCid > blockCol.cid) {
18,994,025 ✔
444
          if (br.offset >= buffer0->size) {
12,033,936 ✔
445
            blockCol.cid = INT16_MAX;
×
446
            break;
×
447
          }
448

449
          TAOS_CHECK_GOTO(tGetBlockCol(&br, &blockCol, hdr.fmtVer, hdr.cmprAlg), &lino, _exit);
12,033,936 ✔
450
        }
451

452
        if (extraColCid == blockCol.cid) {
6,960,089 ✔
453
          lastNonNoneBlockCol = blockCol;
6,961,505 ✔
454
          continue;
6,961,505 ✔
455
        }
456

457
        if (blockCol.cid == INT16_MAX) {
×
458
          break;
×
459
        }
460
      }
461

462
      if (lastNonNoneBlockCol.cid > 0) {
1,816,865 ✔
463
        szHint = lastNonNoneBlockCol.offset + lastNonNoneBlockCol.szBitmap + lastNonNoneBlockCol.szOffset +
1,818,104 ✔
464
                 lastNonNoneBlockCol.szValue - offset;
1,818,104 ✔
465
      }
466
    }
467
  }
468

469
  // load each column
470
  SBlockCol blockCol = {
3,613,613 ✔
471
      .cid = 0,
472
  };
473
  bool firstRead = true;
3,613,790 ✔
474
  br = BUFFER_READER_INITIALIZER(0, buffer0);
3,613,790 ✔
475
  for (int32_t i = 0; i < ncid; i++) {
12,370,627 ✔
476
    int16_t cid = cids[i];
8,757,014 ✔
477

478
    if (tBlockDataGetColData(bData, cid)) {  // already loaded
8,757,014 ✔
479
      continue;
×
480
    }
481

482
    while (cid > blockCol.cid) {
31,095,612 ✔
483
      if (br.offset >= buffer0->size) {
22,337,359 ✔
484
        blockCol.cid = INT16_MAX;
×
485
        break;
×
486
      }
487

488
      TAOS_CHECK_GOTO(tGetBlockCol(&br, &blockCol, hdr.fmtVer, hdr.cmprAlg), &lino, _exit);
22,337,359 ✔
489
    }
490

491
    if (cid < blockCol.cid) {
8,758,253 ✔
492
      const STColumn *tcol = tTSchemaSearchColumn(pTSchema, cid);
×
493
      TSDB_CHECK_NULL(tcol, code, lino, _exit, TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER);
×
494
      SBlockCol none = {
×
495
          .cid = cid,
496
          .type = tcol->type,
×
497
          .cflag = tcol->flags,
×
498
          .flag = HAS_NONE,
499
          .szOrigin = 0,
500
          .szBitmap = 0,
501
          .szOffset = 0,
502
          .szValue = 0,
503
          .offset = 0,
504
      };
505
      TAOS_CHECK_GOTO(tBlockDataDecompressColData(&hdr, &none, &br, bData, assist), &lino, _exit);
×
506
    } else if (cid == blockCol.cid) {
8,758,253 ✔
507
      SEncryptData *pEncryptData = &(reader->config->tsdb->pVnode->config.tsdbCfg.encryptData);
8,756,660 ✔
508

509
      // load from file
510
      tBufferClear(buffer1);
×
511
      TAOS_CHECK_GOTO(tsdbReadFileToBuffer(reader->fd[TSDB_FTYPE_DATA],
8,756,660 ✔
512
                                           record->blockOffset + record->blockKeySize + hdr.szBlkCol + blockCol.offset,
513
                                           blockCol.szBitmap + blockCol.szOffset + blockCol.szValue, buffer1,
514
                                           firstRead ? szHint : 0, pEncryptData),
515
                      &lino, _exit);
516

517
      firstRead = false;
8,757,545 ✔
518

519
      // decode the buffer
520
      SBufferReader br1 = BUFFER_READER_INITIALIZER(0, buffer1);
8,757,545 ✔
521
      TAOS_CHECK_GOTO(tBlockDataDecompressColData(&hdr, &blockCol, &br1, bData, assist), &lino, _exit);
8,757,545 ✔
522
    }
523
  }
524

525
_exit:
4,070,301 ✔
526
  if (code) {
4,068,885 ✔
527
    tsdbError("vgId:%d %s fid:%d failed at %s:%d since %s", TD_VID(reader->config->tsdb->pVnode), __func__, fid,
×
528
              __FILE__, lino, tstrerror(code));
529
  }
530
  return code;
4,068,885 ✔
531
}
532

533
int32_t tsdbDataFileReadBlockSma(SDataFileReader *reader, const SBrinRecord *record,
4,311,526 ✔
534
                                 TColumnDataAggArray *columnDataAggArray) {
535
  int32_t  code = 0;
4,311,526 ✔
536
  int32_t  lino = 0;
4,311,526 ✔
537
  SBuffer *buffer = reader->buffers + 0;
4,311,526 ✔
538

539
  TARRAY2_CLEAR(columnDataAggArray, NULL);
4,311,526 ✔
540
  if (record->smaSize > 0) {
4,311,526 ✔
541
    tBufferClear(buffer);
×
542
    SEncryptData *pEncryptData = &(reader->config->tsdb->pVnode->config.tsdbCfg.encryptData);
4,311,495 ✔
543

544
    TAOS_CHECK_GOTO(
4,311,495 ✔
545
        tsdbReadFileToBuffer(reader->fd[TSDB_FTYPE_SMA], record->smaOffset, record->smaSize, buffer, 0, pEncryptData),
546
        &lino, _exit);
547

548
    // decode sma data
549
    SBufferReader br = BUFFER_READER_INITIALIZER(0, buffer);
4,311,911 ✔
550
    while (br.offset < record->smaSize) {
38,991,118 ✔
551
      SColumnDataAgg sma[1];
34,674,778 ✔
552

553
      TAOS_CHECK_GOTO(tGetColumnDataAgg(&br, sma), &lino, _exit);
34,675,207 ✔
554
      TAOS_CHECK_GOTO(TARRAY2_APPEND_PTR(columnDataAggArray, sma), &lino, _exit);
69,351,697 ✔
555
    }
556
    if (br.offset != record->smaSize) {
4,316,340 ✔
557
      tsdbError("vgId:%d %s failed at %s:%d since sma data size mismatch, expected: %u, actual: %u, fname:%s",
×
558
                TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, __LINE__, record->smaSize, br.offset,
559
                reader->fd[TSDB_FTYPE_SMA]->path);
560
      TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
×
561
    }
562
  }
563

564
_exit:
4,311,942 ✔
565
  if (code) {
4,311,911 ✔
566
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, lino,
×
567
              tstrerror(code));
568
  }
569
  return code;
4,311,911 ✔
570
}
571

572
int32_t tsdbDataFileReadTombBlk(SDataFileReader *reader, const TTombBlkArray **tombBlkArray) {
1,577,715 ✔
573
  int32_t code = 0;
1,577,715 ✔
574
  int32_t lino = 0;
1,577,715 ✔
575
  void   *data = NULL;
1,577,715 ✔
576

577
  if (!reader->ctx->tombBlkLoaded) {
1,577,715 ✔
578
    TAOS_CHECK_GOTO(tsdbDataFileReadTombFooter(reader), &lino, _exit);
896,263 ✔
579

580
    if (reader->tombFooter->tombBlkPtr->size > 0) {
896,263 ✔
581
      if ((data = taosMemoryMalloc(reader->tombFooter->tombBlkPtr->size)) == NULL) {
865,328 ✔
582
        TAOS_CHECK_GOTO(terrno, &lino, _exit);
×
583
      }
584

585
      SEncryptData *pEncryptData = &(reader->config->tsdb->pVnode->config.tsdbCfg.encryptData);
865,328 ✔
586

587
      TAOS_CHECK_GOTO(tsdbReadFile(reader->fd[TSDB_FTYPE_TOMB], reader->tombFooter->tombBlkPtr->offset, data,
865,328 ✔
588
                                   reader->tombFooter->tombBlkPtr->size, 0, pEncryptData),
589
                      &lino, _exit);
590

591
      int32_t size = reader->tombFooter->tombBlkPtr->size / sizeof(STombBlk);
865,328 ✔
592
      TARRAY2_INIT_EX(reader->tombBlkArray, size, size, data);
865,328 ✔
593
    } else {
594
      TARRAY2_INIT(reader->tombBlkArray);
30,935 ✔
595
    }
596

597
    reader->ctx->tombBlkLoaded = true;
896,263 ✔
598
  }
599
  tombBlkArray[0] = reader->tombBlkArray;
1,577,715 ✔
600

601
_exit:
1,577,715 ✔
602
  if (code) {
1,577,715 ✔
603
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, lino,
×
604
              tstrerror(code));
605
    taosMemoryFree(data);
×
606
  }
607
  return code;
1,577,715 ✔
608
}
609

610
int32_t tsdbDataFileReadTombBlock(SDataFileReader *reader, const STombBlk *tombBlk, STombBlock *tData) {
935,717 ✔
611
  int32_t code = 0;
935,717 ✔
612
  int32_t lino = 0;
935,717 ✔
613

614
  SBuffer *buffer0 = reader->buffers + 0;
935,717 ✔
615
  SBuffer *assist = reader->buffers + 1;
935,717 ✔
616

617
  tBufferClear(buffer0);
×
618
  SEncryptData *pEncryptData = &(reader->config->tsdb->pVnode->config.tsdbCfg.encryptData);
935,717 ✔
619

620
  TAOS_CHECK_GOTO(tsdbReadFileToBuffer(reader->fd[TSDB_FTYPE_TOMB], tombBlk->dp->offset, tombBlk->dp->size, buffer0, 0,
935,717 ✔
621
                                       pEncryptData),
622
                  &lino, _exit);
623

624
  int32_t       size = 0;
935,717 ✔
625
  SBufferReader br = BUFFER_READER_INITIALIZER(0, buffer0);
935,717 ✔
626
  tTombBlockClear(tData);
935,717 ✔
627
  tData->numOfRecords = tombBlk->numRec;
935,717 ✔
628
  for (int32_t i = 0; i < ARRAY_SIZE(tData->buffers); ++i) {
5,614,302 ✔
629
    SCompressInfo cinfo = {
4,678,585 ✔
630
        .cmprAlg = tombBlk->cmprAlg,
4,678,585 ✔
631
        .dataType = TSDB_DATA_TYPE_BIGINT,
632
        .originalSize = tombBlk->numRec * sizeof(int64_t),
4,678,585 ✔
633
        .compressedSize = tombBlk->size[i],
4,678,585 ✔
634
    };
635
    TAOS_CHECK_GOTO(tDecompressDataToBuffer(BR_PTR(&br), &cinfo, tData->buffers + i, assist), &lino, _exit);
4,678,585 ✔
636
    br.offset += tombBlk->size[i];
4,678,585 ✔
637
  }
638

639
_exit:
935,717 ✔
640
  if (code) {
935,717 ✔
641
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(reader->config->tsdb->pVnode), __func__, __FILE__, lino,
×
642
              tstrerror(code));
643
  }
644
  return code;
935,717 ✔
645
}
646

647
// SDataFileWriter =============================================
648
struct SDataFileWriter {
649
  SDataFileWriterConfig config[1];
650

651
  SSkmInfo skmTb[1];
652
  SSkmInfo skmRow[1];
653
  SBuffer  local[10];
654
  SBuffer *buffers;
655

656
  struct {
657
    bool             opened;
658
    SDataFileReader *reader;
659

660
    // for ts data
661
    TABLEID tbid[1];
662
    bool    tbHasOldData;
663

664
    const TBrinBlkArray *brinBlkArray;
665
    int32_t              brinBlkArrayIdx;
666
    SBrinBlock           brinBlock[1];
667
    int32_t              brinBlockIdx;
668
    SBlockData           blockData[1];
669
    int32_t              blockDataIdx;
670
    // for tomb data
671
    bool                 hasOldTomb;
672
    const TTombBlkArray *tombBlkArray;
673
    int32_t              tombBlkArrayIdx;
674
    STombBlock           tombBlock[1];
675
    int32_t              tombBlockIdx;
676
    // range
677
    SVersionRange range;
678
    SVersionRange tombRange;
679
  } ctx[1];
680

681
  STFile   files[TSDB_FTYPE_MAX];
682
  STsdbFD *fd[TSDB_FTYPE_MAX];
683

684
  SHeadFooter headFooter[1];
685
  STombFooter tombFooter[1];
686

687
  TBrinBlkArray brinBlkArray[1];
688
  SBrinBlock    brinBlock[1];
689
  SBlockData    blockData[1];
690

691
  TTombBlkArray tombBlkArray[1];
692
  STombBlock    tombBlock[1];
693
};
694

695
static int32_t tsdbDataFileWriterCloseAbort(SDataFileWriter *writer) {
×
696
  tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, __LINE__,
×
697
            "not implemented");
698
  return 0;
×
699
}
700

701
static void tsdbDataFileWriterDoClose(SDataFileWriter *writer) {
150,724 ✔
702
  if (writer->ctx->reader) {
150,724 ✔
703
    tsdbDataFileReaderClose(&writer->ctx->reader);
87,010 ✔
704
  }
705

706
  tTombBlockDestroy(writer->tombBlock);
150,939 ✔
707
  TARRAY2_DESTROY(writer->tombBlkArray, NULL);
150,509 ✔
708
  tBlockDataDestroy(writer->blockData);
150,509 ✔
709
  tBrinBlockDestroy(writer->brinBlock);
150,724 ✔
710
  TARRAY2_DESTROY(writer->brinBlkArray, NULL);
150,723 ✔
711

712
  tTombBlockDestroy(writer->ctx->tombBlock);
150,510 ✔
713
  tBlockDataDestroy(writer->ctx->blockData);
150,509 ✔
714
  tBrinBlockDestroy(writer->ctx->brinBlock);
150,724 ✔
715

716
  for (int32_t i = 0; i < ARRAY_SIZE(writer->local); ++i) {
1,660,104 ✔
717
    tBufferDestroy(writer->local + i);
1,509,166 ✔
718
  }
719

720
  tDestroyTSchema(writer->skmRow->pTSchema);
150,938 ✔
721
  tDestroyTSchema(writer->skmTb->pTSchema);
150,938 ✔
722
}
150,938 ✔
723

724
static int32_t tsdbDataFileWriterDoOpenReader(SDataFileWriter *writer) {
150,938 ✔
725
  int32_t code = 0;
150,938 ✔
726
  int32_t lino = 0;
150,938 ✔
727

728
  for (int32_t i = 0; i < TSDB_FTYPE_MAX; ++i) {
485,077 ✔
729
    if (writer->config->files[i].exist) {
421,364 ✔
730
      SDataFileReaderConfig config[1] = {{
87,225 ✔
731
          .tsdb = writer->config->tsdb,
87,225 ✔
732
          .szPage = writer->config->szPage,
87,225 ✔
733
          .buffers = writer->buffers,
87,225 ✔
734
      }};
735

736
      for (int32_t i = 0; i < TSDB_FTYPE_MAX; ++i) {
436,125 ✔
737
        config->files[i].exist = writer->config->files[i].exist;
348,900 ✔
738
        if (config->files[i].exist) {
348,900 ✔
739
          config->files[i].file = writer->config->files[i].file;
208,817 ✔
740
        }
741
      }
742

743
      TAOS_CHECK_GOTO(tsdbDataFileReaderOpen(NULL, config, &writer->ctx->reader), &lino, _exit);
87,225 ✔
744
      break;
87,225 ✔
745
    }
746
  }
747

748
_exit:
150,938 ✔
749
  if (code) {
150,938 ✔
750
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
751
              tstrerror(code));
752
  }
753
  return code;
150,938 ✔
754
}
755

756
static int32_t tsdbDataFileWriterDoOpen(SDataFileWriter *writer) {
150,938 ✔
757
  int32_t code = 0;
150,938 ✔
758
  int32_t lino = 0;
150,938 ✔
759
  int32_t ftype;
×
760
  SDiskID diskId = {0};
150,938 ✔
761

762
  if (!writer->config->skmTb) writer->config->skmTb = writer->skmTb;
150,938 ✔
763
  if (!writer->config->skmRow) writer->config->skmRow = writer->skmRow;
150,938 ✔
764
  writer->buffers = writer->config->buffers;
150,938 ✔
765
  if (writer->buffers == NULL) {
150,938 ✔
766
    writer->buffers = writer->local;
×
767
  }
768

769
  // open reader
770
  TAOS_CHECK_GOTO(tsdbDataFileWriterDoOpenReader(writer), &lino, _exit);
150,938 ✔
771

772
  // .head
773
  ftype = TSDB_FTYPE_HEAD;
150,938 ✔
774
  code = tsdbAllocateDisk(writer->config->tsdb, tsdbFTypeLabel(ftype), writer->config->expLevel, &diskId);
150,938 ✔
775
  TSDB_CHECK_CODE(code, lino, _exit);
150,938 ✔
776
  writer->files[ftype] = (STFile){
150,938 ✔
777
      .type = ftype,
778
      .did = diskId,
779
      .fid = writer->config->fid,
150,938 ✔
780
      .cid = writer->config->cid,
150,938 ✔
781
      .size = 0,
782
      .minVer = VERSION_MAX,
783
      .maxVer = VERSION_MIN,
784
  };
785

786
  // .data
787
  ftype = TSDB_FTYPE_DATA;
150,938 ✔
788
  if (writer->config->files[ftype].exist) {
150,938 ✔
789
    writer->files[ftype] = writer->config->files[ftype].file;
60,796 ✔
790
  } else {
791
    code = tsdbAllocateDisk(writer->config->tsdb, tsdbFTypeLabel(ftype), writer->config->expLevel, &diskId);
90,142 ✔
792
    TSDB_CHECK_CODE(code, lino, _exit);
90,142 ✔
793
    writer->files[ftype] = (STFile){
180,284 ✔
794
        .type = ftype,
795
        .did = diskId,
796
        .fid = writer->config->fid,
90,142 ✔
797
        .cid = writer->config->cid,
90,142 ✔
798
        .size = 0,
799
        .lcn = writer->config->lcn == 0 ? -1 : 0,
90,142 ✔
800
        .minVer = VERSION_MAX,
801
        .maxVer = VERSION_MIN,
802
    };
803
  }
804

805
  // .sma
806
  ftype = TSDB_FTYPE_SMA;
150,938 ✔
807
  if (writer->config->files[ftype].exist) {
150,938 ✔
808
    writer->files[ftype] = writer->config->files[ftype].file;
60,796 ✔
809
  } else {
810
    code = tsdbAllocateDisk(writer->config->tsdb, tsdbFTypeLabel(ftype), writer->config->expLevel, &diskId);
90,142 ✔
811
    TSDB_CHECK_CODE(code, lino, _exit);
90,142 ✔
812
    writer->files[ftype] = (STFile){
90,142 ✔
813
        .type = ftype,
814
        .did = diskId,
815
        .fid = writer->config->fid,
90,142 ✔
816
        .cid = writer->config->cid,
90,142 ✔
817
        .size = 0,
818
        .minVer = VERSION_MAX,
819
        .maxVer = VERSION_MIN,
820
    };
821
  }
822

823
  // .tomb
824
  ftype = TSDB_FTYPE_TOMB;
150,938 ✔
825
  code = tsdbAllocateDisk(writer->config->tsdb, tsdbFTypeLabel(ftype), writer->config->expLevel, &diskId);
150,938 ✔
826
  TSDB_CHECK_CODE(code, lino, _exit);
150,938 ✔
827
  writer->files[ftype] = (STFile){
150,938 ✔
828
      .type = ftype,
829
      .did = diskId,
830
      .fid = writer->config->fid,
150,938 ✔
831
      .cid = writer->config->cid,
150,938 ✔
832
      .size = 0,
833
      .minVer = VERSION_MAX,
834
      .maxVer = VERSION_MIN,
835
  };
836

837
  // range
838
  writer->ctx->range = (SVersionRange){.minVer = VERSION_MAX, .maxVer = VERSION_MIN};
150,938 ✔
839
  writer->ctx->tombRange = (SVersionRange){.minVer = VERSION_MAX, .maxVer = VERSION_MIN};
150,938 ✔
840

841
  writer->ctx->opened = true;
150,938 ✔
842

843
_exit:
150,938 ✔
844
  if (code) {
150,938 ✔
845
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
846
              tstrerror(code));
847
  }
848
  return code;
150,938 ✔
849
}
850

851
void tsdbWriterUpdVerRange(SVersionRange *range, int64_t minVer, int64_t maxVer) {
13,954,594 ✔
852
  range->minVer = TMIN(range->minVer, minVer);
13,954,594 ✔
853
  range->maxVer = TMAX(range->maxVer, maxVer);
13,954,594 ✔
854
}
13,954,594 ✔
855

856
int32_t tsdbFileWriteBrinBlock(STsdbFD *fd, SBrinBlock *brinBlock, uint32_t cmprAlg, int64_t *fileSize,
134,731 ✔
857
                               TBrinBlkArray *brinBlkArray, SBuffer *buffers, SVersionRange *range,
858
                               SEncryptData *encryptData) {
859
  if (brinBlock->numOfRecords == 0) {
134,731 ✔
860
    return 0;
×
861
  }
862

863
  int32_t  code;
×
864
  SBuffer *buffer0 = buffers + 0;
134,731 ✔
865
  SBuffer *buffer1 = buffers + 1;
134,731 ✔
866
  SBuffer *assist = buffers + 2;
134,731 ✔
867

868
  SBrinBlk brinBlk = {
134,731 ✔
869
      .dp[0] =
870
          {
871
              .offset = *fileSize,
134,731 ✔
872
              .size = 0,
873
          },
874
      .numRec = brinBlock->numOfRecords,
134,731 ✔
875
      .numOfPKs = brinBlock->numOfPKs,
134,731 ✔
876
      .cmprAlg = cmprAlg,
877
  };
878
  for (int i = 0; i < brinBlock->numOfRecords; i++) {
7,749,592 ✔
879
    SBrinRecord record;
7,614,861 ✔
880

881
    TAOS_CHECK_RETURN(tBrinBlockGet(brinBlock, i, &record));
7,614,861 ✔
882
    if (i == 0) {
7,614,861 ✔
883
      brinBlk.minTbid.suid = record.suid;
134,731 ✔
884
      brinBlk.minTbid.uid = record.uid;
134,731 ✔
885
      brinBlk.minVer = record.minVer;
134,731 ✔
886
      brinBlk.maxVer = record.maxVer;
134,731 ✔
887
    }
888
    if (i == brinBlock->numOfRecords - 1) {
7,614,861 ✔
889
      brinBlk.maxTbid.suid = record.suid;
134,731 ✔
890
      brinBlk.maxTbid.uid = record.uid;
134,731 ✔
891
    }
892
    if (record.minVer < brinBlk.minVer) {
7,614,861 ✔
893
      brinBlk.minVer = record.minVer;
127,389 ✔
894
    }
895
    if (record.maxVer > brinBlk.maxVer) {
7,614,861 ✔
896
      brinBlk.maxVer = record.maxVer;
3,078,802 ✔
897
    }
898
  }
899

900
  tsdbWriterUpdVerRange(range, brinBlk.minVer, brinBlk.maxVer);
134,731 ✔
901

902
  // write to file
903
  for (int32_t i = 0; i < 10; ++i) {
1,482,041 ✔
904
    SCompressInfo info = {
1,347,310 ✔
905
        .cmprAlg = cmprAlg,
906
        .dataType = TSDB_DATA_TYPE_BIGINT,
907
        .originalSize = brinBlock->buffers[i].size,
1,347,310 ✔
908
    };
909

910
    tBufferClear(buffer0);
×
911
    TAOS_CHECK_RETURN(tCompressDataToBuffer(brinBlock->buffers[i].data, &info, buffer0, assist));
1,347,310 ✔
912
    TAOS_CHECK_RETURN(tsdbWriteFile(fd, *fileSize, buffer0->data, buffer0->size, encryptData));
1,347,310 ✔
913
    brinBlk.size[i] = info.compressedSize;
1,347,310 ✔
914
    brinBlk.dp->size += info.compressedSize;
1,347,310 ✔
915
    *fileSize += info.compressedSize;
1,347,310 ✔
916
  }
917
  for (int32_t i = 10; i < 15; ++i) {
808,386 ✔
918
    SCompressInfo info = {
673,655 ✔
919
        .cmprAlg = cmprAlg,
920
        .dataType = TSDB_DATA_TYPE_INT,
921
        .originalSize = brinBlock->buffers[i].size,
673,655 ✔
922
    };
923

924
    tBufferClear(buffer0);
×
925
    TAOS_CHECK_RETURN(tCompressDataToBuffer(brinBlock->buffers[i].data, &info, buffer0, assist));
673,655 ✔
926
    TAOS_CHECK_RETURN(tsdbWriteFile(fd, *fileSize, buffer0->data, buffer0->size, encryptData));
673,655 ✔
927
    brinBlk.size[i] = info.compressedSize;
673,655 ✔
928
    brinBlk.dp->size += info.compressedSize;
673,655 ✔
929
    *fileSize += info.compressedSize;
673,655 ✔
930
  }
931

932
  // write primary keys to file
933
  if (brinBlock->numOfPKs > 0) {
134,731 ✔
934
    tBufferClear(buffer0);
×
935
    tBufferClear(buffer1);
×
936

937
    // encode
938
    for (int i = 0; i < brinBlock->numOfPKs; i++) {
1,400 ✔
939
      SValueColumnCompressInfo info = {.cmprAlg = cmprAlg};
700 ✔
940
      TAOS_CHECK_RETURN(tValueColumnCompress(&brinBlock->firstKeyPKs[i], &info, buffer1, assist));
700 ✔
941
      TAOS_CHECK_RETURN(tValueColumnCompressInfoEncode(&info, buffer0));
700 ✔
942
    }
943
    for (int i = 0; i < brinBlock->numOfPKs; i++) {
1,400 ✔
944
      SValueColumnCompressInfo info = {.cmprAlg = cmprAlg};
700 ✔
945
      TAOS_CHECK_RETURN(tValueColumnCompress(&brinBlock->lastKeyPKs[i], &info, buffer1, assist));
700 ✔
946
      TAOS_CHECK_RETURN(tValueColumnCompressInfoEncode(&info, buffer0));
700 ✔
947
    }
948

949
    // write to file
950
    TAOS_CHECK_RETURN(tsdbWriteFile(fd, *fileSize, buffer0->data, buffer0->size, encryptData));
700 ✔
951
    *fileSize += buffer0->size;
700 ✔
952
    brinBlk.dp->size += buffer0->size;
700 ✔
953
    TAOS_CHECK_RETURN(tsdbWriteFile(fd, *fileSize, buffer1->data, buffer1->size, encryptData));
700 ✔
954
    *fileSize += buffer1->size;
700 ✔
955
    brinBlk.dp->size += buffer1->size;
700 ✔
956
  }
957

958
  // append to brinBlkArray
959
  TAOS_CHECK_RETURN(TARRAY2_APPEND_PTR(brinBlkArray, &brinBlk));
269,462 ✔
960

961
  tBrinBlockClear(brinBlock);
134,731 ✔
962

963
  return 0;
134,731 ✔
964
}
965

966
static int32_t tsdbDataFileWriteBrinBlock(SDataFileWriter *writer) {
134,731 ✔
967
  if (writer->brinBlock->numOfRecords == 0) {
134,731 ✔
968
    return 0;
×
969
  }
970

971
  int32_t code = 0;
134,731 ✔
972
  int32_t lino = 0;
134,731 ✔
973

974
  SEncryptData *pEncryptData = &(writer->config->tsdb->pVnode->config.tsdbCfg.encryptData);
134,731 ✔
975

976
  TAOS_CHECK_GOTO(tsdbFileWriteBrinBlock(writer->fd[TSDB_FTYPE_HEAD], writer->brinBlock, writer->config->cmprAlg,
134,731 ✔
977
                                         &writer->files[TSDB_FTYPE_HEAD].size, writer->brinBlkArray, writer->buffers,
978
                                         &writer->ctx->range, pEncryptData),
979
                  &lino, _exit);
980

981
_exit:
134,731 ✔
982
  if (code) {
134,731 ✔
983
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
984
              tstrerror(code));
985
  }
986
  return code;
134,731 ✔
987
}
988

989
static int32_t tsdbDataFileWriteBrinRecord(SDataFileWriter *writer, const SBrinRecord *record) {
7,614,182 ✔
990
  int32_t code = 0;
7,614,182 ✔
991
  int32_t lino = 0;
7,614,182 ✔
992

993
  for (;;) {
×
994
    code = tBrinBlockPut(writer->brinBlock, record);
7,614,182 ✔
995
    if (code == TSDB_CODE_INVALID_PARA) {
7,613,327 ✔
996
      // different records with different primary keys
997
      TAOS_CHECK_GOTO(tsdbDataFileWriteBrinBlock(writer), &lino, _exit);
×
998
      continue;
×
999
    } else {
1000
      TSDB_CHECK_CODE(code, lino, _exit);
7,613,896 ✔
1001
    }
1002
    break;
7,613,896 ✔
1003
  }
1004

1005
  if ((writer->brinBlock->numOfRecords) >= 256) {
7,613,896 ✔
1006
    TAOS_CHECK_GOTO(tsdbDataFileWriteBrinBlock(writer), &lino, _exit);
10,834 ✔
1007
  }
1008

1009
_exit:
7,613,896 ✔
1010
  if (code) {
7,614,478 ✔
1011
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1012
              tstrerror(code));
1013
  }
1014
  return code;
7,614,478 ✔
1015
}
1016

1017
static int32_t tsdbDataFileDoWriteBlockData(SDataFileWriter *writer, SBlockData *bData) {
9,167,846 ✔
1018
  if (bData->nRow == 0) {
9,167,846 ✔
1019
    return 0;
3,662,103 ✔
1020
  }
1021

1022
  if (!bData->uid) {
5,505,743 ✔
1023
    return TSDB_CODE_INVALID_PARA;
×
1024
  }
1025

1026
  int32_t  code = 0;
5,505,743 ✔
1027
  int32_t  lino = 0;
5,505,743 ✔
1028
  SBuffer *buffers = writer->buffers;
5,506,120 ✔
1029
  SBuffer *assist = writer->buffers + 4;
5,506,120 ✔
1030

1031
  SColCompressInfo cmprInfo = {.pColCmpr = NULL, .defaultCmprAlg = writer->config->cmprAlg};
5,506,120 ✔
1032

1033
  SBrinRecord record[1] = {{
5,506,025 ✔
1034
      .suid = bData->suid,
5,506,025 ✔
1035
      .uid = bData->uid,
5,506,025 ✔
1036
      .minVer = bData->aVersion[0],
5,506,025 ✔
1037
      .maxVer = bData->aVersion[0],
5,506,025 ✔
1038
      .blockOffset = writer->files[TSDB_FTYPE_DATA].size,
5,506,025 ✔
1039
      .smaOffset = writer->files[TSDB_FTYPE_SMA].size,
5,506,025 ✔
1040
      .blockSize = 0,
1041
      .blockKeySize = 0,
1042
      .smaSize = 0,
1043
      .numRow = bData->nRow,
5,506,025 ✔
1044
      .count = 1,
1045
  }};
1046

1047
  tsdbRowGetKey(&tsdbRowFromBlockData(bData, 0), &record->firstKey);
5,506,025 ✔
1048
  tsdbRowGetKey(&tsdbRowFromBlockData(bData, bData->nRow - 1), &record->lastKey);
5,506,222 ✔
1049

1050
  for (int32_t i = 1; i < bData->nRow; ++i) {
2,147,483,647 ✔
1051
    if (tsdbRowCompareWithoutVersion(&tsdbRowFromBlockData(bData, i - 1), &tsdbRowFromBlockData(bData, i)) != 0) {
2,147,483,647 ✔
1052
      record->count++;
2,147,483,647 ✔
1053
    }
1054
    if (bData->aVersion[i] < record->minVer) {
2,147,483,647 ✔
1055
      record->minVer = bData->aVersion[i];
1,684,874 ✔
1056
    }
1057
    if (bData->aVersion[i] > record->maxVer) {
2,147,483,647 ✔
1058
      record->maxVer = bData->aVersion[i];
36,496,399 ✔
1059
    }
1060
  }
1061

1062
  tsdbWriterUpdVerRange(&writer->ctx->range, record->minVer, record->maxVer);
5,506,564 ✔
1063

1064
  code = metaGetColCmpr(writer->config->tsdb->pVnode->pMeta, bData->suid != 0 ? bData->suid : bData->uid,
5,506,564 ✔
1065
                        &cmprInfo.pColCmpr);
1066
  if (code) {
5,506,564 ✔
1067
    tsdbWarn("vgId:%d failed to get column compress algrithm", TD_VID(writer->config->tsdb->pVnode));
×
1068
  }
1069

1070
  TAOS_CHECK_GOTO(tBlockDataCompress(bData, &cmprInfo, buffers, assist), &lino, _exit);
5,506,564 ✔
1071

1072
  record->blockKeySize = buffers[0].size + buffers[1].size;
5,505,557 ✔
1073
  record->blockSize = record->blockKeySize + buffers[2].size + buffers[3].size;
5,505,557 ✔
1074

1075
  SEncryptData *pEncryptData = &(writer->config->tsdb->pVnode->config.tsdbCfg.encryptData);
5,505,557 ✔
1076

1077
  for (int i = 0; i < 4; i++) {
27,526,261 ✔
1078
    TAOS_CHECK_GOTO(tsdbWriteFile(writer->fd[TSDB_FTYPE_DATA], writer->files[TSDB_FTYPE_DATA].size, buffers[i].data,
22,021,419 ✔
1079
                                  buffers[i].size, pEncryptData),
1080
                    &lino, _exit);
1081
    writer->files[TSDB_FTYPE_DATA].size += buffers[i].size;
22,020,704 ✔
1082
  }
1083

1084
  // to .sma file
1085
  tBufferClear(&buffers[0]);
×
1086
  for (int32_t i = 0; i < bData->nColData; ++i) {
36,539,447 ✔
1087
    SColData *colData = bData->aColData + i;
31,034,936 ✔
1088
    if ((colData->cflag & COL_SMA_ON) == 0 || ((colData->flag & HAS_VALUE) == 0)) continue;
31,034,936 ✔
1089

1090
    SColumnDataAgg sma[1] = {{.colId = colData->cid}};
29,654,283 ✔
1091
    tColDataCalcSMA[colData->type](colData, sma);
29,653,913 ✔
1092

1093
    TAOS_CHECK_GOTO(tPutColumnDataAgg(&buffers[0], sma), &lino, _exit);
29,654,709 ✔
1094
  }
1095
  record->smaSize = buffers[0].size;
5,504,511 ✔
1096

1097
  if (record->smaSize > 0) {
5,504,511 ✔
1098
    TAOS_CHECK_GOTO(
5,506,513 ✔
1099
        tsdbWriteFile(writer->fd[TSDB_FTYPE_SMA], record->smaOffset, buffers[0].data, record->smaSize, pEncryptData),
1100
        &lino, _exit);
1101
    writer->files[TSDB_FTYPE_SMA].size += record->smaSize;
5,505,784 ✔
1102
  }
1103

1104
  // append SBrinRecord
1105
  TAOS_CHECK_GOTO(tsdbDataFileWriteBrinRecord(writer, record), &lino, _exit);
5,503,782 ✔
1106

1107
  tBlockDataClear(bData);
5,505,523 ✔
1108

1109
_exit:
5,504,946 ✔
1110
  if (code) {
5,505,476 ✔
1111
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1112
              tstrerror(code));
1113
  }
1114
  taosHashCleanup(cmprInfo.pColCmpr);
5,505,476 ✔
1115
  return code;
5,504,308 ✔
1116
}
1117

1118
static int32_t tsdbDataFileDoWriteTSRow(SDataFileWriter *writer, TSDBROW *row) {
2,147,483,647 ✔
1119
  int32_t code = 0;
2,147,483,647 ✔
1120
  int32_t lino = 0;
2,147,483,647 ✔
1121

1122
  // update/append
1123
  if (row->type == TSDBROW_ROW_FMT) {
2,147,483,647 ✔
1124
    TAOS_CHECK_GOTO(
×
1125
        tsdbUpdateSkmRow(writer->config->tsdb, writer->ctx->tbid, TSDBROW_SVERSION(row), writer->config->skmRow), &lino,
1126
        _exit);
1127
  }
1128

1129
  if (TSDBROW_VERSION(row) <= writer->config->compactVersion  //
2,147,483,647 ✔
1130
      && writer->blockData->nRow > 0                          //
2,147,483,647 ✔
1131
      &&
2,147,483,647 ✔
1132
      tsdbRowCompareWithoutVersion(row, &tsdbRowFromBlockData(writer->blockData, writer->blockData->nRow - 1)) == 0  //
2,147,483,647 ✔
1133
  ) {
1134
    TAOS_CHECK_GOTO(tBlockDataUpdateRow(writer->blockData, row, writer->config->skmRow->pTSchema), &lino, _exit);
1,692,149,980 ✔
1135
  } else {
1136
    if (writer->blockData->nRow >= writer->config->maxRow) {
2,147,483,647 ✔
1137
      TAOS_CHECK_GOTO(tsdbDataFileDoWriteBlockData(writer, writer->blockData), &lino, _exit);
702,664 ✔
1138
    }
1139

1140
    TAOS_CHECK_GOTO(
2,147,483,647 ✔
1141
        tBlockDataAppendRow(writer->blockData, row, writer->config->skmRow->pTSchema, writer->ctx->tbid->uid), &lino,
1142
        _exit);
1143
  }
1144

1145
_exit:
2,147,483,647 ✔
1146
  if (code) {
2,147,483,647 ✔
1147
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1148
              tstrerror(code));
1149
  }
1150
  return code;
2,147,483,647 ✔
1151
}
1152

1153
static FORCE_INLINE int32_t tsdbRowKeyCmprNullAsLargest(const STsdbRowKey *key1, const STsdbRowKey *key2) {
×
1154
  if (key1 == NULL) {
2,147,483,647 ✔
1155
    return 1;
140,544 ✔
1156
  } else if (key2 == NULL) {
2,147,483,647 ✔
1157
    return -1;
1,510,652 ✔
1158
  } else {
1159
    return tsdbRowKeyCmpr(key1, key2);
2,147,483,647 ✔
1160
  }
1161
}
1162

1163
static int32_t tsdbDataFileDoWriteTableOldData(SDataFileWriter *writer, const STsdbRowKey *key) {
2,147,483,647 ✔
1164
  if (writer->ctx->tbHasOldData == false) {
2,147,483,647 ✔
1165
    return 0;
×
1166
  }
1167

1168
  int32_t     code = 0;
2,147,483,647 ✔
1169
  int32_t     lino = 0;
2,147,483,647 ✔
1170
  STsdbRowKey rowKey;
2,147,483,647 ✔
1171

1172
  for (;;) {
2,628 ✔
1173
    for (;;) {
1174
      // SBlockData
1175
      for (; writer->ctx->blockDataIdx < writer->ctx->blockData->nRow; writer->ctx->blockDataIdx++) {
2,147,483,647 ✔
1176
        TSDBROW row = tsdbRowFromBlockData(writer->ctx->blockData, writer->ctx->blockDataIdx);
2,147,483,647 ✔
1177

1178
        tsdbRowGetKey(&row, &rowKey);
2,147,483,647 ✔
1179
        if (tsdbRowKeyCmprNullAsLargest(&rowKey, key) < 0) {  // key <= rowKey
2,147,483,647 ✔
1180
          TAOS_CHECK_GOTO(tsdbDataFileDoWriteTSRow(writer, &row), &lino, _exit);
2,147,483,647 ✔
1181
        } else {
1182
          goto _exit;
2,147,483,647 ✔
1183
        }
1184
      }
1185

1186
      // SBrinBlock
1187
      if (writer->ctx->brinBlockIdx >= writer->ctx->brinBlock->numOfRecords) {
4,727,098 ✔
1188
        break;
44,820 ✔
1189
      }
1190

1191
      for (; writer->ctx->brinBlockIdx < writer->ctx->brinBlock->numOfRecords; writer->ctx->brinBlockIdx++) {
5,199,179 ✔
1192
        SBrinRecord record;
1,641,877 ✔
1193
        code = tBrinBlockGet(writer->ctx->brinBlock, writer->ctx->brinBlockIdx, &record);
1,641,877 ✔
1194
        TSDB_CHECK_CODE(code, lino, _exit);
1,641,877 ✔
1195
        if (record.uid != writer->ctx->tbid->uid) {
1,641,877 ✔
1196
          writer->ctx->tbHasOldData = false;
36,572 ✔
1197
          goto _exit;
36,572 ✔
1198
        }
1199

1200
        if (tsdbRowKeyCmprNullAsLargest(key, &record.firstKey) < 0) {  // key < record->firstKey
1,605,305 ✔
1201
          goto _exit;
515,664 ✔
1202
        } else {
1203
          SBrinRecord record[1];
1,089,641 ✔
1204
          code = tBrinBlockGet(writer->ctx->brinBlock, writer->ctx->brinBlockIdx, record);
1,089,641 ✔
1205
          TSDB_CHECK_CODE(code, lino, _exit);
1,089,641 ✔
1206
          if (tsdbRowKeyCmprNullAsLargest(key, &record->lastKey) > 0) {  // key > record->lastKey
1,089,641 ✔
1207
            if (writer->blockData->nRow > 0) {
516,901 ✔
1208
              TAOS_CHECK_GOTO(tsdbDataFileDoWriteBlockData(writer, writer->blockData), &lino, _exit);
288 ✔
1209
            }
1210

1211
            TAOS_CHECK_GOTO(tsdbDataFileWriteBrinRecord(writer, record), &lino, _exit);
516,901 ✔
1212
          } else {
1213
            TAOS_CHECK_GOTO(tsdbDataFileReadBlockData(writer->ctx->reader, record, writer->ctx->blockData), &lino,
572,740 ✔
1214
                            _exit);
1215

1216
            writer->ctx->blockDataIdx = 0;
572,740 ✔
1217
            writer->ctx->brinBlockIdx++;
572,740 ✔
1218
            break;
572,740 ✔
1219
          }
1220
        }
1221
      }
1222
    }
1223

1224
    // SBrinBlk
1225
    if (writer->ctx->brinBlkArrayIdx >= TARRAY2_SIZE(writer->ctx->brinBlkArray)) {
44,820 ✔
1226
      writer->ctx->brinBlkArray = NULL;
42,192 ✔
1227
      writer->ctx->tbHasOldData = false;
42,192 ✔
1228
      goto _exit;
42,192 ✔
1229
    } else {
1230
      const SBrinBlk *brinBlk = TARRAY2_GET_PTR(writer->ctx->brinBlkArray, writer->ctx->brinBlkArrayIdx);
2,628 ✔
1231

1232
      if (brinBlk->minTbid.uid != writer->ctx->tbid->uid) {
2,628 ✔
1233
        writer->ctx->tbHasOldData = false;
×
1234
        goto _exit;
×
1235
      }
1236

1237
      TAOS_CHECK_GOTO(tsdbDataFileReadBrinBlock(writer->ctx->reader, brinBlk, writer->ctx->brinBlock), &lino, _exit);
2,628 ✔
1238

1239
      writer->ctx->brinBlockIdx = 0;
2,628 ✔
1240
      writer->ctx->brinBlkArrayIdx++;
2,628 ✔
1241
    }
1242
  }
1243

1244
_exit:
2,147,483,647 ✔
1245
  if (code) {
2,147,483,647 ✔
1246
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1247
              tstrerror(code));
1248
  }
1249
  return code;
2,147,483,647 ✔
1250
}
1251

1252
static int32_t tsdbDataFileDoWriteTSData(SDataFileWriter *writer, TSDBROW *row) {
2,147,483,647 ✔
1253
  int32_t code = 0;
2,147,483,647 ✔
1254
  int32_t lino = 0;
2,147,483,647 ✔
1255

1256
  if (writer->ctx->tbHasOldData) {
2,147,483,647 ✔
1257
    STsdbRowKey key;
2,147,483,647 ✔
1258
    tsdbRowGetKey(row, &key);
2,147,483,647 ✔
1259
    TAOS_CHECK_GOTO(tsdbDataFileDoWriteTableOldData(writer, &key), &lino, _exit);
2,147,483,647 ✔
1260
  }
1261

1262
  TAOS_CHECK_GOTO(tsdbDataFileDoWriteTSRow(writer, row), &lino, _exit);
2,147,483,647 ✔
1263

1264
_exit:
2,147,483,647 ✔
1265
  if (code) {
2,147,483,647 ✔
1266
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1267
              tstrerror(code));
1268
  }
1269
  return code;
2,147,483,647 ✔
1270
}
1271

1272
static int32_t tsdbDataFileWriteTableDataEnd(SDataFileWriter *writer) {
3,897,612 ✔
1273
  if (writer->ctx->tbid->uid == 0) {
3,897,612 ✔
1274
    return 0;
123,897 ✔
1275
  }
1276

1277
  int32_t code = 0;
3,773,715 ✔
1278
  int32_t lino = 0;
3,773,715 ✔
1279

1280
  if (writer->ctx->tbHasOldData) {
3,773,715 ✔
1281
    TAOS_CHECK_GOTO(tsdbDataFileDoWriteTableOldData(writer, NULL /* as the largest key */), &lino, _exit);
22,588 ✔
1282
  }
1283

1284
  TAOS_CHECK_GOTO(tsdbDataFileDoWriteBlockData(writer, writer->blockData), &lino, _exit);
3,773,715 ✔
1285

1286
_exit:
3,774,006 ✔
1287
  if (code) {
3,774,006 ✔
1288
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1289
              tstrerror(code));
1290
  }
1291
  return code;
3,774,006 ✔
1292
}
1293

1294
static int32_t tsdbDataFileWriteTableDataBegin(SDataFileWriter *writer, const TABLEID *tbid) {
3,897,416 ✔
1295
  int32_t code = 0;
3,897,416 ✔
1296
  int32_t lino = 0;
3,897,416 ✔
1297

1298
  SMetaInfo info;
3,897,701 ✔
1299
  bool      drop = false;
3,897,701 ✔
1300
  TABLEID   tbid1[1];
3,897,701 ✔
1301
  writer->ctx->tbHasOldData = false;
3,897,903 ✔
1302
  while (writer->ctx->brinBlkArray) {  // skip data of previous table
3,958,855 ✔
1303
    for (; writer->ctx->brinBlockIdx < writer->ctx->brinBlock->numOfRecords; writer->ctx->brinBlockIdx++) {
2,408,467 ✔
1304
      SBrinRecord record;
2,328,911 ✔
1305
      TAOS_CHECK_GOTO(tBrinBlockGet(writer->ctx->brinBlock, writer->ctx->brinBlockIdx, &record), &lino, _exit);
2,328,911 ✔
1306

1307
      if (record.uid == tbid->uid) {
2,328,860 ✔
1308
        writer->ctx->tbHasOldData = true;
78,764 ✔
1309
        goto _begin;
78,764 ✔
1310
      } else if (record.suid > tbid->suid || (record.suid == tbid->suid && record.uid > tbid->uid)) {
2,250,096 ✔
1311
        goto _begin;
658,751 ✔
1312
      } else {
1313
        if (record.uid != writer->ctx->tbid->uid) {
1,591,345 ✔
1314
          if (drop && tbid1->uid == record.uid) {
1,091,976 ✔
1315
            continue;
×
1316
          } else if (metaGetInfo(writer->config->tsdb->pVnode->pMeta, record.uid, &info, NULL) != 0) {
1,091,976 ✔
1317
            drop = true;
×
1318
            tbid1->suid = record.suid;
×
1319
            tbid1->uid = record.uid;
×
1320
            continue;
×
1321
          } else {
1322
            drop = false;
1,091,976 ✔
1323
            writer->ctx->tbid->suid = record.suid;
1,091,976 ✔
1324
            writer->ctx->tbid->uid = record.uid;
1,091,976 ✔
1325
          }
1326
        }
1327

1328
        TAOS_CHECK_GOTO(tsdbDataFileWriteBrinRecord(writer, &record), &lino, _exit);
1,591,345 ✔
1329
      }
1330
    }
1331

1332
    if (writer->ctx->brinBlkArrayIdx >= TARRAY2_SIZE(writer->ctx->brinBlkArray)) {
79,556 ✔
1333
      writer->ctx->brinBlkArray = NULL;
18,604 ✔
1334
      break;
18,604 ✔
1335
    } else {
1336
      const SBrinBlk *brinBlk = TARRAY2_GET_PTR(writer->ctx->brinBlkArray, writer->ctx->brinBlkArrayIdx);
60,952 ✔
1337

1338
      TAOS_CHECK_GOTO(tsdbDataFileReadBrinBlock(writer->ctx->reader, brinBlk, writer->ctx->brinBlock), &lino, _exit);
60,952 ✔
1339

1340
      writer->ctx->brinBlockIdx = 0;
60,952 ✔
1341
      writer->ctx->brinBlkArrayIdx++;
60,952 ✔
1342
    }
1343
  }
1344

1345
_begin:
3,897,903 ✔
1346
  writer->ctx->tbid[0] = *tbid;
3,897,805 ✔
1347

1348
  if (tbid->uid == INT64_MAX) {
3,897,805 ✔
1349
    goto _exit;
123,897 ✔
1350
  }
1351

1352
  TAOS_CHECK_GOTO(tsdbUpdateSkmTb(writer->config->tsdb, tbid, writer->config->skmTb), &lino, _exit);
3,773,908 ✔
1353
  TAOS_CHECK_GOTO(tBlockDataInit(writer->blockData, writer->ctx->tbid, writer->config->skmTb->pTSchema, NULL, 0), &lino,
3,774,006 ✔
1354
                  _exit);
1355

1356
_exit:
3,897,808 ✔
1357
  if (code) {
3,897,710 ✔
1358
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1359
              tstrerror(code));
1360
  }
1361
  return code;
3,897,710 ✔
1362
}
1363

1364
int32_t tsdbFileWriteHeadFooter(STsdbFD *fd, int64_t *fileSize, const SHeadFooter *footer, SEncryptData *encryptData) {
123,897 ✔
1365
  TAOS_CHECK_RETURN(tsdbWriteFile(fd, *fileSize, (const uint8_t *)footer, sizeof(*footer), encryptData));
123,897 ✔
1366
  *fileSize += sizeof(*footer);
123,897 ✔
1367
  return 0;
123,897 ✔
1368
}
1369

1370
int32_t tsdbFileWriteTombBlock(STsdbFD *fd, STombBlock *tombBlock, int8_t cmprAlg, int64_t *fileSize,
415,579 ✔
1371
                               TTombBlkArray *tombBlkArray, SBuffer *buffers, SVersionRange *range,
1372
                               SEncryptData *encryptData) {
1373
  int32_t code;
×
1374

1375
  if (TOMB_BLOCK_SIZE(tombBlock) == 0) {
415,579 ✔
1376
    return 0;
×
1377
  }
1378

1379
  SBuffer *buffer0 = buffers + 0;
415,579 ✔
1380
  SBuffer *assist = buffers + 1;
415,579 ✔
1381

1382
  STombBlk tombBlk = {
415,579 ✔
1383
      .dp[0] =
1384
          {
1385
              .offset = *fileSize,
415,579 ✔
1386
              .size = 0,
1387
          },
1388
      .numRec = TOMB_BLOCK_SIZE(tombBlock),
415,579 ✔
1389
      .cmprAlg = cmprAlg,
1390
  };
1391
  for (int i = 0; i < TOMB_BLOCK_SIZE(tombBlock); i++) {
10,441,793 ✔
1392
    STombRecord record;
10,026,214 ✔
1393
    TAOS_CHECK_RETURN(tTombBlockGet(tombBlock, i, &record));
10,026,214 ✔
1394

1395
    if (i == 0) {
10,026,214 ✔
1396
      tombBlk.minTbid.suid = record.suid;
415,579 ✔
1397
      tombBlk.minTbid.uid = record.uid;
415,579 ✔
1398
      tombBlk.minVer = record.version;
415,579 ✔
1399
      tombBlk.maxVer = record.version;
415,579 ✔
1400
    }
1401
    if (i == TOMB_BLOCK_SIZE(tombBlock) - 1) {
10,026,214 ✔
1402
      tombBlk.maxTbid.suid = record.suid;
415,579 ✔
1403
      tombBlk.maxTbid.uid = record.uid;
415,579 ✔
1404
    }
1405
    if (record.version < tombBlk.minVer) {
10,026,214 ✔
1406
      tombBlk.minVer = record.version;
325,878 ✔
1407
    }
1408
    if (record.version > tombBlk.maxVer) {
10,026,214 ✔
1409
      tombBlk.maxVer = record.version;
933,990 ✔
1410
    }
1411
  }
1412

1413
  tsdbWriterUpdVerRange(range, tombBlk.minVer, tombBlk.maxVer);
415,579 ✔
1414

1415
  for (int32_t i = 0; i < ARRAY_SIZE(tombBlock->buffers); i++) {
2,493,474 ✔
1416
    tBufferClear(buffer0);
×
1417

1418
    SCompressInfo cinfo = {
2,077,895 ✔
1419
        .cmprAlg = cmprAlg,
1420
        .dataType = TSDB_DATA_TYPE_BIGINT,
1421
        .originalSize = tombBlock->buffers[i].size,
2,077,895 ✔
1422
    };
1423
    TAOS_CHECK_RETURN(tCompressDataToBuffer(tombBlock->buffers[i].data, &cinfo, buffer0, assist));
2,077,895 ✔
1424
    TAOS_CHECK_RETURN(tsdbWriteFile(fd, *fileSize, buffer0->data, buffer0->size, encryptData));
2,077,895 ✔
1425

1426
    tombBlk.size[i] = cinfo.compressedSize;
2,077,895 ✔
1427
    tombBlk.dp->size += tombBlk.size[i];
2,077,895 ✔
1428
    *fileSize += tombBlk.size[i];
2,077,895 ✔
1429
  }
1430

1431
  TAOS_CHECK_RETURN(TARRAY2_APPEND_PTR(tombBlkArray, &tombBlk));
831,158 ✔
1432

1433
  tTombBlockClear(tombBlock);
415,579 ✔
1434
  return 0;
415,579 ✔
1435
}
1436

1437
static int32_t tsdbDataFileWriteHeadFooter(SDataFileWriter *writer) {
123,897 ✔
1438
  int32_t code = 0;
123,897 ✔
1439
  int32_t lino = 0;
123,897 ✔
1440

1441
  SEncryptData *pEncryptData = &(writer->config->tsdb->pVnode->config.tsdbCfg.encryptData);
123,897 ✔
1442

1443
  TAOS_CHECK_GOTO(tsdbFileWriteHeadFooter(writer->fd[TSDB_FTYPE_HEAD], &writer->files[TSDB_FTYPE_HEAD].size,
123,897 ✔
1444
                                          writer->headFooter, pEncryptData),
1445
                  &lino, _exit);
1446

1447
_exit:
123,897 ✔
1448
  if (code) {
123,897 ✔
1449
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1450
              tstrerror(code));
1451
  }
1452
  return code;
123,897 ✔
1453
}
1454

1455
static int32_t tsdbDataFileDoWriteTombBlock(SDataFileWriter *writer) {
27,377 ✔
1456
  if (TOMB_BLOCK_SIZE(writer->tombBlock) == 0) return 0;
27,377 ✔
1457

1458
  int32_t code = 0;
27,377 ✔
1459
  int32_t lino = 0;
27,377 ✔
1460

1461
  SEncryptData *pEncryptData = &(writer->config->tsdb->pVnode->config.tsdbCfg.encryptData);
27,377 ✔
1462

1463
  TAOS_CHECK_GOTO(tsdbFileWriteTombBlock(writer->fd[TSDB_FTYPE_TOMB], writer->tombBlock, writer->config->cmprAlg,
27,377 ✔
1464
                                         &writer->files[TSDB_FTYPE_TOMB].size, writer->tombBlkArray, writer->buffers,
1465
                                         &writer->ctx->tombRange, pEncryptData),
1466
                  &lino, _exit);
1467

1468
_exit:
27,377 ✔
1469
  if (code) {
27,377 ✔
1470
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1471
              tstrerror(code));
1472
  }
1473
  return code;
27,377 ✔
1474
}
1475

1476
int32_t tsdbFileWriteTombBlk(STsdbFD *fd, const TTombBlkArray *tombBlkArray, SFDataPtr *ptr, int64_t *fileSize,
1,289,689 ✔
1477
                             SEncryptData *encryptData) {
1478
  ptr->size = TARRAY2_DATA_LEN(tombBlkArray);
1,289,689 ✔
1479
  if (ptr->size > 0) {
1,289,689 ✔
1480
    ptr->offset = *fileSize;
415,579 ✔
1481

1482
    TAOS_CHECK_RETURN(
415,579 ✔
1483
        tsdbWriteFile(fd, *fileSize, (const uint8_t *)TARRAY2_DATA(tombBlkArray), ptr->size, encryptData));
1484

1485
    *fileSize += ptr->size;
415,579 ✔
1486
  }
1487
  return 0;
1,288,733 ✔
1488
}
1489

1490
static int32_t tsdbDataFileDoWriteTombBlk(SDataFileWriter *writer) {
27,377 ✔
1491
  if (TARRAY2_SIZE(writer->tombBlkArray) <= 0) {
27,377 ✔
1492
    return TSDB_CODE_INVALID_PARA;
×
1493
  }
1494

1495
  int32_t code = 0;
27,377 ✔
1496
  int32_t lino = 0;
27,377 ✔
1497

1498
  SEncryptData *pEncryptData = &(writer->config->tsdb->pVnode->config.tsdbCfg.encryptData);
27,377 ✔
1499

1500
  TAOS_CHECK_GOTO(
27,377 ✔
1501
      tsdbFileWriteTombBlk(writer->fd[TSDB_FTYPE_TOMB], writer->tombBlkArray, writer->tombFooter->tombBlkPtr,
1502
                           &writer->files[TSDB_FTYPE_TOMB].size, pEncryptData),
1503
      &lino, _exit);
1504

1505
_exit:
27,377 ✔
1506
  if (code) {
27,377 ✔
1507
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1508
              tstrerror(code));
1509
  }
1510
  return code;
27,377 ✔
1511
}
1512

1513
int32_t tsdbFileWriteTombFooter(STsdbFD *fd, const STombFooter *footer, int64_t *fileSize, SEncryptData *encryptData) {
27,377 ✔
1514
  TAOS_CHECK_RETURN(tsdbWriteFile(fd, *fileSize, (const uint8_t *)footer, sizeof(*footer), encryptData));
27,377 ✔
1515
  *fileSize += sizeof(*footer);
27,377 ✔
1516
  return 0;
27,377 ✔
1517
}
1518

1519
static int32_t tsdbDataFileWriteTombFooter(SDataFileWriter *writer) {
27,377 ✔
1520
  int32_t code = 0;
27,377 ✔
1521
  int32_t lino = 0;
27,377 ✔
1522

1523
  SEncryptData *pEncryptData = &(writer->config->tsdb->pVnode->config.tsdbCfg.encryptData);
27,377 ✔
1524

1525
  TAOS_CHECK_GOTO(tsdbFileWriteTombFooter(writer->fd[TSDB_FTYPE_TOMB], writer->tombFooter,
27,377 ✔
1526
                                          &writer->files[TSDB_FTYPE_TOMB].size, pEncryptData),
1527
                  &lino, _exit);
1528

1529
_exit:
27,377 ✔
1530
  if (code) {
27,377 ✔
1531
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1532
              tstrerror(code));
1533
  }
1534
  return code;
27,377 ✔
1535
}
1536

1537
static int32_t tsdbDataFileDoWriteTombRecord(SDataFileWriter *writer, const STombRecord *record) {
121,829 ✔
1538
  int32_t code = 0;
121,829 ✔
1539
  int32_t lino = 0;
121,829 ✔
1540

1541
  while (writer->ctx->hasOldTomb) {
148,258 ✔
1542
    for (; writer->ctx->tombBlockIdx < TOMB_BLOCK_SIZE(writer->ctx->tombBlock); writer->ctx->tombBlockIdx++) {
8,528,178 ✔
1543
      STombRecord record1[1];
8,475,320 ✔
1544
      TAOS_CHECK_GOTO(tTombBlockGet(writer->ctx->tombBlock, writer->ctx->tombBlockIdx, record1), &lino, _exit);
8,475,320 ✔
1545

1546
      int32_t c = tTombRecordCompare(record, record1);
8,475,320 ✔
1547
      if (c < 0) {
8,475,320 ✔
1548
        goto _write;
88,375 ✔
1549
      } else if (c > 0) {
8,386,945 ✔
1550
        TAOS_CHECK_GOTO(tTombBlockPut(writer->tombBlock, record1), &lino, _exit);
8,386,945 ✔
1551

1552
        tsdbTrace("vgId:%d write tomb record to tomb file:%s, cid:%" PRId64 ", suid:%" PRId64 ", uid:%" PRId64
8,386,945 ✔
1553
                  ", version:%" PRId64,
1554
                  TD_VID(writer->config->tsdb->pVnode), writer->fd[TSDB_FTYPE_TOMB]->path, writer->config->cid,
1555
                  record1->suid, record1->uid, record1->version);
1556

1557
        if (TOMB_BLOCK_SIZE(writer->tombBlock) >= writer->config->maxRow) {
8,386,945 ✔
1558
          TAOS_CHECK_GOTO(tsdbDataFileDoWriteTombBlock(writer), &lino, _exit);
×
1559
        }
1560
      } else {
1561
        tsdbError("vgId:%d duplicate tomb record, cid:%" PRId64 ", suid:%" PRId64 ", uid:%" PRId64 ", version:%" PRId64,
×
1562
                  TD_VID(writer->config->tsdb->pVnode), writer->config->cid, record->suid, record->uid,
1563
                  record->version);
1564
      }
1565
    }
1566

1567
    if (writer->ctx->tombBlkArrayIdx >= TARRAY2_SIZE(writer->ctx->tombBlkArray)) {
52,858 ✔
1568
      writer->ctx->hasOldTomb = false;
26,429 ✔
1569
      break;
26,429 ✔
1570
    } else {
1571
      const STombBlk *tombBlk = TARRAY2_GET_PTR(writer->ctx->tombBlkArray, writer->ctx->tombBlkArrayIdx);
26,429 ✔
1572

1573
      TAOS_CHECK_GOTO(tsdbDataFileReadTombBlock(writer->ctx->reader, tombBlk, writer->ctx->tombBlock), &lino, _exit);
26,429 ✔
1574

1575
      writer->ctx->tombBlockIdx = 0;
26,429 ✔
1576
      writer->ctx->tombBlkArrayIdx++;
26,429 ✔
1577
    }
1578
  }
1579

1580
_write:
121,829 ✔
1581
  if (record->suid == INT64_MAX) {
121,829 ✔
1582
    goto _exit;
27,377 ✔
1583
  }
1584

1585
  TAOS_CHECK_GOTO(tTombBlockPut(writer->tombBlock, record), &lino, _exit);
94,452 ✔
1586

1587
  tsdbTrace("vgId:%d write tomb record to tomb file:%s, cid:%" PRId64 ", suid:%" PRId64 ", uid:%" PRId64
94,452 ✔
1588
            ", version:%" PRId64,
1589
            TD_VID(writer->config->tsdb->pVnode), writer->fd[TSDB_FTYPE_TOMB]->path, writer->config->cid, record->suid,
1590
            record->uid, record->version);
1591

1592
  if (TOMB_BLOCK_SIZE(writer->tombBlock) >= writer->config->maxRow) {
94,452 ✔
1593
    TAOS_CHECK_GOTO(tsdbDataFileDoWriteTombBlock(writer), &lino, _exit);
×
1594
  }
1595

1596
_exit:
121,829 ✔
1597
  if (code) {
121,829 ✔
1598
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1599
              tstrerror(code));
1600
  }
1601
  return code;
121,829 ✔
1602
}
1603

1604
int32_t tsdbFileWriteBrinBlk(STsdbFD *fd, TBrinBlkArray *brinBlkArray, SFDataPtr *ptr, int64_t *fileSize,
123,897 ✔
1605
                             SEncryptData *encryptData) {
1606
  if (TARRAY2_SIZE(brinBlkArray) <= 0) {
123,897 ✔
1607
    return TSDB_CODE_INVALID_PARA;
×
1608
  }
1609
  ptr->offset = *fileSize;
123,897 ✔
1610
  ptr->size = TARRAY2_DATA_LEN(brinBlkArray);
123,897 ✔
1611

1612
  TAOS_CHECK_RETURN(tsdbWriteFile(fd, ptr->offset, (uint8_t *)TARRAY2_DATA(brinBlkArray), ptr->size, encryptData));
123,897 ✔
1613

1614
  *fileSize += ptr->size;
123,897 ✔
1615
  return 0;
123,897 ✔
1616
}
1617

1618
static int32_t tsdbDataFileWriteBrinBlk(SDataFileWriter *writer) {
123,897 ✔
1619
  int32_t code = 0;
123,897 ✔
1620
  int32_t lino = 0;
123,897 ✔
1621

1622
  SEncryptData *pEncryptData = &(writer->config->tsdb->pVnode->config.tsdbCfg.encryptData);
123,897 ✔
1623

1624
  TAOS_CHECK_GOTO(
123,897 ✔
1625
      tsdbFileWriteBrinBlk(writer->fd[TSDB_FTYPE_HEAD], writer->brinBlkArray, writer->headFooter->brinBlkPtr,
1626
                           &writer->files[TSDB_FTYPE_HEAD].size, pEncryptData),
1627
      &lino, _exit);
1628

1629
_exit:
123,897 ✔
1630
  if (code) {
123,897 ✔
1631
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1632
              tstrerror(code));
1633
  }
1634
  return code;
123,897 ✔
1635
}
1636

1637
void tsdbTFileUpdVerRange(STFile *f, SVersionRange range) {
1,814,266 ✔
1638
  f->minVer = TMIN(f->minVer, range.minVer);
1,814,266 ✔
1639
  f->maxVer = TMAX(f->maxVer, range.maxVer);
1,814,266 ✔
1640
}
1,814,266 ✔
1641

1642
static int32_t tsdbDataFileWriterCloseCommit(SDataFileWriter *writer, TFileOpArray *opArr) {
150,938 ✔
1643
  int32_t code = 0;
150,938 ✔
1644
  int32_t lino = 0;
150,938 ✔
1645

1646
  int32_t  ftype;
×
1647
  STFileOp op;
150,938 ✔
1648

1649
  if (writer->fd[TSDB_FTYPE_HEAD]) {
150,938 ✔
1650
    TABLEID tbid[1] = {{
123,897 ✔
1651
        .suid = INT64_MAX,
1652
        .uid = INT64_MAX,
1653
    }};
1654

1655
    TAOS_CHECK_GOTO(tsdbDataFileWriteTableDataEnd(writer), &lino, _exit);
123,897 ✔
1656
    TAOS_CHECK_GOTO(tsdbDataFileWriteTableDataBegin(writer, tbid), &lino, _exit);
123,897 ✔
1657
    TAOS_CHECK_GOTO(tsdbDataFileWriteBrinBlock(writer), &lino, _exit);
123,897 ✔
1658
    TAOS_CHECK_GOTO(tsdbDataFileWriteBrinBlk(writer), &lino, _exit);
123,897 ✔
1659
    TAOS_CHECK_GOTO(tsdbDataFileWriteHeadFooter(writer), &lino, _exit);
123,897 ✔
1660

1661
    SVersionRange ofRange = {.minVer = VERSION_MAX, .maxVer = VERSION_MIN};
123,897 ✔
1662

1663
    // .head
1664
    ftype = TSDB_FTYPE_HEAD;
123,897 ✔
1665
    if (writer->config->files[ftype].exist) {
123,897 ✔
1666
      op = (STFileOp){
60,796 ✔
1667
          .optype = TSDB_FOP_REMOVE,
1668
          .fid = writer->config->fid,
60,796 ✔
1669
          .of = writer->config->files[ftype].file,
60,796 ✔
1670
      };
1671
      ofRange = (SVersionRange){.minVer = op.of.minVer, .maxVer = op.of.maxVer};
60,796 ✔
1672
      TAOS_CHECK_GOTO(TARRAY2_APPEND(opArr, op), &lino, _exit);
121,592 ✔
1673
    }
1674
    op = (STFileOp){
123,897 ✔
1675
        .optype = TSDB_FOP_CREATE,
1676
        .fid = writer->config->fid,
123,897 ✔
1677
        .nf = writer->files[ftype],
123,897 ✔
1678
    };
1679
    tsdbTFileUpdVerRange(&op.nf, ofRange);
123,897 ✔
1680
    tsdbTFileUpdVerRange(&op.nf, writer->ctx->range);
123,897 ✔
1681
    TAOS_CHECK_GOTO(TARRAY2_APPEND(opArr, op), &lino, _exit);
247,794 ✔
1682

1683
    // .data
1684
    ftype = TSDB_FTYPE_DATA;
123,897 ✔
1685
    if (!writer->config->files[ftype].exist) {
123,897 ✔
1686
      op = (STFileOp){
63,101 ✔
1687
          .optype = TSDB_FOP_CREATE,
1688
          .fid = writer->config->fid,
63,101 ✔
1689
          .nf = writer->files[ftype],
63,101 ✔
1690
      };
1691
      tsdbTFileUpdVerRange(&op.nf, writer->ctx->range);
63,101 ✔
1692
      TAOS_CHECK_GOTO(TARRAY2_APPEND(opArr, op), &lino, _exit);
126,202 ✔
1693
    } else if (writer->config->files[ftype].file.size != writer->files[ftype].size) {
60,796 ✔
1694
      op = (STFileOp){
60,796 ✔
1695
          .optype = TSDB_FOP_MODIFY,
1696
          .fid = writer->config->fid,
60,796 ✔
1697
          .of = writer->config->files[ftype].file,
60,796 ✔
1698
          .nf = writer->files[ftype],
60,796 ✔
1699
      };
1700
      tsdbTFileUpdVerRange(&op.nf, writer->ctx->range);
60,796 ✔
1701
      TAOS_CHECK_GOTO(TARRAY2_APPEND(opArr, op), &lino, _exit);
121,592 ✔
1702
    }
1703

1704
    // .sma
1705
    ftype = TSDB_FTYPE_SMA;
123,897 ✔
1706
    if (!writer->config->files[ftype].exist) {
123,897 ✔
1707
      op = (STFileOp){
63,101 ✔
1708
          .optype = TSDB_FOP_CREATE,
1709
          .fid = writer->config->fid,
63,101 ✔
1710
          .nf = writer->files[ftype],
63,101 ✔
1711
      };
1712
      tsdbTFileUpdVerRange(&op.nf, writer->ctx->range);
63,101 ✔
1713
      TAOS_CHECK_GOTO(TARRAY2_APPEND(opArr, op), &lino, _exit);
126,202 ✔
1714
    } else if (writer->config->files[ftype].file.size != writer->files[ftype].size) {
60,796 ✔
1715
      op = (STFileOp){
60,796 ✔
1716
          .optype = TSDB_FOP_MODIFY,
1717
          .fid = writer->config->fid,
60,796 ✔
1718
          .of = writer->config->files[ftype].file,
60,796 ✔
1719
          .nf = writer->files[ftype],
60,796 ✔
1720
      };
1721
      tsdbTFileUpdVerRange(&op.nf, writer->ctx->range);
60,796 ✔
1722
      TAOS_CHECK_GOTO(TARRAY2_APPEND(opArr, op), &lino, _exit);
121,592 ✔
1723
    }
1724
  }
1725

1726
  if (writer->fd[TSDB_FTYPE_TOMB]) {
150,938 ✔
1727
    STombRecord record[1] = {{
27,377 ✔
1728
        .suid = INT64_MAX,
1729
        .uid = INT64_MAX,
1730
        .version = INT64_MAX,
1731
    }};
1732

1733
    TAOS_CHECK_GOTO(tsdbDataFileDoWriteTombRecord(writer, record), &lino, _exit);
27,377 ✔
1734
    TAOS_CHECK_GOTO(tsdbDataFileDoWriteTombBlock(writer), &lino, _exit);
27,377 ✔
1735
    TAOS_CHECK_GOTO(tsdbDataFileDoWriteTombBlk(writer), &lino, _exit);
27,377 ✔
1736
    TAOS_CHECK_GOTO(tsdbDataFileWriteTombFooter(writer), &lino, _exit);
27,377 ✔
1737

1738
    SVersionRange ofRange = (SVersionRange){.minVer = VERSION_MAX, .maxVer = VERSION_MIN};
27,377 ✔
1739

1740
    ftype = TSDB_FTYPE_TOMB;
27,377 ✔
1741
    if (writer->config->files[ftype].exist) {
27,377 ✔
1742
      op = (STFileOp){
26,429 ✔
1743
          .optype = TSDB_FOP_REMOVE,
1744
          .fid = writer->config->fid,
26,429 ✔
1745
          .of = writer->config->files[ftype].file,
26,429 ✔
1746
      };
1747
      ofRange = (SVersionRange){.minVer = op.of.minVer, .maxVer = op.of.maxVer};
26,429 ✔
1748
      TAOS_CHECK_GOTO(TARRAY2_APPEND(opArr, op), &lino, _exit);
52,858 ✔
1749
    }
1750
    op = (STFileOp){
27,377 ✔
1751
        .optype = TSDB_FOP_CREATE,
1752
        .fid = writer->config->fid,
27,377 ✔
1753
        .nf = writer->files[ftype],
27,377 ✔
1754
    };
1755
    tsdbTFileUpdVerRange(&op.nf, ofRange);
27,377 ✔
1756
    tsdbTFileUpdVerRange(&op.nf, writer->ctx->tombRange);
27,377 ✔
1757
    TAOS_CHECK_GOTO(TARRAY2_APPEND(opArr, op), &lino, _exit);
54,754 ✔
1758
  }
1759
  SEncryptData *pEncryptData = &(writer->config->tsdb->pVnode->config.tsdbCfg.encryptData);
150,938 ✔
1760
  for (int32_t i = 0; i < TSDB_FTYPE_MAX; ++i) {
753,427 ✔
1761
    if (writer->fd[i]) {
602,798 ✔
1762
      TAOS_CHECK_GOTO(tsdbFsyncFile(writer->fd[i], pEncryptData), &lino, _exit);
398,821 ✔
1763
      tsdbCloseFile(&writer->fd[i]);
398,396 ✔
1764
    }
1765
  }
1766

1767
_exit:
150,629 ✔
1768
  if (code) {
150,797 ✔
1769
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1770
              tstrerror(code));
1771
  }
1772
  return code;
150,797 ✔
1773
}
1774

1775
static int32_t tsdbDataFileWriterOpenDataFD(SDataFileWriter *writer) {
123,897 ✔
1776
  int32_t code = 0;
123,897 ✔
1777
  int32_t lino = 0;
123,897 ✔
1778

1779
  int32_t ftypes[] = {TSDB_FTYPE_HEAD, TSDB_FTYPE_DATA, TSDB_FTYPE_SMA};
123,897 ✔
1780

1781
  for (int32_t i = 0; i < ARRAY_SIZE(ftypes); ++i) {
495,588 ✔
1782
    int32_t ftype = ftypes[i];
371,691 ✔
1783

1784
    char    fname[TSDB_FILENAME_LEN];
371,691 ✔
1785
    int32_t flag = TD_FILE_READ | TD_FILE_WRITE;
371,476 ✔
1786

1787
    if (writer->files[ftype].size == 0) {
371,476 ✔
1788
      flag |= (TD_FILE_CREATE | TD_FILE_TRUNC);
250,099 ✔
1789
    }
1790

1791
    int32_t lcn = writer->files[ftype].lcn;
371,476 ✔
1792
    tsdbTFileName(writer->config->tsdb, &writer->files[ftype], fname);
371,476 ✔
1793
    TAOS_CHECK_GOTO(tsdbOpenFile(fname, writer->config->tsdb, flag, &writer->fd[ftype], lcn), &lino, _exit);
371,691 ✔
1794

1795
    if (writer->files[ftype].size == 0) {
371,691 ✔
1796
      uint8_t hdr[TSDB_FHDR_SIZE] = {0};
250,099 ✔
1797

1798
      SEncryptData *pEncryptData = &(writer->config->tsdb->pVnode->config.tsdbCfg.encryptData);
250,099 ✔
1799

1800
      TAOS_CHECK_GOTO(tsdbWriteFile(writer->fd[ftype], 0, hdr, TSDB_FHDR_SIZE, pEncryptData), &lino, _exit);
250,099 ✔
1801

1802
      writer->files[ftype].size += TSDB_FHDR_SIZE;
250,099 ✔
1803
    }
1804
  }
1805

1806
  if (writer->ctx->reader) {
123,897 ✔
1807
    TAOS_CHECK_GOTO(tsdbDataFileReadBrinBlk(writer->ctx->reader, &writer->ctx->brinBlkArray), &lino, _exit);
60,796 ✔
1808
  }
1809

1810
_exit:
123,897 ✔
1811
  if (code) {
123,897 ✔
1812
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1813
              tstrerror(code));
1814
  }
1815
  return code;
123,897 ✔
1816
}
1817

1818
int32_t tsdbDataFileWriterOpen(const SDataFileWriterConfig *config, SDataFileWriter **writer) {
254,904 ✔
1819
  writer[0] = taosMemoryCalloc(1, sizeof(*writer[0]));
254,904 ✔
1820
  if (!writer[0]) {
254,763 ✔
1821
    return terrno;
×
1822
  }
1823

1824
  writer[0]->config[0] = config[0];
254,763 ✔
1825
  return 0;
254,763 ✔
1826
}
1827

1828
int32_t tsdbDataFileWriterClose(SDataFileWriter **writer, bool abort, TFileOpArray *opArr) {
254,904 ✔
1829
  if (writer == NULL || writer[0] == NULL) return 0;
254,904 ✔
1830

1831
  int32_t code = 0;
254,904 ✔
1832
  int32_t lino = 0;
254,904 ✔
1833

1834
  if (writer[0]->ctx->opened) {
254,904 ✔
1835
    if (abort) {
150,938 ✔
1836
      TAOS_CHECK_GOTO(tsdbDataFileWriterCloseAbort(writer[0]), &lino, _exit);
×
1837
    } else {
1838
      TAOS_CHECK_GOTO(tsdbDataFileWriterCloseCommit(writer[0], opArr), &lino, _exit);
150,938 ✔
1839
    }
1840
    tsdbDataFileWriterDoClose(writer[0]);
150,723 ✔
1841
  }
1842
  taosMemoryFree(writer[0]);
254,904 ✔
1843
  writer[0] = NULL;
254,548 ✔
1844

1845
_exit:
254,548 ✔
1846
  if (code) {
254,548 ✔
1847
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer[0]->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1848
              tstrerror(code));
1849
  }
1850
  return code;
254,530 ✔
1851
}
1852

1853
int32_t tsdbDataFileWriteRow(SDataFileWriter *writer, SRowInfo *row) {
497,585,091 ✔
1854
  int32_t code = 0;
497,585,091 ✔
1855
  int32_t lino = 0;
497,585,091 ✔
1856

1857
  if (!writer->ctx->opened) {
497,611,313 ✔
1858
    TAOS_CHECK_GOTO(tsdbDataFileWriterDoOpen(writer), &lino, _exit);
16,012 ✔
1859
  }
1860

1861
  if (writer->fd[TSDB_FTYPE_HEAD] == NULL) {
497,611,313 ✔
1862
    TAOS_CHECK_GOTO(tsdbDataFileWriterOpenDataFD(writer), &lino, _exit);
16,012 ✔
1863
  }
1864

1865
  if (row->uid != writer->ctx->tbid->uid) {
497,611,313 ✔
1866
    TAOS_CHECK_GOTO(tsdbDataFileWriteTableDataEnd(writer), &lino, _exit);
33,690 ✔
1867
    TAOS_CHECK_GOTO(tsdbDataFileWriteTableDataBegin(writer, (TABLEID *)row), &lino, _exit);
33,690 ✔
1868
  }
1869

1870
  TAOS_CHECK_GOTO(tsdbDataFileDoWriteTSData(writer, &row->row), &lino, _exit);
497,611,313 ✔
1871

1872
_exit:
497,671,985 ✔
1873
  if (code) {
497,717,555 ✔
1874
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1875
              tstrerror(code));
1876
  }
1877
  return code;
497,717,555 ✔
1878
}
1879

1880
int32_t tsdbDataFileWriteBlockData(SDataFileWriter *writer, SBlockData *bData) {
5,151,410 ✔
1881
  if (bData->nRow == 0) {
5,151,410 ✔
1882
    return 0;
×
1883
  }
1884

1885
  int32_t code = 0;
5,151,410 ✔
1886
  int32_t lino = 0;
5,151,410 ✔
1887

1888
  if (!bData->uid) {
5,151,410 ✔
1889
    return TSDB_CODE_INVALID_PARA;
×
1890
  }
1891

1892
  if (!writer->ctx->opened) {
5,151,410 ✔
1893
    TAOS_CHECK_GOTO(tsdbDataFileWriterDoOpen(writer), &lino, _exit);
107,641 ✔
1894
  }
1895

1896
  if (writer->fd[TSDB_FTYPE_DATA] == NULL) {
5,151,410 ✔
1897
    TAOS_CHECK_GOTO(tsdbDataFileWriterOpenDataFD(writer), &lino, _exit);
107,885 ✔
1898
  }
1899

1900
  if (bData->uid != writer->ctx->tbid->uid) {
5,151,410 ✔
1901
    TAOS_CHECK_GOTO(tsdbDataFileWriteTableDataEnd(writer), &lino, _exit);
3,740,319 ✔
1902
    TAOS_CHECK_GOTO(tsdbDataFileWriteTableDataBegin(writer, (TABLEID *)bData), &lino, _exit);
3,740,316 ✔
1903
  }
1904

1905
  if (writer->ctx->tbHasOldData) {
5,151,110 ✔
1906
    STsdbRowKey key;
565,880 ✔
1907

1908
    tsdbRowGetKey(&tsdbRowFromBlockData(bData, 0), &key);
565,880 ✔
1909
    TAOS_CHECK_GOTO(tsdbDataFileDoWriteTableOldData(writer, &key), &lino, _exit);
565,880 ✔
1910
  }
1911

1912
  if (!writer->ctx->tbHasOldData       //
5,151,312 ✔
1913
      && writer->blockData->nRow == 0  //
4,639,209 ✔
1914
  ) {
1915
    TAOS_CHECK_GOTO(tsdbDataFileDoWriteBlockData(writer, bData), &lino, _exit);
4,604,168 ✔
1916

1917
  } else {
1918
    for (int32_t i = 0; i < bData->nRow; ++i) {
2,147,483,647 ✔
1919
      TSDBROW row[1] = {tsdbRowFromBlockData(bData, i)};
2,147,483,647 ✔
1920
      TAOS_CHECK_GOTO(tsdbDataFileDoWriteTSData(writer, row), &lino, _exit);
2,147,483,647 ✔
1921
    }
1922
  }
1923

1924
_exit:
5,154,351 ✔
1925
  if (code) {
5,148,993 ✔
1926
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1927
              tstrerror(code));
1928
  }
1929
  return code;
5,149,284 ✔
1930
}
1931

1932
int32_t tsdbDataFileFlush(SDataFileWriter *writer) {
108,503 ✔
1933
  if (!writer->ctx->opened) {
108,503 ✔
1934
    return TSDB_CODE_INVALID_PARA;
×
1935
  }
1936

1937
  if (writer->blockData->nRow == 0) return 0;
108,503 ✔
1938
  if (writer->ctx->tbHasOldData) return 0;
108,503 ✔
1939

1940
  return tsdbDataFileDoWriteBlockData(writer, writer->blockData);
87,443 ✔
1941
}
1942

1943
static int32_t tsdbDataFileWriterOpenTombFD(SDataFileWriter *writer) {
27,377 ✔
1944
  int32_t code = 0;
27,377 ✔
1945
  int32_t lino = 0;
27,377 ✔
1946

1947
  char    fname[TSDB_FILENAME_LEN];
27,377 ✔
1948
  int32_t ftype = TSDB_FTYPE_TOMB;
27,377 ✔
1949

1950
  int32_t flag = (TD_FILE_READ | TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC);
27,377 ✔
1951

1952
  int32_t lcn = writer->files[ftype].lcn;
27,377 ✔
1953
  tsdbTFileName(writer->config->tsdb, writer->files + ftype, fname);
27,377 ✔
1954

1955
  TAOS_CHECK_GOTO(tsdbOpenFile(fname, writer->config->tsdb, flag, &writer->fd[ftype], lcn), &lino, _exit);
27,377 ✔
1956

1957
  uint8_t hdr[TSDB_FHDR_SIZE] = {0};
27,377 ✔
1958
  SEncryptData *pEncryptData = &(writer->config->tsdb->pVnode->config.tsdbCfg.encryptData);
27,377 ✔
1959

1960
  TAOS_CHECK_GOTO(tsdbWriteFile(writer->fd[ftype], 0, hdr, TSDB_FHDR_SIZE, pEncryptData), &lino, _exit);
27,377 ✔
1961
  writer->files[ftype].size += TSDB_FHDR_SIZE;
27,377 ✔
1962

1963
  if (writer->ctx->reader) {
27,377 ✔
1964
    TAOS_CHECK_GOTO(tsdbDataFileReadTombBlk(writer->ctx->reader, &writer->ctx->tombBlkArray), &lino, _exit);
26,429 ✔
1965

1966
    if (TARRAY2_SIZE(writer->ctx->tombBlkArray) > 0) {
26,429 ✔
1967
      writer->ctx->hasOldTomb = true;
26,429 ✔
1968
    }
1969

1970
    writer->ctx->tombBlkArrayIdx = 0;
26,429 ✔
1971
    tTombBlockClear(writer->ctx->tombBlock);
26,429 ✔
1972
    writer->ctx->tombBlockIdx = 0;
26,429 ✔
1973
  }
1974

1975
_exit:
27,377 ✔
1976
  if (code) {
27,377 ✔
1977
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
1978
              tstrerror(code));
1979
  }
1980
  return code;
27,377 ✔
1981
}
1982

1983
int32_t tsdbDataFileWriteTombRecord(SDataFileWriter *writer, const STombRecord *record) {
94,452 ✔
1984
  int32_t code = 0;
94,452 ✔
1985
  int32_t lino = 0;
94,452 ✔
1986

1987
  if (!writer->ctx->opened) {
94,452 ✔
1988
    TAOS_CHECK_GOTO(tsdbDataFileWriterDoOpen(writer), &lino, _exit);
27,285 ✔
1989
  }
1990

1991
  if (writer->fd[TSDB_FTYPE_TOMB] == NULL) {
94,452 ✔
1992
    TAOS_CHECK_GOTO(tsdbDataFileWriterOpenTombFD(writer), &lino, _exit);
27,377 ✔
1993
  }
1994

1995
  TAOS_CHECK_GOTO(tsdbDataFileDoWriteTombRecord(writer, record), &lino, _exit);
94,452 ✔
1996

1997
_exit:
94,452 ✔
1998
  if (code) {
94,452 ✔
1999
    tsdbError("vgId:%d %s failed at %s:%d since %s", TD_VID(writer->config->tsdb->pVnode), __func__, __FILE__, lino,
×
2000
              tstrerror(code));
2001
  }
2002
  return code;
94,452 ✔
2003
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc