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

H
Hongze Cheng 已提交
16
#include "tsdbFSet2.h"
H
Hongze Cheng 已提交
17

H
Hongze Cheng 已提交
18
int32_t tsdbSttLvlInit(int32_t level, SSttLvl **lvl) {
H
Hongze Cheng 已提交
19
  if (!(lvl[0] = taosMemoryMalloc(sizeof(SSttLvl)))) return TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
20
  lvl[0]->level = level;
H
Hongze Cheng 已提交
21
  TARRAY2_INIT(lvl[0]->fobjArr);
H
Hongze Cheng 已提交
22 23
  return 0;
}
H
Hongze Cheng 已提交
24

H
Hongze Cheng 已提交
25 26 27 28 29 30 31 32
static void tsdbSttLvlClearFObj(void *data) { tsdbTFileObjUnref(*(STFileObj **)data); }

int32_t tsdbSttLvlClear(SSttLvl **lvl) {
  if (lvl[0] != NULL) {
    TARRAY2_DESTROY(lvl[0]->fobjArr, tsdbSttLvlClearFObj);
    taosMemoryFree(lvl[0]);
    lvl[0] = NULL;
  }
H
Hongze Cheng 已提交
33 34
  return 0;
}
H
Hongze Cheng 已提交
35

H
Hongze Cheng 已提交
36
static int32_t tsdbSttLvlInitEx(STsdb *pTsdb, const SSttLvl *lvl1, SSttLvl **lvl) {
H
Hongze Cheng 已提交
37 38 39 40
  int32_t code = tsdbSttLvlInit(lvl1->level, lvl);
  if (code) return code;

  const STFileObj *fobj1;
H
Hongze Cheng 已提交
41
  TARRAY2_FOREACH(lvl1->fobjArr, fobj1) {
H
Hongze Cheng 已提交
42
    STFileObj *fobj;
H
Hongze Cheng 已提交
43
    code = tsdbTFileObjInit(pTsdb, fobj1->f, &fobj);
H
Hongze Cheng 已提交
44 45 46 47 48
    if (code) {
      tsdbSttLvlClear(lvl);
      return code;
    }

H
Hongze Cheng 已提交
49
    TARRAY2_APPEND(lvl[0]->fobjArr, fobj);
H
Hongze Cheng 已提交
50 51 52 53
  }
  return 0;
}

H
Hongze Cheng 已提交
54 55 56 57 58 59 60 61 62 63 64 65 66
static int32_t tsdbSttLvlInitRef(STsdb *pTsdb, const SSttLvl *lvl1, SSttLvl **lvl) {
  int32_t code = tsdbSttLvlInit(lvl1->level, lvl);
  if (code) return code;

  STFileObj *fobj1;
  TARRAY2_FOREACH(lvl1->fobjArr, fobj1) {
    tsdbTFileObjRef(fobj1);
    code = TARRAY2_APPEND(lvl[0]->fobjArr, fobj1);
    if (code) return code;
  }
  return 0;
}

H
Hongze Cheng 已提交
67 68
static void tsdbSttLvlRemoveFObj(void *data) { tsdbTFileObjRemove(*(STFileObj **)data); }
static void tsdbSttLvlRemove(SSttLvl **lvl) {
H
Hongze Cheng 已提交
69
  TARRAY2_DESTROY(lvl[0]->fobjArr, tsdbSttLvlRemoveFObj);
H
Hongze Cheng 已提交
70 71 72 73
  taosMemoryFree(lvl[0]);
  lvl[0] = NULL;
}

H
Hongze Cheng 已提交
74 75 76 77 78 79
static int32_t tsdbSttLvlApplyEdit(STsdb *pTsdb, const SSttLvl *lvl1, SSttLvl *lvl2) {
  int32_t code = 0;

  ASSERT(lvl1->level == lvl2->level);

  int32_t i1 = 0, i2 = 0;
H
Hongze Cheng 已提交
80 81 82
  while (i1 < TARRAY2_SIZE(lvl1->fobjArr) || i2 < TARRAY2_SIZE(lvl2->fobjArr)) {
    STFileObj *fobj1 = i1 < TARRAY2_SIZE(lvl1->fobjArr) ? TARRAY2_GET(lvl1->fobjArr, i1) : NULL;
    STFileObj *fobj2 = i2 < TARRAY2_SIZE(lvl2->fobjArr) ? TARRAY2_GET(lvl2->fobjArr, i2) : NULL;
H
Hongze Cheng 已提交
83 84

    if (fobj1 && fobj2) {
H
Hongze Cheng 已提交
85
      if (fobj1->f->cid < fobj2->f->cid) {
H
Hongze Cheng 已提交
86
        // create a file obj
H
Hongze Cheng 已提交
87
        code = tsdbTFileObjInit(pTsdb, fobj1->f, &fobj2);
H
Hongze Cheng 已提交
88
        if (code) return code;
H
Hongze Cheng 已提交
89
        code = TARRAY2_APPEND(lvl2->fobjArr, fobj2);
H
Hongze Cheng 已提交
90 91 92
        if (code) return code;
        i1++;
        i2++;
H
Hongze Cheng 已提交
93
      } else if (fobj1->f->cid > fobj2->f->cid) {
H
Hongze Cheng 已提交
94
        // remove a file obj
H
Hongze Cheng 已提交
95
        TARRAY2_REMOVE(lvl2->fobjArr, i2, tsdbSttLvlRemoveFObj);
H
Hongze Cheng 已提交
96
      } else {
H
Hongze Cheng 已提交
97 98 99
        if (tsdbIsSameTFile(fobj1->f, fobj2->f)) {
          if (tsdbIsTFileChanged(fobj1->f, fobj2->f)) {
            fobj2->f[0] = fobj1->f[0];
H
Hongze Cheng 已提交
100 101
          }
        } else {
H
Hongze Cheng 已提交
102
          TARRAY2_REMOVE(lvl2->fobjArr, i2, tsdbSttLvlRemoveFObj);
H
Hongze Cheng 已提交
103
          code = tsdbTFileObjInit(pTsdb, fobj1->f, &fobj2);
H
Hongze Cheng 已提交
104
          if (code) return code;
H
Hongze Cheng 已提交
105
          code = TARRAY2_SORT_INSERT(lvl2->fobjArr, fobj2, tsdbTFileObjCmpr);
H
Hongze Cheng 已提交
106 107 108 109 110 111 112
          if (code) return code;
        }
        i1++;
        i2++;
      }
    } else if (fobj1) {
      // create a file obj
H
Hongze Cheng 已提交
113
      code = tsdbTFileObjInit(pTsdb, fobj1->f, &fobj2);
H
Hongze Cheng 已提交
114
      if (code) return code;
H
Hongze Cheng 已提交
115
      code = TARRAY2_APPEND(lvl2->fobjArr, fobj2);
H
Hongze Cheng 已提交
116 117 118 119 120
      if (code) return code;
      i1++;
      i2++;
    } else {
      // remove a file obj
H
Hongze Cheng 已提交
121
      TARRAY2_REMOVE(lvl2->fobjArr, i2, tsdbSttLvlRemoveFObj);
H
Hongze Cheng 已提交
122 123 124 125 126
    }
  }
  return 0;
}

H
Hongze Cheng 已提交
127 128 129
static int32_t tsdbSttLvlCmprFn(const SSttLvl **lvl1, const SSttLvl **lvl2) {
  if (lvl1[0]->level < lvl2[0]->level) return -1;
  if (lvl1[0]->level > lvl2[0]->level) return 1;
H
Hongze Cheng 已提交
130 131 132
  return 0;
}

H
Hongze Cheng 已提交
133
static int32_t tsdbSttLvlToJson(const SSttLvl *lvl, cJSON *json) {
H
Hongze Cheng 已提交
134
  if (cJSON_AddNumberToObject(json, "level", lvl->level) == NULL) {
H
Hongze Cheng 已提交
135 136 137
    return TSDB_CODE_OUT_OF_MEMORY;
  }

H
Hongze Cheng 已提交
138
  cJSON *ajson = cJSON_AddArrayToObject(json, "files");
H
Hongze Cheng 已提交
139
  if (ajson == NULL) return TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
140
  const STFileObj *fobj;
H
Hongze Cheng 已提交
141
  TARRAY2_FOREACH(lvl->fobjArr, fobj) {
H
Hongze Cheng 已提交
142 143
    cJSON *item = cJSON_CreateObject();
    if (item == NULL) return TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
144
    cJSON_AddItemToArray(ajson, item);
H
Hongze Cheng 已提交
145

H
Hongze Cheng 已提交
146
    int32_t code = tsdbTFileToJson(fobj->f, item);
H
Hongze Cheng 已提交
147
    if (code) return code;
H
Hongze Cheng 已提交
148
  }
H
Hongze Cheng 已提交
149 150 151 152

  return 0;
}

H
Hongze Cheng 已提交
153
static int32_t tsdbJsonToSttLvl(STsdb *pTsdb, const cJSON *json, SSttLvl **lvl) {
H
Hongze Cheng 已提交
154
  const cJSON *item1, *item2;
H
Hongze Cheng 已提交
155
  int32_t      level;
H
Hongze Cheng 已提交
156

H
Hongze Cheng 已提交
157
  item1 = cJSON_GetObjectItem(json, "level");
H
Hongze Cheng 已提交
158
  if (cJSON_IsNumber(item1)) {
H
Hongze Cheng 已提交
159
    level = item1->valuedouble;
H
Hongze Cheng 已提交
160 161 162 163
  } else {
    return TSDB_CODE_FILE_CORRUPTED;
  }

H
Hongze Cheng 已提交
164 165
  int32_t code = tsdbSttLvlInit(level, lvl);
  if (code) return code;
H
Hongze Cheng 已提交
166

H
Hongze Cheng 已提交
167
  item1 = cJSON_GetObjectItem(json, "files");
H
Hongze Cheng 已提交
168 169
  if (!cJSON_IsArray(item1)) {
    tsdbSttLvlClear(lvl);
H
Hongze Cheng 已提交
170 171 172
    return TSDB_CODE_FILE_CORRUPTED;
  }

H
Hongze Cheng 已提交
173 174 175 176 177 178 179
  cJSON_ArrayForEach(item2, item1) {
    STFile tf;
    code = tsdbJsonToTFile(item2, TSDB_FTYPE_STT, &tf);
    if (code) {
      tsdbSttLvlClear(lvl);
      return code;
    }
H
Hongze Cheng 已提交
180

H
Hongze Cheng 已提交
181
    STFileObj *fobj;
H
Hongze Cheng 已提交
182
    code = tsdbTFileObjInit(pTsdb, &tf, &fobj);
H
Hongze Cheng 已提交
183 184 185 186
    if (code) {
      tsdbSttLvlClear(lvl);
      return code;
    }
H
Hongze Cheng 已提交
187

H
Hongze Cheng 已提交
188
    TARRAY2_APPEND(lvl[0]->fobjArr, fobj);
H
Hongze Cheng 已提交
189 190 191 192
  }
  return 0;
}

H
Hongze Cheng 已提交
193
int32_t tsdbTFileSetToJson(const STFileSet *fset, cJSON *json) {
H
Hongze Cheng 已提交
194
  int32_t code = 0;
H
Hongze Cheng 已提交
195
  cJSON  *item1, *item2;
H
Hongze Cheng 已提交
196

H
Hongze Cheng 已提交
197 198 199 200
  // fid
  if (cJSON_AddNumberToObject(json, "fid", fset->fid) == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
H
Hongze Cheng 已提交
201

H
Hongze Cheng 已提交
202
  for (int32_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
H
Hongze Cheng 已提交
203
    if (fset->farr[ftype] == NULL) continue;
H
Hongze Cheng 已提交
204

H
Hongze Cheng 已提交
205
    code = tsdbTFileToJson(fset->farr[ftype]->f, json);
H
Hongze Cheng 已提交
206
    if (code) return code;
H
Hongze Cheng 已提交
207 208 209
  }

  // each level
H
Hongze Cheng 已提交
210
  item1 = cJSON_AddArrayToObject(json, "stt lvl");
H
Hongze Cheng 已提交
211
  if (item1 == NULL) return TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
212
  const SSttLvl *lvl;
H
Hongze Cheng 已提交
213
  TARRAY2_FOREACH(fset->lvlArr, lvl) {
H
Hongze Cheng 已提交
214 215 216 217
    item2 = cJSON_CreateObject();
    if (!item2) return TSDB_CODE_OUT_OF_MEMORY;
    cJSON_AddItemToArray(item1, item2);

H
Hongze Cheng 已提交
218
    code = tsdbSttLvlToJson(lvl, item2);
H
Hongze Cheng 已提交
219 220
    if (code) return code;
  }
H
Hongze Cheng 已提交
221 222

  return 0;
H
Hongze Cheng 已提交
223 224
}

H
Hongze Cheng 已提交
225
int32_t tsdbJsonToTFileSet(STsdb *pTsdb, const cJSON *json, STFileSet **fset) {
H
Hongze Cheng 已提交
226 227 228 229
  int32_t      code;
  const cJSON *item1, *item2;
  int32_t      fid;
  STFile       tf;
H
Hongze Cheng 已提交
230

H
Hongze Cheng 已提交
231 232 233 234 235 236 237
  // fid
  item1 = cJSON_GetObjectItem(json, "fid");
  if (cJSON_IsNumber(item1)) {
    fid = item1->valuedouble;
  } else {
    return TSDB_CODE_FILE_CORRUPTED;
  }
H
Hongze Cheng 已提交
238

H
Hongze Cheng 已提交
239 240
  code = tsdbTFileSetInit(fid, fset);
  if (code) return code;
H
Hongze Cheng 已提交
241

H
Hongze Cheng 已提交
242 243 244 245 246 247 248
  for (tsdb_ftype_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
    code = tsdbJsonToTFile(json, ftype, &tf);
    if (code == TSDB_CODE_NOT_FOUND) {
      continue;
    } else if (code) {
      tsdbTFileSetClear(fset);
      return code;
H
Hongze Cheng 已提交
249 250 251
    } else {
      code = tsdbTFileObjInit(pTsdb, &tf, &(*fset)->farr[ftype]);
      if (code) return code;
H
Hongze Cheng 已提交
252 253
    }
  }
H
Hongze Cheng 已提交
254

H
Hongze Cheng 已提交
255 256 257 258 259
  // each level
  item1 = cJSON_GetObjectItem(json, "stt lvl");
  if (cJSON_IsArray(item1)) {
    cJSON_ArrayForEach(item2, item1) {
      SSttLvl *lvl;
H
Hongze Cheng 已提交
260
      code = tsdbJsonToSttLvl(pTsdb, item2, &lvl);
H
Hongze Cheng 已提交
261 262 263 264 265
      if (code) {
        tsdbTFileSetClear(fset);
        return code;
      }

H
Hongze Cheng 已提交
266
      TARRAY2_APPEND((*fset)->lvlArr, lvl);
H
Hongze Cheng 已提交
267 268 269 270
    }
  } else {
    return TSDB_CODE_FILE_CORRUPTED;
  }
H
Hongze Cheng 已提交
271

H
Hongze Cheng 已提交
272
  return 0;
H
Hongze Cheng 已提交
273 274
}

H
Hongze Cheng 已提交
275
// NOTE: the api does not remove file, only do memory operation
H
Hongze Cheng 已提交
276
int32_t tsdbTFileSetEdit(STsdb *pTsdb, STFileSet *fset, const STFileOp *op) {
H
Hongze Cheng 已提交
277
  int32_t code = 0;
H
Hongze Cheng 已提交
278

H
Hongze Cheng 已提交
279 280 281 282 283 284
  if (op->optype == TSDB_FOP_CREATE) {
    // create a new file
    STFileObj *fobj;
    code = tsdbTFileObjInit(pTsdb, &op->nf, &fobj);
    if (code) return code;

H
Hongze Cheng 已提交
285
    if (fobj->f->type == TSDB_FTYPE_STT) {
H
Hongze Cheng 已提交
286
      SSttLvl *lvl = tsdbTFileSetGetSttLvl(fset, fobj->f->stt->level);
H
Hongze Cheng 已提交
287
      if (!lvl) {
H
Hongze Cheng 已提交
288
        code = tsdbSttLvlInit(fobj->f->stt->level, &lvl);
H
Hongze Cheng 已提交
289 290
        if (code) return code;

H
Hongze Cheng 已提交
291
        code = TARRAY2_SORT_INSERT(fset->lvlArr, lvl, tsdbSttLvlCmprFn);
H
Hongze Cheng 已提交
292 293 294
        if (code) return code;
      }

H
Hongze Cheng 已提交
295
      code = TARRAY2_SORT_INSERT(lvl->fobjArr, fobj, tsdbTFileObjCmpr);
H
Hongze Cheng 已提交
296 297
      if (code) return code;
    } else {
H
Hongze Cheng 已提交
298 299
      ASSERT(fset->farr[fobj->f->type] == NULL);
      fset->farr[fobj->f->type] = fobj;
H
Hongze Cheng 已提交
300 301 302 303
    }
  } else if (op->optype == TSDB_FOP_REMOVE) {
    // delete a file
    if (op->of.type == TSDB_FTYPE_STT) {
H
Hongze Cheng 已提交
304
      SSttLvl *lvl = tsdbTFileSetGetSttLvl(fset, op->of.stt->level);
H
Hongze Cheng 已提交
305 306
      ASSERT(lvl);

H
Hongze Cheng 已提交
307
      STFileObj  tfobj = {.f[0] = {.cid = op->of.cid}};
H
Hongze Cheng 已提交
308
      STFileObj *tfobjp = &tfobj;
H
Hongze Cheng 已提交
309
      int32_t    idx = TARRAY2_SEARCH_IDX(lvl->fobjArr, &tfobjp, tsdbTFileObjCmpr, TD_EQ);
H
Hongze Cheng 已提交
310
      ASSERT(idx >= 0);
H
Hongze Cheng 已提交
311
      TARRAY2_REMOVE(lvl->fobjArr, idx, tsdbSttLvlClearFObj);
H
Hongze Cheng 已提交
312

H
Hongze Cheng 已提交
313
      if (TARRAY2_SIZE(lvl->fobjArr) == 0) {
H
Hongze Cheng 已提交
314 315 316 317
        // TODO: remove the stt level if no file exists anymore
        // TARRAY2_REMOVE(&fset->lvlArr, lvl - fset->lvlArr.data, tsdbSttLvlClear);
      }
    } else {
H
Hongze Cheng 已提交
318
      ASSERT(tsdbIsSameTFile(&op->of, fset->farr[op->of.type]->f));
H
Hongze Cheng 已提交
319 320 321 322 323
      tsdbTFileObjUnref(fset->farr[op->of.type]);
      fset->farr[op->of.type] = NULL;
    }
  } else {
    if (op->nf.type == TSDB_FTYPE_STT) {
H
Hongze Cheng 已提交
324
      SSttLvl *lvl = tsdbTFileSetGetSttLvl(fset, op->of.stt->level);
H
Hongze Cheng 已提交
325 326
      ASSERT(lvl);

H
Hongze Cheng 已提交
327 328 329
      STFileObj   tfobj = {.f[0] = {.cid = op->of.cid}}, *tfobjp = &tfobj;
      STFileObj **fobjPtr = TARRAY2_SEARCH(lvl->fobjArr, &tfobjp, tsdbTFileObjCmpr, TD_EQ);
      tfobjp = (fobjPtr ? *fobjPtr : NULL);
H
Hongze Cheng 已提交
330 331 332

      ASSERT(tfobjp);

H
Hongze Cheng 已提交
333
      tfobjp->f[0] = op->nf;
H
Hongze Cheng 已提交
334
    } else {
H
Hongze Cheng 已提交
335
      fset->farr[op->nf.type]->f[0] = op->nf;
H
Hongze Cheng 已提交
336 337
    }
  }
H
Hongze Cheng 已提交
338

H
Hongze Cheng 已提交
339 340 341
  return 0;
}

H
Hongze Cheng 已提交
342 343 344 345 346 347
int32_t tsdbTFileSetApplyEdit(STsdb *pTsdb, const STFileSet *fset1, STFileSet *fset2) {
  int32_t code = 0;

  ASSERT(fset1->fid == fset2->fid);

  for (tsdb_ftype_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
H
Hongze Cheng 已提交
348 349
    if (!fset1->farr[ftype] && !fset2->farr[ftype]) continue;

H
Hongze Cheng 已提交
350 351 352 353
    STFileObj *fobj1 = fset1->farr[ftype];
    STFileObj *fobj2 = fset2->farr[ftype];

    if (fobj1 && fobj2) {
H
Hongze Cheng 已提交
354 355 356
      if (tsdbIsSameTFile(fobj1->f, fobj2->f)) {
        if (tsdbIsTFileChanged(fobj1->f, fobj2->f)) {
          fobj2->f[0] = fobj1->f[0];
H
Hongze Cheng 已提交
357 358 359
        }
      } else {
        tsdbTFileObjRemove(fobj2);
H
Hongze Cheng 已提交
360
        code = tsdbTFileObjInit(pTsdb, fobj1->f, &fset2->farr[ftype]);
H
Hongze Cheng 已提交
361 362 363 364
        if (code) return code;
      }
    } else if (fobj1) {
      // create a new file
H
Hongze Cheng 已提交
365
      code = tsdbTFileObjInit(pTsdb, fobj1->f, &fset2->farr[ftype]);
H
Hongze Cheng 已提交
366 367 368 369 370 371 372 373 374 375
      if (code) return code;
    } else {
      // remove the file
      tsdbTFileObjRemove(fobj2);
      fset2->farr[ftype] = NULL;
    }
  }

  // stt part
  int32_t i1 = 0, i2 = 0;
H
Hongze Cheng 已提交
376 377 378
  while (i1 < TARRAY2_SIZE(fset1->lvlArr) || i2 < TARRAY2_SIZE(fset2->lvlArr)) {
    SSttLvl *lvl1 = i1 < TARRAY2_SIZE(fset1->lvlArr) ? TARRAY2_GET(fset1->lvlArr, i1) : NULL;
    SSttLvl *lvl2 = i2 < TARRAY2_SIZE(fset2->lvlArr) ? TARRAY2_GET(fset2->lvlArr, i2) : NULL;
H
Hongze Cheng 已提交
379 380 381 382 383 384

    if (lvl1 && lvl2) {
      if (lvl1->level < lvl2->level) {
        // add a new stt level
        code = tsdbSttLvlInitEx(pTsdb, lvl1, &lvl2);
        if (code) return code;
H
Hongze Cheng 已提交
385
        code = TARRAY2_SORT_INSERT(fset2->lvlArr, lvl2, tsdbSttLvlCmprFn);
H
Hongze Cheng 已提交
386 387 388 389 390
        if (code) return code;
        i1++;
        i2++;
      } else if (lvl1->level > lvl2->level) {
        // remove the stt level
H
Hongze Cheng 已提交
391
        TARRAY2_REMOVE(fset2->lvlArr, i2, tsdbSttLvlRemove);
H
Hongze Cheng 已提交
392 393 394 395 396 397 398 399 400 401 402
      } else {
        // apply edit on stt level
        code = tsdbSttLvlApplyEdit(pTsdb, lvl1, lvl2);
        if (code) return code;
        i1++;
        i2++;
      }
    } else if (lvl1) {
      // add a new stt level
      code = tsdbSttLvlInitEx(pTsdb, lvl1, &lvl2);
      if (code) return code;
H
Hongze Cheng 已提交
403
      code = TARRAY2_SORT_INSERT(fset2->lvlArr, lvl2, tsdbSttLvlCmprFn);
H
Hongze Cheng 已提交
404 405 406 407 408
      if (code) return code;
      i1++;
      i2++;
    } else {
      // remove the stt level
H
Hongze Cheng 已提交
409
      TARRAY2_REMOVE(fset2->lvlArr, i2, tsdbSttLvlRemove);
H
Hongze Cheng 已提交
410 411 412
    }
  }

H
Hongze Cheng 已提交
413 414 415
  return 0;
}

H
Hongze Cheng 已提交
416
int32_t tsdbTFileSetInit(int32_t fid, STFileSet **fset) {
H
Hongze Cheng 已提交
417 418 419 420
  fset[0] = taosMemoryCalloc(1, sizeof(STFileSet));
  if (fset[0] == NULL) return TSDB_CODE_OUT_OF_MEMORY;

  fset[0]->fid = fid;
H
Hongze Cheng 已提交
421
  TARRAY2_INIT(fset[0]->lvlArr);
H
Hongze Cheng 已提交
422 423
  return 0;
}
H
Hongze Cheng 已提交
424

H
Hongze Cheng 已提交
425
int32_t tsdbTFileSetInitDup(STsdb *pTsdb, const STFileSet *fset1, STFileSet **fset) {
H
Hongze Cheng 已提交
426
  int32_t code = tsdbTFileSetInit(fset1->fid, fset);
H
Hongze Cheng 已提交
427
  if (code) return code;
H
Hongze Cheng 已提交
428 429 430 431

  for (int32_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
    if (fset1->farr[ftype] == NULL) continue;

H
Hongze Cheng 已提交
432
    code = tsdbTFileObjInit(pTsdb, fset1->farr[ftype]->f, &fset[0]->farr[ftype]);
H
Hongze Cheng 已提交
433
    if (code) {
H
Hongze Cheng 已提交
434
      tsdbTFileSetClear(fset);
H
Hongze Cheng 已提交
435 436
      return code;
    }
H
Hongze Cheng 已提交
437 438
  }

H
Hongze Cheng 已提交
439
  const SSttLvl *lvl1;
H
Hongze Cheng 已提交
440
  TARRAY2_FOREACH(fset1->lvlArr, lvl1) {
H
Hongze Cheng 已提交
441
    SSttLvl *lvl;
H
Hongze Cheng 已提交
442
    code = tsdbSttLvlInitEx(pTsdb, lvl1, &lvl);
H
Hongze Cheng 已提交
443
    if (code) {
H
Hongze Cheng 已提交
444
      tsdbTFileSetClear(fset);
H
Hongze Cheng 已提交
445
      return code;
H
Hongze Cheng 已提交
446
    }
H
Hongze Cheng 已提交
447

H
Hongze Cheng 已提交
448
    code = TARRAY2_APPEND(fset[0]->lvlArr, lvl);
H
Hongze Cheng 已提交
449
    if (code) return code;
H
Hongze Cheng 已提交
450
  }
H
Hongze Cheng 已提交
451

H
Hongze Cheng 已提交
452 453 454
  return 0;
}

H
Hongze Cheng 已提交
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
int32_t tsdbTFileSetInitRef(STsdb *pTsdb, const STFileSet *fset1, STFileSet **fset) {
  int32_t code = tsdbTFileSetInit(fset1->fid, fset);
  if (code) return code;

  for (int32_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
    if (fset1->farr[ftype] == NULL) continue;

    tsdbTFileObjRef(fset1->farr[ftype]);
    fset[0]->farr[ftype] = fset1->farr[ftype];
  }

  const SSttLvl *lvl1;
  TARRAY2_FOREACH(fset1->lvlArr, lvl1) {
    SSttLvl *lvl;
    code = tsdbSttLvlInitRef(pTsdb, lvl1, &lvl);
    if (code) {
      tsdbTFileSetClear(fset);
      return code;
    }

    code = TARRAY2_APPEND(fset[0]->lvlArr, lvl);
    if (code) return code;
  }

  return 0;
}

H
Hongze Cheng 已提交
482 483
int32_t tsdbTFileSetClear(STFileSet **fset) {
  if (!fset[0]) return 0;
H
Hongze Cheng 已提交
484

H
Hongze Cheng 已提交
485 486 487
  for (tsdb_ftype_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
    if (fset[0]->farr[ftype] == NULL) continue;
    tsdbTFileObjUnref(fset[0]->farr[ftype]);
H
Hongze Cheng 已提交
488
  }
H
Hongze Cheng 已提交
489

H
Hongze Cheng 已提交
490
  TARRAY2_DESTROY(fset[0]->lvlArr, tsdbSttLvlClear);
H
Hongze Cheng 已提交
491 492 493 494

  taosMemoryFree(fset[0]);
  fset[0] = NULL;

H
Hongze Cheng 已提交
495
  return 0;
H
Hongze Cheng 已提交
496
}
H
Hongze Cheng 已提交
497

H
Hongze Cheng 已提交
498 499 500 501 502 503
int32_t tsdbTFileSetRemove(STFileSet **fset) {
  for (tsdb_ftype_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
    if (fset[0]->farr[ftype] == NULL) continue;
    tsdbTFileObjRemove(fset[0]->farr[ftype]);
  }

H
Hongze Cheng 已提交
504
  TARRAY2_DESTROY(fset[0]->lvlArr, tsdbSttLvlRemove);
H
Hongze Cheng 已提交
505 506 507 508 509
  taosMemoryFree(fset[0]);
  fset[0] = NULL;
  return 0;
}

H
Hongze Cheng 已提交
510
SSttLvl *tsdbTFileSetGetSttLvl(STFileSet *fset, int32_t level) {
H
Hongze Cheng 已提交
511 512 513 514
  SSttLvl   sttLvl = {.level = level};
  SSttLvl  *lvl = &sttLvl;
  SSttLvl **lvlPtr = TARRAY2_SEARCH(fset->lvlArr, &lvl, tsdbSttLvlCmprFn, TD_EQ);
  return lvlPtr ? lvlPtr[0] : NULL;
H
Hongze Cheng 已提交
515 516 517 518 519 520
}

int32_t tsdbTFileSetCmprFn(const STFileSet **fset1, const STFileSet **fset2) {
  if (fset1[0]->fid < fset2[0]->fid) return -1;
  if (fset1[0]->fid > fset2[0]->fid) return 1;
  return 0;
H
Hongze Cheng 已提交
521 522 523 524 525 526
}

int64_t tsdbTFileSetMaxCid(const STFileSet *fset) {
  int64_t maxCid = 0;
  for (tsdb_ftype_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
    if (fset->farr[ftype] == NULL) continue;
H
Hongze Cheng 已提交
527
    maxCid = TMAX(maxCid, fset->farr[ftype]->f->cid);
H
Hongze Cheng 已提交
528 529 530
  }
  const SSttLvl   *lvl;
  const STFileObj *fobj;
H
Hongze Cheng 已提交
531 532
  TARRAY2_FOREACH(fset->lvlArr, lvl) {
    TARRAY2_FOREACH(lvl->fobjArr, fobj) { maxCid = TMAX(maxCid, fobj->f->cid); }
H
Hongze Cheng 已提交
533 534
  }
  return maxCid;
H
Hongze Cheng 已提交
535 536 537 538 539 540
}

bool tsdbTFileSetIsEmpty(const STFileSet *fset) {
  for (tsdb_ftype_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
    if (fset->farr[ftype] != NULL) return false;
  }
H
Hongze Cheng 已提交
541
  return TARRAY2_SIZE(fset->lvlArr) == 0;
H
Hongze Cheng 已提交
542
}