more code
This commit is contained in:
parent
2876f597f0
commit
34abb83796
|
@ -29,11 +29,12 @@ typedef struct SRBTreeIter SRBTreeIter;
|
||||||
typedef int32_t (*tRBTreeCmprFn)(const void *, const void *);
|
typedef int32_t (*tRBTreeCmprFn)(const void *, const void *);
|
||||||
|
|
||||||
// SRBTree =============================================
|
// SRBTree =============================================
|
||||||
#define tRBTreeCreate(compare) \
|
#define tRBTreeMin(T) ((T)->min == ((T)->NIL) ? NULL : (T)->min)
|
||||||
(SRBTree) { .cmprFn = (compare), .root = NULL, .min = NULL, .max = NULL }
|
#define tRBTreeMax(T) ((T)->max == ((T)->NIL) ? NULL : (T)->max)
|
||||||
|
|
||||||
SRBTreeNode *tRBTreePut(SRBTree *pTree, SRBTreeNode *pNew);
|
void tRBTreeCreate(SRBTree *pTree, tRBTreeCmprFn cmprFn);
|
||||||
void tRBTreeDrop(SRBTree *pTree, SRBTreeNode *pNode);
|
SRBTreeNode *tRBTreePut(SRBTree *pTree, SRBTreeNode *z);
|
||||||
|
void tRBTreeDrop(SRBTree *pTree, SRBTreeNode *z);
|
||||||
SRBTreeNode *tRBTreeDropByKey(SRBTree *pTree, void *pKey);
|
SRBTreeNode *tRBTreeDropByKey(SRBTree *pTree, void *pKey);
|
||||||
SRBTreeNode *tRBTreeGet(SRBTree *pTree, void *pKey);
|
SRBTreeNode *tRBTreeGet(SRBTree *pTree, void *pKey);
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ struct SRBTreeNode {
|
||||||
SRBTreeNode *parent;
|
SRBTreeNode *parent;
|
||||||
SRBTreeNode *left;
|
SRBTreeNode *left;
|
||||||
SRBTreeNode *right;
|
SRBTreeNode *right;
|
||||||
uint8_t payload[];
|
uint8_t payload[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SRBTree {
|
struct SRBTree {
|
||||||
|
@ -58,6 +59,8 @@ struct SRBTree {
|
||||||
SRBTreeNode *root;
|
SRBTreeNode *root;
|
||||||
SRBTreeNode *min;
|
SRBTreeNode *min;
|
||||||
SRBTreeNode *max;
|
SRBTreeNode *max;
|
||||||
|
SRBTreeNode *NIL;
|
||||||
|
SRBTreeNode NILNODE;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SRBTreeIter {
|
struct SRBTreeIter {
|
||||||
|
|
|
@ -55,7 +55,7 @@ static int32_t tRowInfoCmprFn(const void *p1, const void *p2) {
|
||||||
|
|
||||||
static void tDataMergerInit(SDataMerger *pMerger, SArray *aNodeP) {
|
static void tDataMergerInit(SDataMerger *pMerger, SArray *aNodeP) {
|
||||||
pMerger->pNode = NULL;
|
pMerger->pNode = NULL;
|
||||||
pMerger->rbt = tRBTreeCreate(tRowInfoCmprFn);
|
tRBTreeCreate(&pMerger->rbt, tRowInfoCmprFn);
|
||||||
for (int32_t iNode = 0; iNode < taosArrayGetSize(aNodeP); iNode++) {
|
for (int32_t iNode = 0; iNode < taosArrayGetSize(aNodeP); iNode++) {
|
||||||
SRBTreeNode *pNode = (SRBTreeNode *)taosArrayGetP(aNodeP, iNode);
|
SRBTreeNode *pNode = (SRBTreeNode *)taosArrayGetP(aNodeP, iNode);
|
||||||
|
|
||||||
|
@ -90,8 +90,9 @@ static int32_t tDataMergeNext(SDataMerger *pMerger, SRowInfo **ppInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMerger->pNode && pMerger->rbt.min) {
|
SRBTreeNode *pMinNode = tRBTreeMin(&pMerger->rbt);
|
||||||
int32_t c = tRowInfoCmprFn(pMerger->pNode->payload, pMerger->rbt.min->payload);
|
if (pMerger->pNode && pMinNode) {
|
||||||
|
int32_t c = tRowInfoCmprFn(pMerger->pNode->payload, pMinNode->payload);
|
||||||
if (c > 0) {
|
if (c > 0) {
|
||||||
pMerger->pNode = tRBTreePut(&pMerger->rbt, pMerger->pNode);
|
pMerger->pNode = tRBTreePut(&pMerger->rbt, pMerger->pNode);
|
||||||
ASSERT(pMerger->pNode);
|
ASSERT(pMerger->pNode);
|
||||||
|
@ -103,7 +104,7 @@ static int32_t tDataMergeNext(SDataMerger *pMerger, SRowInfo **ppInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMerger->pNode == NULL) {
|
if (pMerger->pNode == NULL) {
|
||||||
pMerger->pNode = pMerger->rbt.min;
|
pMerger->pNode = tRBTreeMin(&pMerger->rbt);
|
||||||
if (pMerger->pNode) {
|
if (pMerger->pNode) {
|
||||||
tRBTreeDrop(&pMerger->rbt, pMerger->pNode);
|
tRBTreeDrop(&pMerger->rbt, pMerger->pNode);
|
||||||
}
|
}
|
||||||
|
@ -155,7 +156,7 @@ static int32_t tsdbMergeFileDataStart(STsdbMerger *pMerger, SDFileSet *pSet) {
|
||||||
if (code) goto _err;
|
if (code) goto _err;
|
||||||
|
|
||||||
pMerger->dReader.merger.pNode = NULL;
|
pMerger->dReader.merger.pNode = NULL;
|
||||||
pMerger->dReader.merger.rbt = tRBTreeCreate(tRowInfoCmprFn);
|
tRBTreeCreate(&pMerger->dReader.merger.rbt, tRowInfoCmprFn);
|
||||||
for (int8_t iLast = 0; iLast < pSet->nLastF; iLast++) {
|
for (int8_t iLast = 0; iLast < pSet->nLastF; iLast++) {
|
||||||
SRBTreeNode *pNode = (SRBTreeNode *)taosMemoryCalloc(1, sizeof(*pNode) + sizeof(SLDataIter));
|
SRBTreeNode *pNode = (SRBTreeNode *)taosMemoryCalloc(1, sizeof(*pNode) + sizeof(SLDataIter));
|
||||||
if (pNode == NULL) {
|
if (pNode == NULL) {
|
||||||
|
|
|
@ -15,17 +15,14 @@
|
||||||
|
|
||||||
#include "trbtree.h"
|
#include "trbtree.h"
|
||||||
|
|
||||||
#define RBTREE_NODE_COLOR(N) ((N) ? (N)->color : BLACK)
|
|
||||||
|
|
||||||
// SRBTree ================================================
|
|
||||||
static void tRBTreeRotateLeft(SRBTree *pTree, SRBTreeNode *x) {
|
static void tRBTreeRotateLeft(SRBTree *pTree, SRBTreeNode *x) {
|
||||||
SRBTreeNode *y = x->right;
|
SRBTreeNode *y = x->right;
|
||||||
x->right = y->left;
|
x->right = y->left;
|
||||||
if (y->left) {
|
if (y->left != pTree->NIL) {
|
||||||
y->left->parent = x;
|
y->left->parent = x;
|
||||||
}
|
}
|
||||||
y->parent = x->parent;
|
y->parent = x->parent;
|
||||||
if (x->parent == NULL) {
|
if (x->parent == pTree->NIL) {
|
||||||
pTree->root = y;
|
pTree->root = y;
|
||||||
} else if (x == x->parent->left) {
|
} else if (x == x->parent->left) {
|
||||||
x->parent->left = y;
|
x->parent->left = y;
|
||||||
|
@ -39,269 +36,263 @@ static void tRBTreeRotateLeft(SRBTree *pTree, SRBTreeNode *x) {
|
||||||
static void tRBTreeRotateRight(SRBTree *pTree, SRBTreeNode *x) {
|
static void tRBTreeRotateRight(SRBTree *pTree, SRBTreeNode *x) {
|
||||||
SRBTreeNode *y = x->left;
|
SRBTreeNode *y = x->left;
|
||||||
x->left = y->right;
|
x->left = y->right;
|
||||||
if (y->right) {
|
if (y->right != pTree->NIL) {
|
||||||
y->right->parent = x;
|
y->right->parent = x;
|
||||||
}
|
}
|
||||||
y->parent = x->parent;
|
y->parent = x->parent;
|
||||||
if (x->parent == NULL) {
|
if (x->parent == pTree->NIL) {
|
||||||
pTree->root = y;
|
pTree->root = y;
|
||||||
} else if (x == x->parent->left) {
|
} else if (x == x->parent->right) {
|
||||||
x->parent->left = y;
|
|
||||||
} else {
|
|
||||||
x->parent->right = y;
|
x->parent->right = y;
|
||||||
|
} else {
|
||||||
|
x->parent->left = y;
|
||||||
}
|
}
|
||||||
y->right = x;
|
y->right = x;
|
||||||
x->parent = y;
|
x->parent = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRBTreeNode *tRBTreeSuccessor(SRBTreeNode *pNode) {
|
static void tRBTreePutFix(SRBTree *pTree, SRBTreeNode *z) {
|
||||||
if (pNode->right) {
|
while (z->parent->color == RED) {
|
||||||
|
if (z->parent == z->parent->parent->left) { // z.parent is the left child
|
||||||
|
|
||||||
|
SRBTreeNode *y = z->parent->parent->right; // uncle of z
|
||||||
|
|
||||||
|
if (y->color == RED) { // case 1
|
||||||
|
z->parent->color = BLACK;
|
||||||
|
y->color = BLACK;
|
||||||
|
z->parent->parent->color = RED;
|
||||||
|
z = z->parent->parent;
|
||||||
|
} else { // case2 or case3
|
||||||
|
if (z == z->parent->right) { // case2
|
||||||
|
z = z->parent; // marked z.parent as new z
|
||||||
|
tRBTreeRotateLeft(pTree, z);
|
||||||
|
}
|
||||||
|
// case3
|
||||||
|
z->parent->color = BLACK; // made parent black
|
||||||
|
z->parent->parent->color = RED; // made parent red
|
||||||
|
tRBTreeRotateRight(pTree, z->parent->parent);
|
||||||
|
}
|
||||||
|
} else { // z.parent is the right child
|
||||||
|
SRBTreeNode *y = z->parent->parent->left; // uncle of z
|
||||||
|
|
||||||
|
if (y->color == RED) {
|
||||||
|
z->parent->color = BLACK;
|
||||||
|
y->color = BLACK;
|
||||||
|
z->parent->parent->color = RED;
|
||||||
|
z = z->parent->parent;
|
||||||
|
} else {
|
||||||
|
if (z == z->parent->left) {
|
||||||
|
z = z->parent; // marked z.parent as new z
|
||||||
|
tRBTreeRotateRight(pTree, z);
|
||||||
|
}
|
||||||
|
z->parent->color = BLACK; // made parent black
|
||||||
|
z->parent->parent->color = RED; // made parent red
|
||||||
|
tRBTreeRotateLeft(pTree, z->parent->parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pTree->root->color = BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tRBTreeTransplant(SRBTree *pTree, SRBTreeNode *u, SRBTreeNode *v) {
|
||||||
|
if (u->parent == pTree->NIL)
|
||||||
|
pTree->root = v;
|
||||||
|
else if (u == u->parent->left)
|
||||||
|
u->parent->left = v;
|
||||||
|
else
|
||||||
|
u->parent->right = v;
|
||||||
|
v->parent = u->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tRBTreeDropFix(SRBTree *pTree, SRBTreeNode *x) {
|
||||||
|
while (x != pTree->root && x->color == BLACK) {
|
||||||
|
if (x == x->parent->left) {
|
||||||
|
SRBTreeNode *w = x->parent->right;
|
||||||
|
if (w->color == RED) {
|
||||||
|
w->color = BLACK;
|
||||||
|
x->parent->color = RED;
|
||||||
|
tRBTreeRotateLeft(pTree, x->parent);
|
||||||
|
w = x->parent->right;
|
||||||
|
}
|
||||||
|
if (w->left->color == BLACK && w->right->color == BLACK) {
|
||||||
|
w->color = RED;
|
||||||
|
x = x->parent;
|
||||||
|
} else {
|
||||||
|
if (w->right->color == BLACK) {
|
||||||
|
w->left->color = BLACK;
|
||||||
|
w->color = RED;
|
||||||
|
tRBTreeRotateRight(pTree, w);
|
||||||
|
w = x->parent->right;
|
||||||
|
}
|
||||||
|
w->color = x->parent->color;
|
||||||
|
x->parent->color = BLACK;
|
||||||
|
w->right->color = BLACK;
|
||||||
|
tRBTreeRotateLeft(pTree, x->parent);
|
||||||
|
x = pTree->root;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SRBTreeNode *w = x->parent->left;
|
||||||
|
if (w->color == RED) {
|
||||||
|
w->color = BLACK;
|
||||||
|
x->parent->color = RED;
|
||||||
|
tRBTreeRotateRight(pTree, x->parent);
|
||||||
|
w = x->parent->left;
|
||||||
|
}
|
||||||
|
if (w->right->color == BLACK && w->left->color == BLACK) {
|
||||||
|
w->color = RED;
|
||||||
|
x = x->parent;
|
||||||
|
} else {
|
||||||
|
if (w->left->color == BLACK) {
|
||||||
|
w->right->color = BLACK;
|
||||||
|
w->color = RED;
|
||||||
|
tRBTreeRotateLeft(pTree, w);
|
||||||
|
w = x->parent->left;
|
||||||
|
}
|
||||||
|
w->color = x->parent->color;
|
||||||
|
x->parent->color = BLACK;
|
||||||
|
w->left->color = BLACK;
|
||||||
|
tRBTreeRotateRight(pTree, x->parent);
|
||||||
|
x = pTree->root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x->color = BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRBTreeNode *tRBTreeSuccessor(SRBTree *pTree, SRBTreeNode *pNode) {
|
||||||
|
if (pNode->right != pTree->NIL) {
|
||||||
pNode = pNode->right;
|
pNode = pNode->right;
|
||||||
while (pNode->left) {
|
while (pNode->left != pTree->NIL) {
|
||||||
pNode = pNode->left;
|
pNode = pNode->left;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (pNode->parent) {
|
if (pNode->parent == pTree->NIL || pNode == pNode->parent->left) {
|
||||||
if (pNode == pNode->parent->left) {
|
|
||||||
pNode = pNode->parent;
|
pNode = pNode->parent;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
pNode = pNode->parent;
|
pNode = pNode->parent;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
pNode = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRBTreeNode *tRBTreePredecessor(SRBTreeNode *pNode) {
|
static SRBTreeNode *tRBTreePredecessor(SRBTree *pTree, SRBTreeNode *pNode) {
|
||||||
if (pNode->left) {
|
if (pNode->left != pTree->NIL) {
|
||||||
pNode = pNode->left;
|
pNode = pNode->left;
|
||||||
while (pNode->right) {
|
while (pNode->right != pTree->NIL) {
|
||||||
pNode = pNode->right;
|
pNode = pNode->right;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (pNode->parent) {
|
if (pNode->parent == pTree->NIL || pNode == pNode->parent->right) {
|
||||||
if (pNode == pNode->parent->right) {
|
|
||||||
pNode = pNode->parent;
|
pNode = pNode->parent;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
pNode = pNode->parent;
|
pNode = pNode->parent;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
pNode = NULL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return NULL;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRBTreeNode *tRBTreePut(SRBTree *pTree, SRBTreeNode *pNew) {
|
void tRBTreeCreate(SRBTree *pTree, tRBTreeCmprFn cmprFn) {
|
||||||
pNew->left = NULL;
|
pTree->cmprFn = cmprFn;
|
||||||
pNew->right = NULL;
|
pTree->NIL = &pTree->NILNODE;
|
||||||
pNew->color = RED;
|
pTree->NIL->color = BLACK;
|
||||||
|
pTree->NIL->parent = NULL;
|
||||||
|
pTree->NIL->left = NULL;
|
||||||
|
pTree->NIL->right = NULL;
|
||||||
|
pTree->root = pTree->NIL;
|
||||||
|
pTree->min = pTree->NIL;
|
||||||
|
pTree->max = pTree->NIL;
|
||||||
|
}
|
||||||
|
|
||||||
// insert
|
SRBTreeNode *tRBTreePut(SRBTree *pTree, SRBTreeNode *z) {
|
||||||
if (pTree->root == NULL) {
|
SRBTreeNode *y = pTree->NIL; // variable for the parent of the added node
|
||||||
pNew->parent = NULL;
|
SRBTreeNode *temp = pTree->root;
|
||||||
pTree->root = pNew;
|
|
||||||
} else {
|
|
||||||
SRBTreeNode *pNode = pTree->root;
|
|
||||||
while (true) {
|
|
||||||
ASSERT(pNode);
|
|
||||||
|
|
||||||
int32_t c = pTree->cmprFn(pNew->payload, pNode->payload);
|
while (temp != pTree->NIL) {
|
||||||
|
y = temp;
|
||||||
|
|
||||||
|
int32_t c = pTree->cmprFn(z->payload, temp->payload);
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
if (pNode->left) {
|
temp = temp->left;
|
||||||
pNode = pNode->left;
|
|
||||||
} else {
|
|
||||||
pNew->parent = pNode;
|
|
||||||
pNode->left = pNew;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (c > 0) {
|
} else if (c > 0) {
|
||||||
if (pNode->right) {
|
temp = temp->right;
|
||||||
pNode = pNode->right;
|
|
||||||
} else {
|
|
||||||
pNew->parent = pNode;
|
|
||||||
pNode->right = pNew;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
z->parent = y;
|
||||||
|
|
||||||
// fix
|
if (y == pTree->NIL) {
|
||||||
SRBTreeNode *pNode = pNew;
|
pTree->root = z;
|
||||||
while (pNode->parent && pNode->parent->color == RED) {
|
} else if (pTree->cmprFn(z->payload, y->payload) < 0) {
|
||||||
SRBTreeNode *p = pNode->parent;
|
y->left = z;
|
||||||
SRBTreeNode *g = p->parent;
|
|
||||||
|
|
||||||
if (p == g->left) {
|
|
||||||
SRBTreeNode *u = g->right;
|
|
||||||
|
|
||||||
if (RBTREE_NODE_COLOR(u) == RED) {
|
|
||||||
p->color = BLACK;
|
|
||||||
u->color = BLACK;
|
|
||||||
g->color = RED;
|
|
||||||
pNode = g;
|
|
||||||
} else {
|
} else {
|
||||||
if (pNode == p->right) {
|
y->right = z;
|
||||||
pNode = p;
|
|
||||||
tRBTreeRotateLeft(pTree, pNode);
|
|
||||||
}
|
}
|
||||||
pNode->parent->color = BLACK;
|
|
||||||
pNode->parent->parent->color = RED;
|
|
||||||
tRBTreeRotateRight(pTree, pNode->parent->parent);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SRBTreeNode *u = g->left;
|
|
||||||
|
|
||||||
if (RBTREE_NODE_COLOR(u) == RED) {
|
z->color = RED;
|
||||||
p->color = BLACK;
|
z->left = pTree->NIL;
|
||||||
u->color = BLACK;
|
z->right = pTree->NIL;
|
||||||
g->color = RED;
|
|
||||||
} else {
|
tRBTreePutFix(pTree, z);
|
||||||
if (pNode == p->left) {
|
|
||||||
pNode = p;
|
|
||||||
tRBTreeRotateRight(pTree, pNode);
|
|
||||||
}
|
|
||||||
pNode->parent->color = BLACK;
|
|
||||||
pNode->parent->parent->color = RED;
|
|
||||||
tRBTreeRotateLeft(pTree, pNode->parent->parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pTree->root->color = BLACK;
|
|
||||||
|
|
||||||
// update min/max node
|
// update min/max node
|
||||||
if (pTree->min == NULL || pTree->cmprFn(pTree->min->payload, pNew->payload) > 0) {
|
if (pTree->min == pTree->NIL || pTree->cmprFn(pTree->min->payload, z->payload) > 0) {
|
||||||
pTree->min = pNew;
|
pTree->min = z;
|
||||||
}
|
}
|
||||||
if (pTree->max == NULL || pTree->cmprFn(pTree->max->payload, pNew->payload) < 0) {
|
if (pTree->max == pTree->NIL || pTree->cmprFn(pTree->max->payload, z->payload) < 0) {
|
||||||
pTree->max = pNew;
|
pTree->max = z;
|
||||||
}
|
}
|
||||||
|
return z;
|
||||||
return pNew;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tRBTreeTransplant(SRBTree *pTree, SRBTreeNode *u, SRBTreeNode *v) {
|
void tRBTreeDrop(SRBTree *pTree, SRBTreeNode *z) {
|
||||||
if (u->parent == NULL) {
|
SRBTreeNode *y = z;
|
||||||
pTree->root = v;
|
SRBTreeNode *x;
|
||||||
} else if (u == u->parent->left) {
|
ECOLOR y_orignal_color = y->color;
|
||||||
u->parent->left = v;
|
|
||||||
} else {
|
|
||||||
u->parent->right = v;
|
|
||||||
}
|
|
||||||
if (v) {
|
|
||||||
v->parent = u->parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tRBTreeDropFixup(SRBTree *t, SRBTreeNode *x) {
|
|
||||||
while (x != t->root && x->color == BLACK) {
|
|
||||||
if (x == x->parent->left) {
|
|
||||||
SRBTreeNode *w = x->parent->right;
|
|
||||||
if (RBTREE_NODE_COLOR(w) == RED) {
|
|
||||||
w->color = BLACK;
|
|
||||||
x->parent->color = RED;
|
|
||||||
tRBTreeRotateLeft(t, x->parent);
|
|
||||||
w = x->parent->right;
|
|
||||||
}
|
|
||||||
if (RBTREE_NODE_COLOR(w->left) == BLACK && RBTREE_NODE_COLOR(w->right) == BLACK) {
|
|
||||||
w->color = RED;
|
|
||||||
x = x->parent;
|
|
||||||
} else {
|
|
||||||
if (RBTREE_NODE_COLOR(w->right) == BLACK) {
|
|
||||||
w->left->color = BLACK;
|
|
||||||
w->color = RED;
|
|
||||||
tRBTreeRotateRight(t, w);
|
|
||||||
w = x->parent->right;
|
|
||||||
}
|
|
||||||
w->color = x->parent->color;
|
|
||||||
x->parent->color = BLACK;
|
|
||||||
w->right->color = BLACK;
|
|
||||||
tRBTreeRotateLeft(t, x->parent);
|
|
||||||
x = t->root;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SRBTreeNode *w = x->parent->left;
|
|
||||||
if (RBTREE_NODE_COLOR(w) == RED) {
|
|
||||||
w->color = BLACK;
|
|
||||||
x->parent->color = RED;
|
|
||||||
tRBTreeRotateRight(t, x->parent);
|
|
||||||
w = x->parent->left;
|
|
||||||
}
|
|
||||||
if (RBTREE_NODE_COLOR(w->right) == BLACK && RBTREE_NODE_COLOR(w->left) == BLACK) {
|
|
||||||
w->color = RED;
|
|
||||||
x = x->parent;
|
|
||||||
} else {
|
|
||||||
if (RBTREE_NODE_COLOR(w->left) == BLACK) {
|
|
||||||
w->right->color = BLACK;
|
|
||||||
w->color = RED;
|
|
||||||
tRBTreeRotateLeft(t, w);
|
|
||||||
w = x->parent->left;
|
|
||||||
}
|
|
||||||
w->color = x->parent->color;
|
|
||||||
x->parent->color = BLACK;
|
|
||||||
w->left->color = BLACK;
|
|
||||||
tRBTreeRotateRight(t, x->parent);
|
|
||||||
x = t->root;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
x->color = BLACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tRBTreeDrop(SRBTree *t, SRBTreeNode *z) {
|
|
||||||
// update min/max node
|
// update min/max node
|
||||||
if (t->min == z) {
|
if (pTree->min == z) {
|
||||||
t->min = tRBTreeSuccessor(t->min);
|
pTree->min = tRBTreeSuccessor(pTree, pTree->min);
|
||||||
}
|
}
|
||||||
if (t->max == z) {
|
if (pTree->max == z) {
|
||||||
t->max = tRBTreePredecessor(t->max);
|
pTree->max = tRBTreePredecessor(pTree, pTree->max);
|
||||||
}
|
}
|
||||||
|
|
||||||
// drop impl
|
// drop impl
|
||||||
SRBTreeNode *y = z;
|
if (z->left == pTree->NIL) {
|
||||||
SRBTreeNode *x;
|
|
||||||
ECOLOR oColor = y->color;
|
|
||||||
|
|
||||||
if (z->left == NULL) {
|
|
||||||
x = z->right;
|
x = z->right;
|
||||||
tRBTreeTransplant(t, z, z->right);
|
tRBTreeTransplant(pTree, z, z->right);
|
||||||
} else if (z->right == NULL) {
|
} else if (z->right == pTree->NIL) {
|
||||||
x = z->left;
|
x = z->left;
|
||||||
tRBTreeTransplant(t, z, z->left);
|
tRBTreeTransplant(pTree, z, z->left);
|
||||||
} else {
|
} else {
|
||||||
y = tRBTreeSuccessor(z);
|
y = tRBTreeSuccessor(pTree, z);
|
||||||
oColor = y->color;
|
y_orignal_color = y->color;
|
||||||
x = y->right;
|
x = y->right;
|
||||||
if (y->parent == z) {
|
if (y->parent == z) {
|
||||||
x->parent = z;
|
x->parent = z;
|
||||||
} else {
|
} else {
|
||||||
tRBTreeTransplant(t, y, y->right);
|
tRBTreeTransplant(pTree, y, y->right);
|
||||||
y->right = z->right;
|
y->right = z->right;
|
||||||
y->right->parent = y;
|
y->right->parent = y;
|
||||||
}
|
}
|
||||||
tRBTreeTransplant(t, z, y);
|
tRBTreeTransplant(pTree, z, y);
|
||||||
y->left = z->left;
|
y->left = z->left;
|
||||||
y->left->parent = y;
|
y->left->parent = y;
|
||||||
y->color = z->color;
|
y->color = z->color;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix
|
// fix
|
||||||
if (oColor == BLACK) {
|
if (y_orignal_color == BLACK) {
|
||||||
tRBTreeDropFixup(t, x);
|
tRBTreeDropFix(pTree, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +309,7 @@ SRBTreeNode *tRBTreeDropByKey(SRBTree *pTree, void *pKey) {
|
||||||
SRBTreeNode *tRBTreeGet(SRBTree *pTree, void *pKey) {
|
SRBTreeNode *tRBTreeGet(SRBTree *pTree, void *pKey) {
|
||||||
SRBTreeNode *pNode = pTree->root;
|
SRBTreeNode *pNode = pTree->root;
|
||||||
|
|
||||||
while (pNode) {
|
while (pNode != pTree->NIL) {
|
||||||
int32_t c = pTree->cmprFn(pKey, pNode->payload);
|
int32_t c = pTree->cmprFn(pKey, pNode->payload);
|
||||||
|
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
|
@ -330,23 +321,23 @@ SRBTreeNode *tRBTreeGet(SRBTree *pTree, void *pKey) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pNode;
|
return (pNode == pTree->NIL) ? NULL : pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SRBTreeIter ================================================
|
// SRBTreeIter ================================================
|
||||||
SRBTreeNode *tRBTreeIterNext(SRBTreeIter *pIter) {
|
SRBTreeNode *tRBTreeIterNext(SRBTreeIter *pIter) {
|
||||||
SRBTreeNode *pNode = pIter->pNode;
|
SRBTreeNode *pNode = pIter->pNode;
|
||||||
|
|
||||||
if (pIter->pNode) {
|
if (pIter->pNode != pIter->pTree->NIL) {
|
||||||
if (pIter->asc) {
|
if (pIter->asc) {
|
||||||
// ascend
|
// ascend
|
||||||
pIter->pNode = tRBTreeSuccessor(pIter->pNode);
|
pIter->pNode = tRBTreeSuccessor(pIter->pTree, pIter->pNode);
|
||||||
} else {
|
} else {
|
||||||
// descend
|
// descend
|
||||||
pIter->pNode = tRBTreePredecessor(pIter->pNode);
|
pIter->pNode = tRBTreePredecessor(pIter->pTree, pIter->pNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_exit:
|
_exit:
|
||||||
return pNode;
|
return (pNode == pIter->pTree->NIL) ? NULL : pNode;
|
||||||
}
|
}
|
|
@ -15,7 +15,8 @@ static int32_t tCmprInteger(const void *p1, const void *p2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(trbtreeTest, rbtree_test1) {
|
TEST(trbtreeTest, rbtree_test1) {
|
||||||
SRBTree rt = tRBTreeCreate(tCmprInteger);
|
SRBTree rt;
|
||||||
|
tRBTreeCreate(&rt, tCmprInteger);
|
||||||
int a[] = {1, 3, 4, 2, 7, 5, 8};
|
int a[] = {1, 3, 4, 2, 7, 5, 8};
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
|
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
|
||||||
|
|
Loading…
Reference in New Issue