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

taosdata / TDengine / #5069

17 May 2026 01:15AM UTC coverage: 73.389% (+0.02%) from 73.368%
#5069

push

travis-ci

web-flow
feat (TDgpt): Dynamic Model Synchronization Enhancements (#35344)

* refactor: do some internal refactor.

* fix: fix multiprocess sync issue.

* feat: add dynamic anomaly detection and forecasting services

* fix: log error message for undeploying model in exception handling

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: handle undeploy when model exists only on disk

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/286aafa0-c3ce-4c27-b803-2707571e9dc1

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: guard dynamic registry concurrent access

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: tighten service list locking scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: restore prophet support and update tests per review feedback

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: improve test name and move copy inside lock scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* Potential fix for pull request finding

Co-au... (continued)

281664 of 383795 relevant lines covered (73.39%)

139049899.73 hits per line

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

79.11
/source/dnode/vnode/src/tsdb/tsdbSnapInfo.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 "tsdb.h"
17
#include "tsdbFS2.h"
18

19
#define TSDB_SNAP_MSG_VER 1
20

21
// fset partition
22
static int32_t tsdbFSetPartCmprFn(STsdbFSetPartition* x, STsdbFSetPartition* y) {
33,806✔
23
  if (x->fid < y->fid) return -1;
33,806✔
24
  if (x->fid > y->fid) return 1;
18,313✔
25
  return 0;
×
26
}
27

28
static int32_t tVersionRangeCmprFn(SVersionRange* x, SVersionRange* y) {
15,190✔
29
  if (x->minVer < y->minVer) return -1;
15,190✔
30
  if (x->minVer > y->minVer) return 1;
×
31
  if (x->maxVer < y->maxVer) return -1;
×
32
  if (x->maxVer > y->maxVer) return 1;
×
33
  return 0;
×
34
}
35

36
static int32_t tsdbTFileSetRangeCmprFn(STFileSetRange* x, STFileSetRange* y) {
×
37
  if (x->fid < y->fid) return -1;
×
38
  if (x->fid > y->fid) return 1;
×
39
  return 0;
×
40
}
41

42
STsdbFSetPartition* tsdbFSetPartitionCreate() {
44,378✔
43
  STsdbFSetPartition* pSP = taosMemoryCalloc(1, sizeof(STsdbFSetPartition));
44,378✔
44
  if (pSP == NULL) {
44,378✔
45
    return NULL;
×
46
  }
47
  for (int32_t i = 0; i < TSDB_FSET_RANGE_TYP_MAX; i++) {
266,268✔
48
    TARRAY2_INIT(&pSP->verRanges[i]);
221,890✔
49
  }
50
  return pSP;
44,378✔
51
}
52

53
void tsdbFSetPartitionClear(STsdbFSetPartition** ppSP) {
44,378✔
54
  if (ppSP == NULL || ppSP[0] == NULL) {
44,378✔
55
    return;
×
56
  }
57
  for (int32_t i = 0; i < TSDB_FSET_RANGE_TYP_MAX; i++) {
266,268✔
58
    TARRAY2_DESTROY(&ppSP[0]->verRanges[i], NULL);
221,890✔
59
  }
60
  taosMemoryFree(ppSP[0]);
44,378✔
61
  ppSP[0] = NULL;
44,378✔
62
}
63

64
static int32_t tsdbFTypeToFRangeType(tsdb_ftype_t ftype) {
101,787✔
65
  switch (ftype) {
101,787✔
66
    case TSDB_FTYPE_HEAD:
33,929✔
67
      return TSDB_FSET_RANGE_TYP_HEAD;
33,929✔
68
    case TSDB_FTYPE_DATA:
33,929✔
69
      return TSDB_FSET_RANGE_TYP_DATA;
33,929✔
70
    case TSDB_FTYPE_SMA:
33,929✔
71
      return TSDB_FSET_RANGE_TYP_SMA;
33,929✔
72
    case TSDB_FTYPE_TOMB:
×
73
      return TSDB_FSET_RANGE_TYP_TOMB;
×
74
    case TSDB_FTYPE_STT:
×
75
      return TSDB_FSET_RANGE_TYP_STT;
×
76
  }
77
  return TSDB_FSET_RANGE_TYP_MAX;
×
78
}
79

80
static int32_t tsdbTFileSetToFSetPartition(STFileSet* fset, STsdbFSetPartition** ppSP) {
43,568✔
81
  STsdbFSetPartition* p = tsdbFSetPartitionCreate();
43,568✔
82
  if (p == NULL) {
43,568✔
83
    return terrno;
×
84
  }
85

86
  p->fid = fset->fid;
43,568✔
87

88
  int32_t code = 0;
43,568✔
89
  int32_t typ = 0;
43,568✔
90
  int32_t corrupt = false;
43,568✔
91
  int32_t count = 0;
43,568✔
92
  for (int32_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
217,840✔
93
    if (fset->farr[ftype] == NULL) continue;
174,272✔
94
    typ = tsdbFTypeToFRangeType(ftype);
101,787✔
95
    STFile* f = fset->farr[ftype]->f;
101,787✔
96
    if (f->maxVer > fset->maxVerValid) {
101,787✔
97
      corrupt = true;
×
98
      tsdbError("skip incomplete data file: fid:%d, maxVerValid:%" PRId64 ", minVer:%" PRId64 ", maxVer:%" PRId64
×
99
                ", ftype: %d",
100
                fset->fid, fset->maxVerValid, f->minVer, f->maxVer, ftype);
101
      continue;
×
102
    }
103
    count++;
101,787✔
104
    SVersionRange vr = {.minVer = f->minVer, .maxVer = f->maxVer};
101,787✔
105
    code = TARRAY2_SORT_INSERT(&p->verRanges[typ], vr, tVersionRangeCmprFn);
101,787✔
106
    if (code) {
101,787✔
107
      tsdbFSetPartitionClear(&p);
×
108
      return code;
×
109
    }
110
  }
111

112
  typ = TSDB_FSET_RANGE_TYP_STT;
43,568✔
113
  const SSttLvl* lvl;
114
  TARRAY2_FOREACH(fset->lvlArr, lvl) {
82,802✔
115
    STFileObj* fobj;
116
    TARRAY2_FOREACH(lvl->fobjArr, fobj) {
78,468✔
117
      STFile* f = fobj->f;
39,234✔
118
      if (f->maxVer > fset->maxVerValid) {
39,234✔
119
        corrupt = true;
×
120
        tsdbError("skip incomplete stt file.fid:%d, maxVerValid:%" PRId64 ", minVer:%" PRId64 ", maxVer:%" PRId64
×
121
                  ", ftype: %d",
122
                  fset->fid, fset->maxVerValid, f->minVer, f->maxVer, typ);
123
        continue;
×
124
      }
125
      count++;
39,234✔
126
      SVersionRange vr = {.minVer = f->minVer, .maxVer = f->maxVer};
39,234✔
127
      code = TARRAY2_SORT_INSERT(&p->verRanges[typ], vr, tVersionRangeCmprFn);
39,234✔
128
      if (code) {
39,234✔
129
        tsdbFSetPartitionClear(&p);
×
130
        return code;
×
131
      }
132
    }
133
  }
134
  if (corrupt && count == 0) {
43,568✔
135
    SVersionRange vr = {.minVer = VERSION_MIN, .maxVer = fset->maxVerValid};
×
136
    code = TARRAY2_SORT_INSERT(&p->verRanges[typ], vr, tVersionRangeCmprFn);
×
137
    if (code) {
×
138
      tsdbFSetPartitionClear(&p);
×
139
      return code;
×
140
    }
141
  }
142
  ppSP[0] = p;
43,568✔
143
  return 0;
43,568✔
144
}
145

146
// fset partition list
147
STsdbFSetPartList* tsdbFSetPartListCreate() {
135,256✔
148
  STsdbFSetPartList* pList = taosMemoryCalloc(1, sizeof(STsdbFSetPartList));
135,256✔
149
  if (pList == NULL) {
135,256✔
150
    return NULL;
×
151
  }
152
  TARRAY2_INIT(pList);
135,256✔
153
  return pList;
135,256✔
154
}
155

156
void tsdbFSetPartListDestroy(STsdbFSetPartList** ppList) {
135,256✔
157
  if (ppList == NULL || ppList[0] == NULL) return;
135,256✔
158

159
  TARRAY2_DESTROY(ppList[0], tsdbFSetPartitionClear);
179,634✔
160
  taosMemoryFree(ppList[0]);
135,256✔
161
  ppList[0] = NULL;
135,256✔
162
}
163

164
int32_t tsdbFSetPartListToRangeDiff(STsdbFSetPartList* pList, TFileSetRangeArray** ppRanges) {
67,628✔
165
  int32_t code = 0;
67,628✔
166

167
  TFileSetRangeArray* pDiff = taosMemoryCalloc(1, sizeof(TFileSetRangeArray));
67,628✔
168
  if (pDiff == NULL) {
67,628✔
169
    code = terrno;
×
170
    goto _err;
×
171
  }
172
  TARRAY2_INIT(pDiff);
67,628✔
173

174
  STsdbFSetPartition* part;
175
  TARRAY2_FOREACH(pList, part) {
68,438✔
176
    STFileSetRange* r = taosMemoryCalloc(1, sizeof(STFileSetRange));
810✔
177
    if (r == NULL) {
810✔
178
      code = terrno;
×
179
      goto _err;
×
180
    }
181
    int64_t maxVerValid = -1;
810✔
182
    int32_t typMax = TSDB_FSET_RANGE_TYP_MAX;
810✔
183
    for (int32_t i = 0; i < typMax; i++) {
4,860✔
184
      SVerRangeList* iList = &part->verRanges[i];
4,050✔
185
      SVersionRange  vr = {0};
4,050✔
186
      TARRAY2_FOREACH(iList, vr) {
4,860✔
187
        if (vr.maxVer < vr.minVer) {
810✔
188
          continue;
×
189
        }
190
        maxVerValid = TMAX(maxVerValid, vr.maxVer);
810✔
191
      }
192
    }
193
    r->fid = part->fid;
810✔
194
    r->sver = maxVerValid + 1;
810✔
195
    r->ever = VERSION_MAX;
810✔
196
    tsdbDebug("range diff fid:%" PRId64 ", sver:%" PRId64 ", ever:%" PRId64, part->fid, r->sver, r->ever);
810✔
197
    code = TARRAY2_SORT_INSERT(pDiff, r, tsdbTFileSetRangeCmprFn);
810✔
198
    if (code) {
810✔
199
      taosMemoryFree(r);
×
200
      goto _err;
×
201
    }
202
  }
203
  ppRanges[0] = pDiff;
67,628✔
204

205
  tsdbInfo("pDiff size:%d", TARRAY2_SIZE(pDiff));
67,628✔
206
  return 0;
67,628✔
207

208
_err:
×
209
  if (pDiff) {
×
210
    tsdbTFileSetRangeArrayDestroy(&pDiff);
×
211
  }
212
  return code;
×
213
}
214

215
// serialization
216
int32_t tTsdbFSetPartListDataLenCalc(STsdbFSetPartList* pList) {
67,628✔
217
  int32_t hdrLen = sizeof(int32_t);
67,628✔
218
  int32_t datLen = 0;
67,628✔
219

220
  int8_t  msgVer = 1;
67,628✔
221
  int32_t len = TARRAY2_SIZE(pList);
67,628✔
222
  hdrLen += sizeof(msgVer);
67,628✔
223
  hdrLen += sizeof(len);
67,628✔
224
  datLen += hdrLen;
67,628✔
225

226
  for (int32_t u = 0; u < len; u++) {
111,196✔
227
    STsdbFSetPartition* p = TARRAY2_GET(pList, u);
43,568✔
228
    int32_t             typMax = TSDB_FSET_RANGE_TYP_MAX;
43,568✔
229
    int32_t             uItem = 0;
43,568✔
230
    uItem += sizeof(STsdbFSetPartition);
43,568✔
231
    uItem += sizeof(typMax);
43,568✔
232

233
    for (int32_t i = 0; i < typMax; i++) {
261,408✔
234
      int32_t iLen = TARRAY2_SIZE(&p->verRanges[i]);
217,840✔
235
      int32_t jItem = 0;
217,840✔
236
      jItem += sizeof(SVersionRange);
217,840✔
237
      jItem += sizeof(int64_t);
217,840✔
238
      uItem += sizeof(iLen) + jItem * iLen;
217,840✔
239
    }
240
    datLen += uItem;
43,568✔
241
  }
242
  return datLen;
67,628✔
243
}
244

245
static int32_t tSerializeTsdbFSetPartList(void* buf, int32_t bufLen, STsdbFSetPartList* pList, int32_t* encodeSize) {
67,628✔
246
  SEncoder encoder = {0};
67,628✔
247
  int8_t   reserved8 = 0;
67,628✔
248
  int16_t  reserved16 = 0;
67,628✔
249
  int64_t  reserved64 = 0;
67,628✔
250
  int8_t   msgVer = TSDB_SNAP_MSG_VER;
67,628✔
251
  int32_t  len = TARRAY2_SIZE(pList);
67,628✔
252
  int32_t  code = 0;
67,628✔
253

254
  tEncoderInit(&encoder, buf, bufLen);
67,628✔
255
  if ((code = tStartEncode(&encoder))) goto _exit;
67,628✔
256
  if ((code = tEncodeI8(&encoder, msgVer))) goto _exit;
135,256✔
257
  if ((code = tEncodeI32(&encoder, len))) goto _exit;
67,628✔
258

259
  for (int32_t u = 0; u < len; u++) {
111,196✔
260
    STsdbFSetPartition* p = TARRAY2_GET(pList, u);
43,568✔
261
    if ((code = tEncodeI64(&encoder, p->fid))) goto _exit;
87,136✔
262
    if ((code = tEncodeI8(&encoder, p->stat))) goto _exit;
87,136✔
263
    if ((code = tEncodeI8(&encoder, reserved8))) goto _exit;
87,136✔
264
    if ((code = tEncodeI16(&encoder, reserved16))) goto _exit;
87,136✔
265

266
    int32_t typMax = TSDB_FSET_RANGE_TYP_MAX;
43,568✔
267
    if ((code = tEncodeI32(&encoder, typMax))) goto _exit;
43,568✔
268

269
    for (int32_t i = 0; i < typMax; i++) {
261,408✔
270
      SVerRangeList* iList = &p->verRanges[i];
217,840✔
271
      int32_t        iLen = TARRAY2_SIZE(iList);
217,840✔
272

273
      if ((code = tEncodeI32(&encoder, iLen))) goto _exit;
217,840✔
274
      for (int32_t j = 0; j < iLen; j++) {
358,861✔
275
        SVersionRange r = TARRAY2_GET(iList, j);
141,021✔
276
        if ((code = tEncodeI64(&encoder, r.minVer))) goto _exit;
282,042✔
277
        if ((code = tEncodeI64(&encoder, r.maxVer))) goto _exit;
282,042✔
278
        if ((code = tEncodeI64(&encoder, reserved64))) goto _exit;
141,021✔
279
      }
280
    }
281
  }
282

283
  tEndEncode(&encoder);
67,628✔
284

285
  if (encodeSize) {
67,628✔
286
    encodeSize[0] = encoder.pos;
67,628✔
287
  }
288

289
_exit:
67,628✔
290
  tEncoderClear(&encoder);
67,628✔
291
  return code;
67,628✔
292
}
293

294
int32_t tDeserializeTsdbFSetPartList(void* buf, int32_t bufLen, STsdbFSetPartList* pList) {
67,628✔
295
  SDecoder decoder = {0};
67,628✔
296
  int8_t   reserved8 = 0;
67,628✔
297
  int16_t  reserved16 = 0;
67,628✔
298
  int64_t  reserved64 = 0;
67,628✔
299
  int32_t  code = 0;
67,628✔
300

301
  STsdbFSetPartition* p = NULL;
67,628✔
302

303
  tDecoderInit(&decoder, buf, bufLen);
67,628✔
304
  int8_t  msgVer = 0;
67,628✔
305
  int32_t len = 0;
67,628✔
306
  if ((code = tStartDecode(&decoder))) goto _err;
67,628✔
307
  if ((code = tDecodeI8(&decoder, &msgVer))) goto _err;
67,628✔
308
  if (msgVer != TSDB_SNAP_MSG_VER) {
67,628✔
309
    code = TSDB_CODE_INVALID_MSG;
×
310
    goto _err;
×
311
  }
312
  if ((code = tDecodeI32(&decoder, &len))) goto _err;
67,628✔
313

314
  for (int32_t u = 0; u < len; u++) {
68,438✔
315
    p = tsdbFSetPartitionCreate();
810✔
316
    if (p == NULL) {
810✔
317
      code = terrno;
×
318
      goto _err;
×
319
    }
320

321
    if ((code = tDecodeI64(&decoder, &p->fid))) goto _err;
1,620✔
322
    if ((code = tDecodeI8(&decoder, &p->stat))) goto _err;
1,620✔
323
    if ((code = tDecodeI8(&decoder, &reserved8))) goto _err;
810✔
324
    if ((code = tDecodeI16(&decoder, &reserved16))) goto _err;
810✔
325

326
    int32_t typMax = 0;
810✔
327
    if ((code = tDecodeI32(&decoder, &typMax))) goto _err;
810✔
328

329
    for (int32_t i = 0; i < typMax; i++) {
4,860✔
330
      SVerRangeList* iList = &p->verRanges[i];
4,050✔
331
      int32_t        iLen = 0;
4,050✔
332
      if ((code = tDecodeI32(&decoder, &iLen))) goto _err;
4,050✔
333
      for (int32_t j = 0; j < iLen; j++) {
4,860✔
334
        SVersionRange r = {0};
810✔
335
        if ((code = tDecodeI64(&decoder, &r.minVer))) goto _err;
810✔
336
        if ((code = tDecodeI64(&decoder, &r.maxVer))) goto _err;
810✔
337
        if ((code = tDecodeI64(&decoder, &reserved64))) goto _err;
810✔
338
        if ((code = TARRAY2_APPEND(iList, r))) goto _err;
1,620✔
339
      }
340
    }
341
    if ((code = TARRAY2_APPEND(pList, p))) goto _err;
1,620✔
342
    p = NULL;
810✔
343
  }
344

345
  tEndDecode(&decoder);
67,628✔
346
  tDecoderClear(&decoder);
67,628✔
347
  return 0;
67,628✔
348

349
_err:
×
350
  if (p) {
×
351
    tsdbFSetPartitionClear(&p);
×
352
  }
353
  tDecoderClear(&decoder);
×
354
  return code;
×
355
}
356

357
// fs state
358
static STsdbFSetPartList* tsdbSnapGetFSetPartList(STFileSystem* fs) {
67,628✔
359
  STsdbFSetPartList* pList = tsdbFSetPartListCreate();
67,628✔
360
  if (pList == NULL) {
67,628✔
361
    return NULL;
×
362
  }
363

364
  int32_t code = 0;
67,628✔
365
  (void)taosThreadMutexLock(&fs->tsdb->mutex);
67,628✔
366
  STFileSet* fset;
367
  TARRAY2_FOREACH(fs->fSetArr, fset) {
111,196✔
368
    STsdbFSetPartition* pItem = NULL;
43,568✔
369
    code = tsdbTFileSetToFSetPartition(fset, &pItem);
43,568✔
370
    if (code) {
43,568✔
371
      terrno = code;
×
372
      break;
×
373
    }
374
    code = TARRAY2_SORT_INSERT(pList, pItem, tsdbFSetPartCmprFn);
43,568✔
375
    if (code) {
43,568✔
376
      terrno = code;
×
377
      break;
×
378
    }
379
  }
380
  (void)taosThreadMutexUnlock(&fs->tsdb->mutex);
67,628✔
381

382
  if (code) {
67,628✔
383
    TARRAY2_DESTROY(pList, tsdbFSetPartitionClear);
×
384
    taosMemoryFree(pList);
×
385
    pList = NULL;
×
386
  }
387
  return pList;
67,628✔
388
}
389

390
ETsdbFsState tsdbSnapGetFsState(SVnode* pVnode) { return pVnode->pTsdb->pFS->fsstate; }
129,951,279✔
391

392
// description
393
typedef struct STsdbPartitionInfo {
394
  int32_t            vgId;
395
  int32_t            tsdbMaxCnt;
396
  int32_t            subTyps[TSDB_RETENTION_MAX];
397
  STsdbFSetPartList* pLists[TSDB_RETENTION_MAX];
398
} STsdbPartitionInfo;
399

400
static int32_t tsdbPartitionInfoInit(SVnode* pVnode, STsdbPartitionInfo* pInfo) {
67,628✔
401
  int32_t subTyps[TSDB_RETENTION_MAX] = {SNAP_DATA_TSDB, SNAP_DATA_RSMA1, SNAP_DATA_RSMA2};
67,628✔
402
  pInfo->vgId = TD_VID(pVnode);
67,628✔
403
  pInfo->tsdbMaxCnt = 1;
67,628✔
404

405
  if (!(sizeof(pInfo->subTyps) == sizeof(subTyps))) {
406
    return TSDB_CODE_INVALID_PARA;
407
  }
408
  memcpy(pInfo->subTyps, (char*)subTyps, sizeof(subTyps));
67,628✔
409

410
  // fset partition list
411
  memset(pInfo->pLists, 0, sizeof(pInfo->pLists[0]) * TSDB_RETENTION_MAX);
67,628✔
412
  for (int32_t j = 0; j < pInfo->tsdbMaxCnt; ++j) {
135,256✔
413
    STsdb* pTsdb = SMA_RSMA_GET_TSDB(pVnode, j);
67,628✔
414
    pInfo->pLists[j] = tsdbSnapGetFSetPartList(pTsdb->pFS);
67,628✔
415
    if (pInfo->pLists[j] == NULL) {
67,628✔
416
      return terrno;
×
417
    }
418
  }
419
  return 0;
67,628✔
420
}
421

422
static void tsdbPartitionInfoClear(STsdbPartitionInfo* pInfo) {
67,628✔
423
  for (int32_t j = 0; j < pInfo->tsdbMaxCnt; ++j) {
135,256✔
424
    if (pInfo->pLists[j] == NULL) continue;
67,628✔
425
    tsdbFSetPartListDestroy(&pInfo->pLists[j]);
67,628✔
426
  }
427
}
67,628✔
428

429
static int32_t tsdbPartitionInfoEstSize(STsdbPartitionInfo* pInfo) {
67,628✔
430
  int32_t dataLen = 0;
67,628✔
431
  for (int32_t j = 0; j < pInfo->tsdbMaxCnt; ++j) {
135,256✔
432
    dataLen += sizeof(SSyncTLV);  // subTyps[j]
67,628✔
433
    dataLen += tTsdbFSetPartListDataLenCalc(pInfo->pLists[j]);
67,628✔
434
  }
435
  return dataLen;
67,628✔
436
}
437

438
static int32_t tsdbPartitionInfoSerialize(STsdbPartitionInfo* pInfo, uint8_t* buf, int32_t bufLen) {
67,628✔
439
  int32_t tlen = 0;
67,628✔
440
  int32_t offset = 0;
67,628✔
441
  for (int32_t j = 0; j < pInfo->tsdbMaxCnt; ++j) {
135,256✔
442
    SSyncTLV* pSubHead = (void*)((char*)buf + offset);
67,628✔
443
    int32_t   valOffset = offset + sizeof(*pSubHead);
67,628✔
444
    int32_t   code = tSerializeTsdbFSetPartList(pSubHead->val, bufLen - valOffset, pInfo->pLists[j], &tlen);
67,628✔
445
    if (code) {
67,628✔
446
      tsdbError("vgId:%d, failed to serialize fset partition list of tsdb %d since %s", pInfo->vgId, j, terrstr());
×
447
      return code;
×
448
    }
449
    pSubHead->typ = pInfo->subTyps[j];
67,628✔
450
    pSubHead->len = tlen;
67,628✔
451
    offset += sizeof(*pSubHead) + tlen;
67,628✔
452
  }
453
  return offset;
67,628✔
454
}
455

456
// tsdb replication opts
457
static int32_t tTsdbRepOptsDataLenCalc(STsdbRepOpts* pInfo) {
67,628✔
458
  int32_t hdrLen = sizeof(int32_t);
67,628✔
459
  int32_t datLen = 0;
67,628✔
460

461
  int8_t  msgVer = 0;
67,628✔
462
  int64_t reserved64 = 0;
67,628✔
463
  int16_t format = 0;
67,628✔
464
  hdrLen += sizeof(msgVer);
67,628✔
465
  datLen += hdrLen;
67,628✔
466
  datLen += sizeof(format);
67,628✔
467
  datLen += sizeof(reserved64);
67,628✔
468
  datLen += sizeof(*pInfo);
67,628✔
469
  return datLen;
67,628✔
470
}
471

472
int32_t tSerializeTsdbRepOpts(void* buf, int32_t bufLen, STsdbRepOpts* pOpts) {
67,628✔
473
  int32_t  code = 0;
67,628✔
474
  SEncoder encoder = {0};
67,628✔
475
  int64_t  reserved64 = 0;
67,628✔
476
  int8_t   msgVer = TSDB_SNAP_MSG_VER;
67,628✔
477

478
  tEncoderInit(&encoder, buf, bufLen);
67,628✔
479

480
  if ((code = tStartEncode(&encoder))) goto _err;
67,628✔
481
  if ((code = tEncodeI8(&encoder, msgVer))) goto _err;
135,256✔
482
  int16_t format = pOpts->format;
67,628✔
483
  if ((code = tEncodeI16(&encoder, format))) goto _err;
135,256✔
484
  if ((code = tEncodeI64(&encoder, reserved64))) goto _err;
67,628✔
485

486
  tEndEncode(&encoder);
67,628✔
487
  int32_t tlen = encoder.pos;
67,628✔
488
  tEncoderClear(&encoder);
67,628✔
489
  return tlen;
67,628✔
490

491
_err:
×
492
  tEncoderClear(&encoder);
×
493
  return code;
×
494
}
495

496
int32_t tDeserializeTsdbRepOpts(void* buf, int32_t bufLen, STsdbRepOpts* pOpts) {
101,441✔
497
  int32_t  code;
498
  SDecoder decoder = {0};
101,441✔
499
  int64_t  reserved64 = 0;
101,441✔
500
  int8_t   msgVer = 0;
101,441✔
501

502
  tDecoderInit(&decoder, buf, bufLen);
101,441✔
503

504
  if ((code = tStartDecode(&decoder))) goto _err;
101,441✔
505
  if ((code = tDecodeI8(&decoder, &msgVer))) goto _err;
101,441✔
506
  if (msgVer != TSDB_SNAP_MSG_VER) goto _err;
101,441✔
507
  int16_t format = 0;
101,441✔
508
  if ((code = tDecodeI16(&decoder, &format))) goto _err;
101,441✔
509
  pOpts->format = format;
101,441✔
510
  if ((code = tDecodeI64(&decoder, &reserved64))) goto _err;
101,441✔
511

512
  tEndDecode(&decoder);
101,441✔
513
  tDecoderClear(&decoder);
101,441✔
514
  return 0;
101,441✔
515

516
_err:
×
517
  tDecoderClear(&decoder);
×
518
  return code;
×
519
}
520

521
static int32_t tsdbRepOptsEstSize(STsdbRepOpts* pOpts) {
67,628✔
522
  int32_t dataLen = 0;
67,628✔
523
  dataLen += sizeof(SSyncTLV);
67,628✔
524
  dataLen += tTsdbRepOptsDataLenCalc(pOpts);
67,628✔
525
  return dataLen;
67,628✔
526
}
527

528
static int32_t tsdbRepOptsSerialize(STsdbRepOpts* pOpts, void* buf, int32_t bufLen) {
67,628✔
529
  SSyncTLV* pSubHead = buf;
67,628✔
530
  int32_t   offset = 0;
67,628✔
531
  int32_t   tlen = 0;
67,628✔
532
  if ((tlen = tSerializeTsdbRepOpts(pSubHead->val, bufLen, pOpts)) < 0) {
67,628✔
533
    return tlen;
×
534
  }
535
  pSubHead->typ = SNAP_DATA_RAW;
67,628✔
536
  pSubHead->len = tlen;
67,628✔
537
  offset += sizeof(*pSubHead) + tlen;
67,628✔
538
  return offset;
67,628✔
539
}
540

541
// snap info
542
static int32_t tsdbSnapPrepDealWithSnapInfo(SVnode* pVnode, SSnapshot* pSnap, STsdbRepOpts* pInfo) {
33,813✔
543
  if (!pSnap->data) {
33,813✔
544
    return 0;
×
545
  }
546
  int32_t code = 0;
33,813✔
547

548
  SSyncTLV* pHead = (void*)pSnap->data;
33,813✔
549
  int32_t   offset = 0;
33,813✔
550

551
  while (offset + sizeof(*pHead) < pHead->len) {
101,439✔
552
    SSyncTLV* pField = (void*)(pHead->val + offset);
67,626✔
553
    offset += sizeof(*pField) + pField->len;
67,626✔
554
    void*   buf = pField->val;
67,626✔
555
    int32_t bufLen = pField->len;
67,626✔
556

557
    switch (pField->typ) {
67,626✔
558
      case SNAP_DATA_TSDB:
33,813✔
559
      case SNAP_DATA_RSMA1:
560
      case SNAP_DATA_RSMA2: {
561
      } break;
33,813✔
562
      case SNAP_DATA_RAW: {
33,813✔
563
        code = tDeserializeTsdbRepOpts(buf, bufLen, pInfo);
33,813✔
564
        if (code < 0) {
33,813✔
565
          tsdbError("vgId:%d, failed to deserialize tsdb rep opts since %s", TD_VID(pVnode), terrstr());
×
566
          return code;
×
567
        }
568
      } break;
33,813✔
569
      default:
×
570
        code = TSDB_CODE_INVALID_MSG;
×
571
        tsdbError("vgId:%d, unexpected subfield type of snap info. typ:%d", TD_VID(pVnode), pField->typ);
×
572
        return code;
×
573
    }
574
  }
575

576
  return code;
33,813✔
577
}
578

579
int32_t tsdbSnapPrepDescription(SVnode* pVnode, SSnapshot* pSnap) {
67,628✔
580
  STsdbPartitionInfo  partitionInfo = {0};
67,628✔
581
  int                 code = 0;
67,628✔
582
  STsdbPartitionInfo* pInfo = &partitionInfo;
67,628✔
583

584
  code = tsdbPartitionInfoInit(pVnode, pInfo);
67,628✔
585
  if (code) {
67,628✔
586
    goto _out;
×
587
  }
588

589
  // deal with snap info for reply
590
  STsdbRepOpts opts = {.format = TSDB_SNAP_REP_FMT_RAW};
67,628✔
591
  if (pSnap->type == TDMT_SYNC_PREP_SNAPSHOT_REPLY) {
67,628✔
592
    STsdbRepOpts leaderOpts = {0};
33,813✔
593
    if ((code = tsdbSnapPrepDealWithSnapInfo(pVnode, pSnap, &leaderOpts)) < 0) {
33,813✔
594
      tsdbError("vgId:%d, failed to deal with snap info for reply since %s", TD_VID(pVnode), terrstr());
×
595
      goto _out;
×
596
    }
597
    opts.format = TMIN(opts.format, leaderOpts.format);
33,813✔
598
  }
599

600
  // info data realloc
601
  const int32_t headLen = sizeof(SSyncTLV);
67,628✔
602
  int32_t       bufLen = headLen;
67,628✔
603
  bufLen += tsdbPartitionInfoEstSize(pInfo);
67,628✔
604
  bufLen += tsdbRepOptsEstSize(&opts);
67,628✔
605
  if ((code = syncSnapInfoDataRealloc(pSnap, bufLen)) != 0) {
67,628✔
606
    tsdbError("vgId:%d, failed to realloc memory for data of snap info. bytes:%d", TD_VID(pVnode), bufLen);
×
607
    goto _out;
×
608
  }
609

610
  // serialization
611
  char*   buf = (void*)pSnap->data;
67,628✔
612
  int32_t offset = headLen;
67,628✔
613
  int32_t tlen = 0;
67,628✔
614

615
  if ((tlen = tsdbPartitionInfoSerialize(pInfo, (uint8_t*)(buf + offset), bufLen - offset)) < 0) {
67,628✔
616
    code = tlen;
×
617
    tsdbError("vgId:%d, failed to serialize tsdb partition info since %s", TD_VID(pVnode), terrstr());
×
618
    goto _out;
×
619
  }
620
  offset += tlen;
67,628✔
621

622
  if ((tlen = tsdbRepOptsSerialize(&opts, buf + offset, bufLen - offset)) < 0) {
67,628✔
623
    code = tlen;
×
624
    tsdbError("vgId:%d, failed to serialize tsdb rep opts since %s", TD_VID(pVnode), terrstr());
×
625
    goto _out;
×
626
  }
627
  offset += tlen;
67,628✔
628

629
  // set header of info data
630
  SSyncTLV* pHead = pSnap->data;
67,628✔
631
  pHead->typ = pSnap->type;
67,628✔
632
  pHead->len = offset - headLen;
67,628✔
633

634
  tsdbInfo("vgId:%d, tsdb snap info prepared. type:%s, val length:%d", TD_VID(pVnode), TMSG_INFO(pHead->typ),
67,628✔
635
           pHead->len);
636

637
_out:
67,628✔
638
  tsdbPartitionInfoClear(pInfo);
67,628✔
639
  return code;
67,628✔
640
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc