Bool SplayFindLast(Tree *nodeReturn, SplayTree splay, SplayTestNodeFunction testNode, SplayTestTreeFunction testTree, void *closureP, Size closureS) { SplayFindClosureStruct closureStruct; Bool found; AVER(nodeReturn != NULL); AVERT(SplayTree, splay); AVER(FUNCHECK(testNode)); AVER(FUNCHECK(testTree)); if (SplayTreeIsEmpty(splay) || !testTree(splay, SplayTreeRoot(splay), closureP, closureS)) return FALSE; /* no suitable nodes in tree */ closureStruct.p = closureP; closureStruct.s = closureS; closureStruct.testNode = testNode; closureStruct.testTree = testTree; closureStruct.splay = splay; found = SplaySplay(splay, &closureStruct, SplayFindLastCompare) == CompareEQUAL && closureStruct.found; while (!found) { Tree oldRoot, newRoot; oldRoot = SplayTreeRoot(splay); newRoot = TreeLeft(oldRoot); if (newRoot == TreeEMPTY || !(*testTree)(splay, newRoot, closureP, closureS)) return FALSE; /* no suitable nodes in the rest of the tree */ /* Temporarily chop off the right half-tree, inclusive of root, so that the search excludes any nodes we've seen already. */ SplayTreeSetRoot(splay, newRoot); TreeSetLeft(oldRoot, TreeEMPTY); found = SplaySplay(splay, &closureStruct, SplayFindLastCompare) == CompareEQUAL && closureStruct.found; /* Restore the right tree, then rotate right so that the node we just splayed is at the root. Update both. */ newRoot = SplayTreeRoot(splay); TreeSetLeft(oldRoot, newRoot); SplayTreeSetRoot(splay, oldRoot); TreeRotateRight(&splay->root); splay->updateNode(splay, oldRoot); splay->updateNode(splay, newRoot); } *nodeReturn = SplayTreeRoot(splay); return TRUE; }
static Tree SplayZigZig(Tree middle, Tree *rightFirstIO, Tree rightNext) { AVERT_CRITICAL(Tree, middle); AVER_CRITICAL(rightFirstIO != NULL); AVERT_CRITICAL(Tree, *rightFirstIO); TreeSetLeft(*rightFirstIO, TreeRight(middle)); TreeSetRight(middle, *rightFirstIO); TreeSetLeft(rightNext, middle); *rightFirstIO = middle; return TreeLeft(middle); }
static Tree SplayZigZigRev(Tree middle, Tree *rightFirstIO) { Tree child; AVERT_CRITICAL(Tree, middle); AVER_CRITICAL(rightFirstIO != NULL); AVERT_CRITICAL(Tree, *rightFirstIO); child = TreeLeft(middle); TreeSetLeft(middle, TreeLeft(*rightFirstIO)); TreeSetLeft(*rightFirstIO, TreeRight(middle)); TreeSetRight(middle, *rightFirstIO); *rightFirstIO = middle; return child; }
static Tree SplayTreeSuccessor(SplayTree splay) { Tree oldRoot, newRoot; AVERT(SplayTree, splay); AVER(!SplayTreeIsEmpty(splay)); oldRoot = SplayTreeRoot(splay); if (!TreeHasRight(oldRoot)) return TreeEMPTY; /* No successor */ /* temporarily chop off the left half-tree, inclusive of root */ SplayTreeSetRoot(splay, TreeRight(oldRoot)); TreeSetRight(oldRoot, TreeEMPTY); (void)SplaySplay(splay, NULL, compareLess); newRoot = SplayTreeRoot(splay); AVER(newRoot != TreeEMPTY); AVER(TreeLeft(newRoot) == TreeEMPTY); TreeSetLeft(newRoot, oldRoot); splay->updateNode(splay, oldRoot); splay->updateNode(splay, newRoot); return newRoot; }
static Tree stepUpRight(Tree node, Tree *parentIO) { Tree parent = *parentIO; Tree grandparent = TreeLeft(parent); TreeSetLeft(parent, node); *parentIO = grandparent; return parent; }
static Tree stepDownLeft(Tree node, Tree *parentIO) { Tree parent = *parentIO; Tree child = TreeLeft(node); TreeSetLeft(node, parent); *parentIO = node; return child; }
static void SplayAssembleDown(SplayTree splay, SplayState state) { AVERT(SplayTree, splay); AVER(state->middle != TreeEMPTY); AVER(!SplayHasUpdate(splay)); if (state->left != TreeEMPTY) { AVER_CRITICAL(state->leftLast != TreeEMPTY); TreeSetRight(state->leftLast, TreeLeft(state->middle)); TreeSetLeft(state->middle, state->left); } if (state->right != TreeEMPTY) { AVER_CRITICAL(state->rightFirst != TreeEMPTY); TreeSetLeft(state->rightFirst, TreeRight(state->middle)); TreeSetRight(state->middle, state->right); } }
Bool SplayTreeInsert(SplayTree splay, Tree node) { Tree neighbour; AVERT(SplayTree, splay); AVERT(Tree, node); AVER(TreeLeft(node) == TreeEMPTY); AVER(TreeRight(node) == TreeEMPTY); if (SplayTreeIsEmpty(splay)) { SplayTreeSetRoot(splay, node); return TRUE; } switch (SplaySplay(splay, splay->nodeKey(node), splay->compare)) { default: NOTREACHED; /* fall through */ case CompareEQUAL: /* duplicate node */ return FALSE; case CompareGREATER: /* left neighbour is at root */ neighbour = SplayTreeRoot(splay); SplayTreeSetRoot(splay, node); TreeSetRight(node, TreeRight(neighbour)); TreeSetLeft(node, neighbour); TreeSetRight(neighbour, TreeEMPTY); break; case CompareLESS: /* right neighbour is at root */ neighbour = SplayTreeRoot(splay); SplayTreeSetRoot(splay, node); TreeSetLeft(node, TreeLeft(neighbour)); TreeSetRight(node, neighbour); TreeSetLeft(neighbour, TreeEMPTY); break; } splay->updateNode(splay, neighbour); splay->updateNode(splay, node); return TRUE; }
static Tree SplayZagZag(Tree middle, Tree *leftLastIO, Tree leftPrev) { AVERT_CRITICAL(Tree, middle); AVER_CRITICAL(leftLastIO != NULL); AVERT_CRITICAL(Tree, *leftLastIO); TreeSetRight(*leftLastIO, TreeLeft(middle)); TreeSetLeft(middle, *leftLastIO); TreeSetRight(leftPrev, middle); *leftLastIO = middle; return TreeRight(middle); }
static Tree SplayZagZagRev(Tree middle, Tree *leftLastIO) { Tree child; AVERT_CRITICAL(Tree, middle); AVER_CRITICAL(leftLastIO != NULL); AVERT_CRITICAL(Tree, *leftLastIO); child = TreeRight(middle); TreeSetRight(middle, TreeRight(*leftLastIO)); TreeSetRight(*leftLastIO, TreeLeft(middle)); TreeSetLeft(middle, *leftLastIO); *leftLastIO = middle; return child; }
static Tree SplayUpdateLeftSpine(SplayTree splay, Tree node, Tree child) { AVERT_CRITICAL(SplayTree, splay); AVERT_CRITICAL(Tree, node); AVERT_CRITICAL(Tree, child); while(node != TreeEMPTY) { Tree parent = TreeLeft(node); TreeSetLeft(node, child); /* un-reverse pointer */ splay->updateNode(splay, node); child = node; node = parent; } return child; }
void TreeRotateRight(Tree *treeIO) { Tree tree, left; AVER(treeIO != NULL); tree = *treeIO; AVERT(Tree, tree); left = TreeLeft(tree); AVERT(Tree, left); TreeSetLeft(*treeIO, TreeRight(left)); TreeSetRight(left, *treeIO); *treeIO = left; }
void TreeRotateLeft(Tree *treeIO) { Tree tree, right; AVER(treeIO != NULL); tree = *treeIO; AVERT(Tree, tree); right = TreeRight(tree); AVERT(Tree, right); TreeSetRight(tree, TreeLeft(right)); TreeSetLeft(right, tree); *treeIO = right; }
static void SplayAssembleRev(SplayTree splay, SplayState state) { Tree left, right; AVERT(SplayTree, splay); AVER(state->middle != TreeEMPTY); left = TreeLeft(state->middle); left = SplayUpdateRightSpine(splay, state->leftLast, left); TreeSetLeft(state->middle, left); right = TreeRight(state->middle); right = SplayUpdateLeftSpine(splay, state->rightFirst, right); TreeSetRight(state->middle, right); splay->updateNode(splay, state->middle); }
Tree TreeReverseLeftSpine(Tree tree) { Tree node, parent; AVERT(Tree, tree); parent = TreeEMPTY; node = tree; while (node != TreeEMPTY) { Tree child = TreeLeft(node); TreeSetLeft(node, parent); parent = node; node = child; } return parent; }