/** 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(); } }
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()); } } }
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(); } }