in xsec/utils/XSECXPathNodeList.cpp [300:400]
void XSECXPathNodeList::addNode(const DOMNode *n) {
btn * v;
if (m_num == 0) {
XSECnew(mp_tree, btn);
mp_tree->l = mp_tree->r = NULL;
mp_tree->v = n;
mp_tree->p = NULL;
mp_tree->h = 1;
m_num = 1;
return;
}
// Find the node
btn * t = mp_tree;
btn * last = NULL;
while (t != NULL && t->v != n) {
last = t;
if (n > t->v)
t = t->r;
else
t = t->l;
}
if (t != NULL)
// Node already exists in tree!
return;
// Work out the insertion.
XSECnew(v, btn);
v->v = n;
v->r = v->l = NULL;
v->h = 1;
v->p = last;
// Determine on which leg to place the new value
if (n > last->v)
last->r = v;
else
last->l = v;
// Recalculate heights
t = last;
long newh;
while (t != NULL) {
newh = calc_height(t);
if (newh > t->h) {
t->h = newh;
t = t->p;
}
else
// If the height is the same here, then nothing will have changed above
t = NULL;
}
// Rebalance!
t = last;
while (t != NULL) {
long bal = balance_count(t);
long balrc = balance_count(t->r);
long ballc = balance_count(t->l);
// Case 1 - Balance is OK
if (bal <= 1 && bal >= -1) {
// Do nothing!
}
// Case 2a - Balance is -2 and LC = -1
else if (bal == -2 && ballc == -1) {
// Rotate current node right
rotate_right(t);
}
// Or balance is +2 and RC = +1
else if (bal == 2 && balrc == 1) {
// Rotate current node left
rotate_left(t);
}
// Case 2b = Balance is -2 and LC = +1
else if (bal == -2 && ballc == 1) {
// Double Right rotation
rotate_left(t->l);
rotate_right(t);
}
else {
rotate_right(t->r);
rotate_left(t);
}
t = t->p;
}
}