enh: add group cache func
This commit is contained in:
parent
2d3f9c739d
commit
185071fae9
|
@ -443,6 +443,7 @@ typedef struct SGroupCachePhysiNode {
|
||||||
SPhysiNode node;
|
SPhysiNode node;
|
||||||
bool grpColsMayBeNull;
|
bool grpColsMayBeNull;
|
||||||
SArray* pDownstreamKey;
|
SArray* pDownstreamKey;
|
||||||
|
bool grpByUid;
|
||||||
SNodeList* pGroupCols;
|
SNodeList* pGroupCols;
|
||||||
} SGroupCachePhysiNode;
|
} SGroupCachePhysiNode;
|
||||||
|
|
||||||
|
|
|
@ -517,6 +517,7 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_QRY_JOB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x072F)
|
#define TSDB_CODE_QRY_JOB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x072F)
|
||||||
#define TSDB_CODE_QRY_QWORKER_QUIT TAOS_DEF_ERROR_CODE(0, 0x0730)
|
#define TSDB_CODE_QRY_QWORKER_QUIT TAOS_DEF_ERROR_CODE(0, 0x0730)
|
||||||
#define TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR TAOS_DEF_ERROR_CODE(0, 0x0731)
|
#define TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR TAOS_DEF_ERROR_CODE(0, 0x0731)
|
||||||
|
#define TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x0732)
|
||||||
|
|
||||||
// grant
|
// grant
|
||||||
#define TSDB_CODE_GRANT_EXPIRED TAOS_DEF_ERROR_CODE(0, 0x0800)
|
#define TSDB_CODE_GRANT_EXPIRED TAOS_DEF_ERROR_CODE(0, 0x0800)
|
||||||
|
|
|
@ -37,9 +37,10 @@ typedef struct SGcBufPageInfo {
|
||||||
|
|
||||||
typedef struct SGroupCacheData {
|
typedef struct SGroupCacheData {
|
||||||
TdThreadMutex mutex;
|
TdThreadMutex mutex;
|
||||||
SSHashObj* waitQueue;
|
SArray* waitQueue;
|
||||||
bool fetchDone;
|
bool fetchDone;
|
||||||
int64_t fetchSessionId;
|
bool needCache;
|
||||||
|
SSDataBlock* pBlock;
|
||||||
SGcBlkBufInfo* pFirstBlk;
|
SGcBlkBufInfo* pFirstBlk;
|
||||||
SGcBlkBufInfo* pLastBlk;
|
SGcBlkBufInfo* pLastBlk;
|
||||||
} SGroupCacheData;
|
} SGroupCacheData;
|
||||||
|
@ -60,11 +61,26 @@ typedef struct SGroupColsInfo {
|
||||||
char* pData;
|
char* pData;
|
||||||
} SGroupColsInfo;
|
} SGroupColsInfo;
|
||||||
|
|
||||||
|
typedef struct SGcNewGroupInfo {
|
||||||
|
int64_t uid;
|
||||||
|
SOperatorParam* pParam;
|
||||||
|
} SGcNewGroupInfo;
|
||||||
|
|
||||||
|
typedef struct SGcDownstreamCtx {
|
||||||
|
SRWLatch lock;
|
||||||
|
int64_t fetchSessionId;
|
||||||
|
SArray* pNewGrpList; // SArray<SGcNewGroupInfo>
|
||||||
|
SArray* pGrpUidList;
|
||||||
|
} SGcDownstreamCtx;
|
||||||
|
|
||||||
typedef struct SGcSessionCtx {
|
typedef struct SGcSessionCtx {
|
||||||
int32_t downstreamIdx;
|
int32_t downstreamIdx;
|
||||||
bool needCache;
|
bool needCache;
|
||||||
SGroupCacheData* pGroupData;
|
SGcOperatorParam* pParam;
|
||||||
SGcBlkBufInfo* pLastBlk;
|
SGroupCacheData* pGroupData;
|
||||||
|
SGcBlkBufInfo* pLastBlk;
|
||||||
|
bool semInit;
|
||||||
|
tsem_t waitSem;
|
||||||
} SGcSessionCtx;
|
} SGcSessionCtx;
|
||||||
|
|
||||||
typedef struct SGcExecInfo {
|
typedef struct SGcExecInfo {
|
||||||
|
@ -72,9 +88,17 @@ typedef struct SGcExecInfo {
|
||||||
int64_t* pDownstreamBlkNum;
|
int64_t* pDownstreamBlkNum;
|
||||||
} SGcExecInfo;
|
} SGcExecInfo;
|
||||||
|
|
||||||
|
typedef struct SGcNewGroupInfo {
|
||||||
|
int64_t uid;
|
||||||
|
} SGcNewGroupInfo;
|
||||||
|
|
||||||
typedef struct SGroupCacheOperatorInfo {
|
typedef struct SGroupCacheOperatorInfo {
|
||||||
|
TdThreadMutex sessionMutex;
|
||||||
|
SGcNewGroupInfo newGroup;
|
||||||
SSHashObj* pSessionHash;
|
SSHashObj* pSessionHash;
|
||||||
SGroupColsInfo groupColsInfo;
|
SGroupColsInfo groupColsInfo;
|
||||||
|
bool grpByUid;
|
||||||
|
SGcDownstreamCtx* pDownstreams;
|
||||||
SArray* pBlkBufs;
|
SArray* pBlkBufs;
|
||||||
SHashObj* pBlkHash;
|
SHashObj* pBlkHash;
|
||||||
SGcExecInfo execInfo;
|
SGcExecInfo execInfo;
|
||||||
|
|
|
@ -110,29 +110,218 @@ static FORCE_INLINE char* retrieveBlkFromBlkBufs(SArray* pBlkBufs, SGcBlkBufInfo
|
||||||
return pPage->data + pBlkInfo->offset;
|
return pPage->data + pBlkInfo->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t getBlkFromSessionCacheImpl(struct SOperatorInfo* pOperator, int64_t sessionId, SGcSessionCtx* pSession, SSDataBlock** ppRes) {
|
static FORCE_INLINE int32_t appendNewGroupToDownstream(struct SOperatorInfo* pOperator, int32_t downstreamIdx) {
|
||||||
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
|
SGcDownstreamCtx* pCtx = &pGCache->pDownstreams[downstreamIdx];
|
||||||
|
|
||||||
|
taosWLockLatch(&pGCache->pDownstreams[pParam->downstreamIdx].lock);
|
||||||
|
|
||||||
|
if (NULL == taosArrayPush(pCtx->pGrpUidList, &pGCache->newGroup.uid)) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
pGCache->newGroup.uid = 0;
|
||||||
|
taosThreadMutexUnlock(&pGCache->sessionMutex);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FORCE_INLINE int32_t getBlkFromDownstreamOperator(struct SOperatorInfo* pOperator, int32_t downstreamIdx, SSDataBlock** ppRes) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
if (NULL == pSession->pLastBlk) {
|
if (pGCache->pDownstreams[downstreamIdx].pNewGrpList) {
|
||||||
if (pSession->pGroupData->pFirstBlk) {
|
code = appendNewGroupToDownstream(pOperator, downstreamIdx, &pGCache->newGroup.uid);
|
||||||
*ppRes = retrieveBlkFromBlkBufs(pGCache->pBlkBufs, pSession->pGroupData->pFirstBlk);
|
if (code) {
|
||||||
pSession->pLastBlk = pSession->pGroupData->pFirstBlk;
|
return code;
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atomic_load_64(&pSession->pGroupData->fetchSessionId) == sessionId) {
|
|
||||||
getBlkFromDownstreamOperator(pOperator, pSession->downstreamIdx, ppRes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SGcBlkBufInfo* pCurr = (*ppLastBlk)->next;
|
SSDataBlock* pBlock = getNextBlockFromDownstreamOnce(pOperator, downstreamIdx);
|
||||||
*ppLastBlk = pCurr;
|
if (pBlock) {
|
||||||
if (pCurr) {
|
pGCache->execInfo.pDownstreamBlkNum[downstreamIdx]++;
|
||||||
SGcBufPageInfo *pPage = taosArrayGet(pBlkBufs, pCurr->pageId);
|
}
|
||||||
return pPage->data + pCurr->offset;
|
|
||||||
|
*ppRes = pBlock;
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addBlkToGroupCache(struct SOperatorInfo* pOperator, SSDataBlock* pBlock, SSDataBlock** ppRes) {
|
||||||
|
*ppRes = pBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void notifyWaitingSessions(SArray* pWaitQueue) {
|
||||||
|
if (NULL == pWaitQueue || taosArrayGetSize(pWaitQueue) <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t n = taosArrayGetSize(pWaitQueue);
|
||||||
|
for (int32_t i = 0; i < n; ++i) {
|
||||||
|
SGcSessionCtx* pSession = taosArrayGetP(pWaitQueue, i);
|
||||||
|
tsem_post(&pSession->waitSem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t handleGroupCacheRetrievedBlk(struct SOperatorInfo* pOperator, SSDataBlock* pBlock, SGcSessionCtx* pSession, bool* continueFetch) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
|
if (pGCache->grpByUid) {
|
||||||
|
SGroupCacheData* pGroup = taosHashGet(pGCache->pBlkHash, &pBlock->info.id.uid, sizeof(pBlock->info.id.uid));
|
||||||
|
pGroup->pBlock = pBlock;
|
||||||
|
|
||||||
|
if (pGroup->needCache) {
|
||||||
|
SGcBlkBufInfo* pNewBlk = NULL;
|
||||||
|
code = addBlkToGroupCache(pOperator, pBlock, &pNewBlk);
|
||||||
|
if (code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pGroup->pLastBlk) {
|
||||||
|
pGroup->pLastBlk->next = pNewBlk;
|
||||||
|
pGroup->pLastBlk = pNewBlk;
|
||||||
|
} else {
|
||||||
|
pGroup->pFirstBlk = pNewBlk;
|
||||||
|
pGroup->pLastBlk = pNewBlk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyWaitingSessions(pGroup->waitQueue);
|
||||||
|
if (pGroup == pSession->pGroupData) {
|
||||||
|
*continueFetch = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return TSDB_CODE_INVALID_PARA;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t handleDownstreamFetchDone(struct SOperatorInfo* pOperator, SGcSessionCtx* pSession) {
|
||||||
|
notifyWaitingSessions();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t getCacheBlkFromDownstreamOperator(struct SOperatorInfo* pOperator, SGcSessionCtx* pSession, SSDataBlock** ppRes) {
|
||||||
|
bool continueFetch = true;
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
while (continueFetch && TSDB_CODE_SUCCESS == code) {
|
||||||
|
int32_t code = getBlkFromDownstreamOperator(pOperator, pSession->downstreamIdx, ppRes);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == *ppRes) {
|
||||||
|
code = handleDownstreamFetchDone(pOperator, pSession);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
code = handleGroupCacheRetrievedBlk(pOperator, *ppRes, pSession, &continueFetch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t groupCacheSessionWait(SGroupCacheOperatorInfo* pGCache, SGroupCacheData* pGroup, SGcSessionCtx* pSession, SSDataBlock** ppRes) {
|
||||||
|
if (NULL == pGroup->waitQueue) {
|
||||||
|
pGroup->waitQueue = taosArrayInit(1, POINTER_BYTES);
|
||||||
|
if (NULL == pGroup->waitQueue) {
|
||||||
|
taosThreadMutexUnlock(&pSession->pGroupData->mutex);
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayPush(pGroup->waitQueue, &pSession);
|
||||||
|
|
||||||
|
if (!pSession->semInit) {
|
||||||
|
tsem_init(&pSession->waitSem, 0, 0);
|
||||||
|
pSession->semInit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosThreadMutexUnlock(&pSession->pGroupData->mutex);
|
||||||
|
|
||||||
|
tsem_wait(&pSession->waitSem);
|
||||||
|
|
||||||
|
if (pSession->pGroupData->needCache) {
|
||||||
|
if (NULL == pSession->pLastBlk) {
|
||||||
|
if (pSession->pGroupData->pFirstBlk) {
|
||||||
|
*ppRes = retrieveBlkFromBlkBufs(pGCache->pBlkBufs, pSession->pGroupData->pFirstBlk);
|
||||||
|
pSession->pLastBlk = pSession->pGroupData->pFirstBlk;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
} else if (pGroup->fetchDone) {
|
||||||
|
*ppRes = NULL;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
} else if (pSession->pLastBlk->next) {
|
||||||
|
*ppRes = retrieveBlkFromBlkBufs(pGCache->pBlkBufs, pSession->pLastBlk->next);
|
||||||
|
pSession->pLastBlk = pSession->pLastBlk->next;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*ppRes = pSession->pGroupData->pBlock;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
qError("no block retrieved from downstream and waked up");
|
||||||
|
return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t getBlkFromSessionCacheImpl(struct SOperatorInfo* pOperator, int64_t sessionId, SGcSessionCtx* pSession, SSDataBlock** ppRes) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
|
bool locked = false;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (pSession->pGroupData->needCache) {
|
||||||
|
if (NULL == pSession->pLastBlk) {
|
||||||
|
if (pSession->pGroupData->pFirstBlk) {
|
||||||
|
*ppRes = retrieveBlkFromBlkBufs(pGCache->pBlkBufs, pSession->pGroupData->pFirstBlk);
|
||||||
|
pSession->pLastBlk = pSession->pGroupData->pFirstBlk;
|
||||||
|
goto _return;
|
||||||
|
}
|
||||||
|
} else if (pSession->pLastBlk->next) {
|
||||||
|
*ppRes = retrieveBlkFromBlkBufs(pGCache->pBlkBufs, pSession->pLastBlk->next);
|
||||||
|
pSession->pLastBlk = pSession->pLastBlk->next;
|
||||||
|
goto _return;
|
||||||
|
}
|
||||||
|
} else if (pSession->pGroupData->pBlock || pSession->pGroupData->fetchDone) {
|
||||||
|
*ppRes = pSession->pGroupData->pBlock;
|
||||||
|
pSession->pGroupData->pBlock = NULL;
|
||||||
|
goto _return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((atomic_load_64(&pGCache->pDownstreams[pSession->downstreamIdx].fetchSessionId) == sessionId)
|
||||||
|
|| (-1 == atomic_val_compare_exchange_64(&pGCache->pDownstreams[pSession->downstreamIdx].fetchSessionId, -1, sessionId))) {
|
||||||
|
if (locked) {
|
||||||
|
taosThreadMutexUnlock(&pSession->pGroupData->mutex);
|
||||||
|
locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = getCacheBlkFromDownstreamOperator(pOperator, pSession, ppRes);
|
||||||
|
goto _return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (locked) {
|
||||||
|
code = groupCacheSessionWait(pGCache, pSession->pGroupData, pSession, ppRes);
|
||||||
|
locked = false;
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
goto _return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosThreadMutexLock(&pSession->pGroupData->mutex);
|
||||||
|
locked = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
_return:
|
||||||
|
|
||||||
|
if (locked) {
|
||||||
|
taosThreadMutexUnlock(&pSession->pGroupData->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,9 +334,11 @@ static int32_t initGroupCacheBufPages(SGroupCacheOperatorInfo* pInfo) {
|
||||||
return addPageToGroupCacheBuf(pInfo->pBlkBufs);
|
return addPageToGroupCacheBuf(pInfo->pBlkBufs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t initGroupCacheGroupData(SGroupCacheOperatorInfo* pGCache, SGcOperatorParam* pParam, SGroupCacheData** ppGrp) {
|
static int32_t initGroupCacheGroupData(struct SOperatorInfo* pOperator, SGcOperatorParam* pParam, SGroupCacheData** ppGrp) {
|
||||||
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
SGroupCacheData grpData = {0};
|
SGroupCacheData grpData = {0};
|
||||||
grpData.fetchSessionId = pParam->sessionId;
|
grpData.needCache = pParam->needCache;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (0 != taosHashPut(pGCache->pBlkHash, pParam->pGroupValue, pParam->groupValueSize, &grpData, sizeof(grpData))) {
|
if (0 != taosHashPut(pGCache->pBlkHash, pParam->pGroupValue, pParam->groupValueSize, &grpData, sizeof(grpData))) {
|
||||||
if (terrno == TSDB_CODE_DUP_KEY) {
|
if (terrno == TSDB_CODE_DUP_KEY) {
|
||||||
|
@ -162,6 +353,16 @@ static int32_t initGroupCacheGroupData(SGroupCacheOperatorInfo* pGCache, SGcOper
|
||||||
|
|
||||||
*ppGrp = taosHashAcquire(pGCache->pBlkHash, pParam->pGroupValue, pParam->groupValueSize);
|
*ppGrp = taosHashAcquire(pGCache->pBlkHash, pParam->pGroupValue, pParam->groupValueSize);
|
||||||
if (*ppGrp) {
|
if (*ppGrp) {
|
||||||
|
SGcNewGroupInfo newGroup;
|
||||||
|
newGroup.uid = *(int64_t*)pParam->pGroupValue;
|
||||||
|
newGroup.pParam = pOperator->pDownstreamParams[pParam->downstreamIdx];
|
||||||
|
taosWLockLatch(&pGCache->pDownstreams[pParam->downstreamIdx].lock);
|
||||||
|
if (NULL == taosArrayPush(pGCache->pDownstreams[pParam->downstreamIdx].pNewGrpList, &newGroup)) {
|
||||||
|
taosWUnLockLatch(&pGCache->pDownstreams[pParam->downstreamIdx].lock);
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
taosWUnLockLatch(&pGCache->pDownstreams[pParam->downstreamIdx].lock);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,14 +378,15 @@ static int32_t initGroupCacheSession(struct SOperatorInfo* pOperator, SGcOperato
|
||||||
if (pGroup) {
|
if (pGroup) {
|
||||||
ctx.pGroupData = pGroup;
|
ctx.pGroupData = pGroup;
|
||||||
} else {
|
} else {
|
||||||
code = initGroupCacheGroupData(pGCache, pParam, &ctx.pGroupData);
|
code = initGroupCacheGroupData(pOperator, pParam, &ctx.pGroupData);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taosThreadMutexUnlock(&pGCache->sessionMutex);
|
||||||
|
|
||||||
ctx.downstreamIdx = pParam->downstreamIdx;
|
ctx.pParam = pParam;
|
||||||
ctx.needCache = pParam->needCache;
|
|
||||||
|
|
||||||
int32_t code = tSimpleHashPut(pGCache->pSessionHash, &pParam->sessionId, sizeof(pParam->sessionId), &ctx, sizeof(ctx));
|
int32_t code = tSimpleHashPut(pGCache->pSessionHash, &pParam->sessionId, sizeof(pParam->sessionId), &ctx, sizeof(ctx));
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
@ -196,19 +398,20 @@ static int32_t initGroupCacheSession(struct SOperatorInfo* pOperator, SGcOperato
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t getBlkFromSessionCache(struct SOperatorInfo* pOperator, SGroupCacheOperatorInfo* pGCache, SGcOperatorParam* pParam, SSDataBlock** ppRes, SGcSessionCtx** ppSession) {
|
static int32_t getBlkFromSessionCache(struct SOperatorInfo* pOperator, SSDataBlock** ppRes) {
|
||||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
SGcSessionCtx* pCtx = tSimpleHashGet(pGCache->pSessionHash, &pParam->sessionId, sizeof(pParam->sessionId));
|
SGcOperatorParam* pGcParam = pOperator->pOperatorParam->value;
|
||||||
if (NULL == pCtx) {
|
SGcSessionCtx* pSession = tSimpleHashGet(pGCache->pSessionHash, &pGcParam->sessionId, sizeof(pGcParam->sessionId));
|
||||||
int32_t code = initGroupCacheSession(pOperator, pParam, ppSession);
|
if (NULL == pSession) {
|
||||||
|
int32_t code = initGroupCacheSession(pOperator, pGcParam, &pSession);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*ppSession = pCtx;
|
taosThreadMutexUnlock(&pGCache->sessionMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getBlkFromSessionCacheImpl(pOperator, pParam->sessionId, *ppSession, ppRes);
|
return getBlkFromSessionCacheImpl(pOperator, pGcParam->sessionId, pSession, ppRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE void destroyCurrentGroupCacheSession(SGroupCacheOperatorInfo* pGCache, SGcSessionCtx** ppCurrent, int64_t* pCurrentId) {
|
static FORCE_INLINE void destroyCurrentGroupCacheSession(SGroupCacheOperatorInfo* pGCache, SGcSessionCtx** ppCurrent, int64_t* pCurrentId) {
|
||||||
|
@ -223,48 +426,16 @@ static FORCE_INLINE void destroyCurrentGroupCacheSession(SGroupCacheOperatorInfo
|
||||||
*pCurrentId = 0;
|
*pCurrentId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setCurrentGroupCacheDone(struct SOperatorInfo* pOperator) {
|
SSDataBlock* getBlkFromGroupCache(struct SOperatorInfo* pOperator) {
|
||||||
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
|
||||||
//destroyCurrentGroupCacheSession(pGCache, &pGCache->pCurrent, &pGCache->pCurrentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addBlkToGroupCache(struct SOperatorInfo* pOperator, SSDataBlock* pBlock, SSDataBlock** ppRes) {
|
|
||||||
*ppRes = pBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSDataBlock* getFromGroupCache(struct SOperatorInfo* pOperator) {
|
|
||||||
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
|
||||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
SGcOperatorParam* pParam = (SGcOperatorParam*)pOperator->pOperatorParam->value;
|
|
||||||
SGcSessionCtx* pSession = NULL;
|
|
||||||
SSDataBlock* pRes = NULL;
|
SSDataBlock* pRes = NULL;
|
||||||
int32_t code = getBlkFromSessionCache(pOperator, pGCache, pParam, &pRes, &pSession);
|
|
||||||
|
int32_t code = getBlkFromSessionCache(pOperator, &pRes);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
pTaskInfo->code = code;
|
pTaskInfo->code = code;
|
||||||
T_LONG_JMP(pTaskInfo->env, pTaskInfo->code);
|
T_LONG_JMP(pTaskInfo->env, pTaskInfo->code);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pRes) {
|
|
||||||
return pRes;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
SSDataBlock* pBlock = getNextBlockFromDownstreamOnce(pOperator, pSession->downstreamIdx);
|
|
||||||
if (NULL == pBlock) {
|
|
||||||
setCurrentGroupCacheDone(pOperator);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pGCache->execInfo.pDownstreamBlkNum[pSession->downstreamIdx]++;
|
|
||||||
|
|
||||||
if (pSession->needCache) {
|
|
||||||
addBlkToGroupCache(pOperator, pBlock, &pRes);
|
|
||||||
} else {
|
|
||||||
pRes = pBlock;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pRes;
|
return pRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,6 +449,39 @@ static int32_t initGroupCacheExecInfo(SOperatorInfo* pOperator) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t initGroupCacheDownstreamCtx(SOperatorInfo* pOperator) {
|
||||||
|
SGroupCacheOperatorInfo* pInfo = pOperator->info;
|
||||||
|
pInfo->pDownstreams = taosMemoryMalloc(pOperator->numOfDownstream * sizeof(*pInfo->pDownstreams));
|
||||||
|
if (NULL == pInfo->pDownstreams) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
|
||||||
|
pInfo->pDownstreams[i].fetchSessionId = -1;
|
||||||
|
pInfo->pDownstreams[i].pGrpUidList = taosArrayInit(10, sizeof(int64_t));
|
||||||
|
if (NULL == pInfo->pDownstreams[i].pGrpUidList) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSDataBlock* groupCacheGetNext(struct SOperatorInfo* pOperator, SOperatorParam* pParam) {
|
||||||
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
|
|
||||||
|
taosThreadMutexLock(&pGCache->sessionMutex);
|
||||||
|
|
||||||
|
int32_t code = setOperatorParams(pOperator, pParam);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
pOperator->pTaskInfo->code = code;
|
||||||
|
T_LONG_JMP(pOperator->pTaskInfo->env, pOperator->pTaskInfo->code);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getBlkFromGroupCache(pOperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SOperatorInfo* createGroupCacheOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream,
|
SOperatorInfo* createGroupCacheOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream,
|
||||||
SGroupCachePhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo) {
|
SGroupCachePhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo) {
|
||||||
SGroupCacheOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SGroupCacheOperatorInfo));
|
SGroupCacheOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SGroupCacheOperatorInfo));
|
||||||
|
@ -293,9 +497,17 @@ 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);
|
||||||
|
|
||||||
code = initGroupColsInfo(&pInfo->groupColsInfo, pPhyciNode->grpColsMayBeNull, pPhyciNode->pGroupCols);
|
pInfo->grpByUid = pPhyciNode->grpByUid;
|
||||||
if (code) {
|
if (!pInfo->grpByUid) {
|
||||||
goto _error;
|
qError("only group cache by uid is supported now");
|
||||||
|
return TSDB_CODE_INVALID_PARA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pPhyciNode->pGroupCols) {
|
||||||
|
code = initGroupColsInfo(&pInfo->groupColsInfo, pPhyciNode->grpColsMayBeNull, pPhyciNode->pGroupCols);
|
||||||
|
if (code) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
code = initGroupCacheBufPages(pInfo);
|
code = initGroupCacheBufPages(pInfo);
|
||||||
|
@ -320,12 +532,17 @@ SOperatorInfo* createGroupCacheOperatorInfo(SOperatorInfo** pDownstream, int32_t
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code = initGroupCacheDownstreamCtx(pOperator);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
code = initGroupCacheExecInfo(pOperator);
|
code = initGroupCacheExecInfo(pOperator);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, getFromGroupCache, NULL, destroyGroupCacheOperator, optrDefaultBufFn, NULL, optrDefaultGetNextExtFn, NULL);
|
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, getBlkFromGroupCache, NULL, destroyGroupCacheOperator, optrDefaultBufFn, NULL, groupCacheGetNext, NULL);
|
||||||
|
|
||||||
return pOperator;
|
return pOperator;
|
||||||
|
|
||||||
|
|
|
@ -406,6 +406,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_JSON_IN_GROUP_ERROR, "Json not support in g
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_JOB_NOT_EXIST, "Job not exist")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_JOB_NOT_EXIST, "Job not exist")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_QWORKER_QUIT, "Vnode/Qnode is quitting")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_QWORKER_QUIT, "Vnode/Qnode is quitting")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR, "Geometry not support in this operator")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR, "Geometry not support in this operator")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR, "Executor internal error")
|
||||||
|
|
||||||
// grant
|
// grant
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, "License expired")
|
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, "License expired")
|
||||||
|
|
Loading…
Reference in New Issue