enh: support concurrent fetch from group cache
This commit is contained in:
parent
6763c6f98c
commit
2312f10372
|
@ -160,6 +160,8 @@ typedef struct SInterpFuncLogicNode {
|
||||||
typedef struct SGroupCacheLogicNode {
|
typedef struct SGroupCacheLogicNode {
|
||||||
SLogicNode node;
|
SLogicNode node;
|
||||||
bool grpColsMayBeNull;
|
bool grpColsMayBeNull;
|
||||||
|
bool grpByUid;
|
||||||
|
bool globalGrp;
|
||||||
SNodeList* pGroupCols;
|
SNodeList* pGroupCols;
|
||||||
} SGroupCacheLogicNode;
|
} SGroupCacheLogicNode;
|
||||||
|
|
||||||
|
@ -441,8 +443,8 @@ typedef struct SHashJoinPhysiNode {
|
||||||
typedef struct SGroupCachePhysiNode {
|
typedef struct SGroupCachePhysiNode {
|
||||||
SPhysiNode node;
|
SPhysiNode node;
|
||||||
bool grpColsMayBeNull;
|
bool grpColsMayBeNull;
|
||||||
SArray* pDownstreamKey;
|
|
||||||
bool grpByUid;
|
bool grpByUid;
|
||||||
|
bool globalGrp;
|
||||||
SNodeList* pGroupCols;
|
SNodeList* pGroupCols;
|
||||||
} SGroupCachePhysiNode;
|
} SGroupCachePhysiNode;
|
||||||
|
|
||||||
|
|
|
@ -109,8 +109,8 @@ typedef struct SGcOperatorParam {
|
||||||
int64_t sessionId;
|
int64_t sessionId;
|
||||||
int32_t downstreamIdx;
|
int32_t downstreamIdx;
|
||||||
bool needCache;
|
bool needCache;
|
||||||
void* pGroupValue;
|
int32_t vgId;
|
||||||
int32_t groupValueSize;
|
int64_t tbUid;
|
||||||
} SGcOperatorParam;
|
} SGcOperatorParam;
|
||||||
|
|
||||||
typedef struct SExprSupp {
|
typedef struct SExprSupp {
|
||||||
|
@ -158,7 +158,7 @@ typedef struct SExchangeOperatorBasicParam {
|
||||||
|
|
||||||
typedef struct SExchangeOperatorBatchParam {
|
typedef struct SExchangeOperatorBatchParam {
|
||||||
bool multiParams;
|
bool multiParams;
|
||||||
SArray* pBatchs; // SArray<SExchangeOperatorBasicParam>
|
SSHashObj* pBatchs; // SExchangeOperatorBasicParam
|
||||||
} SExchangeOperatorBatchParam;
|
} SExchangeOperatorBatchParam;
|
||||||
|
|
||||||
typedef struct SExchangeOperatorParam {
|
typedef struct SExchangeOperatorParam {
|
||||||
|
@ -717,6 +717,9 @@ uint64_t calcGroupId(char* pData, int32_t len);
|
||||||
void streamOpReleaseState(struct SOperatorInfo* pOperator);
|
void streamOpReleaseState(struct SOperatorInfo* pOperator);
|
||||||
void streamOpReloadState(struct SOperatorInfo* pOperator);
|
void streamOpReloadState(struct SOperatorInfo* pOperator);
|
||||||
|
|
||||||
|
void destroyOperatorParamValue(void* pValues);
|
||||||
|
int32_t mergeOperatorParams(SOperatorParam* pDst, SOperatorParam* pSrc);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,21 +19,27 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GROUP_CACHE_DEFAULT_PAGE_SIZE 10485760
|
#define GROUP_CACHE_DEFAULT_MAX_FILE_SIZE 104857600
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
typedef struct SGcBlkBufInfo {
|
typedef struct SGcBlkBufInfo {
|
||||||
|
void* prev;
|
||||||
void* next;
|
void* next;
|
||||||
uint16_t pageId;
|
int64_t blkId;
|
||||||
int32_t offset;
|
int64_t offset;
|
||||||
|
int64_t bufSize;
|
||||||
|
void* pBuf;
|
||||||
|
uint32_t fileId;
|
||||||
} SGcBlkBufInfo;
|
} SGcBlkBufInfo;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
typedef struct SGcBufPageInfo {
|
|
||||||
int32_t pageSize;
|
typedef struct SGcVgroupCtx {
|
||||||
int32_t offset;
|
SArray* pTbList;
|
||||||
char* data;
|
uint64_t lastUid;
|
||||||
} SGcBufPageInfo;
|
int64_t fileSize;
|
||||||
|
uint32_t fileId;
|
||||||
|
} SGcVgroupCtx;
|
||||||
|
|
||||||
typedef struct SGroupCacheData {
|
typedef struct SGroupCacheData {
|
||||||
TdThreadMutex mutex;
|
TdThreadMutex mutex;
|
||||||
|
@ -41,8 +47,13 @@ typedef struct SGroupCacheData {
|
||||||
bool fetchDone;
|
bool fetchDone;
|
||||||
bool needCache;
|
bool needCache;
|
||||||
SSDataBlock* pBlock;
|
SSDataBlock* pBlock;
|
||||||
SGcBlkBufInfo* pFirstBlk;
|
SGcVgroupCtx* pVgCtx;
|
||||||
SGcBlkBufInfo* pLastBlk;
|
int32_t downstreamIdx;
|
||||||
|
int32_t vgId;
|
||||||
|
uint32_t fileId;
|
||||||
|
int64_t startBlkId;
|
||||||
|
int64_t endBlkId;
|
||||||
|
int64_t startOffset;
|
||||||
} SGroupCacheData;
|
} SGroupCacheData;
|
||||||
|
|
||||||
typedef struct SGroupColInfo {
|
typedef struct SGroupColInfo {
|
||||||
|
@ -62,15 +73,22 @@ typedef struct SGroupColsInfo {
|
||||||
} SGroupColsInfo;
|
} SGroupColsInfo;
|
||||||
|
|
||||||
typedef struct SGcNewGroupInfo {
|
typedef struct SGcNewGroupInfo {
|
||||||
|
int32_t vgId;
|
||||||
int64_t uid;
|
int64_t uid;
|
||||||
|
SGroupCacheData* pGroup;
|
||||||
SOperatorParam* pParam;
|
SOperatorParam* pParam;
|
||||||
} SGcNewGroupInfo;
|
} SGcNewGroupInfo;
|
||||||
|
|
||||||
typedef struct SGcDownstreamCtx {
|
typedef struct SGcDownstreamCtx {
|
||||||
SRWLatch lock;
|
SRWLatch grpLock;
|
||||||
int64_t fetchSessionId;
|
int64_t fetchSessionId;
|
||||||
SArray* pNewGrpList; // SArray<SGcNewGroupInfo>
|
SArray* pNewGrpList; // SArray<SGcNewGroupInfo>
|
||||||
SArray* pGrpUidList;
|
SSHashObj* pVgTbHash;
|
||||||
|
SHashObj* pGrpHash;
|
||||||
|
SRWLatch blkLock;
|
||||||
|
SSDataBlock* pBaseBlock;
|
||||||
|
SArray* pFreeBlock;
|
||||||
|
int64_t lastBlkUid;
|
||||||
} SGcDownstreamCtx;
|
} SGcDownstreamCtx;
|
||||||
|
|
||||||
typedef struct SGcSessionCtx {
|
typedef struct SGcSessionCtx {
|
||||||
|
@ -78,7 +96,8 @@ typedef struct SGcSessionCtx {
|
||||||
bool needCache;
|
bool needCache;
|
||||||
SGcOperatorParam* pParam;
|
SGcOperatorParam* pParam;
|
||||||
SGroupCacheData* pGroupData;
|
SGroupCacheData* pGroupData;
|
||||||
SGcBlkBufInfo* pLastBlk;
|
int64_t lastBlkId;
|
||||||
|
int64_t nextOffset;
|
||||||
bool semInit;
|
bool semInit;
|
||||||
tsem_t waitSem;
|
tsem_t waitSem;
|
||||||
} SGcSessionCtx;
|
} SGcSessionCtx;
|
||||||
|
@ -88,14 +107,38 @@ typedef struct SGcExecInfo {
|
||||||
int64_t* pDownstreamBlkNum;
|
int64_t* pDownstreamBlkNum;
|
||||||
} SGcExecInfo;
|
} SGcExecInfo;
|
||||||
|
|
||||||
|
typedef struct SGcCacheFile {
|
||||||
|
uint32_t grpNum;
|
||||||
|
uint32_t grpDone;
|
||||||
|
int64_t fileSize;
|
||||||
|
} SGcCacheFile;
|
||||||
|
|
||||||
|
typedef struct SGcReadBlkInfo {
|
||||||
|
SSDataBlock* pBlock;
|
||||||
|
int64_t nextOffset;
|
||||||
|
} SGcReadBlkInfo;
|
||||||
|
|
||||||
|
typedef struct SGcBlkCacheInfo {
|
||||||
|
SRWLatch dirtyLock;
|
||||||
|
SSHashObj* pCacheFile;
|
||||||
|
SHashObj* pDirtyBlk;
|
||||||
|
SGcBlkBufInfo* pDirtyHead;
|
||||||
|
SGcBlkBufInfo* pDirtyTail;
|
||||||
|
SHashObj* pReadBlk;
|
||||||
|
int64_t blkCacheSize;
|
||||||
|
} SGcBlkCacheInfo;
|
||||||
|
|
||||||
typedef struct SGroupCacheOperatorInfo {
|
typedef struct SGroupCacheOperatorInfo {
|
||||||
TdThreadMutex sessionMutex;
|
TdThreadMutex sessionMutex;
|
||||||
SSHashObj* pSessionHash;
|
int64_t maxCacheSize;
|
||||||
|
int64_t currentBlkId;
|
||||||
|
SHashObj* pSessionHash;
|
||||||
SGroupColsInfo groupColsInfo;
|
SGroupColsInfo groupColsInfo;
|
||||||
|
bool globalGrp;
|
||||||
bool grpByUid;
|
bool grpByUid;
|
||||||
SGcDownstreamCtx* pDownstreams;
|
SGcDownstreamCtx* pDownstreams;
|
||||||
SArray* pBlkBufs;
|
SGcBlkCacheInfo blkCache;
|
||||||
SHashObj* pBlkHash;
|
SHashObj* pGrpHash;
|
||||||
SGcExecInfo execInfo;
|
SGcExecInfo execInfo;
|
||||||
} SGroupCacheOperatorInfo;
|
} SGroupCacheOperatorInfo;
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ static void destroyDynQueryCtrlOperator(void* param) {
|
||||||
taosMemoryFreeClear(param);
|
taosMemoryFreeClear(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE int32_t buildGroupCacheOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, bool needCache, void* pGrpValue, int32_t grpValSize, SOperatorParam* pChild) {
|
static FORCE_INLINE int32_t buildGroupCacheOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, bool needCache, int32_t vgId, int64_t tbUid, SOperatorParam* pChild) {
|
||||||
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
|
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
|
||||||
if (NULL == *ppRes) {
|
if (NULL == *ppRes) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
@ -57,8 +57,8 @@ static FORCE_INLINE int32_t buildGroupCacheOperatorParam(SOperatorParam** ppRes,
|
||||||
pGc->sessionId = atomic_add_fetch_64(&gSessionId, 1);
|
pGc->sessionId = atomic_add_fetch_64(&gSessionId, 1);
|
||||||
pGc->downstreamIdx = downstreamIdx;
|
pGc->downstreamIdx = downstreamIdx;
|
||||||
pGc->needCache = needCache;
|
pGc->needCache = needCache;
|
||||||
pGc->pGroupValue = pGrpValue;
|
pGc->vgId = vgId;
|
||||||
pGc->groupValueSize = grpValSize;
|
pGc->tbUid = tbUid;
|
||||||
|
|
||||||
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE;
|
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE;
|
||||||
(*ppRes)->downstreamIdx = downstreamIdx;
|
(*ppRes)->downstreamIdx = downstreamIdx;
|
||||||
|
@ -79,14 +79,15 @@ static FORCE_INLINE int32_t buildExchangeOperatorParam(SOperatorParam** ppRes, i
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
pExc->vgId = *pVgId;
|
pExc->multiParams = false;
|
||||||
pExc->srcOpType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN;
|
pExc->basic.vgId = *pVgId;
|
||||||
pExc->uidList = taosArrayInit(1, sizeof(int64_t));
|
pExc->basic.srcOpType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN;
|
||||||
if (NULL == pExc->uidList) {
|
pExc->basic.uidList = taosArrayInit(1, sizeof(int64_t));
|
||||||
|
if (NULL == pExc->basic.uidList) {
|
||||||
taosMemoryFree(pExc);
|
taosMemoryFree(pExc);
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
taosArrayPush(pExc->uidList, pUid);
|
taosArrayPush(pExc->basic.uidList, pUid);
|
||||||
|
|
||||||
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
|
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
|
||||||
(*ppRes)->downstreamIdx = downstreamIdx;
|
(*ppRes)->downstreamIdx = downstreamIdx;
|
||||||
|
@ -145,10 +146,10 @@ static int32_t buildStbJoinOperatorParam(SDynQueryCtrlOperatorInfo* pInfo, SStbJ
|
||||||
code = buildExchangeOperatorParam(&pExcParam1, 1, rightVg, rightUid, NULL);
|
code = buildExchangeOperatorParam(&pExcParam1, 1, rightVg, rightUid, NULL);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = buildGroupCacheOperatorParam(&pGcParam0, 0, false, leftUid, pUid0->info.bytes, pExcParam0);
|
code = buildGroupCacheOperatorParam(&pGcParam0, 0, false, *leftVg, *leftUid, pExcParam0);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = buildGroupCacheOperatorParam(&pGcParam1, 1, false, rightUid, pUid1->info.bytes, pExcParam1);
|
code = buildGroupCacheOperatorParam(&pGcParam1, 1, false, *rightVg, *rightUid, pExcParam1);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = buildMergeJoinOperatorParam(ppParam, pGcParam0, pGcParam1);
|
code = buildMergeJoinOperatorParam(ppParam, pGcParam0, pGcParam1);
|
||||||
|
|
|
@ -745,24 +745,45 @@ _error:
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t addDynamicExchangeSource(SOperatorInfo* pOperator) {
|
int32_t addSingleExchangeSource(SOperatorInfo* pOperator, SExchangeOperatorBasicParam* pBasicParam) {
|
||||||
SExchangeInfo* pExchangeInfo = pOperator->info;
|
SExchangeInfo* pExchangeInfo = pOperator->info;
|
||||||
SExchangeOperatorParam* pParam = (SExchangeOperatorParam*)pOperator->pOperatorParam->value;
|
int32_t* pIdx = tSimpleHashGet(pExchangeInfo->pHashSources, &pBasicParam->vgId, sizeof(pBasicParam->vgId));
|
||||||
int32_t* pIdx = tSimpleHashGet(pExchangeInfo->pHashSources, &pParam->vgId, sizeof(pParam->vgId));
|
|
||||||
if (NULL == pIdx) {
|
if (NULL == pIdx) {
|
||||||
qError("No exchange source for vgId: %d", pParam->vgId);
|
qError("No exchange source for vgId: %d", pBasicParam->vgId);
|
||||||
pOperator->pTaskInfo->code = TSDB_CODE_INVALID_PARA;
|
return TSDB_CODE_INVALID_PARA;
|
||||||
T_LONG_JMP(pOperator->pTaskInfo->env, pOperator->pTaskInfo->code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SSourceDataInfo dataInfo = {0};
|
SSourceDataInfo dataInfo = {0};
|
||||||
dataInfo.status = EX_SOURCE_DATA_NOT_READY;
|
dataInfo.status = EX_SOURCE_DATA_NOT_READY;
|
||||||
dataInfo.taskId = GET_TASKID(pOperator->pTaskInfo);
|
dataInfo.taskId = GET_TASKID(pOperator->pTaskInfo);
|
||||||
dataInfo.index = *pIdx;
|
dataInfo.index = *pIdx;
|
||||||
dataInfo.pSrcUidList = taosArrayDup(pParam->uidList, NULL);
|
dataInfo.pSrcUidList = taosArrayDup(pBasicParam->uidList, NULL);
|
||||||
dataInfo.srcOpType = pParam->srcOpType;
|
dataInfo.srcOpType = pBasicParam->srcOpType;
|
||||||
taosArrayPush(pExchangeInfo->pSourceDataInfo, &dataInfo);
|
taosArrayPush(pExchangeInfo->pSourceDataInfo, &dataInfo);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t addDynamicExchangeSource(SOperatorInfo* pOperator) {
|
||||||
|
SExchangeInfo* pExchangeInfo = pOperator->info;
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
SExchangeOperatorBasicParam* pBasicParam = NULL;
|
||||||
|
SExchangeOperatorParam* pParam = (SExchangeOperatorParam*)pOperator->pOperatorParam->value;
|
||||||
|
if (pParam->multiParams) {
|
||||||
|
SExchangeOperatorBatchParam* pBatch = (SExchangeOperatorBatchParam*)pOperator->pOperatorParam->value;
|
||||||
|
int32_t iter = 0;
|
||||||
|
while (pBasicParam = tSimpleHashIterate(pBatch->pBatchs, pBasicParam, &iter)) {
|
||||||
|
code = addSingleExchangeSource(pOperator, pBasicParam);
|
||||||
|
if (code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pBasicParam = &pParam->basic;
|
||||||
|
code = addSingleExchangeSource(pOperator, pBasicParam);
|
||||||
|
}
|
||||||
|
|
||||||
pOperator->pOperatorParam = NULL;
|
pOperator->pOperatorParam = NULL;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
|
@ -61,11 +61,6 @@ static int32_t initGroupColsInfo(SGroupColsInfo* pCols, bool grpColsMayBeNull, S
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freeGroupCacheBufPage(void* param) {
|
|
||||||
SGcBufPageInfo* pInfo = (SGcBufPageInfo*)param;
|
|
||||||
taosMemoryFree(pInfo->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void logGroupCacheExecInfo(SGroupCacheOperatorInfo* pGrpCacheOperator) {
|
static void logGroupCacheExecInfo(SGroupCacheOperatorInfo* pGrpCacheOperator) {
|
||||||
char* buf = taosMemoryMalloc(pGrpCacheOperator->execInfo.downstreamNum * 32 + 100);
|
char* buf = taosMemoryMalloc(pGrpCacheOperator->execInfo.downstreamNum * 32 + 100);
|
||||||
if (NULL == buf) {
|
if (NULL == buf) {
|
||||||
|
@ -85,33 +80,155 @@ static void destroyGroupCacheOperator(void* param) {
|
||||||
|
|
||||||
taosMemoryFree(pGrpCacheOperator->groupColsInfo.pColsInfo);
|
taosMemoryFree(pGrpCacheOperator->groupColsInfo.pColsInfo);
|
||||||
taosMemoryFree(pGrpCacheOperator->groupColsInfo.pBuf);
|
taosMemoryFree(pGrpCacheOperator->groupColsInfo.pBuf);
|
||||||
taosArrayDestroyEx(pGrpCacheOperator->pBlkBufs, freeGroupCacheBufPage);
|
taosHashCleanup(pGrpCacheOperator->pSessionHash);
|
||||||
tSimpleHashCleanup(pGrpCacheOperator->pSessionHash);
|
taosHashCleanup(pGrpCacheOperator->pGrpHash);
|
||||||
taosHashCleanup(pGrpCacheOperator->pBlkHash);
|
|
||||||
|
|
||||||
taosMemoryFreeClear(param);
|
taosMemoryFreeClear(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE int32_t addPageToGroupCacheBuf(SArray* pBlkBufs) {
|
static int32_t addBlkToDirtyBufList(SGroupCacheOperatorInfo* pGCache, SGcBlkCacheInfo* pCache, SGcBlkBufInfo* pBufInfo) {
|
||||||
SGcBufPageInfo page;
|
if (0 != taosHashPut(pCache->pDirtyBlk, &pBufInfo->blkId, sizeof(pBufInfo->blkId), pBufInfo, sizeof(*pBufInfo))) {
|
||||||
page.pageSize = GROUP_CACHE_DEFAULT_PAGE_SIZE;
|
|
||||||
page.offset = 0;
|
|
||||||
page.data = taosMemoryMalloc(page.pageSize);
|
|
||||||
if (NULL == page.data) {
|
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
pBufInfo = taosHashGet(pCache->pDirtyBlk, &pBufInfo->blkId, sizeof(pBufInfo->blkId));
|
||||||
|
|
||||||
|
taosWLockLatch(&pCache->dirtyLock);
|
||||||
|
if (NULL == pCache->pDirtyHead) {
|
||||||
|
pCache->pDirtyHead = pBufInfo;
|
||||||
|
} else {
|
||||||
|
pBufInfo->prev = pCache->pDirtyTail;
|
||||||
|
pCache->pDirtyTail->next = pBufInfo;
|
||||||
|
}
|
||||||
|
pCache->pDirtyTail = pBufInfo;
|
||||||
|
taosWUnLockLatch(&pCache->dirtyLock);
|
||||||
|
|
||||||
|
int64_t blkCacheSize = atomic_add_fetch_64(&pCache->blkCacheSize, pBufInfo->bufSize);
|
||||||
|
qDebug("group cache block cache num:%d size:%" PRId64 , taosHashGetSize(pCache->pDirtyBlk), blkCacheSize);
|
||||||
|
|
||||||
|
if (pGCache->maxCacheSize > 0 && blkCacheSize > pGCache->maxCacheSize) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
taosArrayPush(pBlkBufs, &page);
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addBlkToBlkBufs(struct SOperatorInfo* pOperator, SSDataBlock* pBlock, SGcBlkBufInfo** ppBuf) {
|
static int32_t addBlkToBufCache(struct SOperatorInfo* pOperator, SSDataBlock* pBlock, SGcDownstreamCtx* pCtx, SGroupCacheData* pGroup, SGcBlkBufInfo* pBufInfo) {
|
||||||
*ppRes = pBlock;
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
|
int64_t bufSize = blockDataGetSize(pBlock) + sizeof(int32_t) + taosArrayGetSize(pBlock->pDataBlock) * sizeof(int32_t);
|
||||||
|
pBufInfo->pBuf = taosMemoryMalloc(bufSize);
|
||||||
|
if (NULL == pBufInfo->pBuf) {
|
||||||
|
qError("group cache add block to cache failed, size:%" PRId64, bufSize);
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
blockDataToBuf(pBufInfo->pBuf, pBlock);
|
||||||
|
|
||||||
|
pBufInfo->prev = NULL;
|
||||||
|
pBufInfo->next = NULL;
|
||||||
|
pBufInfo->blkId = atomic_add_fetch_64(&pGCache->currentBlkId, 1);
|
||||||
|
pBufInfo->fileId = pGroup->fileId;
|
||||||
|
pBufInfo->offset = pGroup->pVgCtx->fileSize;
|
||||||
|
pBufInfo->bufSize = bufSize;
|
||||||
|
|
||||||
|
pGroup->pVgCtx->fileSize += bufSize;
|
||||||
|
|
||||||
|
int32_t code = addBlkToDirtyBufList(pGCache, &pGCache->blkCache, pBufInfo);
|
||||||
|
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE char* retrieveBlkFromBlkBufs(SArray* pBlkBufs, SGcBlkBufInfo* pBlkInfo) {
|
|
||||||
SGcBufPageInfo *pPage = taosArrayGet(pBlkBufs, pBlkInfo->pageId);
|
static int32_t buildGroupCacheBaseBlock(SSDataBlock** ppDst, SSDataBlock* pSrc) {
|
||||||
return pPage->data + pBlkInfo->offset;
|
*ppDst = taosMemoryMalloc(sizeof(*pSrc));
|
||||||
|
if (NULL == *ppDst) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
(*ppDst)->pBlockAgg = NULL;
|
||||||
|
(*ppDst)->pDataBlock = taosArrayDup(pSrc->pDataBlock, NULL);
|
||||||
|
if (NULL == (*ppDst)->pDataBlock) {
|
||||||
|
taosMemoryFree(*ppDst);
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
memcpy(&(*ppDst)->info, &pSrc->info, sizeof(pSrc->info));
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t acquireBaseBlockFromList(SGcDownstreamCtx* pCtx, SSDataBlock** ppRes) {
|
||||||
|
taosWLockLatch(&pCtx->blkLock);
|
||||||
|
if (taosArrayGetSize(pCtx->pFreeBlock) <= 0) {
|
||||||
|
taosWUnLockLatch(&pCtx->blkLock);
|
||||||
|
return buildGroupCacheBaseBlock(ppRes, pCtx->pBaseBlock);
|
||||||
|
}
|
||||||
|
*ppRes = taosArrayPop(pCtx->pFreeBlock);
|
||||||
|
taosWUnLockLatch(&pCtx->blkLock);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t releaseBaseBlockFromList(SGcDownstreamCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
|
taosWLockLatch(&pCtx->blkLock);
|
||||||
|
taosArrayPush(pCtx->pFreeBlock, &pBlock);
|
||||||
|
taosWUnLockLatch(&pCtx->blkLock);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32_t buildGroupCacheResultBlock(SGroupCacheOperatorInfo* pGCache, int32_t downstreamIdx, SGcBlkBufInfo* pBufInfo, SSDataBlock** ppRes) {
|
||||||
|
int32_t code = acquireBaseBlockFromList(&pGCache->pDownstreams[downstreamIdx], ppRes);
|
||||||
|
if (code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
//TODO OPTIMIZE PERF
|
||||||
|
return blockDataFromBuf(*ppRes, pBufInfo->pBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t retrieveBlkFromBufCache(SGroupCacheOperatorInfo* pGCache, SGroupCacheData* pGrp, int64_t blkId, int64_t* nextOffset, SSDataBlock** ppRes) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
SGcBlkCacheInfo* pCache = &pGCache->blkCache;
|
||||||
|
SGcReadBlkInfo* pReadBlk = taosHashAcquire(pCache->pReadBlk, &blkId, sizeof(blkId));
|
||||||
|
if (pReadBlk) {
|
||||||
|
*ppRes = pReadBlk->pBlock;
|
||||||
|
*nextOffset = pReadBlk->nextOffset;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosRLockLatch(&pCache->dirtyLock);
|
||||||
|
SGcBlkBufInfo* pBufInfo = taosHashAcquire(pCache->pDirtyBlk, &blkId, sizeof(blkId));
|
||||||
|
if (pBufInfo) {
|
||||||
|
code = buildGroupCacheResultBlock(pGCache, pGrp->downstreamIdx, pBufInfo, ppRes);
|
||||||
|
taosRUnLockLatch(&pCache->dirtyLock);
|
||||||
|
if (code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
*nextOffset = pBufInfo->offset + pBufInfo->bufSize;
|
||||||
|
SGcReadBlkInfo readBlk = {.pBlock = *ppRes, .nextOffset = *nextOffset};
|
||||||
|
taosHashPut(pCache->pReadBlk, &blkId, sizeof(blkId), &readBlk, sizeof(readBlk));
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
taosRUnLockLatch(&pCache->dirtyLock);
|
||||||
|
|
||||||
|
//TODO READ FROM FILE
|
||||||
|
code = TSDB_CODE_INVALID_PARA;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t addNewGroupToVgHash(SSHashObj* pHash, SGcNewGroupInfo* pNew) {
|
||||||
|
SGcVgroupCtx* pVgCtx = pNew->pGroup->pVgCtx;
|
||||||
|
if (NULL == pVgCtx) {
|
||||||
|
SArray* pList = taosArrayInit(10, sizeof(*pNew));
|
||||||
|
if (NULL == pList) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
taosArrayPush(pList, pNew);
|
||||||
|
SGcVgroupCtx vgCtx = {.pTbList = pList, .lastUid = 0, .fileSize = 0, .fileId = 0};
|
||||||
|
tSimpleHashPut(pHash, &pNew->vgId, sizeof(pNew->vgId), &vgCtx, sizeof(vgCtx));
|
||||||
|
pNew->pGroup->pVgCtx = tSimpleHashGet(pHash, &pNew->vgId, sizeof(pNew->vgId));
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayPush(pVgCtx->pTbList, pNew);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE int32_t appendNewGroupToDownstream(struct SOperatorInfo* pOperator, int32_t downstreamIdx, SOperatorParam** ppParam) {
|
static FORCE_INLINE int32_t appendNewGroupToDownstream(struct SOperatorInfo* pOperator, int32_t downstreamIdx, SOperatorParam** ppParam) {
|
||||||
|
@ -120,7 +237,7 @@ static FORCE_INLINE int32_t appendNewGroupToDownstream(struct SOperatorInfo* pOp
|
||||||
SGcDownstreamCtx* pCtx = &pGCache->pDownstreams[downstreamIdx];
|
SGcDownstreamCtx* pCtx = &pGCache->pDownstreams[downstreamIdx];
|
||||||
SOperatorParam* pDst = NULL;
|
SOperatorParam* pDst = NULL;
|
||||||
|
|
||||||
taosWLockLatch(&pCtx->lock);
|
taosWLockLatch(&pCtx->grpLock);
|
||||||
int32_t num = taosArrayGetSize(pCtx->pNewGrpList);
|
int32_t num = taosArrayGetSize(pCtx->pNewGrpList);
|
||||||
if (num <= 0) {
|
if (num <= 0) {
|
||||||
goto _return;
|
goto _return;
|
||||||
|
@ -128,10 +245,11 @@ static FORCE_INLINE int32_t appendNewGroupToDownstream(struct SOperatorInfo* pOp
|
||||||
|
|
||||||
for (int32_t i = 0; i < num; ++i) {
|
for (int32_t i = 0; i < num; ++i) {
|
||||||
SGcNewGroupInfo* pNew = taosArrayGet(pCtx->pNewGrpList, i);
|
SGcNewGroupInfo* pNew = taosArrayGet(pCtx->pNewGrpList, i);
|
||||||
if (NULL == taosArrayPush(pCtx->pGrpUidList, &pNew->uid)) {
|
code = addNewGroupToVgHash(pCtx->pVgTbHash, pNew);
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
if (code) {
|
||||||
goto _return;
|
goto _return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num > 1) {
|
if (num > 1) {
|
||||||
if (0 == i) {
|
if (0 == i) {
|
||||||
pDst = pNew->pParam;
|
pDst = pNew->pParam;
|
||||||
|
@ -150,7 +268,7 @@ static FORCE_INLINE int32_t appendNewGroupToDownstream(struct SOperatorInfo* pOp
|
||||||
|
|
||||||
_return:
|
_return:
|
||||||
|
|
||||||
taosWUnLockLatch(&pCtx->lock);
|
taosWUnLockLatch(&pCtx->grpLock);
|
||||||
*ppParam = pDst;
|
*ppParam = pDst;
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -174,11 +292,18 @@ static FORCE_INLINE int32_t getBlkFromDownstreamOperator(struct SOperatorInfo* p
|
||||||
|
|
||||||
if (pBlock) {
|
if (pBlock) {
|
||||||
pGCache->execInfo.pDownstreamBlkNum[downstreamIdx]++;
|
pGCache->execInfo.pDownstreamBlkNum[downstreamIdx]++;
|
||||||
|
if (NULL == pGCache->pDownstreams[downstreamIdx].pBaseBlock) {
|
||||||
|
code = buildGroupCacheBaseBlock(&pGCache->pDownstreams[downstreamIdx].pBaseBlock, pBlock);
|
||||||
|
if (code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
taosArrayPush(pGCache->pDownstreams[downstreamIdx].pFreeBlock, &pGCache->pDownstreams[downstreamIdx].pBaseBlock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppRes = pBlock;
|
*ppRes = pBlock;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void notifyWaitingSessions(SArray* pWaitQueue) {
|
static void notifyWaitingSessions(SArray* pWaitQueue) {
|
||||||
|
@ -193,26 +318,70 @@ static void notifyWaitingSessions(SArray* pWaitQueue) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t handleGroupCacheRetrievedBlk(struct SOperatorInfo* pOperator, SSDataBlock* pBlock, SGcSessionCtx* pSession, bool* continueFetch) {
|
static FORCE_INLINE void handleGroupFetchDone(SGroupCacheData* pGroup) {
|
||||||
|
pGroup->pBlock = NULL;
|
||||||
|
pGroup->fetchDone = true;
|
||||||
|
|
||||||
|
taosThreadMutexLock(&pGroup->mutex);
|
||||||
|
notifyWaitingSessions(pGroup->waitQueue);
|
||||||
|
taosArrayClear(pGroup->waitQueue);
|
||||||
|
taosThreadMutexUnlock(&pGroup->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleVgroupTableFetchDone(SGcDownstreamCtx* pCtx, SGroupCacheData* pGroup, uint64_t uid) {
|
||||||
|
if (pCtx->lastBlkUid == uid || pGroup->pVgCtx->lastUid == uid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pCtx->lastBlkUid = uid;
|
||||||
|
pGroup->pVgCtx->lastUid = uid;
|
||||||
|
|
||||||
|
int32_t i = 0;
|
||||||
|
while (true) {
|
||||||
|
SGcNewGroupInfo* pNew = taosArrayGet(pGroup->pVgCtx->pTbList, i++);
|
||||||
|
if (NULL == pNew || pNew->uid == uid) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
handleGroupFetchDone(pNew->pGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pGroup->pVgCtx->fileSize >= GROUP_CACHE_DEFAULT_MAX_FILE_SIZE) {
|
||||||
|
pGroup->pVgCtx->fileId++;
|
||||||
|
pGroup->pVgCtx->fileSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pGroup->fileId = pGroup->pVgCtx->fileId;
|
||||||
|
pGroup->startOffset = pGroup->pVgCtx->fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t handleGroupCacheRetrievedBlk(struct SOperatorInfo* pOperator, SSDataBlock* pBlock, SGcSessionCtx* pSession, bool* continueFetch) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
|
SGcDownstreamCtx* pCtx = &pGCache->pDownstreams[pSession->downstreamIdx];
|
||||||
|
SHashObj* pGrpHash = pGCache->globalGrp ? pGCache->pGrpHash : pCtx->pGrpHash;
|
||||||
|
|
||||||
if (pGCache->grpByUid) {
|
if (pGCache->grpByUid) {
|
||||||
SGroupCacheData* pGroup = taosHashGet(pGCache->pBlkHash, &pBlock->info.id.uid, sizeof(pBlock->info.id.uid));
|
SGroupCacheData* pGroup = taosHashGet(pGrpHash, &pBlock->info.id.uid, sizeof(pBlock->info.id.uid));
|
||||||
|
if (NULL == pGroup) {
|
||||||
|
qError("table uid:%" PRIu64 " not found in group hash", pBlock->info.id.uid);
|
||||||
|
return TSDB_CODE_INVALID_PARA;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleVgroupTableFetchDone(pCtx, pGroup, pBlock->info.id.uid);
|
||||||
|
|
||||||
pGroup->pBlock = pBlock;
|
pGroup->pBlock = pBlock;
|
||||||
|
|
||||||
if (pGroup->needCache) {
|
if (pGroup->needCache) {
|
||||||
SGcBlkBufInfo* pNewBlk = NULL;
|
SGcBlkBufInfo newBlkBuf;
|
||||||
code = addBlkToBlkBufs(pOperator, pBlock, &pNewBlk);
|
code = addBlkToBufCache(pOperator, pBlock, pCtx, pGroup, &newBlkBuf);
|
||||||
if (code) {
|
if (code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pGroup->pLastBlk) {
|
if (pGroup->endBlkId > 0) {
|
||||||
pGroup->pLastBlk->next = pNewBlk;
|
pGroup->endBlkId = newBlkBuf.blkId;
|
||||||
pGroup->pLastBlk = pNewBlk;
|
|
||||||
} else {
|
} else {
|
||||||
pGroup->pFirstBlk = pNewBlk;
|
pGroup->startBlkId = newBlkBuf.blkId;
|
||||||
pGroup->pLastBlk = pNewBlk;
|
pGroup->endBlkId = newBlkBuf.blkId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,16 +400,18 @@ static int32_t handleDownstreamFetchDone(struct SOperatorInfo* pOperator, SGcSes
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
SGcDownstreamCtx* pCtx = &pGCache->pDownstreams[pSession->downstreamIdx];
|
SGcDownstreamCtx* pCtx = &pGCache->pDownstreams[pSession->downstreamIdx];
|
||||||
int32_t uidNum = taosArrayGetSize(pCtx->pGrpUidList);
|
int32_t uidNum = 0;
|
||||||
|
SHashObj* pGrpHash = pGCache->globalGrp ? pGCache->pGrpHash : pCtx->pGrpHash;
|
||||||
|
SGcVgroupCtx* pVgCtx = NULL;
|
||||||
|
int32_t iter = 0;
|
||||||
|
while (pVgCtx = tSimpleHashIterate(pCtx->pVgTbHash, pVgCtx, &iter)) {
|
||||||
|
uidNum = taosArrayGetSize(pVgCtx->pTbList);
|
||||||
for (int32_t i = 0; i < uidNum; ++i) {
|
for (int32_t i = 0; i < uidNum; ++i) {
|
||||||
int64_t* pUid = taosArrayGet(pCtx->pGrpUidList, i);
|
SGcNewGroupInfo* pNew = taosArrayGet(pVgCtx->pTbList, i);
|
||||||
SGroupCacheData* pGroup = taosHashGet(pGCache->pBlkHash, pUid, sizeof(*pUid));
|
handleGroupFetchDone(pNew->pGroup);
|
||||||
pGroup->pBlock = NULL;
|
}
|
||||||
pGroup->fetchDone = true;
|
taosArrayClear(pVgCtx->pTbList);
|
||||||
notifyWaitingSessions(pGroup->waitQueue);
|
|
||||||
}
|
}
|
||||||
taosArrayClear(pCtx->pGrpUidList);
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -267,6 +438,7 @@ static int32_t getCacheBlkFromDownstreamOperator(struct SOperatorInfo* pOperator
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t groupCacheSessionWait(SGroupCacheOperatorInfo* pGCache, SGroupCacheData* pGroup, SGcSessionCtx* pSession, SSDataBlock** ppRes) {
|
static int32_t groupCacheSessionWait(SGroupCacheOperatorInfo* pGCache, SGroupCacheData* pGroup, SGcSessionCtx* pSession, SSDataBlock** ppRes) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
if (NULL == pGroup->waitQueue) {
|
if (NULL == pGroup->waitQueue) {
|
||||||
pGroup->waitQueue = taosArrayInit(1, POINTER_BYTES);
|
pGroup->waitQueue = taosArrayInit(1, POINTER_BYTES);
|
||||||
if (NULL == pGroup->waitQueue) {
|
if (NULL == pGroup->waitQueue) {
|
||||||
|
@ -287,18 +459,22 @@ static int32_t groupCacheSessionWait(SGroupCacheOperatorInfo* pGCache, SGroupCac
|
||||||
tsem_wait(&pSession->waitSem);
|
tsem_wait(&pSession->waitSem);
|
||||||
|
|
||||||
if (pSession->pGroupData->needCache) {
|
if (pSession->pGroupData->needCache) {
|
||||||
if (NULL == pSession->pLastBlk) {
|
if (pSession->lastBlkId < 0) {
|
||||||
if (pSession->pGroupData->pFirstBlk) {
|
int64_t startBlkId = atomic_load_64(&pSession->pGroupData->startBlkId);
|
||||||
*ppRes = retrieveBlkFromBlkBufs(pGCache->pBlkBufs, pSession->pGroupData->pFirstBlk);
|
if (startBlkId > 0) {
|
||||||
pSession->pLastBlk = pSession->pGroupData->pFirstBlk;
|
code = retrieveBlkFromBufCache(pGCache, pSession->pGroupData, startBlkId, &pSession->nextOffset, ppRes);
|
||||||
return TSDB_CODE_SUCCESS;
|
pSession->lastBlkId = startBlkId;
|
||||||
|
return code;
|
||||||
} else if (pGroup->fetchDone) {
|
} else if (pGroup->fetchDone) {
|
||||||
*ppRes = NULL;
|
*ppRes = NULL;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
} else if (pSession->pLastBlk->next) {
|
} else if (pSession->lastBlkId < atomic_load_64(&pSession->pGroupData->endBlkId)) {
|
||||||
*ppRes = retrieveBlkFromBlkBufs(pGCache->pBlkBufs, pSession->pLastBlk->next);
|
code = retrieveBlkFromBufCache(pGCache, pSession->pGroupData, pSession->lastBlkId + 1, &pSession->nextOffset, ppRes);
|
||||||
pSession->pLastBlk = pSession->pLastBlk->next;
|
pSession->lastBlkId++;
|
||||||
|
return code;
|
||||||
|
} else if (pGroup->fetchDone) {
|
||||||
|
*ppRes = NULL;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -317,18 +493,22 @@ static int32_t getBlkFromSessionCacheImpl(struct SOperatorInfo* pOperator, int64
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (pSession->pGroupData->needCache) {
|
if (pSession->pGroupData->needCache) {
|
||||||
if (NULL == pSession->pLastBlk) {
|
if (pSession->lastBlkId < 0) {
|
||||||
if (pSession->pGroupData->pFirstBlk) {
|
int64_t startBlkId = atomic_load_64(&pSession->pGroupData->startBlkId);
|
||||||
*ppRes = retrieveBlkFromBlkBufs(pGCache->pBlkBufs, pSession->pGroupData->pFirstBlk);
|
if (startBlkId > 0) {
|
||||||
pSession->pLastBlk = pSession->pGroupData->pFirstBlk;
|
code = retrieveBlkFromBufCache(pGCache, pSession->pGroupData, startBlkId, &pSession->nextOffset, ppRes);
|
||||||
|
pSession->lastBlkId = startBlkId;
|
||||||
goto _return;
|
goto _return;
|
||||||
}
|
}
|
||||||
} else if (pSession->pLastBlk->next) {
|
} else if (pSession->lastBlkId < atomic_load_64(&pSession->pGroupData->endBlkId)) {
|
||||||
*ppRes = retrieveBlkFromBlkBufs(pGCache->pBlkBufs, pSession->pLastBlk->next);
|
code = retrieveBlkFromBufCache(pGCache, pSession->pGroupData, pSession->lastBlkId + 1, &pSession->nextOffset, ppRes);
|
||||||
pSession->pLastBlk = pSession->pLastBlk->next;
|
pSession->lastBlkId++;
|
||||||
|
goto _return;
|
||||||
|
} else if (atomic_load_8((int8_t*)&pSession->pGroupData->fetchDone)) {
|
||||||
|
*ppRes = NULL;
|
||||||
goto _return;
|
goto _return;
|
||||||
}
|
}
|
||||||
} else if (pSession->pGroupData->pBlock || pSession->pGroupData->fetchDone) {
|
} else if (pSession->pGroupData->pBlock || atomic_load_8((int8_t*)&pSession->pGroupData->fetchDone)) {
|
||||||
*ppRes = pSession->pGroupData->pBlock;
|
*ppRes = pSession->pGroupData->pBlock;
|
||||||
pSession->pGroupData->pBlock = NULL;
|
pSession->pGroupData->pBlock = NULL;
|
||||||
goto _return;
|
goto _return;
|
||||||
|
@ -370,25 +550,48 @@ _return:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int32_t initGroupCacheBufPages(SGroupCacheOperatorInfo* pInfo) {
|
static int32_t initGroupCacheBlockCache(SGroupCacheOperatorInfo* pInfo) {
|
||||||
pInfo->pBlkBufs = taosArrayInit(32, sizeof(SGcBufPageInfo));
|
SGcBlkCacheInfo* pCache = &pInfo->blkCache;
|
||||||
if (NULL == pInfo->pBlkBufs) {
|
pCache->pCacheFile = tSimpleHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT));
|
||||||
|
if (NULL == pCache->pCacheFile) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
pCache->pDirtyBlk = taosHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
|
||||||
|
if (NULL == pCache->pDirtyBlk) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
pCache->pReadBlk = taosHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
|
||||||
|
if (NULL == pCache->pReadBlk) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return addPageToGroupCacheBuf(pInfo->pBlkBufs);
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t initGroupCacheGroupData(struct SOperatorInfo* pOperator, SOperatorParam* pParam, SGroupCacheData** ppGrp) {
|
static FORCE_INLINE void initNewGroupData(SGcDownstreamCtx* pCtx, SGroupCacheData* pGroup, SGcOperatorParam* pGcParam) {
|
||||||
|
taosThreadMutexInit(&pGroup->mutex, NULL);
|
||||||
|
pGroup->needCache = pGcParam->needCache;
|
||||||
|
pGroup->downstreamIdx = pGcParam->downstreamIdx;
|
||||||
|
pGroup->vgId = pGcParam->vgId;
|
||||||
|
pGroup->fileId = -1;
|
||||||
|
pGroup->startBlkId = -1;
|
||||||
|
pGroup->endBlkId = -1;
|
||||||
|
pGroup->startOffset = -1;
|
||||||
|
pGroup->pVgCtx = tSimpleHashGet(pCtx->pVgTbHash, &pGroup->vgId, sizeof(pGroup->vgId));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t addNewGroupData(struct SOperatorInfo* pOperator, SOperatorParam* pParam, SGroupCacheData** ppGrp) {
|
||||||
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
SGcOperatorParam* pGcParam = pParam->value;
|
SGcOperatorParam* pGcParam = pParam->value;
|
||||||
|
SGcDownstreamCtx* pCtx = &pGCache->pDownstreams[pParam->downstreamIdx];
|
||||||
|
SHashObj* pGrpHash = pGCache->globalGrp ? pGCache->pGrpHash : pCtx->pGrpHash;
|
||||||
SGroupCacheData grpData = {0};
|
SGroupCacheData grpData = {0};
|
||||||
grpData.needCache = pGcParam->needCache;
|
initNewGroupData(pCtx, &grpData, pGcParam);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (0 != taosHashPut(pGCache->pBlkHash, pGcParam->pGroupValue, pGcParam->groupValueSize, &grpData, sizeof(grpData))) {
|
if (0 != taosHashPut(pGrpHash, &pGcParam->tbUid, sizeof(pGcParam->tbUid), &grpData, sizeof(grpData))) {
|
||||||
if (terrno == TSDB_CODE_DUP_KEY) {
|
if (terrno == TSDB_CODE_DUP_KEY) {
|
||||||
*ppGrp = taosHashAcquire(pGCache->pBlkHash, pGcParam->pGroupValue, pGcParam->groupValueSize);
|
*ppGrp = taosHashAcquire(pGrpHash, &pGcParam->tbUid, sizeof(pGcParam->tbUid));
|
||||||
if (*ppGrp) {
|
if (*ppGrp) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -397,18 +600,20 @@ static int32_t initGroupCacheGroupData(struct SOperatorInfo* pOperator, SOperato
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppGrp = taosHashAcquire(pGCache->pBlkHash, pGcParam->pGroupValue, pGcParam->groupValueSize);
|
*ppGrp = taosHashAcquire(pGrpHash, &pGcParam->tbUid, sizeof(pGcParam->tbUid));
|
||||||
if (*ppGrp) {
|
if (*ppGrp) {
|
||||||
SGcNewGroupInfo newGroup;
|
SGcNewGroupInfo newGroup;
|
||||||
newGroup.uid = *(int64_t*)pGcParam->pGroupValue;
|
newGroup.pGroup = *ppGrp;
|
||||||
|
newGroup.vgId = pGcParam->vgId;
|
||||||
|
newGroup.uid = pGcParam->tbUid;
|
||||||
newGroup.pParam = taosArrayGet(pParam->pChildren, 0);
|
newGroup.pParam = taosArrayGet(pParam->pChildren, 0);
|
||||||
|
|
||||||
taosWLockLatch(&pGCache->pDownstreams[pParam->downstreamIdx].lock);
|
taosWLockLatch(&pCtx->grpLock);
|
||||||
if (NULL == taosArrayPush(pGCache->pDownstreams[pParam->downstreamIdx].pNewGrpList, &newGroup)) {
|
if (NULL == taosArrayPush(pCtx->pNewGrpList, &newGroup)) {
|
||||||
taosWUnLockLatch(&pGCache->pDownstreams[pParam->downstreamIdx].lock);
|
taosWUnLockLatch(&pCtx->grpLock);
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
taosWUnLockLatch(&pGCache->pDownstreams[pParam->downstreamIdx].lock);
|
taosWUnLockLatch(&pCtx->grpLock);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -418,15 +623,18 @@ static int32_t initGroupCacheGroupData(struct SOperatorInfo* pOperator, SOperato
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t initGroupCacheSession(struct SOperatorInfo* pOperator, SOperatorParam* pParam, SGcSessionCtx** ppSession) {
|
static int32_t initGroupCacheSession(struct SOperatorInfo* pOperator, SOperatorParam* pParam, SGcSessionCtx** ppSession) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SGcSessionCtx ctx = {0};
|
SGcSessionCtx ctx = {0};
|
||||||
int32_t code = 0;
|
|
||||||
SGcOperatorParam* pGcParam = pParam->value;
|
SGcOperatorParam* pGcParam = pParam->value;
|
||||||
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
SGroupCacheData* pGroup = taosHashAcquire(pGCache->pBlkHash, pGcParam->pGroupValue, pGcParam->groupValueSize);
|
SGcDownstreamCtx* pCtx = &pGCache->pDownstreams[pParam->downstreamIdx];
|
||||||
|
SHashObj* pGrpHash = pGCache->globalGrp ? pGCache->pGrpHash : pCtx->pGrpHash;
|
||||||
|
|
||||||
|
SGroupCacheData* pGroup = taosHashAcquire(pGrpHash, &pGcParam->tbUid, sizeof(pGcParam->tbUid));
|
||||||
if (pGroup) {
|
if (pGroup) {
|
||||||
ctx.pGroupData = pGroup;
|
ctx.pGroupData = pGroup;
|
||||||
} else {
|
} else {
|
||||||
code = initGroupCacheGroupData(pOperator, pParam, &ctx.pGroupData);
|
code = addNewGroupData(pOperator, pParam, &ctx.pGroupData);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -434,12 +642,12 @@ static int32_t initGroupCacheSession(struct SOperatorInfo* pOperator, SOperatorP
|
||||||
|
|
||||||
ctx.pParam = pGcParam;
|
ctx.pParam = pGcParam;
|
||||||
|
|
||||||
int32_t code = tSimpleHashPut(pGCache->pSessionHash, &pGcParam->sessionId, sizeof(pGcParam->sessionId), &ctx, sizeof(ctx));
|
code = taosHashPut(pGCache->pSessionHash, &pGcParam->sessionId, sizeof(pGcParam->sessionId), &ctx, sizeof(ctx));
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppSession = tSimpleHashGet(pGCache->pSessionHash, &pGcParam->sessionId, sizeof(pGcParam->sessionId));
|
*ppSession = taosHashGet(pGCache->pSessionHash, &pGcParam->sessionId, sizeof(pGcParam->sessionId));
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -447,7 +655,7 @@ static int32_t initGroupCacheSession(struct SOperatorInfo* pOperator, SOperatorP
|
||||||
static int32_t getBlkFromGroupCache(struct SOperatorInfo* pOperator, SSDataBlock** ppRes, SOperatorParam* pParam) {
|
static int32_t getBlkFromGroupCache(struct SOperatorInfo* pOperator, SSDataBlock** ppRes, SOperatorParam* pParam) {
|
||||||
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
SGcOperatorParam* pGcParam = pParam->value;
|
SGcOperatorParam* pGcParam = pParam->value;
|
||||||
SGcSessionCtx* pSession = tSimpleHashGet(pGCache->pSessionHash, &pGcParam->sessionId, sizeof(pGcParam->sessionId));
|
SGcSessionCtx* pSession = taosHashGet(pGCache->pSessionHash, &pGcParam->sessionId, sizeof(pGcParam->sessionId));
|
||||||
if (NULL == pSession) {
|
if (NULL == pSession) {
|
||||||
int32_t code = initGroupCacheSession(pOperator, pParam, &pSession);
|
int32_t code = initGroupCacheSession(pOperator, pParam, &pSession);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
@ -462,7 +670,7 @@ static FORCE_INLINE void destroyCurrentGroupCacheSession(SGroupCacheOperatorInfo
|
||||||
if (NULL == *ppCurrent) {
|
if (NULL == *ppCurrent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (tSimpleHashRemove(pGCache->pSessionHash, pCurrentId, sizeof(*pCurrentId))) {
|
if (taosHashRemove(pGCache->pSessionHash, pCurrentId, sizeof(*pCurrentId))) {
|
||||||
qError("remove session %" PRIx64 " failed", *pCurrentId);
|
qError("remove session %" PRIx64 " failed", *pCurrentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,8 +697,9 @@ static int32_t initGroupCacheDownstreamCtx(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
|
for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
|
||||||
pInfo->pDownstreams[i].fetchSessionId = -1;
|
pInfo->pDownstreams[i].fetchSessionId = -1;
|
||||||
pInfo->pDownstreams[i].pGrpUidList = taosArrayInit(10, sizeof(int64_t));
|
pInfo->pDownstreams[i].lastBlkUid = 0;
|
||||||
if (NULL == pInfo->pDownstreams[i].pGrpUidList) {
|
pInfo->pDownstreams[i].pVgTbHash = tSimpleHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT));
|
||||||
|
if (NULL == pInfo->pDownstreams[i].pVgTbHash) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,6 +707,17 @@ static int32_t initGroupCacheDownstreamCtx(SOperatorInfo* pOperator) {
|
||||||
if (NULL == pInfo->pDownstreams[i].pNewGrpList) {
|
if (NULL == pInfo->pDownstreams[i].pNewGrpList) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
if (!pInfo->globalGrp) {
|
||||||
|
pInfo->pDownstreams[i].pGrpHash = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
|
||||||
|
if (pInfo->pDownstreams[i].pGrpHash == NULL) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->pDownstreams[i].pFreeBlock = taosArrayInit(10, POINTER_BYTES);
|
||||||
|
if (NULL == pInfo->pDownstreams[i].pFreeBlock) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -531,10 +751,14 @@ SOperatorInfo* createGroupCacheOperatorInfo(SOperatorInfo** pDownstream, int32_t
|
||||||
|
|
||||||
setOperatorInfo(pOperator, "GroupCacheOperator", QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE, false, OP_NOT_OPENED, pInfo, pTaskInfo);
|
setOperatorInfo(pOperator, "GroupCacheOperator", QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE, false, OP_NOT_OPENED, pInfo, pTaskInfo);
|
||||||
|
|
||||||
|
pInfo->maxCacheSize = -1;
|
||||||
pInfo->grpByUid = pPhyciNode->grpByUid;
|
pInfo->grpByUid = pPhyciNode->grpByUid;
|
||||||
|
pInfo->globalGrp = pPhyciNode->globalGrp;
|
||||||
|
|
||||||
if (!pInfo->grpByUid) {
|
if (!pInfo->grpByUid) {
|
||||||
qError("only group cache by uid is supported now");
|
qError("only group cache by uid is supported now");
|
||||||
return TSDB_CODE_INVALID_PARA;
|
code = TSDB_CODE_INVALID_PARA;
|
||||||
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pPhyciNode->pGroupCols) {
|
if (pPhyciNode->pGroupCols) {
|
||||||
|
@ -544,18 +768,20 @@ SOperatorInfo* createGroupCacheOperatorInfo(SOperatorInfo** pDownstream, int32_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
code = initGroupCacheBufPages(pInfo);
|
code = initGroupCacheBlockCache(pInfo);
|
||||||
if (code) {
|
if (code) {
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
pInfo->pBlkHash = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
|
if (pInfo->globalGrp) {
|
||||||
if (pInfo->pBlkHash == NULL) {
|
pInfo->pGrpHash = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
|
||||||
|
if (pInfo->pGrpHash == NULL) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pInfo->pSessionHash = tSimpleHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT));
|
pInfo->pSessionHash = taosHashInit(20, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
|
||||||
if (pInfo->pSessionHash == NULL) {
|
if (pInfo->pSessionHash == NULL) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
goto _error;
|
goto _error;
|
||||||
|
|
|
@ -616,28 +616,37 @@ int32_t mergeOperatorParams(SOperatorParam* pDst, SOperatorParam* pSrc) {
|
||||||
SExchangeOperatorParam* pDExc = pDst->value;
|
SExchangeOperatorParam* pDExc = pDst->value;
|
||||||
SExchangeOperatorParam* pSExc = pSrc->value;
|
SExchangeOperatorParam* pSExc = pSrc->value;
|
||||||
if (!pDExc->multiParams) {
|
if (!pDExc->multiParams) {
|
||||||
|
if (pSExc->basic.vgId != pDExc->basic.vgId) {
|
||||||
SExchangeOperatorBatchParam* pBatch = taosMemoryMalloc(sizeof(SExchangeOperatorBatchParam));
|
SExchangeOperatorBatchParam* pBatch = taosMemoryMalloc(sizeof(SExchangeOperatorBatchParam));
|
||||||
if (NULL == pBatch) {
|
if (NULL == pBatch) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
pBatch->multiParams = true;
|
pBatch->multiParams = true;
|
||||||
pBatch->pBatchs = taosArrayInit(4, sizeof(SExchangeOperatorBasicParam));
|
pBatch->pBatchs = tSimpleHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT));
|
||||||
if (NULL == pBatch->pBatchs) {
|
if (NULL == pBatch->pBatchs) {
|
||||||
taosMemoryFree(pBatch);
|
taosMemoryFree(pBatch);
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
taosArrayPush(pBatch->pBatchs, &pDExc->basic);
|
tSimpleHashPut(pBatch->pBatchs, &pDExc->basic.vgId, sizeof(pDExc->basic.vgId), &pDExc->basic, sizeof(pDExc->basic));
|
||||||
taosArrayPush(pBatch->pBatchs, &pSExc->basic);
|
tSimpleHashPut(pBatch->pBatchs, &pSExc->basic.vgId, sizeof(pSExc->basic.vgId), &pSExc->basic, sizeof(pSExc->basic));
|
||||||
destroyOperatorParamValue(pDst->value);
|
destroyOperatorParamValue(pDst->value);
|
||||||
pDst->value = pBatch;
|
pDst->value = pBatch;
|
||||||
|
} else {
|
||||||
|
taosArrayAddAll(pDExc->basic.uidList, pSExc->basic.uidList);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SExchangeOperatorBatchParam* pBatch = pDst->value;
|
SExchangeOperatorBatchParam* pBatch = pDst->value;
|
||||||
taosArrayPush(pBatch->pBatchs, &pSExc->basic);
|
SExchangeOperatorBasicParam* pBasic = tSimpleHashGet(pBatch->pBatchs, &pSExc->basic.vgId, sizeof(pSExc->basic.vgId));
|
||||||
|
if (pBasic) {
|
||||||
|
taosArrayAddAll(pBasic->uidList, pSExc->basic.uidList);
|
||||||
|
} else {
|
||||||
|
tSimpleHashPut(pBatch->pBatchs, &pSExc->basic.vgId, sizeof(pSExc->basic.vgId), &pSExc->basic, sizeof(pSExc->basic));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
qError("invalid optype %d for merge operator params", (*ppDst)->opType);
|
qError("invalid optype %d for merge operator params", pDst->opType);
|
||||||
return TSDB_CODE_INVALID_PARA;
|
return TSDB_CODE_INVALID_PARA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,7 +687,7 @@ int32_t setOperatorParams(struct SOperatorInfo* pOperator, SOperatorParam* pPara
|
||||||
for (int32_t i = 0; i < childrenNum; ++i) {
|
for (int32_t i = 0; i < childrenNum; ++i) {
|
||||||
SOperatorParam* pChild = *(SOperatorParam**)taosArrayGet(pOperator->pOperatorParam->pChildren, i);
|
SOperatorParam* pChild = *(SOperatorParam**)taosArrayGet(pOperator->pOperatorParam->pChildren, i);
|
||||||
if (pOperator->pDownstreamParams[pChild->downstreamIdx]) {
|
if (pOperator->pDownstreamParams[pChild->downstreamIdx]) {
|
||||||
int32_t code = mergeOperatorParams(&pOperator->pDownstreamParams[pChild->downstreamIdx], pChild);
|
int32_t code = mergeOperatorParams(pOperator->pDownstreamParams[pChild->downstreamIdx], pChild);
|
||||||
if (code) {
|
if (code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1183,6 +1183,8 @@ static int32_t jsonToLogicInterpFuncNode(const SJson* pJson, void* pObj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* jkGroupCacheLogicPlanGrpColsMayBeNull = "GroupColsMayBeNull";
|
static const char* jkGroupCacheLogicPlanGrpColsMayBeNull = "GroupColsMayBeNull";
|
||||||
|
static const char* jkGroupCacheLogicPlanGroupByUid = "GroupByUid";
|
||||||
|
static const char* jkGroupCacheLogicPlanGlobalGroup = "GlobalGroup";
|
||||||
static const char* jkGroupCacheLogicPlanGroupCols = "GroupCols";
|
static const char* jkGroupCacheLogicPlanGroupCols = "GroupCols";
|
||||||
|
|
||||||
static int32_t logicGroupCacheNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t logicGroupCacheNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
|
@ -1192,6 +1194,12 @@ static int32_t logicGroupCacheNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddBoolToObject(pJson, jkGroupCacheLogicPlanGrpColsMayBeNull, pNode->grpColsMayBeNull);
|
code = tjsonAddBoolToObject(pJson, jkGroupCacheLogicPlanGrpColsMayBeNull, pNode->grpColsMayBeNull);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddBoolToObject(pJson, jkGroupCacheLogicPlanGroupByUid, pNode->grpByUid);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddBoolToObject(pJson, jkGroupCacheLogicPlanGlobalGroup, pNode->globalGrp);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = nodeListToJson(pJson, jkGroupCacheLogicPlanGroupCols, pNode->pGroupCols);
|
code = nodeListToJson(pJson, jkGroupCacheLogicPlanGroupCols, pNode->pGroupCols);
|
||||||
}
|
}
|
||||||
|
@ -1206,6 +1214,12 @@ static int32_t jsonToLogicGroupCacheNode(const SJson* pJson, void* pObj) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonGetBoolValue(pJson, jkGroupCacheLogicPlanGrpColsMayBeNull, &pNode->grpColsMayBeNull);
|
code = tjsonGetBoolValue(pJson, jkGroupCacheLogicPlanGrpColsMayBeNull, &pNode->grpColsMayBeNull);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBoolValue(pJson, jkGroupCacheLogicPlanGroupByUid, &pNode->grpByUid);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBoolValue(pJson, jkGroupCacheLogicPlanGlobalGroup, &pNode->globalGrp);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeList(pJson, jkGroupCacheLogicPlanGroupCols, &pNode->pGroupCols);
|
code = jsonToNodeList(pJson, jkGroupCacheLogicPlanGroupCols, &pNode->pGroupCols);
|
||||||
}
|
}
|
||||||
|
@ -2912,12 +2926,24 @@ static int32_t jsonToPhysiDeleteNode(const SJson* pJson, void* pObj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* jkGroupCachePhysiPlanGroupCols = "GroupColumns";
|
static const char* jkGroupCachePhysiPlanGroupCols = "GroupColumns";
|
||||||
|
static const char* jkGroupCachePhysiPlanGrpColsMayBeNull = "GroupColumnsMayBeNull";
|
||||||
|
static const char* jkGroupCachePhysiPlanGroupByUid = "GroupByUid";
|
||||||
|
static const char* jkGroupCachePhysiPlanGlobalGroup = "GlobalGroup";
|
||||||
|
|
||||||
|
|
||||||
static int32_t physiGroupCacheNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t physiGroupCacheNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
const SGroupCachePhysiNode* pNode = (const SGroupCachePhysiNode*)pObj;
|
const SGroupCachePhysiNode* pNode = (const SGroupCachePhysiNode*)pObj;
|
||||||
|
|
||||||
int32_t code = physicPlanNodeToJson(pObj, pJson);
|
int32_t code = physicPlanNodeToJson(pObj, pJson);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddBoolToObject(pJson, jkGroupCachePhysiPlanGrpColsMayBeNull, pNode->grpColsMayBeNull);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddBoolToObject(pJson, jkGroupCachePhysiPlanGroupByUid, pNode->grpByUid);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddBoolToObject(pJson, jkGroupCachePhysiPlanGlobalGroup, pNode->globalGrp);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = nodeListToJson(pJson, jkGroupCachePhysiPlanGroupCols, pNode->pGroupCols);
|
code = nodeListToJson(pJson, jkGroupCachePhysiPlanGroupCols, pNode->pGroupCols);
|
||||||
}
|
}
|
||||||
|
@ -2928,6 +2954,15 @@ static int32_t jsonToPhysiGroupCacheNode(const SJson* pJson, void* pObj) {
|
||||||
SGroupCachePhysiNode* pNode = (SGroupCachePhysiNode*)pObj;
|
SGroupCachePhysiNode* pNode = (SGroupCachePhysiNode*)pObj;
|
||||||
|
|
||||||
int32_t code = jsonToPhysicPlanNode(pJson, pObj);
|
int32_t code = jsonToPhysicPlanNode(pJson, pObj);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBoolValue(pJson, jkGroupCachePhysiPlanGrpColsMayBeNull, &pNode->grpColsMayBeNull);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBoolValue(pJson, jkGroupCachePhysiPlanGroupByUid, &pNode->grpByUid);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBoolValue(pJson, jkGroupCachePhysiPlanGlobalGroup, &pNode->globalGrp);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeList(pJson, jkGroupCachePhysiPlanGroupCols, &pNode->pGroupCols);
|
code = jsonToNodeList(pJson, jkGroupCachePhysiPlanGroupCols, &pNode->pGroupCols);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3527,6 +3527,9 @@ static int32_t msgToPhysiDeleteNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PHY_GROUP_CACHE_CODE_BASE_NODE = 1,
|
PHY_GROUP_CACHE_CODE_BASE_NODE = 1,
|
||||||
|
PHY_GROUP_CACHE_CODE_GROUP_COLS_MAY_BE_NULL,
|
||||||
|
PHY_GROUP_CACHE_CODE_GROUP_BY_UID,
|
||||||
|
PHY_GROUP_CACHE_CODE_GLOBAL_GROUP,
|
||||||
PHY_GROUP_CACHE_CODE_GROUP_COLUMNS
|
PHY_GROUP_CACHE_CODE_GROUP_COLUMNS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3537,6 +3540,16 @@ static int32_t physiGroupCacheNodeToMsg(const void* pObj, STlvEncoder* pEncoder)
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tlvEncodeObj(pEncoder, PHY_GROUP_CACHE_CODE_GROUP_COLUMNS, nodeListToMsg, pNode->pGroupCols);
|
code = tlvEncodeObj(pEncoder, PHY_GROUP_CACHE_CODE_GROUP_COLUMNS, nodeListToMsg, pNode->pGroupCols);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tlvEncodeBool(pEncoder, PHY_GROUP_CACHE_CODE_GROUP_COLS_MAY_BE_NULL, pNode->grpColsMayBeNull);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tlvEncodeBool(pEncoder, PHY_GROUP_CACHE_CODE_GROUP_BY_UID, pNode->grpByUid);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tlvEncodeBool(pEncoder, PHY_GROUP_CACHE_CODE_GLOBAL_GROUP, pNode->globalGrp);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3553,6 +3566,15 @@ static int32_t msgToPhysiGroupCacheNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
case PHY_GROUP_CACHE_CODE_GROUP_COLUMNS:
|
case PHY_GROUP_CACHE_CODE_GROUP_COLUMNS:
|
||||||
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pGroupCols);
|
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pGroupCols);
|
||||||
break;
|
break;
|
||||||
|
case PHY_GROUP_CACHE_CODE_GROUP_COLS_MAY_BE_NULL:
|
||||||
|
code = tlvDecodeBool(pTlv, &pNode->grpColsMayBeNull);
|
||||||
|
break;
|
||||||
|
case PHY_GROUP_CACHE_CODE_GROUP_BY_UID:
|
||||||
|
code = tlvDecodeBool(pTlv, &pNode->grpByUid);
|
||||||
|
break;
|
||||||
|
case PHY_GROUP_CACHE_CODE_GLOBAL_GROUP:
|
||||||
|
code = tlvDecodeBool(pTlv, &pNode->globalGrp);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3231,6 +3231,7 @@ static int32_t stbJoinOptCreateGroupCacheNode(SNodeList* pChildren, SLogicNode**
|
||||||
|
|
||||||
pGrpCache->node.dynamicOp = true;
|
pGrpCache->node.dynamicOp = true;
|
||||||
pGrpCache->grpColsMayBeNull = false;
|
pGrpCache->grpColsMayBeNull = false;
|
||||||
|
pGrpCache->grpByUid = true;
|
||||||
pGrpCache->node.pChildren = pChildren;
|
pGrpCache->node.pChildren = pChildren;
|
||||||
pGrpCache->node.pTargets = nodesMakeList();
|
pGrpCache->node.pTargets = nodesMakeList();
|
||||||
if (NULL == pGrpCache->node.pTargets) {
|
if (NULL == pGrpCache->node.pTargets) {
|
||||||
|
@ -3252,11 +3253,16 @@ static int32_t stbJoinOptCreateGroupCacheNode(SNodeList* pChildren, SLogicNode**
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasCond = false;
|
||||||
SNode* pNode = NULL;
|
SNode* pNode = NULL;
|
||||||
FOREACH(pNode, pChildren) {
|
FOREACH(pNode, pChildren) {
|
||||||
SScanLogicNode* pScan = (SScanLogicNode*)pNode;
|
SScanLogicNode* pScan = (SScanLogicNode*)pNode;
|
||||||
|
if (pScan->node.pConditions) {
|
||||||
|
hasCond = true;
|
||||||
|
}
|
||||||
pScan->node.pParent = (SLogicNode*)pGrpCache;
|
pScan->node.pParent = (SLogicNode*)pGrpCache;
|
||||||
}
|
}
|
||||||
|
pGrpCache->globalGrp = !hasCond;
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
*ppLogic = (SLogicNode*)pGrpCache;
|
*ppLogic = (SLogicNode*)pGrpCache;
|
||||||
|
|
|
@ -986,6 +986,8 @@ static int32_t createGroupCachePhysiNode(SPhysiPlanContext* pCxt, SNodeList* pCh
|
||||||
}
|
}
|
||||||
|
|
||||||
pGrpCache->grpColsMayBeNull = pLogicNode->grpColsMayBeNull;
|
pGrpCache->grpColsMayBeNull = pLogicNode->grpColsMayBeNull;
|
||||||
|
pGrpCache->grpByUid = pLogicNode->grpByUid;
|
||||||
|
pGrpCache->globalGrp = pLogicNode->globalGrp;
|
||||||
SDataBlockDescNode* pChildDesc = ((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc;
|
SDataBlockDescNode* pChildDesc = ((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc;
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
|
Loading…
Reference in New Issue