TDengine/source/libs/stream/src/tstreamFileState.c

1371 lines
46 KiB
C
Raw Normal View History

2023-04-03 06:31:37 +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/>.
*/
#include "tstreamFileState.h"
2023-05-11 09:32:44 +00:00
#include "query.h"
2023-04-07 07:26:15 +00:00
#include "streamBackendRocksdb.h"
2023-04-03 06:31:37 +00:00
#include "taos.h"
2023-04-10 04:51:00 +00:00
#include "tcommon.h"
2023-04-03 06:31:37 +00:00
#include "thash.h"
#include "tsimplehash.h"
2023-04-21 09:47:00 +00:00
#define FLUSH_RATIO 0.5
2023-04-07 07:38:02 +00:00
#define FLUSH_NUM 4
2023-09-06 08:34:25 +00:00
#define DEFAULT_MAX_STREAM_BUFFER_SIZE (128 * 1024 * 1024)
#define MIN_NUM_OF_ROW_BUFF 10240
2024-01-11 01:40:54 +00:00
#define MIN_NUM_OF_RECOVER_ROW_BUFF 128
2024-07-12 03:03:45 +00:00
#define MIN_NUM_SEARCH_BUCKET 128
#define MAX_ARRAY_SIZE 1024
2024-08-06 08:14:15 +00:00
#define MAX_GROUP_ID_NUM 200000
2024-10-16 04:16:59 +00:00
#define NUM_OF_CACHE_WIN 64
#define MAX_NUM_OF_CACHE_WIN 128
2023-04-03 06:31:37 +00:00
2024-04-17 07:02:55 +00:00
#define TASK_KEY "streamFileState"
#define STREAM_STATE_INFO_NAME "StreamStateCheckPoint"
2023-11-07 06:11:08 +00:00
2023-04-03 06:31:37 +00:00
struct SStreamFileState {
2024-08-06 08:14:15 +00:00
SList* usedBuffs;
SList* freeBuffs;
void* rowStateBuff;
void* pFileStore;
int32_t rowSize;
int32_t selectivityRowSize;
int32_t keyLen;
uint64_t preCheckPointVersion;
uint64_t checkPointVersion;
TSKEY maxTs;
TSKEY deleteMark;
TSKEY flushMark;
uint64_t maxRowCount;
uint64_t curRowCount;
GetTsFun getTs;
char* id;
char* cfName;
void* searchBuff;
SSHashObj* pGroupIdMap;
2023-09-22 01:40:08 +00:00
2023-10-07 09:43:50 +00:00
_state_buff_cleanup_fn stateBuffCleanupFn;
_state_buff_remove_fn stateBuffRemoveFn;
_state_buff_remove_by_pos_fn stateBuffRemoveByPosFn;
_state_buff_create_statekey_fn stateBuffCreateStateKeyFn;
2023-09-22 01:40:08 +00:00
_state_file_remove_fn stateFileRemoveFn;
_state_file_get_fn stateFileGetFn;
2024-04-10 09:41:59 +00:00
_state_fun_get_fn stateFunctionGetFn;
2023-04-03 06:31:37 +00:00
};
typedef SRowBuffPos SRowBuffInfo;
2024-10-16 04:16:59 +00:00
int fillStateKeyCompare(const void* pWin1, const void* pDatas, int pos) {
SWinKey* pWin2 = taosArrayGet(pDatas, pos);
return winKeyCmprImpl((SWinKey*)pWin1, pWin2);
}
2023-10-10 06:35:02 +00:00
int32_t stateHashBuffRemoveFn(void* pBuff, const void* pKey, size_t keyLen) {
2023-10-07 09:43:50 +00:00
SRowBuffPos** pos = tSimpleHashGet(pBuff, pKey, keyLen);
if (pos) {
(*pos)->beFlushed = true;
2023-09-26 09:19:21 +00:00
}
2023-09-20 07:06:08 +00:00
return tSimpleHashRemove(pBuff, pKey, keyLen);
}
2024-07-18 02:09:15 +00:00
void stateHashBuffRemoveByPosFn(SStreamFileState* pFileState, SRowBuffPos* pPos) {
2023-10-10 06:35:02 +00:00
size_t keyLen = pFileState->keyLen;
2023-10-07 09:43:50 +00:00
SRowBuffPos** ppPos = tSimpleHashGet(pFileState->rowStateBuff, pPos->pKey, keyLen);
if (ppPos) {
if ((*ppPos) == pPos) {
2024-07-18 02:09:15 +00:00
int32_t tmpRes = tSimpleHashRemove(pFileState->rowStateBuff, pPos->pKey, keyLen);
qTrace("%s at line %d res:%d", __func__, __LINE__, tmpRes);
2023-10-07 09:43:50 +00:00
}
}
}
2023-10-10 06:35:02 +00:00
void stateHashBuffClearFn(void* pBuff) { tSimpleHashClear(pBuff); }
2023-09-20 07:06:08 +00:00
2023-10-10 06:35:02 +00:00
void stateHashBuffCleanupFn(void* pBuff) { tSimpleHashCleanup(pBuff); }
2023-09-20 07:06:08 +00:00
int32_t intervalFileRemoveFn(SStreamFileState* pFileState, const void* pKey) {
return streamStateDel_rocksdb(pFileState->pFileStore, pKey);
}
2024-07-12 03:03:45 +00:00
int32_t intervalFileGetFn(SStreamFileState* pFileState, void* pKey, void** data, int32_t* pDataLen) {
2023-09-20 07:06:08 +00:00
return streamStateGet_rocksdb(pFileState->pFileStore, pKey, data, pDataLen);
}
2023-09-22 01:40:08 +00:00
void* intervalCreateStateKey(SRowBuffPos* pPos, int64_t num) {
SStateKey* pStateKey = taosMemoryCalloc(1, sizeof(SStateKey));
if (pStateKey == NULL) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
return NULL;
}
2024-09-26 07:51:32 +00:00
SWinKey* pWinKey = pPos->pKey;
2023-09-22 01:40:08 +00:00
pStateKey->key = *pWinKey;
pStateKey->opNum = num;
return pStateKey;
}
2024-10-16 04:16:59 +00:00
void* defaultCreateStateKey(SRowBuffPos* pPos, int64_t num) {
SWinKey* pStateKey = taosMemoryCalloc(1, sizeof(SWinKey));
if (pStateKey == NULL) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
return NULL;
}
SWinKey* pWinKey = pPos->pKey;
*pStateKey = *pWinKey;
return pStateKey;
}
2023-09-20 07:06:08 +00:00
int32_t sessionFileRemoveFn(SStreamFileState* pFileState, const void* pKey) {
return streamStateSessionDel_rocksdb(pFileState->pFileStore, pKey);
}
2024-07-12 03:03:45 +00:00
int32_t sessionFileGetFn(SStreamFileState* pFileState, void* pKey, void** data, int32_t* pDataLen) {
2023-09-20 07:06:08 +00:00
return streamStateSessionGet_rocksdb(pFileState->pFileStore, pKey, data, pDataLen);
}
2023-09-22 01:40:08 +00:00
void* sessionCreateStateKey(SRowBuffPos* pPos, int64_t num) {
SStateSessionKey* pStateKey = taosMemoryCalloc(1, sizeof(SStateSessionKey));
if (pStateKey == NULL) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
return NULL;
}
2024-09-26 07:51:32 +00:00
SSessionKey* pWinKey = pPos->pKey;
2023-09-22 01:40:08 +00:00
pStateKey->key = *pWinKey;
pStateKey->opNum = num;
return pStateKey;
}
2023-11-07 06:11:08 +00:00
static void streamFileStateDecode(TSKEY* pKey, void* pBuff, int32_t len) { pBuff = taosDecodeFixedI64(pBuff, pKey); }
static int32_t streamFileStateEncode(TSKEY* pKey, void** pVal, int32_t* pLen) {
2023-11-07 06:11:08 +00:00
*pLen = sizeof(TSKEY);
(*pVal) = taosMemoryCalloc(1, *pLen);
if ((*pVal) == NULL) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
return terrno;
}
2024-07-18 06:01:24 +00:00
void* buff = *pVal;
2024-07-18 02:37:14 +00:00
int32_t tmp = taosEncodeFixedI64(&buff, *pKey);
2024-09-18 06:22:24 +00:00
return TSDB_CODE_SUCCESS;
2023-11-07 06:11:08 +00:00
}
2024-09-14 02:51:57 +00:00
int32_t streamFileStateInit(int64_t memSize, uint32_t keySize, uint32_t rowSize, uint32_t selectRowSize, GetTsFun fp,
void* pFile, TSKEY delMark, const char* taskId, int64_t checkpointId, int8_t type,
SStreamFileState** ppFileState) {
2024-08-06 08:14:15 +00:00
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
2023-04-03 06:31:37 +00:00
if (memSize <= 0) {
memSize = DEFAULT_MAX_STREAM_BUFFER_SIZE;
}
if (rowSize == 0) {
2024-08-06 08:14:15 +00:00
code = TSDB_CODE_INVALID_PARA;
QUERY_CHECK_CODE(code, lino, _end);
2023-04-03 06:31:37 +00:00
}
SStreamFileState* pFileState = taosMemoryCalloc(1, sizeof(SStreamFileState));
2024-08-06 08:14:15 +00:00
QUERY_CHECK_NULL(pFileState, code, lino, _end, terrno);
2023-05-15 08:26:24 +00:00
rowSize += selectRowSize;
2023-04-11 10:47:15 +00:00
pFileState->maxRowCount = TMAX((uint64_t)memSize / rowSize, FLUSH_NUM * 2);
2023-04-03 06:31:37 +00:00
pFileState->usedBuffs = tdListNew(POINTER_BYTES);
2024-08-22 07:59:42 +00:00
QUERY_CHECK_NULL(pFileState->usedBuffs, code, lino, _end, terrno);
2024-08-16 02:26:09 +00:00
2023-04-03 06:31:37 +00:00
pFileState->freeBuffs = tdListNew(POINTER_BYTES);
2024-08-22 07:59:42 +00:00
QUERY_CHECK_NULL(pFileState->freeBuffs, code, lino, _end, terrno);
2024-08-16 02:26:09 +00:00
2023-04-03 06:31:37 +00:00
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
2023-09-06 08:34:25 +00:00
int32_t cap = TMIN(MIN_NUM_OF_ROW_BUFF, pFileState->maxRowCount);
2024-10-16 04:16:59 +00:00
if (type == STREAM_STATE_BUFF_HASH || type == STREAM_STATE_BUFF_HASH_SEARCH) {
2023-09-20 07:06:08 +00:00
pFileState->rowStateBuff = tSimpleHashInit(cap, hashFn);
pFileState->stateBuffCleanupFn = stateHashBuffCleanupFn;
pFileState->stateBuffRemoveFn = stateHashBuffRemoveFn;
2023-10-07 09:43:50 +00:00
pFileState->stateBuffRemoveByPosFn = stateHashBuffRemoveByPosFn;
2023-09-22 01:40:08 +00:00
pFileState->stateBuffCreateStateKeyFn = intervalCreateStateKey;
2023-09-20 07:06:08 +00:00
pFileState->stateFileRemoveFn = intervalFileRemoveFn;
pFileState->stateFileGetFn = intervalFileGetFn;
2023-09-22 01:40:08 +00:00
pFileState->cfName = taosStrdup("state");
2024-08-06 08:14:15 +00:00
pFileState->stateFunctionGetFn = addRowBuffIfNotExist;
2024-07-12 03:03:45 +00:00
} else if (type == STREAM_STATE_BUFF_SORT) {
2023-09-20 07:06:08 +00:00
pFileState->rowStateBuff = tSimpleHashInit(cap, hashFn);
pFileState->stateBuffCleanupFn = sessionWinStateCleanup;
2023-10-07 09:43:50 +00:00
pFileState->stateBuffRemoveFn = deleteSessionWinStateBuffFn;
pFileState->stateBuffRemoveByPosFn = deleteSessionWinStateBuffByPosFn;
2023-09-22 01:40:08 +00:00
pFileState->stateBuffCreateStateKeyFn = sessionCreateStateKey;
2023-09-20 07:06:08 +00:00
pFileState->stateFileRemoveFn = sessionFileRemoveFn;
pFileState->stateFileGetFn = sessionFileGetFn;
2023-09-22 01:40:08 +00:00
pFileState->cfName = taosStrdup("sess");
2024-04-10 09:41:59 +00:00
pFileState->stateFunctionGetFn = getSessionRowBuff;
2024-07-12 03:03:45 +00:00
} else if (type == STREAM_STATE_BUFF_HASH_SORT) {
pFileState->rowStateBuff = tSimpleHashInit(cap, hashFn);
pFileState->searchBuff = tSimpleHashInit(MIN_NUM_SEARCH_BUCKET, hashFn);
2024-08-06 08:14:15 +00:00
QUERY_CHECK_NULL(pFileState->searchBuff, code, lino, _end, terrno);
2024-07-12 03:03:45 +00:00
pFileState->stateBuffCleanupFn = stateHashBuffCleanupFn;
pFileState->stateBuffRemoveFn = stateHashBuffRemoveFn;
pFileState->stateBuffRemoveByPosFn = stateHashBuffRemoveByPosFn;
2024-10-16 04:16:59 +00:00
pFileState->stateBuffCreateStateKeyFn = defaultCreateStateKey;
2024-07-12 03:03:45 +00:00
pFileState->stateFileRemoveFn = hashSortFileRemoveFn;
pFileState->stateFileGetFn = hashSortFileGetFn;
pFileState->cfName = taosStrdup("fill");
pFileState->stateFunctionGetFn = NULL;
2023-09-20 07:06:08 +00:00
}
2024-08-06 08:14:15 +00:00
QUERY_CHECK_NULL(pFileState->usedBuffs, code, lino, _end, terrno);
QUERY_CHECK_NULL(pFileState->freeBuffs, code, lino, _end, terrno);
QUERY_CHECK_NULL(pFileState->rowStateBuff, code, lino, _end, terrno);
QUERY_CHECK_NULL(pFileState->cfName, code, lino, _end, terrno);
2023-06-08 10:59:25 +00:00
2024-10-16 04:16:59 +00:00
if (type == STREAM_STATE_BUFF_HASH_SEARCH) {
pFileState->searchBuff = tSimpleHashInit(MIN_NUM_SEARCH_BUCKET, hashFn);
QUERY_CHECK_NULL(pFileState->searchBuff, code, lino, _end, terrno);
}
2023-04-07 04:50:59 +00:00
pFileState->keyLen = keySize;
2023-04-03 06:31:37 +00:00
pFileState->rowSize = rowSize;
2023-05-15 08:26:24 +00:00
pFileState->selectivityRowSize = selectRowSize;
2023-04-03 06:31:37 +00:00
pFileState->preCheckPointVersion = 0;
pFileState->checkPointVersion = 1;
pFileState->pFileStore = pFile;
2023-04-04 09:08:24 +00:00
pFileState->getTs = fp;
2023-04-03 06:31:37 +00:00
pFileState->curRowCount = 0;
2023-04-04 09:08:24 +00:00
pFileState->deleteMark = delMark;
2023-04-21 09:47:00 +00:00
pFileState->flushMark = INT64_MIN;
pFileState->maxTs = INT64_MIN;
2023-07-12 02:48:58 +00:00
pFileState->id = taosStrdup(taskId);
2024-08-06 08:14:15 +00:00
QUERY_CHECK_NULL(pFileState->id, code, lino, _end, terrno);
pFileState->pGroupIdMap = tSimpleHashInit(1024, hashFn);
QUERY_CHECK_NULL(pFileState->pGroupIdMap, code, lino, _end, terrno);
2023-06-08 10:59:25 +00:00
2024-10-16 04:16:59 +00:00
if (type == STREAM_STATE_BUFF_HASH || type == STREAM_STATE_BUFF_HASH_SEARCH) {
2024-09-14 02:51:57 +00:00
code = recoverSnapshot(pFileState, checkpointId);
2024-07-12 03:03:45 +00:00
} else if (type == STREAM_STATE_BUFF_SORT) {
2024-09-14 02:51:57 +00:00
code = recoverSesssion(pFileState, checkpointId);
2024-07-12 03:03:45 +00:00
} else if (type == STREAM_STATE_BUFF_HASH_SORT) {
code = recoverFillSnapshot(pFileState, checkpointId);
2023-10-07 11:24:21 +00:00
}
QUERY_CHECK_CODE(code, lino, _end);
2023-10-13 03:32:35 +00:00
2023-11-07 06:11:08 +00:00
void* valBuf = NULL;
int32_t len = 0;
2024-08-06 08:14:15 +00:00
int32_t tmpRes = streamDefaultGet_rocksdb(pFileState->pFileStore, STREAM_STATE_INFO_NAME, &valBuf, &len);
if (tmpRes == TSDB_CODE_SUCCESS) {
2024-08-22 07:59:42 +00:00
QUERY_CHECK_CONDITION((len == sizeof(TSKEY)), code, lino, _end, TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR);
2023-11-07 06:11:08 +00:00
streamFileStateDecode(&pFileState->flushMark, valBuf, len);
2023-11-07 07:45:38 +00:00
qDebug("===stream===flushMark read:%" PRId64, pFileState->flushMark);
2023-11-07 06:11:08 +00:00
}
taosMemoryFreeClear(valBuf);
2024-09-14 02:51:57 +00:00
(*ppFileState) = pFileState;
2023-04-03 06:31:37 +00:00
2024-08-06 08:14:15 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
streamFileStateDestroy(pFileState);
2024-08-16 02:26:09 +00:00
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
2024-08-06 08:14:15 +00:00
}
2024-09-14 02:51:57 +00:00
return code;
2023-04-03 06:31:37 +00:00
}
void destroyRowBuffPos(SRowBuffPos* pPos) {
2023-04-04 09:08:24 +00:00
taosMemoryFreeClear(pPos->pKey);
2023-04-03 06:31:37 +00:00
taosMemoryFreeClear(pPos->pRowBuff);
taosMemoryFree(pPos);
}
void destroyRowBuffPosPtr(void* ptr) {
if (!ptr) {
return;
}
2023-04-04 09:08:24 +00:00
SRowBuffPos* pPos = *(SRowBuffPos**)ptr;
2023-04-07 04:50:59 +00:00
if (!pPos->beUsed) {
destroyRowBuffPos(pPos);
}
2023-04-03 06:31:37 +00:00
}
2023-04-18 01:50:13 +00:00
void destroyRowBuffAllPosPtr(void* ptr) {
if (!ptr) {
return;
}
SRowBuffPos* pPos = *(SRowBuffPos**)ptr;
destroyRowBuffPos(pPos);
}
2023-04-04 09:08:24 +00:00
void destroyRowBuff(void* ptr) {
if (!ptr) {
return;
}
taosMemoryFree(*(void**)ptr);
}
void streamFileStateDestroy(SStreamFileState* pFileState) {
if (!pFileState) {
return;
}
2023-06-08 10:59:25 +00:00
taosMemoryFree(pFileState->id);
2023-09-22 01:40:08 +00:00
taosMemoryFree(pFileState->cfName);
2023-04-18 01:50:13 +00:00
tdListFreeP(pFileState->usedBuffs, destroyRowBuffAllPosPtr);
2023-04-04 09:08:24 +00:00
tdListFreeP(pFileState->freeBuffs, destroyRowBuff);
2023-09-20 07:06:08 +00:00
pFileState->stateBuffCleanupFn(pFileState->rowStateBuff);
2024-08-02 05:57:09 +00:00
sessionWinStateCleanup(pFileState->searchBuff);
2024-08-06 09:42:44 +00:00
tSimpleHashCleanup(pFileState->pGroupIdMap);
2023-04-04 09:08:24 +00:00
taosMemoryFree(pFileState);
2023-04-03 06:31:37 +00:00
}
2024-07-18 02:37:14 +00:00
int32_t putFreeBuff(SStreamFileState* pFileState, SRowBuffPos* pPos) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
2023-09-20 07:06:08 +00:00
if (pPos->pRowBuff) {
2024-07-18 02:37:14 +00:00
code = tdListAppend(pFileState->freeBuffs, &(pPos->pRowBuff));
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-09-20 07:06:08 +00:00
pPos->pRowBuff = NULL;
}
2024-07-18 02:37:14 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
2023-09-20 07:06:08 +00:00
}
2023-04-04 09:08:24 +00:00
void clearExpiredRowBuff(SStreamFileState* pFileState, TSKEY ts, bool all) {
2024-07-18 02:37:14 +00:00
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
2023-04-03 06:31:37 +00:00
SListIter iter = {0};
tdListInitIter(pFileState->usedBuffs, &iter, TD_LIST_FORWARD);
SListNode* pNode = NULL;
while ((pNode = tdListNext(&iter)) != NULL) {
2023-04-04 09:08:24 +00:00
SRowBuffPos* pPos = *(SRowBuffPos**)(pNode->data);
2023-06-02 08:51:44 +00:00
if (all || (pFileState->getTs(pPos->pKey) < ts && !pPos->beUsed)) {
2024-07-18 02:37:14 +00:00
code = putFreeBuff(pFileState, pPos);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-09-20 07:06:08 +00:00
2023-04-07 10:45:09 +00:00
if (!all) {
2023-10-07 09:43:50 +00:00
pFileState->stateBuffRemoveByPosFn(pFileState, pPos);
2023-04-07 10:45:09 +00:00
}
2023-04-03 06:31:37 +00:00
destroyRowBuffPos(pPos);
2024-07-18 02:09:15 +00:00
SListNode* tmp = tdListPopNode(pFileState->usedBuffs, pNode);
taosMemoryFreeClear(tmp);
2023-04-03 06:31:37 +00:00
}
}
2024-07-18 02:37:14 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
2023-04-03 06:31:37 +00:00
}
int32_t clearFlushedRowBuff(SStreamFileState* pFileState, SStreamSnapshot* pFlushList, uint64_t max, bool all) {
2024-07-18 02:09:15 +00:00
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
2023-09-26 02:41:12 +00:00
uint64_t i = 0;
SListIter iter = {0};
tdListInitIter(pFileState->usedBuffs, &iter, TD_LIST_FORWARD);
SListNode* pNode = NULL;
while ((pNode = tdListNext(&iter)) != NULL && i < max) {
SRowBuffPos* pPos = *(SRowBuffPos**)pNode->data;
2024-07-12 05:41:22 +00:00
if (isFlushedState(pFileState, pFileState->getTs(pPos->pKey), 0)) {
if (all || !pPos->beUsed) {
if (all && !pPos->pRowBuff) {
continue;
2024-08-06 08:14:15 +00:00
}
code = tdListAppend(pFlushList, &pPos);
QUERY_CHECK_CODE(code, lino, _end);
2024-07-18 02:09:15 +00:00
2024-08-06 08:14:15 +00:00
pFileState->flushMark = TMAX(pFileState->flushMark, pFileState->getTs(pPos->pKey));
2024-07-12 05:41:22 +00:00
pFileState->stateBuffRemoveByPosFn(pFileState, pPos);
SListNode* tmp = tdListPopNode(pFileState->usedBuffs, pNode);
taosMemoryFreeClear(tmp);
2024-07-12 05:41:22 +00:00
if (pPos->pRowBuff) {
i++;
}
2023-09-26 02:41:12 +00:00
}
}
}
2024-07-18 02:09:15 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
2023-09-26 02:41:12 +00:00
}
2023-04-04 09:08:24 +00:00
void streamFileStateClear(SStreamFileState* pFileState) {
2023-04-21 09:47:00 +00:00
pFileState->flushMark = INT64_MIN;
pFileState->maxTs = INT64_MIN;
2023-09-20 07:06:08 +00:00
tSimpleHashClear(pFileState->rowStateBuff);
2023-04-04 09:08:24 +00:00
clearExpiredRowBuff(pFileState, 0, true);
}
2023-05-11 09:32:44 +00:00
bool needClearDiskBuff(SStreamFileState* pFileState) { return pFileState->flushMark > 0; }
2023-04-26 10:58:19 +00:00
2023-10-10 06:35:02 +00:00
void streamFileStateReleaseBuff(SStreamFileState* pFileState, SRowBuffPos* pPos, bool used) { pPos->beUsed = used; }
2023-09-20 07:06:08 +00:00
2024-07-18 02:09:15 +00:00
int32_t popUsedBuffs(SStreamFileState* pFileState, SStreamSnapshot* pFlushList, uint64_t max, bool used) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
2023-04-07 07:26:15 +00:00
uint64_t i = 0;
2023-04-03 06:31:37 +00:00
SListIter iter = {0};
tdListInitIter(pFileState->usedBuffs, &iter, TD_LIST_FORWARD);
SListNode* pNode = NULL;
2023-04-07 04:50:59 +00:00
while ((pNode = tdListNext(&iter)) != NULL && i < max) {
2023-04-03 06:31:37 +00:00
SRowBuffPos* pPos = *(SRowBuffPos**)pNode->data;
2023-04-07 04:50:59 +00:00
if (pPos->beUsed == used) {
2023-10-16 11:49:45 +00:00
if (used && !pPos->pRowBuff) {
QUERY_CHECK_CONDITION((pPos->needFree == true), code, lino, _end, TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR);
2023-10-16 11:49:45 +00:00
continue;
}
2024-07-18 02:09:15 +00:00
code = tdListAppend(pFlushList, &pPos);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2024-07-18 02:09:15 +00:00
2023-04-04 09:08:24 +00:00
pFileState->flushMark = TMAX(pFileState->flushMark, pFileState->getTs(pPos->pKey));
2023-10-07 09:43:50 +00:00
pFileState->stateBuffRemoveByPosFn(pFileState, pPos);
2024-07-18 02:09:15 +00:00
SListNode* tmp = tdListPopNode(pFileState->usedBuffs, pNode);
taosMemoryFreeClear(tmp);
2023-09-20 07:06:08 +00:00
if (pPos->pRowBuff) {
i++;
}
2023-04-03 06:31:37 +00:00
}
}
2023-06-08 10:59:25 +00:00
qInfo("stream state flush %d rows to disk. is used:%d", listNEles(pFlushList), used);
2024-07-18 02:09:15 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
2023-04-07 04:50:59 +00:00
}
int32_t flushRowBuff(SStreamFileState* pFileState) {
2024-07-18 02:09:15 +00:00
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
2023-04-07 04:50:59 +00:00
SStreamSnapshot* pFlushList = tdListNew(POINTER_BYTES);
if (!pFlushList) {
2024-07-18 02:09:15 +00:00
code = TSDB_CODE_OUT_OF_MEMORY;
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-04-07 04:50:59 +00:00
}
2023-06-08 10:59:25 +00:00
2023-04-07 04:50:59 +00:00
uint64_t num = (uint64_t)(pFileState->curRowCount * FLUSH_RATIO);
num = TMAX(num, FLUSH_NUM);
code = clearFlushedRowBuff(pFileState, pFlushList, num, false);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2024-07-18 02:09:15 +00:00
2023-04-07 04:50:59 +00:00
if (isListEmpty(pFlushList)) {
2024-07-18 02:09:15 +00:00
code = popUsedBuffs(pFileState, pFlushList, num, false);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-09-26 02:41:12 +00:00
if (isListEmpty(pFlushList)) {
2024-07-18 02:09:15 +00:00
code = popUsedBuffs(pFileState, pFlushList, num, true);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-09-26 02:41:12 +00:00
}
2023-04-07 04:50:59 +00:00
}
2023-06-08 10:59:25 +00:00
2024-07-12 03:03:45 +00:00
if (pFileState->searchBuff) {
2024-10-09 03:32:20 +00:00
code = clearFlushedRowBuff(pFileState, pFlushList, pFileState->curRowCount, true);
QUERY_CHECK_CODE(code, lino, _end);
2024-07-12 03:03:45 +00:00
}
2023-04-06 08:33:00 +00:00
flushSnapshot(pFileState, pFlushList, false);
2023-06-08 10:59:25 +00:00
2023-04-07 04:50:59 +00:00
SListIter fIter = {0};
tdListInitIter(pFlushList, &fIter, TD_LIST_FORWARD);
SListNode* pNode = NULL;
while ((pNode = tdListNext(&fIter)) != NULL) {
SRowBuffPos* pPos = *(SRowBuffPos**)pNode->data;
2024-07-18 02:37:14 +00:00
code = putFreeBuff(pFileState, pPos);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-04-07 04:50:59 +00:00
}
2023-06-08 10:59:25 +00:00
2023-04-07 04:50:59 +00:00
tdListFreeP(pFlushList, destroyRowBuffPosPtr);
2024-07-18 02:09:15 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
2023-04-03 06:31:37 +00:00
}
int32_t clearRowBuff(SStreamFileState* pFileState) {
2024-09-29 06:53:47 +00:00
if (pFileState->deleteMark != INT64_MAX) {
clearExpiredRowBuff(pFileState, pFileState->maxTs - pFileState->deleteMark, false);
}
2023-04-03 06:31:37 +00:00
if (isListEmpty(pFileState->freeBuffs)) {
return flushRowBuff(pFileState);
}
return TSDB_CODE_SUCCESS;
}
2023-09-20 07:06:08 +00:00
void* getFreeBuff(SStreamFileState* pFileState) {
2023-10-10 06:35:02 +00:00
SList* lists = pFileState->freeBuffs;
int32_t buffSize = pFileState->rowSize;
2023-04-03 06:31:37 +00:00
SListNode* pNode = tdListPopHead(lists);
if (!pNode) {
return NULL;
}
void* ptr = *(void**)pNode->data;
2023-04-04 09:08:24 +00:00
memset(ptr, 0, buffSize);
2023-04-03 06:31:37 +00:00
taosMemoryFree(pNode);
return ptr;
}
2024-07-17 11:35:35 +00:00
void streamFileStateClearBuff(SStreamFileState* pFileState, SRowBuffPos* pPos) {
2023-09-20 07:06:08 +00:00
if (pPos->pRowBuff) {
memset(pPos->pRowBuff, 0, pFileState->rowSize);
}
}
2023-04-03 06:31:37 +00:00
SRowBuffPos* getNewRowPos(SStreamFileState* pFileState) {
2024-07-18 02:09:15 +00:00
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
2023-04-03 06:31:37 +00:00
SRowBuffPos* pPos = taosMemoryCalloc(1, sizeof(SRowBuffPos));
2024-07-18 02:09:15 +00:00
if (!pPos) {
2024-09-23 02:15:20 +00:00
code = terrno;
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _error);
2024-07-18 02:09:15 +00:00
}
2023-04-07 04:50:59 +00:00
pPos->pKey = taosMemoryCalloc(1, pFileState->keyLen);
2024-07-18 02:09:15 +00:00
if (!pPos->pKey) {
2024-09-23 02:15:20 +00:00
code = terrno;
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _error);
2024-07-18 02:09:15 +00:00
}
2023-09-20 07:06:08 +00:00
void* pBuff = getFreeBuff(pFileState);
2023-04-03 06:31:37 +00:00
if (pBuff) {
pPos->pRowBuff = pBuff;
2023-04-07 04:50:59 +00:00
goto _end;
2023-04-03 06:31:37 +00:00
}
if (pFileState->curRowCount < pFileState->maxRowCount) {
pBuff = taosMemoryCalloc(1, pFileState->rowSize);
2024-09-19 05:47:20 +00:00
QUERY_CHECK_NULL(pBuff, code, lino, _error, terrno);
pPos->pRowBuff = pBuff;
pFileState->curRowCount++;
goto _end;
2023-04-03 06:31:37 +00:00
}
2024-07-18 02:09:15 +00:00
code = clearRowBuff(pFileState);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _error);
2024-07-18 02:09:15 +00:00
2023-09-20 07:06:08 +00:00
pPos->pRowBuff = getFreeBuff(pFileState);
2023-04-07 04:50:59 +00:00
_end:
2024-07-18 06:01:24 +00:00
code = tdListAppend(pFileState->usedBuffs, &pPos);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _error);
2024-07-18 06:01:24 +00:00
QUERY_CHECK_CONDITION((pPos->pRowBuff != NULL), code, lino, _error, TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR);
2024-07-18 06:01:24 +00:00
_error:
2024-07-18 02:09:15 +00:00
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
return NULL;
}
2023-04-03 06:31:37 +00:00
return pPos;
}
2023-09-20 07:06:08 +00:00
SRowBuffPos* getNewRowPosForWrite(SStreamFileState* pFileState) {
2024-07-18 08:08:01 +00:00
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
2023-10-10 06:35:02 +00:00
SRowBuffPos* newPos = getNewRowPos(pFileState);
2024-07-18 02:09:15 +00:00
if (!newPos) {
2024-07-18 08:08:01 +00:00
code = TSDB_CODE_OUT_OF_MEMORY;
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _error);
2024-07-18 02:09:15 +00:00
}
2023-09-20 07:06:08 +00:00
newPos->beUsed = true;
newPos->beFlushed = false;
newPos->needFree = false;
2023-10-25 12:29:25 +00:00
newPos->beUpdated = true;
2023-09-20 07:06:08 +00:00
return newPos;
2024-07-18 08:08:01 +00:00
_error:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return NULL;
2023-09-20 07:06:08 +00:00
}
2024-08-06 08:14:15 +00:00
int32_t addRowBuffIfNotExist(SStreamFileState* pFileState, void* pKey, int32_t keyLen, void** pVal, int32_t* pVLen,
int32_t* pWinCode) {
2024-03-21 02:50:07 +00:00
int32_t code = TSDB_CODE_SUCCESS;
2024-07-17 11:35:35 +00:00
int32_t lino = 0;
(*pWinCode) = TSDB_CODE_SUCCESS;
2023-04-04 09:08:24 +00:00
pFileState->maxTs = TMAX(pFileState->maxTs, pFileState->getTs(pKey));
2023-09-20 07:06:08 +00:00
SRowBuffPos** pos = tSimpleHashGet(pFileState->rowStateBuff, pKey, keyLen);
2023-04-03 06:31:37 +00:00
if (pos) {
2024-08-16 02:54:52 +00:00
if (pVal != NULL) {
*pVLen = pFileState->rowSize;
*pVal = *pos;
(*pos)->beUsed = true;
(*pos)->beFlushed = false;
}
2024-07-17 11:35:35 +00:00
goto _end;
2023-04-03 06:31:37 +00:00
}
2023-09-20 07:06:08 +00:00
SRowBuffPos* pNewPos = getNewRowPosForWrite(pFileState);
2024-07-18 02:09:15 +00:00
if (!pNewPos || !pNewPos->pRowBuff) {
code = TSDB_CODE_OUT_OF_MEMORY;
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2024-07-18 02:09:15 +00:00
}
2023-04-04 09:08:24 +00:00
memcpy(pNewPos->pKey, pKey, keyLen);
2024-07-17 11:35:35 +00:00
(*pWinCode) = TSDB_CODE_FAILED;
2023-04-04 09:08:24 +00:00
TSKEY ts = pFileState->getTs(pKey);
2023-09-26 02:41:12 +00:00
if (!isDeteled(pFileState, ts) && isFlushedState(pFileState, ts, 0)) {
2023-04-04 09:08:24 +00:00
int32_t len = 0;
2023-06-08 10:59:25 +00:00
void* p = NULL;
2024-07-30 08:06:40 +00:00
(*pWinCode) = pFileState->stateFileGetFn(pFileState, pKey, &p, &len);
2024-07-17 11:35:35 +00:00
qDebug("===stream===get %" PRId64 " from disc, res %d", ts, (*pWinCode));
if ((*pWinCode) == TSDB_CODE_SUCCESS) {
2023-06-08 10:59:25 +00:00
memcpy(pNewPos->pRowBuff, p, len);
2023-04-07 04:50:59 +00:00
}
2023-06-08 10:59:25 +00:00
taosMemoryFree(p);
2023-04-04 09:08:24 +00:00
}
2024-07-17 11:35:35 +00:00
code = tSimpleHashPut(pFileState->rowStateBuff, pKey, keyLen, &pNewPos, POINTER_BYTES);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2024-07-17 11:35:35 +00:00
2023-04-04 09:08:24 +00:00
if (pVal) {
*pVLen = pFileState->rowSize;
*pVal = pNewPos;
}
2024-07-17 11:35:35 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
2024-03-21 02:50:07 +00:00
return code;
2023-04-03 06:31:37 +00:00
}
2024-07-17 11:35:35 +00:00
void deleteRowBuff(SStreamFileState* pFileState, const void* pKey, int32_t keyLen) {
2023-10-07 09:43:50 +00:00
int32_t code_buff = pFileState->stateBuffRemoveFn(pFileState->rowStateBuff, pKey, keyLen);
2024-07-18 01:01:35 +00:00
qTrace("%s at line %d res:%d", __func__, __LINE__, code_buff);
2023-09-20 07:06:08 +00:00
int32_t code_file = pFileState->stateFileRemoveFn(pFileState, pKey);
2024-07-18 01:01:35 +00:00
qTrace("%s at line %d res:%d", __func__, __LINE__, code_file);
2024-08-16 02:54:52 +00:00
if (pFileState->searchBuff != NULL) {
deleteHashSortRowBuff(pFileState, pKey);
}
2024-01-17 06:22:19 +00:00
}
int32_t resetRowBuff(SStreamFileState* pFileState, const void* pKey, int32_t keyLen) {
int32_t code_buff = pFileState->stateBuffRemoveFn(pFileState->rowStateBuff, pKey, keyLen);
int32_t code_file = pFileState->stateFileRemoveFn(pFileState, pKey);
2024-08-16 02:54:52 +00:00
if (pFileState->searchBuff != NULL) {
deleteHashSortRowBuff(pFileState, pKey);
}
2023-09-20 07:06:08 +00:00
if (code_buff == TSDB_CODE_SUCCESS || code_file == TSDB_CODE_SUCCESS) {
return TSDB_CODE_SUCCESS;
}
return TSDB_CODE_FAILED;
2023-04-04 09:08:24 +00:00
}
2024-07-18 02:09:15 +00:00
static int32_t recoverSessionRowBuff(SStreamFileState* pFileState, SRowBuffPos* pPos) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
2023-09-22 01:40:08 +00:00
int32_t len = 0;
void* pBuff = NULL;
2024-07-18 02:09:15 +00:00
code = pFileState->stateFileGetFn(pFileState, pPos->pKey, &pBuff, &len);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-09-22 01:40:08 +00:00
memcpy(pPos->pRowBuff, pBuff, len);
taosMemoryFree(pBuff);
2024-07-18 02:09:15 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
2023-09-22 01:40:08 +00:00
}
2024-09-05 01:27:36 +00:00
static int32_t recoverStateRowBuff(SStreamFileState* pFileState, SRowBuffPos* pPos) {
2024-07-18 02:09:15 +00:00
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
2023-09-20 07:06:08 +00:00
pPos->pRowBuff = getFreeBuff(pFileState);
2023-04-07 04:50:59 +00:00
if (!pPos->pRowBuff) {
2023-10-07 09:43:50 +00:00
if (pFileState->curRowCount < pFileState->maxRowCount) {
pPos->pRowBuff = taosMemoryCalloc(1, pFileState->rowSize);
2024-07-18 02:09:15 +00:00
if (!pPos->pRowBuff) {
2024-09-11 01:58:41 +00:00
code = terrno;
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2024-07-18 02:09:15 +00:00
}
2023-10-07 09:43:50 +00:00
pFileState->curRowCount++;
} else {
2024-07-18 02:09:15 +00:00
code = clearRowBuff(pFileState);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-10-07 09:43:50 +00:00
pPos->pRowBuff = getFreeBuff(pFileState);
}
QUERY_CHECK_CONDITION((pPos->pRowBuff != NULL), code, lino, _end, TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR);
2023-04-07 04:50:59 +00:00
}
2023-04-03 06:31:37 +00:00
2024-07-18 02:09:15 +00:00
code = recoverSessionRowBuff(pFileState, pPos);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2024-07-18 02:09:15 +00:00
2024-09-05 01:27:36 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
}
int32_t getRowBuffByPos(SStreamFileState* pFileState, SRowBuffPos* pPos, void** pVal) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
if (pPos->pRowBuff) {
if (pPos->needFree) {
code = recoverSessionRowBuff(pFileState, pPos);
QUERY_CHECK_CODE(code, lino, _end);
}
(*pVal) = pPos->pRowBuff;
goto _end;
}
2024-10-09 03:32:20 +00:00
code = recoverStateRowBuff(pFileState, pPos);
QUERY_CHECK_CODE(code, lino, _end);
2024-09-05 01:27:36 +00:00
2023-04-04 09:08:24 +00:00
(*pVal) = pPos->pRowBuff;
2023-09-26 09:19:21 +00:00
if (!pPos->needFree) {
2024-07-18 02:09:15 +00:00
code = tdListPrepend(pFileState->usedBuffs, &pPos);
2024-10-09 03:32:20 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-09-26 09:19:21 +00:00
}
2024-07-18 02:09:15 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
2023-04-04 09:08:24 +00:00
}
bool hasRowBuff(SStreamFileState* pFileState, void* pKey, int32_t keyLen) {
2023-09-20 07:06:08 +00:00
SRowBuffPos** pos = tSimpleHashGet(pFileState->rowStateBuff, pKey, keyLen);
2023-04-04 09:08:24 +00:00
if (pos) {
return true;
}
return false;
2023-04-03 06:31:37 +00:00
}
SStreamSnapshot* getSnapshot(SStreamFileState* pFileState) {
2024-05-07 07:01:45 +00:00
int64_t mark = (pFileState->deleteMark == INT64_MAX || pFileState->maxTs == INT64_MIN)
? INT64_MIN
: pFileState->maxTs - pFileState->deleteMark;
2023-05-15 07:22:29 +00:00
clearExpiredRowBuff(pFileState, mark, false);
2023-04-03 06:31:37 +00:00
return pFileState->usedBuffs;
}
2024-07-17 11:35:35 +00:00
void flushSnapshot(SStreamFileState* pFileState, SStreamSnapshot* pSnapshot, bool flushState) {
2023-04-07 07:26:15 +00:00
int32_t code = TSDB_CODE_SUCCESS;
2024-07-17 11:35:35 +00:00
int32_t lino = 0;
2023-04-03 06:31:37 +00:00
SListIter iter = {0};
tdListInitIter(pSnapshot, &iter, TD_LIST_FORWARD);
2023-04-14 14:05:59 +00:00
const int32_t BATCH_LIMIT = 256;
2023-06-08 10:59:25 +00:00
int64_t st = taosGetTimestampMs();
SListNode* pNode = NULL;
2023-04-07 07:26:15 +00:00
2023-09-22 01:40:08 +00:00
int idx = streamStateGetCfIdx(pFileState->pFileStore, pFileState->cfName);
2023-06-08 13:36:52 +00:00
2024-04-17 07:02:55 +00:00
int32_t len = pFileState->rowSize + sizeof(uint64_t) + sizeof(int32_t) + 64;
2023-06-08 13:36:52 +00:00
char* buf = taosMemoryCalloc(1, len);
2024-07-17 11:35:35 +00:00
if (!buf) {
2024-09-23 02:15:20 +00:00
code = terrno;
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2024-07-17 11:35:35 +00:00
}
2023-06-08 13:36:52 +00:00
2023-04-07 07:26:15 +00:00
void* batch = streamStateCreateBatch();
2024-07-17 11:35:35 +00:00
if (!batch) {
code = TSDB_CODE_OUT_OF_MEMORY;
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2024-07-17 11:35:35 +00:00
}
2023-04-03 06:31:37 +00:00
while ((pNode = tdListNext(&iter)) != NULL && code == TSDB_CODE_SUCCESS) {
SRowBuffPos* pPos = *(SRowBuffPos**)pNode->data;
2023-09-26 09:19:21 +00:00
if (pPos->beFlushed || !pPos->pRowBuff) {
2023-09-06 08:34:25 +00:00
continue;
}
pPos->beFlushed = true;
2023-11-07 06:11:08 +00:00
pFileState->flushMark = TMAX(pFileState->flushMark, pFileState->getTs(pPos->pKey));
2023-06-08 10:59:25 +00:00
2023-10-07 11:11:46 +00:00
qDebug("===stream===flushed start:%" PRId64, pFileState->getTs(pPos->pKey));
2023-04-07 07:26:15 +00:00
if (streamStateGetBatchSize(batch) >= BATCH_LIMIT) {
2024-07-17 11:35:35 +00:00
code = streamStatePutBatch_rocksdb(pFileState->pFileStore, batch);
2023-04-07 07:26:15 +00:00
streamStateClearBatch(batch);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-04-07 07:26:15 +00:00
}
2023-04-10 04:51:00 +00:00
2023-09-22 01:40:08 +00:00
void* pSKey = pFileState->stateBuffCreateStateKeyFn(pPos, ((SStreamState*)pFileState->pFileStore)->number);
2024-09-19 05:47:20 +00:00
QUERY_CHECK_NULL(pSKey, code, lino, _end, terrno);
2023-09-22 01:40:08 +00:00
code = streamStatePutBatchOptimize(pFileState->pFileStore, idx, batch, pSKey, pPos->pRowBuff, pFileState->rowSize,
2023-06-08 13:36:52 +00:00
0, buf);
2023-09-22 01:40:08 +00:00
taosMemoryFreeClear(pSKey);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-06-08 10:59:25 +00:00
// todo handle failure
2023-06-08 13:36:52 +00:00
memset(buf, 0, len);
2023-04-06 08:33:00 +00:00
}
2024-09-26 07:51:32 +00:00
taosMemoryFreeClear(buf);
2023-06-08 09:54:22 +00:00
2024-05-16 08:24:58 +00:00
int32_t numOfElems = streamStateGetBatchSize(batch);
if (numOfElems > 0) {
2024-07-17 11:35:35 +00:00
code = streamStatePutBatch_rocksdb(pFileState->pFileStore, batch);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2024-05-16 08:24:58 +00:00
} else {
goto _end;
2023-04-07 07:26:15 +00:00
}
2023-06-08 09:54:22 +00:00
2023-04-12 05:50:01 +00:00
streamStateClearBatch(batch);
2023-04-07 07:26:15 +00:00
2024-07-12 03:03:45 +00:00
clearSearchBuff(pFileState);
2023-06-08 10:59:25 +00:00
int64_t elapsed = taosGetTimestampMs() - st;
2023-07-13 02:38:21 +00:00
qDebug("%s flush to disk in batch model completed, rows:%d, batch size:%d, elapsed time:%" PRId64 "ms",
pFileState->id, numOfElems, BATCH_LIMIT, elapsed);
2023-06-08 10:59:25 +00:00
2023-04-06 08:33:00 +00:00
if (flushState) {
2023-11-07 07:45:38 +00:00
void* valBuf = NULL;
int32_t len = 0;
code = streamFileStateEncode(&pFileState->flushMark, &valBuf, &len);
QUERY_CHECK_CODE(code, lino, _end);
2023-11-07 07:45:38 +00:00
qDebug("===stream===flushMark write:%" PRId64, pFileState->flushMark);
2024-07-17 11:35:35 +00:00
code = streamStatePutBatch(pFileState->pFileStore, "default", batch, STREAM_STATE_INFO_NAME, valBuf, len, 0);
2023-11-07 07:45:38 +00:00
taosMemoryFree(valBuf);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2024-07-17 11:35:35 +00:00
code = streamStatePutBatch_rocksdb(pFileState->pFileStore, batch);
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2023-04-03 06:31:37 +00:00
}
2023-04-12 07:39:54 +00:00
2024-05-16 08:24:58 +00:00
_end:
2024-07-17 11:35:35 +00:00
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
2024-09-26 07:51:32 +00:00
taosMemoryFree(buf);
2023-06-08 10:59:25 +00:00
streamStateDestroyBatch(batch);
2023-04-03 06:31:37 +00:00
}
2023-04-12 09:33:58 +00:00
2023-04-12 03:03:51 +00:00
int32_t forceRemoveCheckpoint(SStreamFileState* pFileState, int64_t checkpointId) {
2024-04-17 07:02:55 +00:00
char keyBuf[128] = {0};
2023-11-07 06:11:08 +00:00
sprintf(keyBuf, "%s:%" PRId64 "", TASK_KEY, checkpointId);
2023-04-12 03:03:51 +00:00
return streamDefaultDel_rocksdb(pFileState->pFileStore, keyBuf);
}
2023-04-12 09:33:58 +00:00
2023-04-12 03:03:51 +00:00
int32_t getSnapshotIdList(SStreamFileState* pFileState, SArray* list) {
2023-11-07 06:11:08 +00:00
return streamDefaultIterGet_rocksdb(pFileState->pFileStore, TASK_KEY, NULL, list);
2023-04-12 03:03:51 +00:00
}
2023-04-12 09:33:58 +00:00
int32_t deleteExpiredCheckPoint(SStreamFileState* pFileState, TSKEY mark) {
2024-04-17 07:02:55 +00:00
int32_t code = TSDB_CODE_SUCCESS;
int64_t maxCheckPointId = 0;
2023-04-11 14:04:39 +00:00
{
char buf[128] = {0};
void* val = NULL;
int32_t len = 0;
2023-11-07 06:11:08 +00:00
memcpy(buf, TASK_KEY, strlen(TASK_KEY));
2023-04-11 14:04:39 +00:00
code = streamDefaultGet_rocksdb(pFileState->pFileStore, buf, &val, &len);
2023-06-02 10:05:32 +00:00
if (code != 0 || len == 0 || val == NULL) {
2023-04-11 14:04:39 +00:00
return TSDB_CODE_FAILED;
}
2023-06-05 10:52:07 +00:00
memcpy(buf, val, len);
2023-06-02 15:47:14 +00:00
buf[len] = 0;
maxCheckPointId = atol((char*)buf);
2023-06-02 04:08:08 +00:00
taosMemoryFree(val);
2023-04-11 14:04:39 +00:00
}
2023-04-11 14:13:35 +00:00
for (int64_t i = maxCheckPointId; i > 0; i--) {
2023-04-11 14:04:39 +00:00
char buf[128] = {0};
void* val = 0;
int32_t len = 0;
2023-11-07 06:11:08 +00:00
sprintf(buf, "%s:%" PRId64 "", TASK_KEY, i);
2023-04-11 14:04:39 +00:00
code = streamDefaultGet_rocksdb(pFileState->pFileStore, buf, &val, &len);
if (code != 0) {
return TSDB_CODE_FAILED;
}
2023-06-05 10:52:07 +00:00
memcpy(buf, val, len);
2023-06-02 15:47:14 +00:00
buf[len] = 0;
taosMemoryFree(val);
2023-04-11 14:04:39 +00:00
TSKEY ts;
2023-06-02 15:47:14 +00:00
ts = atol((char*)buf);
2023-04-12 09:33:58 +00:00
if (ts < mark) {
2023-04-14 14:05:59 +00:00
// statekey winkey.ts < mark
2024-07-17 11:35:35 +00:00
int32_t tmpRes = forceRemoveCheckpoint(pFileState, i);
2024-07-18 01:01:35 +00:00
qTrace("%s at line %d res:%d", __func__, __LINE__, tmpRes);
2023-04-11 14:04:39 +00:00
break;
}
}
2023-04-12 09:33:58 +00:00
return code;
}
2023-04-11 14:04:39 +00:00
2024-09-14 02:51:57 +00:00
int32_t recoverSesssion(SStreamFileState* pFileState, int64_t ckId) {
2024-07-17 11:35:35 +00:00
int32_t code = TSDB_CODE_SUCCESS;
2024-09-14 02:51:57 +00:00
int32_t lino = 0;
int32_t winRes = TSDB_CODE_SUCCESS;
2023-10-13 03:32:35 +00:00
if (pFileState->maxTs != INT64_MIN) {
int64_t mark = (INT64_MIN + pFileState->deleteMark >= pFileState->maxTs)
? INT64_MIN
: pFileState->maxTs - pFileState->deleteMark;
2024-07-17 11:35:35 +00:00
int32_t tmpRes = deleteExpiredCheckPoint(pFileState, mark);
2024-07-18 01:01:35 +00:00
qTrace("%s at line %d res:%d", __func__, __LINE__, tmpRes);
2023-10-13 03:32:35 +00:00
}
2024-02-04 08:04:23 +00:00
SStreamStateCur* pCur = streamStateSessionSeekToLast_rocksdb(pFileState->pFileStore, INT64_MAX);
2024-07-17 11:35:35 +00:00
int32_t recoverNum = TMIN(MIN_NUM_OF_RECOVER_ROW_BUFF, pFileState->maxRowCount);
2024-09-14 02:51:57 +00:00
while (winRes == TSDB_CODE_SUCCESS) {
2023-10-13 03:32:35 +00:00
if (pFileState->curRowCount >= recoverNum) {
break;
}
2023-10-10 07:12:21 +00:00
void* pVal = NULL;
int32_t vlen = 0;
SSessionKey key = {0};
2024-09-14 02:51:57 +00:00
winRes = streamStateSessionGetKVByCur_rocksdb(pCur, &key, &pVal, &vlen);
if (winRes != TSDB_CODE_SUCCESS) {
2023-10-10 07:12:21 +00:00
break;
}
2024-09-26 07:51:32 +00:00
2024-09-14 02:51:57 +00:00
if (vlen != pFileState->rowSize) {
code = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
QUERY_CHECK_CODE(code, lino, _end);
}
2023-10-13 03:32:35 +00:00
SRowBuffPos* pPos = createSessionWinBuff(pFileState, &key, pVal, &vlen);
2024-09-14 02:51:57 +00:00
winRes = putSessionWinResultBuff(pFileState, pPos);
if (winRes != TSDB_CODE_SUCCESS) {
2024-07-17 11:35:35 +00:00
break;
}
2024-09-14 02:51:57 +00:00
winRes = streamStateSessionCurPrev_rocksdb(pCur);
}
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
2023-10-10 07:12:21 +00:00
}
streamStateFreeCur(pCur);
2024-09-14 02:51:57 +00:00
return code;
2023-10-10 07:12:21 +00:00
}
2023-10-13 03:32:35 +00:00
2024-09-14 02:51:57 +00:00
int32_t recoverSnapshot(SStreamFileState* pFileState, int64_t ckId) {
2023-04-12 09:33:58 +00:00
int32_t code = TSDB_CODE_SUCCESS;
2024-07-18 02:09:15 +00:00
int32_t lino = 0;
2024-07-19 10:36:03 +00:00
int32_t winCode = TSDB_CODE_SUCCESS;
2023-05-15 08:26:24 +00:00
if (pFileState->maxTs != INT64_MIN) {
2023-05-18 05:46:38 +00:00
int64_t mark = (INT64_MIN + pFileState->deleteMark >= pFileState->maxTs)
? INT64_MIN
: pFileState->maxTs - pFileState->deleteMark;
2024-07-17 11:35:35 +00:00
int32_t tmpRes = deleteExpiredCheckPoint(pFileState, mark);
2024-07-18 01:01:35 +00:00
qTrace("%s at line %d res:%d", __func__, __LINE__, tmpRes);
2023-05-15 08:26:24 +00:00
}
2023-04-06 08:33:00 +00:00
2023-10-10 06:35:02 +00:00
SStreamStateCur* pCur = streamStateSeekToLast_rocksdb(pFileState->pFileStore);
2024-07-17 11:35:35 +00:00
int32_t recoverNum = TMIN(MIN_NUM_OF_RECOVER_ROW_BUFF, pFileState->maxRowCount);
2024-07-19 10:36:03 +00:00
while (winCode == TSDB_CODE_SUCCESS) {
2023-10-13 03:32:35 +00:00
if (pFileState->curRowCount >= recoverNum) {
2023-04-06 08:33:00 +00:00
break;
}
2023-10-13 03:32:35 +00:00
2023-04-07 07:26:15 +00:00
void* pVal = NULL;
2023-10-10 07:12:21 +00:00
int32_t vlen = 0;
2023-09-20 07:06:08 +00:00
SRowBuffPos* pNewPos = getNewRowPosForWrite(pFileState);
2024-07-18 02:09:15 +00:00
if (!pNewPos || !pNewPos->pRowBuff) {
code = TSDB_CODE_OUT_OF_MEMORY;
2024-07-19 08:15:37 +00:00
QUERY_CHECK_CODE(code, lino, _end);
2024-07-18 02:09:15 +00:00
}
2024-07-19 10:36:03 +00:00
winCode = streamStateGetKVByCur_rocksdb(pCur, pNewPos->pKey, (const void**)&pVal, &vlen);
if (winCode != TSDB_CODE_SUCCESS || pFileState->getTs(pNewPos->pKey) < pFileState->flushMark) {
2023-04-06 08:33:00 +00:00
destroyRowBuffPos(pNewPos);
2023-04-18 01:50:13 +00:00
SListNode* pNode = tdListPopTail(pFileState->usedBuffs);
taosMemoryFreeClear(pNode);
2023-07-13 11:24:11 +00:00
taosMemoryFreeClear(pVal);
2023-04-06 08:33:00 +00:00
break;
}
if (vlen != pFileState->rowSize) {
code = TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
QUERY_CHECK_CODE(code, lino, _end);
}
2023-10-10 07:12:21 +00:00
memcpy(pNewPos->pRowBuff, pVal, vlen);
2023-07-13 11:24:11 +00:00
taosMemoryFreeClear(pVal);
2023-09-06 08:34:25 +00:00
pNewPos->beFlushed = true;
2023-09-20 07:06:08 +00:00
code = tSimpleHashPut(pFileState->rowStateBuff, pNewPos->pKey, pFileState->keyLen, &pNewPos, POINTER_BYTES);
2023-04-06 08:33:00 +00:00
if (code != TSDB_CODE_SUCCESS) {
destroyRowBuffPos(pNewPos);
break;
}
2024-07-17 11:35:35 +00:00
streamStateCurPrev_rocksdb(pCur);
2023-04-06 08:33:00 +00:00
}
2024-07-18 02:09:15 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
2023-04-17 15:01:47 +00:00
streamStateFreeCur(pCur);
2024-09-14 02:51:57 +00:00
return code;
2023-05-15 08:26:24 +00:00
}
2024-04-10 09:41:59 +00:00
int32_t streamFileStateGetSelectRowSize(SStreamFileState* pFileState) { return pFileState->selectivityRowSize; }
2023-06-15 06:13:17 +00:00
void streamFileStateReloadInfo(SStreamFileState* pFileState, TSKEY ts) {
pFileState->flushMark = TMAX(pFileState->flushMark, ts);
pFileState->maxTs = TMAX(pFileState->maxTs, ts);
}
2023-09-20 07:06:08 +00:00
2023-10-10 06:35:02 +00:00
void* getRowStateBuff(SStreamFileState* pFileState) { return pFileState->rowStateBuff; }
2024-07-12 03:03:45 +00:00
void* getSearchBuff(SStreamFileState* pFileState) { return pFileState->searchBuff; }
2023-09-20 07:06:08 +00:00
2023-10-10 06:35:02 +00:00
void* getStateFileStore(SStreamFileState* pFileState) { return pFileState->pFileStore; }
2023-09-20 07:06:08 +00:00
bool isDeteled(SStreamFileState* pFileState, TSKEY ts) {
2024-07-17 11:35:35 +00:00
return pFileState->deleteMark != INT64_MAX && pFileState->maxTs > 0 &&
ts < (pFileState->maxTs - pFileState->deleteMark);
2023-09-20 07:06:08 +00:00
}
2023-10-10 06:35:02 +00:00
bool isFlushedState(SStreamFileState* pFileState, TSKEY ts, TSKEY gap) { return ts <= (pFileState->flushMark + gap); }
2023-09-20 07:06:08 +00:00
2024-08-06 08:14:15 +00:00
TSKEY getFlushMark(SStreamFileState* pFileState) { return pFileState->flushMark; };
2024-07-12 03:03:45 +00:00
2023-10-10 06:35:02 +00:00
int32_t getRowStateRowSize(SStreamFileState* pFileState) { return pFileState->rowSize; }
2024-04-10 09:41:59 +00:00
int32_t getFunctionRowBuff(SStreamFileState* pFileState, void* pKey, int32_t keyLen, void** pVal, int32_t* pVLen) {
2024-07-17 11:35:35 +00:00
int32_t winCode = TSDB_CODE_SUCCESS;
return pFileState->stateFunctionGetFn(pFileState, pKey, keyLen, pVal, pVLen, &winCode);
2024-04-10 09:41:59 +00:00
}
2024-07-12 03:03:45 +00:00
int32_t recoverFillSnapshot(SStreamFileState* pFileState, int64_t ckId) {
int32_t code = TSDB_CODE_SUCCESS;
2024-10-09 03:32:20 +00:00
int32_t lino = 0;
2024-07-12 03:03:45 +00:00
if (pFileState->maxTs != INT64_MIN) {
int64_t mark = (INT64_MIN + pFileState->deleteMark >= pFileState->maxTs)
? INT64_MIN
: pFileState->maxTs - pFileState->deleteMark;
2024-10-09 03:32:20 +00:00
code = deleteExpiredCheckPoint(pFileState, mark);
QUERY_CHECK_CODE(code, lino, _end);
2024-07-12 03:03:45 +00:00
}
SStreamStateCur* pCur = streamStateFillSeekToLast_rocksdb(pFileState->pFileStore);
if (pCur == NULL) {
2024-09-18 09:00:38 +00:00
return code;
2024-07-12 03:03:45 +00:00
}
int32_t recoverNum = TMIN(MIN_NUM_OF_RECOVER_ROW_BUFF, pFileState->maxRowCount);
2024-09-18 09:00:38 +00:00
int32_t winRes = TSDB_CODE_SUCCESS;
while (winRes == TSDB_CODE_SUCCESS) {
2024-07-12 03:03:45 +00:00
if (pFileState->curRowCount >= recoverNum) {
break;
}
void* pVal = NULL;
int32_t vlen = 0;
SRowBuffPos* pNewPos = getNewRowPosForWrite(pFileState);
2024-09-18 09:00:38 +00:00
winRes = streamStateFillGetKVByCur_rocksdb(pCur, pNewPos->pKey, (const void**)&pVal, &vlen);
if (winRes != TSDB_CODE_SUCCESS || isFlushedState(pFileState, pFileState->getTs(pNewPos->pKey), 0)) {
2024-07-12 03:03:45 +00:00
destroyRowBuffPos(pNewPos);
SListNode* pNode = tdListPopTail(pFileState->usedBuffs);
taosMemoryFreeClear(pNode);
taosMemoryFreeClear(pVal);
break;
}
2024-09-09 09:58:40 +00:00
2024-07-12 03:03:45 +00:00
memcpy(pNewPos->pRowBuff, pVal, vlen);
taosMemoryFreeClear(pVal);
pNewPos->beFlushed = true;
2024-09-18 09:00:38 +00:00
winRes = tSimpleHashPut(pFileState->rowStateBuff, pNewPos->pKey, pFileState->keyLen, &pNewPos, POINTER_BYTES);
if (winRes != TSDB_CODE_SUCCESS) {
2024-07-12 03:03:45 +00:00
destroyRowBuffPos(pNewPos);
break;
}
streamStateCurPrev_rocksdb(pCur);
2024-07-12 03:03:45 +00:00
}
streamStateFreeCur(pCur);
2024-10-09 03:32:20 +00:00
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
2024-09-18 09:00:38 +00:00
return code;
2024-07-12 03:03:45 +00:00
}
2024-08-06 08:14:15 +00:00
int32_t getRowBuff(SStreamFileState* pFileState, void* pKey, int32_t keyLen, void** pVal, int32_t* pVLen,
int32_t* pWinCode) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
(*pWinCode) = TSDB_CODE_FAILED;
pFileState->maxTs = TMAX(pFileState->maxTs, pFileState->getTs(pKey));
2024-09-05 01:27:36 +00:00
SRowBuffPos** ppPos = tSimpleHashGet(pFileState->rowStateBuff, pKey, keyLen);
if (ppPos) {
2024-08-06 08:14:15 +00:00
*pVLen = pFileState->rowSize;
2024-09-05 01:27:36 +00:00
*pVal = *ppPos;
(*ppPos)->beUsed = true;
(*ppPos)->beFlushed = false;
2024-08-06 08:14:15 +00:00
(*pWinCode) = TSDB_CODE_SUCCESS;
2024-09-05 01:27:36 +00:00
if ((*ppPos)->pRowBuff == NULL) {
2024-10-09 03:32:20 +00:00
code = recoverStateRowBuff(pFileState, *ppPos);
QUERY_CHECK_CODE(code, lino, _end);
2024-09-05 01:27:36 +00:00
}
2024-09-04 07:34:14 +00:00
goto _end;
2024-08-06 08:14:15 +00:00
}
TSKEY ts = pFileState->getTs(pKey);
if (!isDeteled(pFileState, ts) && isFlushedState(pFileState, ts, 0)) {
int32_t len = 0;
void* p = NULL;
(*pWinCode) = pFileState->stateFileGetFn(pFileState, pKey, &p, &len);
qDebug("===stream===get %" PRId64 " from disc, res %d", ts, (*pWinCode));
if ((*pWinCode) == TSDB_CODE_SUCCESS) {
SRowBuffPos* pNewPos = getNewRowPosForWrite(pFileState);
if (!pNewPos || !pNewPos->pRowBuff) {
code = TSDB_CODE_OUT_OF_MEMORY;
QUERY_CHECK_CODE(code, lino, _end);
}
memcpy(pNewPos->pKey, pKey, keyLen);
memcpy(pNewPos->pRowBuff, p, len);
code = tSimpleHashPut(pFileState->rowStateBuff, pKey, keyLen, &pNewPos, POINTER_BYTES);
QUERY_CHECK_CODE(code, lino, _end);
if (pVal) {
*pVLen = pFileState->rowSize;
*pVal = pNewPos;
}
}
taosMemoryFree(p);
}
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
}
int32_t streamFileStateGroupPut(SStreamFileState* pFileState, int64_t groupId, void* value, int32_t vLen) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
if (value != NULL) {
code = TSDB_CODE_INVALID_PARA;
QUERY_CHECK_CODE(code, lino, _end);
}
if (tSimpleHashGet(pFileState->pGroupIdMap, &groupId, sizeof(int64_t)) == NULL) {
if (tSimpleHashGetSize(pFileState->pGroupIdMap) <= MAX_GROUP_ID_NUM) {
code = tSimpleHashPut(pFileState->pGroupIdMap, &groupId, sizeof(int64_t), NULL, 0);
QUERY_CHECK_CODE(code, lino, _end);
}
code = streamStatePutParTag_rocksdb(pFileState->pFileStore, groupId, value, vLen);
QUERY_CHECK_CODE(code, lino, _end);
}
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
}
void streamFileStateGroupCurNext(SStreamStateCur* pCur) {
SStreamFileState* pFileState = (SStreamFileState*)pCur->pStreamFileState;
if (pCur->hashIter == -1) {
streamStateCurNext(pFileState->pFileStore, pCur);
2024-09-24 08:58:46 +00:00
return;
2024-08-06 08:14:15 +00:00
}
2024-10-16 04:16:59 +00:00
int64_t gpId = *(int64_t*)tSimpleHashGetKey(pCur->pHashData, NULL);
pCur->minGpId = TMAX(pCur->minGpId, gpId);
2024-08-06 08:14:15 +00:00
SSHashObj* pHash = pFileState->pGroupIdMap;
pCur->pHashData = tSimpleHashIterate(pHash, pCur->pHashData, &pCur->hashIter);
if (!pCur->pHashData) {
pCur->hashIter = -1;
streamStateParTagSeekKeyNext_rocksdb(pFileState->pFileStore, pCur->minGpId, pCur);
2024-09-24 08:58:46 +00:00
return;
2024-08-06 08:14:15 +00:00
}
}
int32_t streamFileStateGroupGetKVByCur(SStreamStateCur* pCur, int64_t* pKey, void** pVal, int32_t* pVLen) {
int32_t code = TSDB_CODE_SUCCESS;
if (pCur->pHashData) {
*pKey = *(int64_t*)tSimpleHashGetKey(pCur->pHashData, NULL);
return code;
}
return streamStateParTagGetKVByCur_rocksdb(pCur, pKey, NULL, NULL);
}
2024-09-24 08:58:46 +00:00
SSHashObj* getGroupIdCache(SStreamFileState* pFileState) {
return pFileState->pGroupIdMap;
}
2024-10-16 04:16:59 +00:00
void clearExpiredState(SStreamFileState* pFileState) {
SSHashObj* pSearchBuff = pFileState->searchBuff;
void* pIte = NULL;
int32_t iter = 0;
while ((pIte = tSimpleHashIterate(pFileState->searchBuff, pIte, &iter)) != NULL) {
SArray* pWinStates = *((void**)pIte);
int32_t size = taosArrayGetSize(pWinStates);
for (int32_t i = 0; i < size - 1; i++) {
SWinKey* pKey = taosArrayGet(pWinStates, i);
int32_t code_buff = pFileState->stateBuffRemoveFn(pFileState->rowStateBuff, pKey, sizeof(SWinKey));
qTrace("%s at line %d res:%d", __func__, __LINE__, code_buff);
int32_t code_file = pFileState->stateFileRemoveFn(pFileState, pKey);
qTrace("%s at line %d res:%d", __func__, __LINE__, code_file);
2024-10-16 05:39:32 +00:00
code_file = streamStateFillDel_rocksdb(pFileState->pFileStore, pKey);
qTrace("%s at line %d res %d", __func__, __LINE__, code_file);
2024-10-16 04:16:59 +00:00
}
taosArrayRemoveBatch(pWinStates, 0, size - 1, NULL);
}
}
int32_t getStateSearchRowBuff(SStreamFileState* pFileState, const SWinKey* pKey, void** pVal, int32_t* pVLen,
int32_t* pWinCode) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
code = addRowBuffIfNotExist(pFileState, (void*)pKey, sizeof(SWinKey), pVal, pVLen, pWinCode);
QUERY_CHECK_CODE(code, lino, _end);
SArray* pWinStates = NULL;
SSHashObj* pSearchBuff = getSearchBuff(pFileState);
void** ppBuff = tSimpleHashGet(pSearchBuff, &pKey->groupId, sizeof(uint64_t));
if (ppBuff) {
pWinStates = (SArray*)(*ppBuff);
} else {
pWinStates = taosArrayInit(16, sizeof(SWinKey));
QUERY_CHECK_NULL(pWinStates, code, lino, _end, terrno);
code = tSimpleHashPut(pSearchBuff, &pKey->groupId, sizeof(uint64_t), &pWinStates, POINTER_BYTES);
QUERY_CHECK_CODE(code, lino, _end);
}
// recover
if (taosArrayGetSize(pWinStates) == 0 && needClearDiskBuff(pFileState)) {
TSKEY ts = getFlushMark(pFileState);
SWinKey start = {.groupId = pKey->groupId, .ts = INT64_MAX};
void* pState = getStateFileStore(pFileState);
SStreamStateCur* pCur = streamStateSeekKeyPrev_rocksdb(pState, &start);
for (int32_t i = 0; i < NUM_OF_CACHE_WIN; i++) {
SWinKey tmpKey = {.groupId = pKey->groupId};
int32_t tmpRes = streamStateGetGroupKVByCur_rocksdb(pCur, &tmpKey, NULL, 0);
if (tmpRes != TSDB_CODE_SUCCESS) {
break;
}
void* tmp = taosArrayPush(pWinStates, &tmpKey);
QUERY_CHECK_NULL(tmp, code, lino, _end, terrno);
streamStateCurPrev_rocksdb(pCur);
}
taosArraySort(pWinStates, winKeyCmprImpl);
streamStateFreeCur(pCur);
}
int32_t size = taosArrayGetSize(pWinStates);
int32_t index = binarySearch(pWinStates, size, pKey, fillStateKeyCompare);
if (!isFlushedState(pFileState, pKey->ts, 0)|| index >= 0) {
// find the first position which is smaller than the pKey
if (index >= 0) {
SWinKey* pTmpKey = taosArrayGet(pWinStates, index);
if (winKeyCmprImpl(pTmpKey, pKey) == 0) {
goto _end;
}
}
index++;
void* tmp = taosArrayInsert(pWinStates, index, pKey);
QUERY_CHECK_NULL(tmp, code, lino, _end, terrno);
}
if (size >= MAX_NUM_OF_CACHE_WIN) {
int32_t num = size - NUM_OF_CACHE_WIN;
taosArrayRemoveBatch(pWinStates, 0, num, NULL);
}
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
}
int32_t getRowStatePrevRow(SStreamFileState* pFileState, const SWinKey* pKey, SWinKey* pResKey, void** ppVal,
int32_t* pVLen, int32_t* pWinCode) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SArray* pWinStates = NULL;
SSHashObj* pSearchBuff = getSearchBuff(pFileState);
void* pState = getStateFileStore(pFileState);
void** ppBuff = (void**) tSimpleHashGet(pSearchBuff, &pKey->groupId, sizeof(uint64_t));
if (ppBuff) {
pWinStates = (SArray*)(*ppBuff);
} else {
qDebug("===stream=== search buff is empty.group id:%" PRId64, pKey->groupId);
SStreamStateCur* pCur = streamStateSeekKeyPrev_rocksdb(pState, pKey);
void* tmpVal = NULL;
int32_t len = 0;
(*pWinCode) = streamStateGetGroupKVByCur_rocksdb(pCur, pResKey, (const void**)&tmpVal, &len);
if ((*pWinCode) == TSDB_CODE_SUCCESS) {
SRowBuffPos* pNewPos = getNewRowPosForWrite(pFileState);
if (!pNewPos || !pNewPos->pRowBuff) {
code = TSDB_CODE_OUT_OF_MEMORY;
QUERY_CHECK_CODE(code, lino, _end);
}
memcpy(pNewPos->pRowBuff, tmpVal, len);
taosMemoryFreeClear(tmpVal);
*pVLen = getRowStateRowSize(pFileState);
(*ppVal) = pNewPos;
}
streamStateFreeCur(pCur);
return code;
}
int32_t size = taosArrayGetSize(pWinStates);
int32_t index = binarySearch(pWinStates, size, pKey, fillStateKeyCompare);
if (index >= 0) {
SWinKey* pCurKey = taosArrayGet(pWinStates, index);
if (winKeyCmprImpl(pCurKey, pKey) == 0) {
index--;
} else {
qDebug("%s failed at line %d since do not find cur SWinKey. trigger may be force window close", __func__, __LINE__);
}
}
if (index == -1) {
SStreamStateCur* pCur = streamStateSeekKeyPrev_rocksdb(pState, pKey);
void* tmpVal = NULL;
int32_t len = 0;
(*pWinCode) = streamStateGetGroupKVByCur_rocksdb(pCur, pResKey, (const void**)&tmpVal, &len);
if ((*pWinCode) == TSDB_CODE_SUCCESS) {
SRowBuffPos* pNewPos = getNewRowPosForWrite(pFileState);
if (!pNewPos || !pNewPos->pRowBuff) {
code = TSDB_CODE_OUT_OF_MEMORY;
QUERY_CHECK_CODE(code, lino, _end);
}
memcpy(pNewPos->pRowBuff, tmpVal, len);
taosMemoryFreeClear(tmpVal);
*pVLen = getRowStateRowSize(pFileState);
(*ppVal) = pNewPos;
}
streamStateFreeCur(pCur);
return code;
} else {
SWinKey* pPrevKey = taosArrayGet(pWinStates, index);
*pResKey = *pPrevKey;
return getHashSortRowBuff(pFileState, pResKey, ppVal, pVLen, pWinCode);
}
(*pWinCode) = TSDB_CODE_FAILED;
_end:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
}