tsdbFSet.c 8.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 "inc/tsdbFSet.h"
H
Hongze Cheng 已提交
17

H
Hongze Cheng 已提交
18
static 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 21 22 23 24 25 26 27 28 29 30
  lvl[0]->level = level;
  TARRAY2_INIT(&lvl[0]->farr);
  return 0;
}
static void    tsdbSttLvlClearFObj(void *data) { tsdbTFileObjUnref(*(STFileObj **)data); }
static int32_t tsdbSttLvlClear(SSttLvl **lvl) {
  TARRAY2_CLEAR_FREE(&lvl[0]->farr, tsdbSttLvlClearFObj);
  taosMemoryFree(lvl[0]);
  lvl[0] = NULL;
  return 0;
}
H
Hongze Cheng 已提交
31
static int32_t tsdbSttLvlInitEx(STsdb *pTsdb, const SSttLvl *lvl1, SSttLvl **lvl) {
H
Hongze Cheng 已提交
32 33 34 35 36 37
  int32_t code = tsdbSttLvlInit(lvl1->level, lvl);
  if (code) return code;

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

    TARRAY2_APPEND(&lvl[0]->farr, fobj);
  }
  return 0;
}

H
Hongze Cheng 已提交
49 50 51
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 已提交
52 53 54
  return 0;
}

H
Hongze Cheng 已提交
55
static int32_t tsdbSttLvlToJson(const SSttLvl *lvl, cJSON *json) {
H
Hongze Cheng 已提交
56
  if (cJSON_AddNumberToObject(json, "level", lvl->level) == NULL) {
H
Hongze Cheng 已提交
57 58 59
    return TSDB_CODE_OUT_OF_MEMORY;
  }

H
Hongze Cheng 已提交
60
  cJSON *ajson = cJSON_AddArrayToObject(json, "files");
H
Hongze Cheng 已提交
61
  if (ajson == NULL) return TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
62 63
  const STFileObj *fobj;
  TARRAY2_FOREACH(&lvl->farr, fobj) {
H
Hongze Cheng 已提交
64 65
    cJSON *item = cJSON_CreateObject();
    if (item == NULL) return TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
66
    cJSON_AddItemToArray(ajson, item);
H
Hongze Cheng 已提交
67

H
Hongze Cheng 已提交
68
    int32_t code = tsdbTFileToJson(&fobj->f, item);
H
Hongze Cheng 已提交
69
    if (code) return code;
H
Hongze Cheng 已提交
70
  }
H
Hongze Cheng 已提交
71 72 73 74

  return 0;
}

H
Hongze Cheng 已提交
75
static int32_t tsdbJsonToSttLvl(STsdb *pTsdb, const cJSON *json, SSttLvl **lvl) {
H
Hongze Cheng 已提交
76
  const cJSON *item1, *item2;
H
Hongze Cheng 已提交
77
  int32_t      level;
H
Hongze Cheng 已提交
78

H
Hongze Cheng 已提交
79
  item1 = cJSON_GetObjectItem(json, "level");
H
Hongze Cheng 已提交
80
  if (cJSON_IsNumber(item1)) {
H
Hongze Cheng 已提交
81
    level = item1->valuedouble;
H
Hongze Cheng 已提交
82 83 84 85
  } else {
    return TSDB_CODE_FILE_CORRUPTED;
  }

H
Hongze Cheng 已提交
86 87
  int32_t code = tsdbSttLvlInit(level, lvl);
  if (code) return code;
H
Hongze Cheng 已提交
88

H
Hongze Cheng 已提交
89
  item1 = cJSON_GetObjectItem(json, "files");
H
Hongze Cheng 已提交
90 91
  if (!cJSON_IsArray(item1)) {
    tsdbSttLvlClear(lvl);
H
Hongze Cheng 已提交
92 93 94
    return TSDB_CODE_FILE_CORRUPTED;
  }

H
Hongze Cheng 已提交
95 96 97 98 99 100 101
  cJSON_ArrayForEach(item2, item1) {
    STFile tf;
    code = tsdbJsonToTFile(item2, TSDB_FTYPE_STT, &tf);
    if (code) {
      tsdbSttLvlClear(lvl);
      return code;
    }
H
Hongze Cheng 已提交
102

H
Hongze Cheng 已提交
103
    STFileObj *fobj;
H
Hongze Cheng 已提交
104
    code = tsdbTFileObjInit(pTsdb, &tf, &fobj);
H
Hongze Cheng 已提交
105 106 107 108
    if (code) {
      tsdbSttLvlClear(lvl);
      return code;
    }
H
Hongze Cheng 已提交
109

H
Hongze Cheng 已提交
110
    TARRAY2_APPEND(&lvl[0]->farr, fobj);
H
Hongze Cheng 已提交
111 112 113 114
  }
  return 0;
}

H
Hongze Cheng 已提交
115
int32_t tsdbTFileSetToJson(const STFileSet *fset, cJSON *json) {
H
Hongze Cheng 已提交
116
  int32_t code = 0;
H
Hongze Cheng 已提交
117
  cJSON  *item1, *item2;
H
Hongze Cheng 已提交
118

H
Hongze Cheng 已提交
119 120 121 122
  // fid
  if (cJSON_AddNumberToObject(json, "fid", fset->fid) == NULL) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
H
Hongze Cheng 已提交
123

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

H
Hongze Cheng 已提交
127 128
    code = tsdbTFileToJson(&fset->farr[ftype]->f, json);
    if (code) return code;
H
Hongze Cheng 已提交
129 130 131
  }

  // each level
H
Hongze Cheng 已提交
132
  item1 = cJSON_AddArrayToObject(json, "stt lvl");
H
Hongze Cheng 已提交
133
  if (item1 == NULL) return TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
134 135
  const SSttLvl *lvl;
  TARRAY2_FOREACH(&fset->lvlArr, lvl) {
H
Hongze Cheng 已提交
136 137 138 139
    item2 = cJSON_CreateObject();
    if (!item2) return TSDB_CODE_OUT_OF_MEMORY;
    cJSON_AddItemToArray(item1, item2);

H
Hongze Cheng 已提交
140
    code = tsdbSttLvlToJson(lvl, item2);
H
Hongze Cheng 已提交
141 142
    if (code) return code;
  }
H
Hongze Cheng 已提交
143 144

  return 0;
H
Hongze Cheng 已提交
145 146
}

H
Hongze Cheng 已提交
147
int32_t tsdbJsonToTFileSet(STsdb *pTsdb, const cJSON *json, STFileSet **fset) {
H
Hongze Cheng 已提交
148 149 150 151
  int32_t      code;
  const cJSON *item1, *item2;
  int32_t      fid;
  STFile       tf;
H
Hongze Cheng 已提交
152

H
Hongze Cheng 已提交
153 154 155 156 157 158 159
  // fid
  item1 = cJSON_GetObjectItem(json, "fid");
  if (cJSON_IsNumber(item1)) {
    fid = item1->valuedouble;
  } else {
    return TSDB_CODE_FILE_CORRUPTED;
  }
H
Hongze Cheng 已提交
160

H
Hongze Cheng 已提交
161 162
  code = tsdbTFileSetInit(fid, fset);
  if (code) return code;
H
Hongze Cheng 已提交
163

H
Hongze Cheng 已提交
164 165 166 167 168 169 170
  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 已提交
171 172 173
    } else {
      code = tsdbTFileObjInit(pTsdb, &tf, &(*fset)->farr[ftype]);
      if (code) return code;
H
Hongze Cheng 已提交
174 175
    }
  }
H
Hongze Cheng 已提交
176

H
Hongze Cheng 已提交
177 178 179 180 181
  // each level
  item1 = cJSON_GetObjectItem(json, "stt lvl");
  if (cJSON_IsArray(item1)) {
    cJSON_ArrayForEach(item2, item1) {
      SSttLvl *lvl;
H
Hongze Cheng 已提交
182
      code = tsdbJsonToSttLvl(pTsdb, item2, &lvl);
H
Hongze Cheng 已提交
183 184 185 186 187 188 189 190 191 192
      if (code) {
        tsdbTFileSetClear(fset);
        return code;
      }

      TARRAY2_APPEND(&(*fset)->lvlArr, lvl);
    }
  } else {
    return TSDB_CODE_FILE_CORRUPTED;
  }
H
Hongze Cheng 已提交
193

H
Hongze Cheng 已提交
194
  return 0;
H
Hongze Cheng 已提交
195 196
}

H
Hongze Cheng 已提交
197
int32_t tsdbTFileSetEdit(STsdb *pTsdb, STFileSet *fset, const STFileOp *op) {
H
Hongze Cheng 已提交
198
  int32_t code = 0;
H
Hongze Cheng 已提交
199

H
Hongze Cheng 已提交
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
  if (op->oState.size == 0  //
      || 0                  /* TODO*/
  ) {
    STFileObj *fobj;
    code = tsdbTFileObjInit(pTsdb, &op->nState, &fobj);
    if (code) return code;

    if (fobj->f.type == TSDB_FTYPE_STT) {
      SSttLvl *lvl = tsdbTFileSetGetLvl(fset, fobj->f.stt.level);
      if (!lvl) {
        code = tsdbSttLvlInit(fobj->f.stt.level, &lvl);
        if (code) return code;

        code = TARRAY2_SORT_INSERT(&fset->lvlArr, lvl, tsdbSttLvlCmprFn);
        if (code) return code;
      }

      code = TARRAY2_SORT_INSERT(&lvl->farr, fobj, tsdbTFileObjCmpr);
      if (code) return code;
    } else {
      fset->farr[fobj->f.type] = fobj;
    }
  } else if (op->nState.size == 0) {
    // delete
    ASSERT(0);
  } else {
    // modify
    ASSERT(0);
  }

H
Hongze Cheng 已提交
230 231 232
  return 0;
}

H
Hongze Cheng 已提交
233
int32_t tsdbTFileSetEditEx(const STFileSet *fset1, STFileSet *fset) {
H
Hongze Cheng 已提交
234
  ASSERT(fset1->fid == fset->fid);
H
Hongze Cheng 已提交
235
  ASSERT(0);
H
Hongze Cheng 已提交
236 237 238
  return 0;
}

H
Hongze Cheng 已提交
239
int32_t tsdbTFileSetInit(int32_t fid, STFileSet **fset) {
H
Hongze Cheng 已提交
240 241 242 243 244 245 246
  fset[0] = taosMemoryCalloc(1, sizeof(STFileSet));
  if (fset[0] == NULL) return TSDB_CODE_OUT_OF_MEMORY;

  fset[0]->fid = fid;
  TARRAY2_INIT(&fset[0]->lvlArr);
  return 0;
}
H
Hongze Cheng 已提交
247

H
Hongze Cheng 已提交
248
int32_t tsdbTFileSetInitEx(STsdb *pTsdb, const STFileSet *fset1, STFileSet **fset) {
H
Hongze Cheng 已提交
249
  int32_t code = tsdbTFileSetInit(fset1->fid, fset);
H
Hongze Cheng 已提交
250
  if (code) return code;
H
Hongze Cheng 已提交
251 252 253 254

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

H
Hongze Cheng 已提交
255
    code = tsdbTFileObjInit(pTsdb, &fset1->farr[ftype]->f, &fset[0]->farr[ftype]);
H
Hongze Cheng 已提交
256
    if (code) {
H
Hongze Cheng 已提交
257
      tsdbTFileSetClear(fset);
H
Hongze Cheng 已提交
258 259
      return code;
    }
H
Hongze Cheng 已提交
260 261
  }

H
Hongze Cheng 已提交
262 263 264
  const SSttLvl *lvl1;
  TARRAY2_FOREACH(&fset1->lvlArr, lvl1) {
    SSttLvl *lvl;
H
Hongze Cheng 已提交
265
    code = tsdbSttLvlInitEx(pTsdb, lvl1, &lvl);
H
Hongze Cheng 已提交
266
    if (code) {
H
Hongze Cheng 已提交
267
      tsdbTFileSetClear(fset);
H
Hongze Cheng 已提交
268
      return code;
H
Hongze Cheng 已提交
269
    }
H
Hongze Cheng 已提交
270

H
Hongze Cheng 已提交
271 272
    code = TARRAY2_APPEND(&fset[0]->lvlArr, lvl);
    if (code) return code;
H
Hongze Cheng 已提交
273
  }
H
Hongze Cheng 已提交
274

H
Hongze Cheng 已提交
275 276 277
  return 0;
}

H
Hongze Cheng 已提交
278 279
int32_t tsdbTFileSetClear(STFileSet **fset) {
  if (!fset[0]) return 0;
H
Hongze Cheng 已提交
280

H
Hongze Cheng 已提交
281 282 283
  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 已提交
284
  }
H
Hongze Cheng 已提交
285 286 287 288 289 290

  TARRAY2_CLEAR_FREE(&fset[0]->lvlArr, tsdbSttLvlClear);

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

H
Hongze Cheng 已提交
291
  return 0;
H
Hongze Cheng 已提交
292
}
H
Hongze Cheng 已提交
293

H
Hongze Cheng 已提交
294 295 296
SSttLvl *tsdbTFileSetGetLvl(const STFileSet *fset, int32_t level) {
  SSttLvl  tlvl = {.level = level};
  SSttLvl *lvl = &tlvl;
H
Hongze Cheng 已提交
297
  return TARRAY2_SEARCH(&fset->lvlArr, &lvl, tsdbSttLvlCmprFn, TD_EQ);
H
Hongze Cheng 已提交
298 299 300 301 302 303
}

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 已提交
304 305 306 307 308 309 310 311 312 313 314 315 316 317
}

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;
    maxCid = TMAX(maxCid, fset->farr[ftype]->f.cid);
  }
  const SSttLvl   *lvl;
  const STFileObj *fobj;
  TARRAY2_FOREACH(&fset->lvlArr, lvl) {
    TARRAY2_FOREACH(&lvl->farr, fobj) { maxCid = TMAX(maxCid, fobj->f.cid); }
  }
  return maxCid;
H
Hongze Cheng 已提交
318
}