/** Balances part of the tree after an alteration to the index. */
  private void balance(Session session, Node x, boolean isleft) throws HsqlException {

    while (true) {
      int sign = isleft ? 1 : -1;

      switch (x.getBalance() * sign) {
        case 1:
          x.setBalance(0);

          return;

        case 0:
          x.setBalance(-sign);
          break;

        case -1:
          Node l = child(x, isleft);

          if (l.getBalance() == -sign) {
            replace(session, x, l);
            set(x, isleft, child(l, !isleft));
            set(l, !isleft, x);
            x.setBalance(0);
            l.setBalance(0);
          } else {
            Node r = child(l, !isleft);

            replace(session, x, r);
            set(l, !isleft, child(r, isleft));
            set(r, isleft, l);
            set(x, isleft, child(r, !isleft));
            set(r, !isleft, x);

            int rb = r.getBalance();

            x.setBalance((rb == -sign) ? sign : 0);
            l.setBalance((rb == sign) ? -sign : 0);
            r.setBalance(0);
          }

          return;
      }

      if (x.equals(getRoot(session))) {
        return;
      }

      isleft = x.isFromLeft();
      x = x.getParent();
    }
  }
Example #2
0
  public void insert_restore_AVL_prop(Node curr) {
    curr.setHeight(-1);
    curr.setBalance(0);

    while (curr != null && curr.getBalance() == 0) {
      curr.setHeight(curr.getHeight() + 1);

      computeBalance(curr);

      curr = curr.getParent();
    }

    if (curr != null) {
      computeBalance(curr);

      if (curr.getBalance() == -2) {
        if (curr.getLeftChild().getBalance() == 1) {

          left_rotate(curr.getLeftChild());
          height_of_node(curr.getLeftChild());
          computeBalance(curr.getLeftChild());
          computeBalance(curr.getLeftChild().getLeftChild());
        }

        right_rotate(curr);
        height_of_node(curr.getParent());
        computeBalance(curr);
        computeBalance(curr.getParent());
      } else if (curr.getBalance() == 2) {
        if (curr.getRightChild().getBalance() == -1) {

          right_rotate(curr.getRightChild());
          height_of_node(curr.getRightChild());
          computeBalance(curr.getRightChild());
          computeBalance(curr.getRightChild().getRightChild());
        }

        left_rotate(curr);
        height_of_node(curr.getParent());
        computeBalance(curr);
        computeBalance(curr.getParent());
      }
    }
  }
Example #3
0
  public void delete_restore_AVL_prop(Node curr) {
    height_of_node(curr);

    while (curr != null) {
      computeBalance(curr);

      if (curr.getBalance() == -2) {
        if (curr.getLeftChild().getBalance() == 1) {

          left_rotate(curr.getLeftChild());
          height_of_node(curr.getLeftChild());
          computeBalance(curr.getLeftChild());
          computeBalance(curr.getLeftChild().getLeftChild());
        }

        right_rotate(curr);
        height_of_node(curr.getParent());
        computeBalance(curr);
        computeBalance(curr.getParent());

        curr = curr.getParent();
      } else if (curr.getBalance() == 2) {
        if (curr.getRightChild().getBalance() == -1) {

          right_rotate(curr.getRightChild());
          height_of_node(curr.getRightChild());
          computeBalance(curr.getRightChild());
          computeBalance(curr.getRightChild().getRightChild());
        }

        left_rotate(curr);
        height_of_node(curr.getParent());
        computeBalance(curr);
        computeBalance(curr.getParent());

        curr = curr.getParent();
      }

      curr = curr.getParent();
    }
  }
  /** Delete a node from the index */
  void delete(Session session, Node x) throws HsqlException {

    if (x == null) {
      return;
    }

    for (IndexRowIterator it = updatableIterators.next; it != updatableIterators; it = it.next) {
      it.updateForDelete(x);
    }

    Node n;

    if (x.getLeft() == null) {
      n = x.getRight();
    } else if (x.getRight() == null) {
      n = x.getLeft();
    } else {
      Node d = x;

      x = x.getLeft();

      /*
                  // todo: this can be improved

                  while (x.getRight() != null) {
                      if (Trace.STOP) {
                          Trace.stop();
                      }

                      x = x.getRight();
                  }
      */
      for (Node temp = x; (temp = temp.getRight()) != null; ) {
        x = temp;
      }

      // x will be replaced with n later
      n = x.getLeft();

      // swap d and x
      int b = x.getBalance();

      x.setBalance(d.getBalance());
      d.setBalance(b);

      // set x.parent
      Node xp = x.getParent();
      Node dp = d.getParent();

      if (d == getRoot(session)) {
        setRoot(session, x);
      }

      x.setParent(dp);

      if (dp != null) {
        if (dp.getRight().equals(d)) {
          dp.setRight(x);
        } else {
          dp.setLeft(x);
        }
      }

      // for in-memory tables we could use: d.rData=x.rData;
      // but not for cached tables
      // relink d.parent, x.left, x.right
      if (xp == d) {
        d.setParent(x);

        if (d.getLeft().equals(x)) {
          x.setLeft(d);
          x.setRight(d.getRight());
        } else {
          x.setRight(d);
          x.setLeft(d.getLeft());
        }
      } else {
        d.setParent(xp);
        xp.setRight(d);
        x.setRight(d.getRight());
        x.setLeft(d.getLeft());
      }

      x.getRight().setParent(x);
      x.getLeft().setParent(x);

      // set d.left, d.right
      d.setLeft(n);

      if (n != null) {
        n.setParent(d);
      }

      d.setRight(null);

      x = d;
    }

    boolean isleft = x.isFromLeft();

    replace(session, x, n);

    n = x.getParent();

    x.delete();

    while (n != null) {
      x = n;

      int sign = isleft ? 1 : -1;

      switch (x.getBalance() * sign) {
        case -1:
          x.setBalance(0);
          break;

        case 0:
          x.setBalance(sign);

          return;

        case 1:
          Node r = child(x, !isleft);
          int b = r.getBalance();

          if (b * sign >= 0) {
            replace(session, x, r);
            set(x, !isleft, child(r, isleft));
            set(r, isleft, x);

            if (b == 0) {
              x.setBalance(sign);
              r.setBalance(-sign);

              return;
            }

            x.setBalance(0);
            r.setBalance(0);

            x = r;
          } else {
            Node l = child(r, isleft);

            replace(session, x, l);

            b = l.getBalance();

            set(r, isleft, child(l, !isleft));
            set(l, !isleft, r);
            set(x, !isleft, child(l, isleft));
            set(l, isleft, x);
            x.setBalance((b == sign) ? -sign : 0);
            r.setBalance((b == -sign) ? sign : 0);
            l.setBalance(0);

            x = l;
          }
      }

      isleft = x.isFromLeft();
      n = x.getParent();
    }
  }