From 2bb859f62b83fe4192be0623ba827b6ebd2c580b Mon Sep 17 00:00:00 2001 From: Richard Brooksby Date: Sat, 22 Feb 2014 10:08:30 +0000 Subject: [PATCH] Avoid dropping children of found node in non-update case. oops. Copied from Perforce Change: 184439 ServerID: perforce.ravenbrook.com --- mps/code/splay.c | 51 +++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/mps/code/splay.c b/mps/code/splay.c index 0618c14608d..309222a8c4a 100644 --- a/mps/code/splay.c +++ b/mps/code/splay.c @@ -187,30 +187,43 @@ static Tree SplayUpdateRightSpine(SplayTree tree, Tree node, Tree top) */ static void SplayAssemble(SplayTree tree, Tree top, - Tree leftTop, Tree rightTop) + Tree leftTop, Tree leftLast, + Tree rightTop, Tree rightFirst) { AVERT(SplayTree, tree); AVERT(Tree, top); AVERT(Tree, leftTop); AVERT(Tree, rightTop); - if (tree->updateNode != SplayTrivUpdate) { - /* Update client property using pointer reversal (Ugh!). */ - Tree leftLast = TreeReverseRightSpine(leftTop); - Tree newLeft = SplayUpdateRightSpine(tree, leftLast, top); - AVER(newLeft == (leftTop != TreeEMPTY ? leftTop : TreeLeft(top))); - TreeSetLeft(top, newLeft); - } else - TreeSetLeft(top, leftTop); + if (leftTop != TreeEMPTY) { + if (tree->updateNode != SplayTrivUpdate) { + /* Update client property using pointer reversal (Ugh!). */ + Tree left, newLeft; + left = TreeReverseRightSpine(leftTop); + AVER(left == leftLast); + newLeft = SplayUpdateRightSpine(tree, left, top); + AVER(newLeft == leftTop); + TreeSetLeft(top, newLeft); + } else { + TreeSetRight(leftLast, TreeLeft(top)); + TreeSetLeft(top, leftTop); + } + } - if (tree->updateNode != SplayTrivUpdate) { - /* Update client property using pointer reversal (Ugh!). */ - Tree rightFirst = TreeReverseLeftSpine(rightTop); - Tree newRight = SplayUpdateLeftSpine(tree, rightFirst, top); - AVER(newRight == (rightTop != TreeEMPTY ? rightTop : TreeRight(top))); - TreeSetRight(top, newRight); - } else - TreeSetRight(top, rightTop); + if (rightTop != TreeEMPTY) { + if (tree->updateNode != SplayTrivUpdate) { + /* Update client property using pointer reversal (Ugh!). */ + Tree right, newRight; + right = TreeReverseLeftSpine(rightTop); + AVER(right == rightFirst); + newRight = SplayUpdateLeftSpine(tree, rightFirst, top); + AVER(newRight == rightTop); + TreeSetRight(top, newRight); + } else { + TreeSetLeft(rightFirst, TreeRight(top)); + TreeSetRight(top, rightTop); + } + } tree->updateNode(tree, top); } @@ -337,7 +350,9 @@ static Compare SplaySplay(SplayTree tree, TreeKey key, TreeCompare compare) } assemble: - SplayAssemble(tree, node, TreeRight(&sides), TreeLeft(&sides)); + SplayAssemble(tree, node, + TreeRight(&sides), leftLast, + TreeLeft(&sides), rightFirst); SplayTreeSetRoot(tree, node); return cmp;