2023-03-27 08:30:22 +00:00
|
|
|
/*
|
|
|
|
|
* 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/>.
|
|
|
|
|
*/
|
|
|
|
|
|
2023-05-08 02:27:55 +00:00
|
|
|
#include "inc/tsdbFSet.h"
|
2023-04-10 09:52:51 +00:00
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
static int32_t tsdbSttLvlInit(int32_t level, SSttLvl **lvl) {
|
|
|
|
|
lvl[0] = taosMemoryMalloc(sizeof(SSttLvl));
|
|
|
|
|
if (lvl[0] == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
static int32_t tsdbSttLvlInitEx(const SSttLvl *lvl1, SSttLvl **lvl) {
|
|
|
|
|
int32_t code = tsdbSttLvlInit(lvl1->level, lvl);
|
|
|
|
|
if (code) return code;
|
|
|
|
|
|
|
|
|
|
const STFileObj *fobj1;
|
|
|
|
|
TARRAY2_FOREACH(&lvl1->farr, fobj1) {
|
|
|
|
|
STFileObj *fobj;
|
|
|
|
|
code = tsdbTFileObjInit(&fobj1->f, &fobj);
|
|
|
|
|
if (code) {
|
|
|
|
|
tsdbSttLvlClear(lvl);
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TARRAY2_APPEND(&lvl[0]->farr, fobj);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int32_t tsdbSttLvlToJson(const SSttLvl *lvl, cJSON *json) {
|
2023-05-16 07:19:13 +00:00
|
|
|
if (cJSON_AddNumberToObject(json, "level", lvl->level) == NULL) {
|
2023-05-08 08:16:45 +00:00
|
|
|
return TSDB_CODE_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-16 02:34:02 +00:00
|
|
|
cJSON *ajson = cJSON_AddArrayToObject(json, "files");
|
2023-05-16 01:36:32 +00:00
|
|
|
if (ajson == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
2023-05-19 07:16:01 +00:00
|
|
|
const STFileObj *fobj;
|
|
|
|
|
TARRAY2_FOREACH(&lvl->farr, fobj) {
|
2023-05-16 01:36:32 +00:00
|
|
|
cJSON *item = cJSON_CreateObject();
|
|
|
|
|
if (item == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
2023-05-16 02:34:02 +00:00
|
|
|
cJSON_AddItemToArray(ajson, item);
|
2023-05-08 08:16:45 +00:00
|
|
|
|
2023-05-16 01:36:32 +00:00
|
|
|
int32_t code = tsdbTFileToJson(&fobj->f, item);
|
2023-05-16 02:34:02 +00:00
|
|
|
if (code) return code;
|
2023-05-16 01:36:32 +00:00
|
|
|
}
|
2023-05-08 08:16:45 +00:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
static int32_t tsdbJsonToSttLvl(const cJSON *json, SSttLvl **lvl) {
|
2023-05-16 03:39:53 +00:00
|
|
|
const cJSON *item1, *item2;
|
2023-05-19 07:16:01 +00:00
|
|
|
int32_t level;
|
2023-05-16 03:39:53 +00:00
|
|
|
|
2023-05-16 07:19:13 +00:00
|
|
|
item1 = cJSON_GetObjectItem(json, "level");
|
2023-05-16 03:39:53 +00:00
|
|
|
if (cJSON_IsNumber(item1)) {
|
2023-05-19 07:16:01 +00:00
|
|
|
level = item1->valuedouble;
|
2023-05-16 03:39:53 +00:00
|
|
|
} else {
|
|
|
|
|
return TSDB_CODE_FILE_CORRUPTED;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
int32_t code = tsdbSttLvlInit(level, lvl);
|
|
|
|
|
if (code) return code;
|
2023-05-16 06:35:57 +00:00
|
|
|
|
2023-05-16 03:39:53 +00:00
|
|
|
item1 = cJSON_GetObjectItem(json, "files");
|
2023-05-19 07:16:01 +00:00
|
|
|
if (!cJSON_IsArray(item1)) {
|
|
|
|
|
tsdbSttLvlClear(lvl);
|
2023-05-16 03:39:53 +00:00
|
|
|
return TSDB_CODE_FILE_CORRUPTED;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
cJSON_ArrayForEach(item2, item1) {
|
|
|
|
|
STFile tf;
|
|
|
|
|
code = tsdbJsonToTFile(item2, TSDB_FTYPE_STT, &tf);
|
|
|
|
|
if (code) {
|
|
|
|
|
tsdbSttLvlClear(lvl);
|
|
|
|
|
return code;
|
|
|
|
|
}
|
2023-05-15 07:47:06 +00:00
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
STFileObj *fobj;
|
|
|
|
|
code = tsdbTFileObjInit(&tf, &fobj);
|
|
|
|
|
if (code) {
|
|
|
|
|
tsdbSttLvlClear(lvl);
|
|
|
|
|
return code;
|
|
|
|
|
}
|
2023-05-16 03:09:15 +00:00
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
TARRAY2_APPEND(&lvl[0]->farr, fobj);
|
2023-05-16 03:09:15 +00:00
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
int32_t tsdbTFileSetToJson(const STFileSet *fset, cJSON *json) {
|
2023-04-10 09:52:51 +00:00
|
|
|
int32_t code = 0;
|
2023-05-16 07:19:13 +00:00
|
|
|
cJSON *item1, *item2;
|
2023-04-10 09:52:51 +00:00
|
|
|
|
2023-05-08 08:16:45 +00:00
|
|
|
// fid
|
|
|
|
|
if (cJSON_AddNumberToObject(json, "fid", fset->fid) == NULL) {
|
|
|
|
|
return TSDB_CODE_OUT_OF_MEMORY;
|
|
|
|
|
}
|
2023-04-10 09:52:51 +00:00
|
|
|
|
2023-05-08 08:16:45 +00:00
|
|
|
for (int32_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
|
2023-05-16 02:34:02 +00:00
|
|
|
if (fset->farr[ftype] == NULL) continue;
|
2023-05-08 08:16:45 +00:00
|
|
|
|
2023-05-16 01:36:32 +00:00
|
|
|
code = tsdbTFileToJson(&fset->farr[ftype]->f, json);
|
|
|
|
|
if (code) return code;
|
2023-05-08 08:16:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// each level
|
2023-05-19 07:16:01 +00:00
|
|
|
item1 = cJSON_AddArrayToObject(json, "stt lvl");
|
2023-05-16 07:19:13 +00:00
|
|
|
if (item1 == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
2023-05-19 05:35:32 +00:00
|
|
|
const SSttLvl *lvl;
|
|
|
|
|
TARRAY2_FOREACH(&fset->lvlArr, lvl) {
|
2023-05-16 07:19:13 +00:00
|
|
|
item2 = cJSON_CreateObject();
|
|
|
|
|
if (!item2) return TSDB_CODE_OUT_OF_MEMORY;
|
|
|
|
|
cJSON_AddItemToArray(item1, item2);
|
|
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
code = tsdbSttLvlToJson(lvl, item2);
|
2023-05-16 01:36:32 +00:00
|
|
|
if (code) return code;
|
|
|
|
|
}
|
2023-05-08 08:16:45 +00:00
|
|
|
|
|
|
|
|
return 0;
|
2023-04-11 09:04:52 +00:00
|
|
|
}
|
|
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
int32_t tsdbJsonToTFileSet(const cJSON *json, STFileSet **fset) {
|
|
|
|
|
int32_t code;
|
|
|
|
|
const cJSON *item1, *item2;
|
|
|
|
|
int32_t fid;
|
|
|
|
|
STFile tf;
|
2023-05-19 05:35:32 +00:00
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
// fid
|
|
|
|
|
item1 = cJSON_GetObjectItem(json, "fid");
|
|
|
|
|
if (cJSON_IsNumber(item1)) {
|
|
|
|
|
fid = item1->valuedouble;
|
|
|
|
|
} else {
|
|
|
|
|
return TSDB_CODE_FILE_CORRUPTED;
|
|
|
|
|
}
|
2023-05-19 05:35:32 +00:00
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
code = tsdbTFileSetInit(fid, fset);
|
|
|
|
|
if (code) return code;
|
2023-05-19 05:35:32 +00:00
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-08 10:15:31 +00:00
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
// each level
|
|
|
|
|
item1 = cJSON_GetObjectItem(json, "stt lvl");
|
|
|
|
|
if (cJSON_IsArray(item1)) {
|
|
|
|
|
cJSON_ArrayForEach(item2, item1) {
|
|
|
|
|
SSttLvl *lvl;
|
|
|
|
|
code = tsdbJsonToSttLvl(item2, &lvl);
|
|
|
|
|
if (code) {
|
|
|
|
|
tsdbTFileSetClear(fset);
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TARRAY2_APPEND(&(*fset)->lvlArr, lvl);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return TSDB_CODE_FILE_CORRUPTED;
|
|
|
|
|
}
|
2023-05-08 10:15:31 +00:00
|
|
|
|
2023-05-11 10:16:55 +00:00
|
|
|
return 0;
|
2023-05-12 01:07:50 +00:00
|
|
|
}
|
|
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
int32_t tsdbTFileSetEdit(STFileSet *fset, const STFileOp *op) {
|
2023-05-16 06:35:57 +00:00
|
|
|
int32_t code = 0;
|
2023-05-12 08:23:07 +00:00
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
// if (op->oState.size == 0 //
|
|
|
|
|
// || 0 /* TODO*/
|
|
|
|
|
// ) {
|
|
|
|
|
// STFileObj *fobj;
|
|
|
|
|
// // code = tsdbTFileObjCreate(&fobj);
|
|
|
|
|
// if (code) return code;
|
|
|
|
|
// fobj->f = op->nState;
|
|
|
|
|
// add_file_to_fset(fset, fobj);
|
|
|
|
|
// } else if (op->nState.size == 0) {
|
|
|
|
|
// // delete
|
|
|
|
|
// ASSERT(0);
|
|
|
|
|
// } else {
|
|
|
|
|
// // modify
|
|
|
|
|
// ASSERT(0);
|
|
|
|
|
// }
|
2023-05-12 08:23:07 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
int32_t tsdbTFileSetInit(int32_t fid, STFileSet **fset) {
|
2023-05-19 05:35:32 +00:00
|
|
|
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;
|
|
|
|
|
}
|
2023-05-12 08:23:07 +00:00
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
int32_t tsdbTFileSetInitEx(const STFileSet *fset1, STFileSet **fset) {
|
|
|
|
|
int32_t code = tsdbTFileSetInit(fset1->fid, fset);
|
2023-05-19 05:35:32 +00:00
|
|
|
if (code) return code;
|
2023-05-17 08:46:10 +00:00
|
|
|
|
|
|
|
|
for (int32_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
|
|
|
|
|
if (fset1->farr[ftype] == NULL) continue;
|
|
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
code = tsdbTFileObjInit(&fset1->farr[ftype]->f, &fset[0]->farr[ftype]);
|
2023-05-19 05:35:32 +00:00
|
|
|
if (code) {
|
2023-05-19 07:16:01 +00:00
|
|
|
tsdbTFileSetClear(fset);
|
2023-05-19 05:35:32 +00:00
|
|
|
return code;
|
|
|
|
|
}
|
2023-05-17 08:46:10 +00:00
|
|
|
}
|
|
|
|
|
|
2023-05-19 05:35:32 +00:00
|
|
|
const SSttLvl *lvl1;
|
|
|
|
|
TARRAY2_FOREACH(&fset1->lvlArr, lvl1) {
|
|
|
|
|
SSttLvl *lvl;
|
2023-05-19 07:16:01 +00:00
|
|
|
code = tsdbSttLvlInitEx(lvl1, &lvl);
|
2023-05-19 05:35:32 +00:00
|
|
|
if (code) {
|
2023-05-19 07:16:01 +00:00
|
|
|
tsdbTFileSetClear(fset);
|
2023-05-19 05:35:32 +00:00
|
|
|
return code;
|
2023-05-17 08:46:10 +00:00
|
|
|
}
|
2023-05-19 07:16:01 +00:00
|
|
|
|
|
|
|
|
TARRAY2_APPEND(&fset[0]->lvlArr, lvl);
|
2023-05-17 08:46:10 +00:00
|
|
|
}
|
2023-05-19 05:35:32 +00:00
|
|
|
|
2023-05-17 08:46:10 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
int32_t tsdbTFileSetClear(STFileSet **fset) {
|
|
|
|
|
if (!fset[0]) return 0;
|
2023-05-19 05:35:32 +00:00
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
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]);
|
2023-05-19 05:35:32 +00:00
|
|
|
}
|
2023-05-19 07:16:01 +00:00
|
|
|
|
|
|
|
|
TARRAY2_CLEAR_FREE(&fset[0]->lvlArr, tsdbSttLvlClear);
|
|
|
|
|
|
|
|
|
|
taosMemoryFree(fset[0]);
|
|
|
|
|
fset[0] = NULL;
|
|
|
|
|
|
2023-05-12 01:07:50 +00:00
|
|
|
return 0;
|
2023-05-12 08:23:07 +00:00
|
|
|
}
|
2023-05-18 07:06:21 +00:00
|
|
|
|
2023-05-19 07:16:01 +00:00
|
|
|
const SSttLvl *tsdbTFileSetGetLvl(const STFileSet *fset, int32_t level) {
|
2023-05-19 05:35:32 +00:00
|
|
|
// SSttLvl tlvl = {.level = level};
|
|
|
|
|
// SRBTreeNode *node = tRBTreeGet(&fset->lvlTree, &tlvl.rbtn);
|
|
|
|
|
// return node ? TCONTAINER_OF(node, SSttLvl, rbtn) : NULL;
|
|
|
|
|
// TODO
|
|
|
|
|
return NULL;
|
2023-05-18 07:06:21 +00:00
|
|
|
}
|