1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-30 04:10:54 -08:00

Simplifying splay tree update prototype and removing special null case.

Copied from Perforce
 Change: 184427
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2014-02-20 17:43:26 +00:00
parent 2e5ca2df04
commit a6d87c91a8
5 changed files with 52 additions and 101 deletions

View file

@ -166,31 +166,26 @@ static Bool cbsTestTree(SplayTree tree, Tree node,
/* cbsUpdateNode -- update size info after restructuring */
static void cbsUpdateNode(SplayTree tree, Tree node,
Tree leftChild, Tree rightChild)
static void cbsUpdateNode(SplayTree tree, Tree node)
{
Size maxSize;
CBSBlock block;
AVERT(SplayTree, tree);
AVERT(Tree, node);
if (leftChild != NULL)
AVERT(Tree, leftChild);
if (rightChild != NULL)
AVERT(Tree, rightChild);
AVER(cbsOfTree(tree)->fastFind);
block = cbsBlockOfNode(node);
maxSize = CBSBlockSize(block);
if (leftChild != NULL) {
Size size = cbsBlockOfNode(leftChild)->maxSize;
if (TreeHasLeft(node)) {
Size size = cbsBlockOfNode(TreeLeft(node))->maxSize;
if (size > maxSize)
maxSize = size;
}
if (rightChild != NULL) {
Size size = cbsBlockOfNode(rightChild)->maxSize;
if (TreeHasRight(node)) {
Size size = cbsBlockOfNode(TreeRight(node))->maxSize;
if (size > maxSize)
maxSize = size;
}
@ -219,7 +214,7 @@ Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment,
extendBy = arg.val.size;
SplayTreeInit(treeOfCBS(cbs), &cbsCompare,
fastFind ? &cbsUpdateNode : NULL);
fastFind ? cbsUpdateNode : SplayTrivUpdate);
MPS_ARGS_BEGIN(pcArgs) {
MPS_ARGS_ADD(pcArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSBlockStruct));
MPS_ARGS_ADD(pcArgs, MPS_KEY_EXTEND_BY, extendBy);
@ -345,7 +340,7 @@ static Res cbsBlockAlloc(CBSBlock *blockReturn, CBS cbs, Range range)
goto failPoolAlloc;
block = (CBSBlock)p;
SplayNodeInit(nodeOfCBSBlock(block));
TreeInit(nodeOfCBSBlock(block));
block->base = RangeBase(range);
block->limit = RangeLimit(range);
block->maxSize = CBSBlockSize(block);

View file

@ -195,7 +195,7 @@ static Res DebugPoolInit(Pool pool, ArgList args)
if (res != ResOK)
goto tagFail;
debug->missingTags = 0;
SplayTreeInit(&debug->index, TagComp, NULL);
SplayTreeInit(&debug->index, TagComp, SplayTrivUpdate);
}
debug->sig = PoolDebugMixinSig;
@ -475,7 +475,7 @@ static void tagFree(PoolDebugMixin debug, Pool pool, Addr old, Size size)
AVER(tag->size == size);
res = SplayTreeDelete(&debug->index, node, (void *)&old);
AVER(res == ResOK);
SplayNodeFinish(node);
TreeFinish(node);
PoolFree(debug->tagPool, (Addr)tag, debug->tagSize);
}

View file

@ -44,7 +44,7 @@ void SplayTreeInit(SplayTree tree, SplayCompareMethod compare,
{
AVER(tree != NULL);
AVER(FUNCHECK(compare));
AVER(updateNode == NULL || FUNCHECK(updateNode));
AVER(FUNCHECK(updateNode));
tree->compare = compare;
tree->updateNode = updateNode;
@ -54,28 +54,6 @@ void SplayTreeInit(SplayTree tree, SplayCompareMethod compare,
}
void SplayNodeInit(Tree node)
{
AVER(node != NULL);
/* We don't try to finish the attached nodes. See .note.stack. */
TreeSetLeft(node, NULL);
TreeSetRight(node, NULL);
AVERT(Tree, node);
}
void SplayNodeFinish(Tree node)
{
AVERT(Tree, node);
/* we don't try to do a recursive finish. See .note.stack. */
TreeSetLeft(node, NULL);
TreeSetRight(node, NULL);
}
void SplayTreeFinish(SplayTree tree)
{
AVERT(SplayTree, tree);
@ -84,15 +62,10 @@ void SplayTreeFinish(SplayTree tree)
}
static void SplayNodeUpdate(SplayTree tree, Tree node)
void SplayTrivUpdate(SplayTree tree, Tree node)
{
AVERT(SplayTree, tree);
AVERT(Tree, node);
AVER(tree->updateNode != NULL);
(*tree->updateNode)(tree, node, TreeLeft(node),
TreeRight(node));
return;
}
@ -172,14 +145,10 @@ static void SplayRotateLeft(Tree *nodeIO, SplayTree tree) {
TreeSetLeft(nodeRight, *nodeIO);
*nodeIO = nodeRight;
if (tree->updateNode != NULL) {
SplayNodeUpdate(tree, TreeLeft(nodeRight));
/* Don't need to update new root because we know that we will */
/* do either a link or an assemble next, and that will sort it */
/* out. */
}
return;
tree->updateNode(tree, TreeLeft(nodeRight));
/* Don't need to update new root because we know that we will */
/* do either a link or an assemble next, and that will sort it */
/* out. */
}
@ -204,14 +173,10 @@ static void SplayRotateRight(Tree *nodeIO, SplayTree tree) {
TreeSetRight(nodeLeft, *nodeIO);
*nodeIO = nodeLeft;
if (tree->updateNode != NULL) {
SplayNodeUpdate(tree, TreeRight(nodeLeft));
/* Don't need to update new root because we know that we will */
/* do either a link or an assemble next, and that will sort it */
/* out. */
}
return;
tree->updateNode(tree, TreeRight(nodeLeft));
/* Don't need to update new root because we know that we will */
/* do either a link or an assemble next, and that will sort it */
/* out. */
}
@ -238,11 +203,11 @@ static void SplayAssemble(SplayTree tree, Tree top,
AVER(rightTop == TreeEMPTY ||
(TreeCheck(rightTop) && TreeCheck(rightFirst)));
if (leftTop != NULL) {
if (leftTop != TreeEMPTY) {
TreeSetRight(leftLast, TreeLeft(top));
TreeSetLeft(top, leftTop);
if (tree->updateNode != NULL) {
if (tree->updateNode != SplayTrivUpdate) {
/* Update client property using pointer reversal (Ugh!). */
Tree node, parent, rightChild;
@ -259,23 +224,23 @@ static void SplayAssemble(SplayTree tree, Tree top,
/* Now restore the pointers, updating the client property. */
/* node is leftLast, parent is the last parent (or NULL). */
SplayNodeUpdate(tree, node);
tree->updateNode(tree, node);
while(node != leftTop) {
rightChild = node;
node = parent;
parent = TreeRight(node);
TreeSetRight(node, rightChild); /* un-reverse pointer */
SplayNodeUpdate(tree, node);
tree->updateNode(tree, node);
}
}
}
/* otherwise leave top->left alone */
if (rightTop != NULL) {
if (rightTop != TreeEMPTY) {
TreeSetLeft(rightFirst, TreeRight(top));
TreeSetRight(top, rightTop);
if (tree->updateNode != NULL) {
if (tree->updateNode != SplayTrivUpdate) {
/* Update client property using pointer reversal (Ugh!). */
Tree node, parent, leftChild;
@ -292,20 +257,19 @@ static void SplayAssemble(SplayTree tree, Tree top,
/* Now restore the pointers, updating the client property. */
/* node is rightFirst, parent is the last parent (or NULL). */
SplayNodeUpdate(tree, node);
tree->updateNode(tree, node);
while(node != rightTop) {
leftChild = node;
node = parent;
parent = TreeLeft(node);
TreeSetLeft(node, leftChild); /* un-reverse pointer */
SplayNodeUpdate(tree, node);
tree->updateNode(tree, node);
}
}
}
/* otherwise leave top->right alone */
if (tree->updateNode != NULL)
SplayNodeUpdate(tree, top);
tree->updateNode(tree, top);
}
@ -344,7 +308,7 @@ static Bool SplaySplay(Tree *nodeReturn, SplayTree tree,
return TRUE;
}
SplayNodeInit(&sides); /* left and right trees now NULL */
TreeInit(&sides); /* left and right trees now TreeEMPTY */
leftLast = &sides;
rightFirst = &sides;
@ -502,10 +466,8 @@ Res SplayTreeInsert(SplayTree tree, Tree node, void *key) {
} break;
}
if (tree->updateNode != NULL) {
SplayNodeUpdate(tree, neighbour);
SplayNodeUpdate(tree, node);
}
tree->updateNode(tree, neighbour);
tree->updateNode(tree, node);
}
return ResOK;
@ -532,23 +494,25 @@ Res SplayTreeDelete(SplayTree tree, Tree node, void *key) {
return ResFAIL;
} else if (TreeLeft(node) == TreeEMPTY) {
SplayTreeSetRoot(tree, TreeRight(node));
TreeClearRight(node);
} else if (TreeRight(node) == TreeEMPTY) {
SplayTreeSetRoot(tree, TreeLeft(node));
TreeClearLeft(node);
} else {
rightHalf = TreeRight(node);
TreeClearRight(node);
SplayTreeSetRoot(tree, TreeLeft(node));
TreeClearLeft(node);
if (SplaySplay(&leftLast, tree, key, tree->compare)) {
return ResFAIL;
} else {
AVER(TreeRight(leftLast) == TreeEMPTY);
TreeSetRight(leftLast, rightHalf);
if (tree->updateNode != NULL) {
SplayNodeUpdate(tree, leftLast);
}
tree->updateNode(tree, leftLast);
}
}
SplayNodeFinish(node);
TreeFinish(node);
return ResOK;
}
@ -603,10 +567,8 @@ static Tree SplayTreePredecessor(SplayTree tree, void *key) {
TreeSetRight(newRoot, oldRoot);
}
if (tree->updateNode != NULL) {
SplayNodeUpdate(tree, oldRoot);
SplayNodeUpdate(tree, newRoot);
}
tree->updateNode(tree, oldRoot);
tree->updateNode(tree, newRoot);
}
return newRoot;
@ -640,10 +602,8 @@ static Tree SplayTreeSuccessor(SplayTree tree, void *key) {
TreeSetLeft(newRoot, oldRoot);
}
if (tree->updateNode != NULL) {
SplayNodeUpdate(tree, oldRoot);
SplayNodeUpdate(tree, newRoot);
}
tree->updateNode(tree, oldRoot);
tree->updateNode(tree, newRoot);
}
return newRoot;
@ -756,7 +716,7 @@ static Res SplayNodeDescribe(Tree node, mps_lib_FILE *stream,
res = WriteF(stream, "( ", NULL);
if (res != ResOK) return res;
if (TreeLeft(node) != NULL) {
if (TreeLeft(node) != TreeEMPTY) {
res = SplayNodeDescribe(TreeLeft(node), stream, nodeDescribe);
if (res != ResOK) return res;
@ -767,7 +727,7 @@ static Res SplayNodeDescribe(Tree node, mps_lib_FILE *stream,
res = (*nodeDescribe)(node, stream);
if (res != ResOK) return res;
if (TreeRight(node) != NULL) {
if (TreeRight(node) != TreeEMPTY) {
res = WriteF(stream, " \\ ", NULL);
if (res != ResOK) return res;
@ -809,13 +769,13 @@ static Compare SplayFindFirstCompare(void *key, Tree node)
testTree = closure->testTree;
tree = closure->tree;
if (TreeLeft(node) != NULL &&
if (TreeLeft(node) != TreeEMPTY &&
(*testTree)(tree, TreeLeft(node), closureP, closureS)) {
return CompareLESS;
} else if ((*testNode)(tree, node, closureP, closureS)) {
return CompareEQUAL;
} else {
AVER(TreeRight(node) != NULL);
AVER(TreeRight(node) != TreeEMPTY);
AVER((*testTree)(tree, TreeRight(node), closureP, closureS));
return CompareGREATER;
}
@ -840,13 +800,13 @@ static Compare SplayFindLastCompare(void *key, Tree node)
testTree = closure->testTree;
tree = closure->tree;
if (TreeRight(node) != NULL &&
if (TreeRight(node) != TreeEMPTY &&
(*testTree)(tree, TreeRight(node), closureP, closureS)) {
return CompareGREATER;
} else if ((*testNode)(tree, node, closureP, closureS)) {
return CompareEQUAL;
} else {
AVER(TreeLeft(node) != NULL);
AVER(TreeLeft(node) != TreeEMPTY);
AVER((*testTree)(tree, TreeLeft(node), closureP, closureS));
return CompareLESS;
}
@ -976,8 +936,7 @@ void SplayNodeRefresh(SplayTree tree, Tree node, void *key)
AVER(b);
AVER(node == node2);
(*tree->updateNode)(tree, node, TreeLeft(node),
TreeRight(node));
tree->updateNode(tree, node);
}
@ -1002,7 +961,7 @@ Res SplayTreeDescribe(SplayTree tree, mps_lib_FILE *stream,
NULL);
if (res != ResOK) return res;
if (SplayTreeRoot(tree) != NULL) {
if (SplayTreeRoot(tree) != TreeEMPTY) {
res = SplayNodeDescribe(SplayTreeRoot(tree), stream, nodeDescribe);
if (res != ResOK) return res;
}

View file

@ -20,11 +20,10 @@ typedef Bool (*SplayTestNodeMethod)(SplayTree tree, Tree node,
void *closureP, Size closureS);
typedef Bool (*SplayTestTreeMethod)(SplayTree tree, Tree node,
void *closureP, Size closureS);
typedef void (*SplayUpdateNodeMethod)(SplayTree tree, Tree node,
Tree leftChild,
Tree rightChild);
typedef Res (*SplayNodeDescribeMethod)(Tree node, mps_lib_FILE *stream);
typedef void (*SplayUpdateNodeMethod)(SplayTree tree, Tree node);
extern void SplayTrivUpdate(SplayTree tree, Tree node);
typedef struct SplayTreeStruct {
SplayCompareMethod compare;
@ -36,8 +35,6 @@ typedef struct SplayTreeStruct {
extern Bool SplayTreeCheck(SplayTree tree);
extern void SplayTreeInit(SplayTree tree, SplayCompareMethod compare,
SplayUpdateNodeMethod updateNode);
extern void SplayNodeInit(Tree node);
extern void SplayNodeFinish(Tree node);
extern void SplayTreeFinish(SplayTree tree);
extern Res SplayTreeInsert(SplayTree tree, Tree node, void *key);

View file

@ -249,7 +249,7 @@ _`.function.splay.tree.init`: This function initialises a
implement a total ordering is undefined. It also requires an
``updateNode`` method, which will be used to keep client properties up
to date when the tree structure changes; the value
``SplayTrivUpdateNode`` may be used for this method if there is no
``SplayTrivUpdate`` may be used for this method if there is no
need to maintain client properties. (See `.usage.initialization`_ for
an example use).