diff --git a/source/dnode/vnode/src/tsdb/tsdbMerge.c b/source/dnode/vnode/src/tsdb/tsdbMerge.c index 42e9c9bc57..1c058fd8f1 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMerge.c +++ b/source/dnode/vnode/src/tsdb/tsdbMerge.c @@ -30,7 +30,8 @@ typedef struct { } SLDataIter; typedef struct { - SRBTree tMerge; + SRBTreeNode *pNode; + SRBTree rbt; } SDataMerger; static int32_t tRowInfoCmprFn(const void *p1, const void *p2) { @@ -52,13 +53,59 @@ static int32_t tRowInfoCmprFn(const void *p1, const void *p2) { return tsdbRowCmprFn(&pInfo1->row, &pInfo2->row); } -static SRowInfo *tDataMergeNext(SDataMerger *pMerger) { - SRowInfo *pRowInfo = NULL; +static int32_t tDataMergeNext(SDataMerger *pMerger, SRowInfo **ppInfo) { + int32_t code = 0; - SRBTreeNode *pNode = pMerger->tMerge.minNode; - if (pNode == NULL) return NULL; + if (pMerger->pNode) { + // next current iter + SLDataIter *pIter = (SLDataIter *)pMerger->pNode->payload; - return pRowInfo; + pIter->iRow++; + if (pIter->iRow < pIter->bData.nRow) { + pIter->rowInfo.uid = pIter->bData.uid ? pIter->bData.uid : pIter->bData.aUid[pIter->iRow]; + pIter->rowInfo.row = tsdbRowFromBlockData(&pIter->bData, pIter->iRow); + } else { + pIter->iBlockL++; + if (pIter->iBlockL < taosArrayGetSize(pIter->aBlockL)) { + code = tsdbReadLastBlock(NULL, (SBlockL *)taosArrayGet(pIter->aBlockL, pIter->iBlockL), &pIter->bData); + if (code) goto _exit; + + pIter->iRow = 0; + pIter->rowInfo.suid = pIter->bData.suid; + pIter->rowInfo.uid = pIter->bData.uid ? pIter->bData.uid : pIter->bData.aUid[0]; + pIter->rowInfo.row = tsdbRowFromBlockData(&pIter->bData, 0); + } else { + pMerger->pNode = NULL; + } + } + + if (pMerger->pNode && pMerger->rbt.minNode) { + int32_t c = tRowInfoCmprFn(pMerger->pNode->payload, pMerger->rbt.minNode->payload); + if (c > 0) { + pMerger->pNode = tRBTreePut(&pMerger->rbt, pMerger->pNode); + ASSERT(pMerger->pNode); + pMerger->pNode = NULL; + } else { + ASSERT(c); + } + } + } + + if (pMerger->pNode == NULL) { + pMerger->pNode = pMerger->rbt.minNode; + if (pMerger->pNode) { + tRBTreeDrop(&pMerger->rbt, pMerger->pNode); + } + } + + if (pMerger->pNode) { + *ppInfo = &((SLDataIter *)pMerger->pNode->payload)[0].rowInfo; + } else { + *ppInfo = NULL; + } + +_exit: + return code; } // ================================================================================ diff --git a/source/util/src/trbtree.c b/source/util/src/trbtree.c index 4b0f286ef3..ba1469dce7 100644 --- a/source/util/src/trbtree.c +++ b/source/util/src/trbtree.c @@ -210,6 +210,36 @@ void tRBTreeDrop(SRBTree *pTree, SRBTreeNode *pNode) { } // drop impl + if (pNode->left == NULL) { + // transplant right + if (pNode->parent == NULL) { + pTree->rootNode = pNode->right; + } else if (pNode == pNode->parent->left) { + pNode->parent->left = pNode->right; + } else { + pNode->parent->right = pNode->right; + } + + if (pNode->right) { + pNode->right->parent = pNode->parent; + } + } else if (pNode->right == NULL) { + // transplant left + if (pNode->parent == NULL) { + pTree->rootNode = pNode->left; + } else if (pNode == pNode->parent->left) { + pNode->parent->left = pNode->left; + } else { + pNode->parent->right = pNode->left; + } + + if (pNode->left) { + pNode->left->parent = pNode->parent; + } + } else { + SRBTreeNode *y = tRBTreeSuccessor(pNode); + pNode->color = RBTREE_NODE_COLOR(y); + } // fix if (pNode->color == BLACK) {