feat: add tsdbSnapDiff

This commit is contained in:
Benguang Zhao 2023-09-05 15:14:43 +08:00
parent 6ae9bd0e9a
commit 44a7f5df47
1 changed files with 243 additions and 11 deletions

View File

@ -983,7 +983,7 @@ int32_t tsdbFSDestroyRefSnapshot(TFileSetArray **fsetArr) {
return 0; return 0;
} }
int32_t tsdbTSnapRangeCmprFn(STSnapRange *fsr1, STSnapRange *fsr2) { static int32_t tsdbTSnapRangeCmprFn(STSnapRange *fsr1, STSnapRange *fsr2) {
if (fsr1->fid < fsr2->fid) return -1; if (fsr1->fid < fsr2->fid) return -1;
if (fsr1->fid > fsr2->fid) return 1; if (fsr1->fid > fsr2->fid) return 1;
if (fsr1->sver < fsr2->sver) return -1; if (fsr1->sver < fsr2->sver) return -1;
@ -993,7 +993,7 @@ int32_t tsdbTSnapRangeCmprFn(STSnapRange *fsr1, STSnapRange *fsr2) {
return 0; return 0;
} }
int32_t tsdbTFileInsertSnapRange(STFile *f, TSnapRangeArray *snapR) { static int32_t tsdbTFileInsertSnapRange(STFile *f, TSnapRangeArray *snapR) {
STSnapRange *fsr = taosMemoryCalloc(1, sizeof(*fsr)); STSnapRange *fsr = taosMemoryCalloc(1, sizeof(*fsr));
if (fsr == NULL) { if (fsr == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY; terrno = TSDB_CODE_OUT_OF_MEMORY;
@ -1011,7 +1011,7 @@ int32_t tsdbTFileInsertSnapRange(STFile *f, TSnapRangeArray *snapR) {
return code; return code;
} }
int32_t tsdbTFSetInsertSnapRange(STFileSet *fset, TSnapRangeArray *snapR) { static int32_t tsdbTFSetInsertSnapRange(STFileSet *fset, TSnapRangeArray *snapR) {
STFile tf = {.fid = fset->fid, .minVer = VERSION_MAX, .maxVer = VERSION_MIN}; STFile tf = {.fid = fset->fid, .minVer = VERSION_MAX, .maxVer = VERSION_MIN};
for (int32_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) { for (int32_t ftype = TSDB_FTYPE_MIN; ftype < TSDB_FTYPE_MAX; ++ftype) {
if (fset->farr[ftype] == NULL) continue; if (fset->farr[ftype] == NULL) continue;
@ -1058,24 +1058,246 @@ TSnapRangeArray *tsdbFSToSnapRangeArray(STFileSystem *fs) {
return snapR; return snapR;
} }
static STSnapRange *taosDupSnapRange(STSnapRange *x) {
STSnapRange *y = taosMemoryCalloc(1, sizeof(STSnapRange));
if (y == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
ASSERTS(terrno == 0, "Out of memory");
return NULL;
}
y->fid = x->fid;
y->sver = x->sver;
y->ever = x->ever;
return y;
}
static TSnapRangeArray *taosDupSnapRangeArray(const TSnapRangeArray *X) {
TSnapRangeArray *Y = taosMemoryCalloc(1, sizeof(*Y));
if (Y == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return NULL;
}
TARRAY2_INIT(Y);
if (X) {
STSnapRange *x;
TARRAY2_FOREACH(X, x) {
STSnapRange *tp = taosDupSnapRange(x);
TARRAY2_APPEND(Y, tp);
}
}
return Y;
}
static TSnapRangeArray *tsdbSnapDiff(const TSnapRangeArray *snapR, const TSnapRangeArray *pExclude) {
TSnapRangeArray *Z = NULL;
TSnapRangeArray *U = NULL;
TSnapRangeArray *V = NULL;
TSnapRangeArray *X = taosDupSnapRangeArray(snapR);
TSnapRangeArray *Y = taosDupSnapRangeArray(pExclude);
int32_t code = -1;
// separate intersections of snap ranges
U = taosMemoryCalloc(1, sizeof(TSnapRangeArray));
if (U == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
goto _out;
}
TARRAY2_INIT(U);
V = taosMemoryCalloc(1, sizeof(TSnapRangeArray));
if (V == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
goto _out;
}
TARRAY2_INIT(V);
int32_t i = 0;
int32_t j = 0;
while (i < TARRAY2_SIZE(X) && j < TARRAY2_SIZE(Y)) {
STSnapRange *x = TARRAY2_GET(X, i);
STSnapRange *y = TARRAY2_GET(Y, j);
if (x->fid < y->fid) {
STSnapRange *tmp = taosDupSnapRange(x);
TARRAY2_APPEND(U, tmp);
i++;
} else if (x->fid > y->fid) {
STSnapRange *tmp = taosDupSnapRange(y);
TARRAY2_APPEND(V, tmp);
j++;
} else {
if (x->sver < y->sver) {
if (x->ever < y->ever) {
STSnapRange *tmp = taosDupSnapRange(x);
TARRAY2_APPEND(U, tmp);
i++;
} else {
STSnapRange *tmp = taosDupSnapRange(x);
tmp->ever = y->sver - 1;
TARRAY2_APPEND(U, tmp);
x->sver = y->sver;
}
} else if (x->sver > y->sver) {
if (y->ever < x->ever) {
STSnapRange *tmp = taosDupSnapRange(y);
TARRAY2_APPEND(V, tmp);
j++;
} else {
STSnapRange *tmp = taosDupSnapRange(y);
tmp->ever = x->sver - 1;
TARRAY2_APPEND(V, tmp);
y->sver = x->sver;
}
} else {
if (x->ever < y->ever) {
STSnapRange *tmp = taosDupSnapRange(x);
TARRAY2_APPEND(U, tmp);
i++;
tmp = taosDupSnapRange(y);
tmp->ever = x->ever;
TARRAY2_APPEND(V, tmp);
y->sver = x->ever + 1;
} else if (x->ever > y->ever) {
STSnapRange *tmp = taosDupSnapRange(y);
TARRAY2_APPEND(V, tmp);
j++;
tmp = taosDupSnapRange(x);
tmp->ever = y->ever;
TARRAY2_APPEND(U, tmp);
x->sver = y->ever + 1;
} else {
STSnapRange *tmp = taosDupSnapRange(x);
TARRAY2_APPEND(U, tmp);
i++;
tmp = taosDupSnapRange(y);
TARRAY2_APPEND(V, tmp);
j++;
}
}
}
}
while (i < TARRAY2_SIZE(X)) {
STSnapRange *x = TARRAY2_GET(X, i);
STSnapRange *tmp = taosDupSnapRange(x);
TARRAY2_APPEND(U, tmp);
i++;
}
while (j < TARRAY2_SIZE(Y)) {
STSnapRange *y = TARRAY2_GET(Y, j);
STSnapRange *tmp = taosDupSnapRange(y);
TARRAY2_APPEND(V, tmp);
j++;
}
// difference of snap ranges
Z = taosMemoryCalloc(1, sizeof(*Z));
if (Z == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
goto _out;
}
TARRAY2_INIT(Z);
i = 0;
j = 0;
while (i < TARRAY2_SIZE(U) && j < TARRAY2_SIZE(V)) {
STSnapRange *u = TARRAY2_GET(U, i);
STSnapRange *v = TARRAY2_GET(V, j);
if (u->fid < v->fid) {
STSnapRange *tmp = taosDupSnapRange(u);
TARRAY2_APPEND(Z, tmp);
i++;
} else if (u->fid == v->fid) {
if (u->sver < v->sver) {
STSnapRange *tmp = taosDupSnapRange(u);
TARRAY2_APPEND(Z, tmp);
i++;
} else if (u->sver > v->sver) {
ASSERT(u->ever > v->ever);
j++;
} else {
ASSERT(u->ever == v->ever);
i++;
j++;
}
}
}
while (i < TARRAY2_SIZE(U)) {
STSnapRange *u = TARRAY2_GET(U, i);
STSnapRange *tmp = taosDupSnapRange(u);
TARRAY2_APPEND(Z, tmp);
i++;
}
code = 0;
_out:
TSnapRangeArray **ppArrs[4] = {&X, &Y, &U, &V};
int len = sizeof(ppArrs) / sizeof(ppArrs[0]);
for (int i = 0; i < len; i++) {
if (ppArrs[i][0] == NULL) continue;
TARRAY2_DESTROY(ppArrs[i][0], tsdbTSnapRangeClear);
taosMemoryFree(ppArrs[i][0]);
ppArrs[i][0] = NULL;
}
if (code != 0 && Z) {
TARRAY2_DESTROY(Z, tsdbTSnapRangeClear);
taosMemoryFree(Z);
Z = NULL;
}
return Z;
}
int32_t tsdbFSCreateRefRangedSnapshot(STFileSystem *fs, int64_t sver, int64_t ever, TSnapRangeArray *pExclude, int32_t tsdbFSCreateRefRangedSnapshot(STFileSystem *fs, int64_t sver, int64_t ever, TSnapRangeArray *pExclude,
TSnapRangeArray **fsrArr) { TSnapRangeArray **fsrArr) {
int32_t code = 0; int32_t code = -1;
STFileSet *fset; STFileSet *fset;
STSnapRange *fsr1 = NULL; STSnapRange *fsr1 = NULL;
fsrArr[0] = taosMemoryCalloc(1, sizeof(*fsrArr[0])); TSnapRangeArray *snapF = tsdbFSToSnapRangeArray(fs);
if (fsrArr[0] == NULL) return TSDB_CODE_OUT_OF_MEMORY; if (snapF == NULL) {
tsdbError("failed to generate snap ranges from fs since %s.", terrstr());
goto _out;
}
TSnapRangeArray *snapD = tsdbSnapDiff(snapF, pExclude);
if (snapD == NULL) {
tsdbError("failed to get diff of snap ranges since %s.", terrstr());
goto _out;
}
fsrArr[0] = taosMemoryCalloc(1, sizeof(*fsrArr[0]));
if (fsrArr[0] == NULL) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _out;
}
int32_t i = 0;
taosThreadRwlockRdlock(&fs->tsdb->rwLock); taosThreadRwlockRdlock(&fs->tsdb->rwLock);
TARRAY2_FOREACH(fs->fSetArr, fset) { TARRAY2_FOREACH(fs->fSetArr, fset) {
code = tsdbTSnapRangeInitRef(fs->tsdb, fset, sver, ever, &fsr1); while (i < TARRAY2_SIZE(snapD)) {
if (code) break; STSnapRange *u = TARRAY2_GET(snapD, i);
if (fset->fid < u->fid) {
break;
} else if (fset->fid > u->fid) {
i++;
continue;
} else {
i++;
}
int64_t sver1 = TMAX(sver, u->sver);
int64_t ever1 = TMIN(ever, u->ever);
if (sver1 > ever1) {
continue;
}
code = tsdbTSnapRangeInitRef(fs->tsdb, fset, sver1, ever1, &fsr1);
if (code) break;
code = TARRAY2_APPEND(fsrArr[0], fsr1); code = TARRAY2_APPEND(fsrArr[0], fsr1);
if (code) break; if (code) break;
fsr1 = NULL; fsr1 = NULL;
}
if (code) break;
} }
taosThreadRwlockUnlock(&fs->tsdb->rwLock); taosThreadRwlockUnlock(&fs->tsdb->rwLock);
@ -1084,6 +1306,16 @@ int32_t tsdbFSCreateRefRangedSnapshot(STFileSystem *fs, int64_t sver, int64_t ev
TARRAY2_DESTROY(fsrArr[0], tsdbTSnapRangeClear); TARRAY2_DESTROY(fsrArr[0], tsdbTSnapRangeClear);
fsrArr[0] = NULL; fsrArr[0] = NULL;
} }
_out:
TSnapRangeArray **ppArrs[2] = {&snapF, &snapD};
int len = sizeof(ppArrs) / sizeof(ppArrs[0]);
for (int i = 0; i < len; i++) {
if (ppArrs[i][0] == NULL) continue;
TARRAY2_DESTROY(ppArrs[i][0], tsdbTSnapRangeClear);
taosMemoryFree(ppArrs[i][0]);
ppArrs[i][0] = NULL;
}
return code; return code;
} }