Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
static Compare SplayFindLastCompare(Tree node, TreeKey key)
{
  SplayFindClosure my;
  SplayTestNodeFunction testNode;
  SplayTestTreeFunction testTree;
  void *testClosure;
  SplayTree splay;

  AVERT_CRITICAL(Tree, node);
  AVER_CRITICAL(key != NULL);

  /* Lift closure values into variables so that they aren't aliased by
     calls to the test functions. */
  my = (SplayFindClosure)key;
  testClosure = my->testClosure;
  testNode = my->testNode;
  testTree = my->testTree;
  splay = my->splay;

  if (TreeHasRight(node) &&
      (*testTree)(splay, TreeRight(node), testClosure)) {
    return CompareGREATER;
  } else if ((*testNode)(splay, node, testClosure)) {
    my->found = TRUE;
    return CompareEQUAL;
  } else {
    /* See SplayFindFirstCompare. */
    if (TreeHasLeft(node) &&
        !(*testTree)(splay, TreeLeft(node), testClosure)) {
      my->found = FALSE;
      return CompareEQUAL;
    }
    return CompareLESS;
  }
}
Пример #4
0
static Tree stepUpRight(Tree node, Tree *parentIO)
{
  Tree parent = *parentIO;
  Tree grandparent = TreeLeft(parent);
  TreeSetLeft(parent, node);
  *parentIO = grandparent;
  return parent;
}
Пример #5
0
static Tree stepDownLeft(Tree node, Tree *parentIO)
{
  Tree parent = *parentIO;
  Tree child = TreeLeft(node);
  TreeSetLeft(node, parent);
  *parentIO = node;
  return child;
}
Пример #6
0
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;
}
Пример #7
0
static Tree SplayZig(Tree middle, Tree *rightFirstIO, Tree *rightNextReturn)
{
  AVERT_CRITICAL(Tree, middle);
  AVER_CRITICAL(rightFirstIO != NULL);
  AVERT_CRITICAL(Tree, *rightFirstIO);
  TreeSetLeft(*rightFirstIO, middle);
  *rightNextReturn = *rightFirstIO;
  *rightFirstIO = middle;
  return TreeLeft(middle);
}
Пример #8
0
void SplayDebugUpdate(SplayTree splay, Tree tree)
{
  AVERT(SplayTree, splay);
  AVERT(Tree, tree);
  if (tree == TreeEMPTY)
    return;
  SplayDebugUpdate(splay, TreeLeft(tree));
  SplayDebugUpdate(splay, TreeRight(tree));
  splay->updateNode(splay, tree);
}
Пример #9
0
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;
}
Пример #10
0
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);
}
Пример #11
0
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;
}
Пример #12
0
Bool SplayTreeDelete(SplayTree splay, Tree node)
{
  Tree leftLast;
  Compare cmp;

  AVERT(SplayTree, splay);
  AVERT(Tree, node);

  if (SplayTreeIsEmpty(splay))
    return FALSE;

  cmp = SplaySplay(splay, splay->nodeKey(node), splay->compare);
  AVER(cmp != CompareEQUAL || SplayTreeRoot(splay) == node);

  if (cmp != CompareEQUAL) {
    return FALSE;
  } else if (!TreeHasLeft(node)) {
    SplayTreeSetRoot(splay, TreeRight(node));
    TreeClearRight(node);
  } else if (!TreeHasRight(node)) {
    SplayTreeSetRoot(splay, TreeLeft(node));
    TreeClearLeft(node);
  } else {
    Tree rightHalf = TreeRight(node);
    TreeClearRight(node);
    SplayTreeSetRoot(splay, TreeLeft(node));
    TreeClearLeft(node);
    (void)SplaySplay(splay, NULL, compareGreater);
    leftLast = SplayTreeRoot(splay);
    AVER(leftLast != TreeEMPTY);
    AVER(!TreeHasRight(leftLast));
    TreeSetRight(leftLast, rightHalf);
    splay->updateNode(splay, leftLast);
  }

  TreeFinish(node);

  return TRUE;
}
Пример #13
0
static Count TreeDebugCountBetween(Tree node,
                                   TreeCompare compare, TreeKeyMethod key,
                                   TreeKey min, TreeKey max)
{
  if (node == TreeEMPTY)
    return 0;
  AVERT(Tree, node);
  AVER(min == NULL || compare(node, min) != CompareGREATER);
  AVER(max == NULL || compare(node, max) != CompareLESS);
  return TreeDebugCountBetween(TreeLeft(node), compare, key, min, key(node)) +
         1 +
         TreeDebugCountBetween(TreeRight(node), compare, key, key(node), max);
}
Пример #14
0
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;
}
Пример #15
0
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;
}
Пример #16
0
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;
}
Пример #17
0
Tree SplayTreeFirst(SplayTree splay) {
  Tree node;

  AVERT(SplayTree, splay);

  if (SplayTreeIsEmpty(splay))
    return TreeEMPTY;

  (void)SplaySplay(splay, NULL, compareLess);
  node = SplayTreeRoot(splay);
  AVER(node != TreeEMPTY);
  AVER(TreeLeft(node) == TreeEMPTY);

  return node;
}
Пример #18
0
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;
}
Пример #19
0
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);
}
Пример #20
0
static Res SplayNodeDescribe(Tree node, mps_lib_FILE *stream,
                             TreeDescribeFunction nodeDescribe)
{
  Res res;

  if (!TreeCheck(node))
    return ResFAIL;
  if (stream == NULL)
    return ResFAIL;
  if (nodeDescribe == NULL)
    return ResFAIL;

  res = WriteF(stream, 0, "( ", NULL);
  if (res != ResOK)
    return res;

  if (TreeHasLeft(node)) {
    res = SplayNodeDescribe(TreeLeft(node), stream, nodeDescribe);
    if (res != ResOK)
      return res;

    res = WriteF(stream, 0, " / ", NULL);
    if (res != ResOK)
      return res;
  }

  res = (*nodeDescribe)(node, stream);
  if (res != ResOK)
    return res;

  if (TreeHasRight(node)) {
    res = WriteF(stream, 0, " \\ ", NULL);
    if (res != ResOK)
      return res;

    res = SplayNodeDescribe(TreeRight(node), stream, nodeDescribe);
    if (res != ResOK)
      return res;
  }

  res = WriteF(stream, 0, " )", NULL);
  if (res != ResOK)
    return res;

  return ResOK;
}
Пример #21
0
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);
  }
}
Пример #22
0
static Compare SplayFindFirstCompare(Tree node, TreeKey key)
{
  SplayFindClosure closure;
  void *closureP;
  Size closureS;
  SplayTestNodeFunction testNode;
  SplayTestTreeFunction testTree;
  SplayTree splay;

  AVERT(Tree, node);
  AVER(key != NULL);

  /* Lift closure values into variables so that they aren't aliased by
     calls to the test functions. */
  closure = (SplayFindClosure)key;
  closureP = closure->p;
  closureS = closure->s;
  testNode = closure->testNode;
  testTree = closure->testTree;
  splay = closure->splay;
  
  if (TreeHasLeft(node) &&
     (*testTree)(splay, TreeLeft(node), closureP, closureS)) {
    return CompareLESS;
  } else if ((*testNode)(splay, node, closureP, closureS)) {
    closure->found = TRUE;
    return CompareEQUAL;
  } else {
    /* If there's a right subtree but it doesn't satisfy the tree test
       then we want to terminate the splay right now.  SplaySplay will
       return TRUE, so the caller must check closure->found to find out
       whether the result node actually satisfies testNode. */
    if (TreeHasRight(node) &&
        !(*testTree)(splay, TreeRight(node), closureP, closureS)) {
      closure->found = FALSE;
      return CompareEQUAL;
    }
    return CompareGREATER;
  }
}
Пример #23
0
static Compare SplayFindLastCompare(Tree node, TreeKey key)
{
  SplayFindClosure closure;
  void *closureP;
  Size closureS;
  SplayTestNodeFunction testNode;
  SplayTestTreeFunction testTree;
  SplayTree splay;

  AVERT(Tree, node);
  AVER(key != NULL);

  /* Lift closure values into variables so that they aren't aliased by
     calls to the test functions. */
  closure = (SplayFindClosure)key;
  closureP = closure->p;
  closureS = closure->s;
  testNode = closure->testNode;
  testTree = closure->testTree;
  splay = closure->splay;

  if (TreeHasRight(node) &&
     (*testTree)(splay, TreeRight(node), closureP, closureS)) {
     return CompareGREATER;
  } else if ((*testNode)(splay, node, closureP, closureS)) {
    closure->found = TRUE;
    return CompareEQUAL;
  } else {
    /* See SplayFindFirstCompare. */
    if (TreeHasLeft(node) &&
        !(*testTree)(splay, TreeLeft(node), closureP, closureS)) {
      closure->found = FALSE;
      return CompareEQUAL;
    }
    return CompareLESS;
  }
}
Пример #24
0
static Compare SplaySplitRev(SplayStateStruct *stateReturn,
                             SplayTree splay, TreeKey key,
                             TreeCompareFunction compare)
{
  Tree middle, leftLast, rightFirst;
  Compare cmp;

  AVERT(SplayTree, splay);
  AVER(FUNCHECK(compare));
  AVER(!SplayTreeIsEmpty(splay));
  
  leftLast = TreeEMPTY;
  rightFirst = TreeEMPTY;
  middle = SplayTreeRoot(splay);
  for (;;) {
    cmp = compare(middle, key);
    switch(cmp) {
    default:
      NOTREACHED;
      /* defensive fall-through */
    case CompareEQUAL:
      goto stop;

    case CompareLESS:
      if (!TreeHasLeft(middle))
        goto stop;
      middle = SplayZigRev(middle, &rightFirst);
      cmp = compare(middle, key);
      switch(cmp) {
      default:
        NOTREACHED;
        /* defensive fall-through */
      case CompareEQUAL:
        goto stop;
      case CompareLESS:
        if (!TreeHasLeft(middle))
          goto stop;
        middle = SplayZigZigRev(middle, &rightFirst);
        splay->updateNode(splay, TreeRight(rightFirst));
        break;
      case CompareGREATER:
        if (!TreeHasRight(middle))
          goto stop;
        middle = SplayZagRev(middle, &leftLast);
        break;
      }
      break;

    case CompareGREATER:
      if (!TreeHasRight(middle))
        goto stop;
      middle = SplayZagRev(middle, &leftLast);
      cmp = compare(middle, key);
      switch(cmp) {
      default:
        NOTREACHED;
        /* defensive fall-through */
      case CompareEQUAL:
        goto stop;
      case CompareGREATER:
        if (!TreeHasRight(middle))
          goto stop;
        middle = SplayZagZagRev(middle, &leftLast);
        splay->updateNode(splay, TreeLeft(leftLast));
        break;
      case CompareLESS:
        if (!TreeHasLeft(middle))
          goto stop;
        middle = SplayZigRev(middle, &rightFirst);
        break;
      }
      break;
    }
  }

stop:
  stateReturn->middle = middle;
  stateReturn->leftLast = leftLast;
  stateReturn->rightFirst = rightFirst;
  return cmp;
}
Пример #25
0
static Compare SplaySplitDown(SplayStateStruct *stateReturn,
                              SplayTree splay, TreeKey key,
                              TreeCompareFunction compare)
{
  TreeStruct sentinel;
  Tree middle, leftLast, rightFirst, leftPrev, rightNext;
  Compare cmp;

  AVERT(SplayTree, splay);
  AVER(FUNCHECK(compare));
  AVER(!SplayTreeIsEmpty(splay));
  AVER(!SplayHasUpdate(splay));
  
  TreeInit(&sentinel);
  leftLast = &sentinel;
  rightFirst = &sentinel;
  middle = SplayTreeRoot(splay);
  for (;;) {
    cmp = compare(middle, key);
    switch(cmp) {
    default:
      NOTREACHED;
      /* defensive fall-through */
    case CompareEQUAL:
      goto stop;

    case CompareLESS:
      if (!TreeHasLeft(middle))
        goto stop;
      middle = SplayZig(middle, &rightFirst, &rightNext);
      cmp = compare(middle, key);
      switch(cmp) {
      default:
        NOTREACHED;
        /* defensive fall-through */
      case CompareEQUAL:
        goto stop;
      case CompareLESS:
        if (!TreeHasLeft(middle))
          goto stop;
        middle = SplayZigZig(middle, &rightFirst, rightNext);
        break;
      case CompareGREATER:
        if (!TreeHasRight(middle))
          goto stop;
        middle = SplayZag(middle, &leftLast, &leftPrev);
        break;
      }
      break;

    case CompareGREATER:
      if (!TreeHasRight(middle))
        goto stop;
      middle = SplayZag(middle, &leftLast, &leftPrev);
      cmp = compare(middle, key);
      switch(cmp) {
      default:
        NOTREACHED;
        /* defensive fall-through */
      case CompareEQUAL:
        goto stop;
      case CompareGREATER:
        if (!TreeHasRight(middle))
          goto stop;
        middle = SplayZagZag(middle, &leftLast, leftPrev);
        break;
      case CompareLESS:
        if (!TreeHasLeft(middle))
          goto stop;
        middle = SplayZig(middle, &rightFirst, &rightNext);
        break;
      }
      break;
    }
  }

stop:
  stateReturn->middle = middle;
  stateReturn->left = TreeRight(&sentinel);
  stateReturn->leftLast = leftLast == &sentinel ? TreeEMPTY : leftLast;
  stateReturn->right = TreeLeft(&sentinel);
  stateReturn->rightFirst = rightFirst == &sentinel ? TreeEMPTY : rightFirst;
  return cmp;
}