private static AVLTree balance(AVLTree l, Object key, Object value, AVLTree r) { if (l.height() > r.height() + 2) { assert !l.isEmpty(); AVLTree ll = l.left(); AVLTree lr = l.right(); if (ll.height() >= lr.height()) { return createNode(ll, l, createNode(lr, key, value, r)); } assert !lr.isEmpty(); AVLTree lrl = lr.left(); AVLTree lrr = lr.right(); return createNode(createNode(ll, l, lrl), lr, createNode(lrr, key, value, r)); } if (r.height() > l.height() + 2) { assert !r.isEmpty(); AVLTree rl = r.left(); AVLTree rr = r.right(); if (rr.height() >= rl.height()) { return createNode(createNode(l, key, value, rl), r, rr); } assert !rl.isEmpty(); AVLTree rll = rl.left(); AVLTree rlr = rl.right(); return createNode(createNode(l, key, value, rll), rl, createNode(rlr, r, rr)); } return createNode(l, key, value, r); }
private static AVLTree removeMinBinding(AVLTree t, NodeRef noderemoved) { assert !t.isEmpty(); if (t.left().isEmpty()) { noderemoved.node = t; return t.right(); } return balance(removeMinBinding(t.left(), noderemoved), t.key(), t.value(), t.right()); }
@SuppressWarnings("unchecked") private void forEach(AVLTree t, PSet.Consumer<K> action) { if (t.isEmpty()) { return; } action.accept((K) t.key()); forEach(t.left(), action); forEach(t.right(), action); }
private static AVLTree remove(Object key, AVLTree t) { if (t.isEmpty()) { return t; } int result = KEY_COMPARATOR.compare(key, t.key()); if (result == 0) { return combineTrees(t.left(), t.right()); } else if (result < 0) { AVLTree left = remove(key, t.left()); if (left == t.left()) { return t; } return balance(left, t.key(), t.value(), t.right()); } else { AVLTree right = remove(key, t.right()); if (right == t.right()) { return t; } return balance(t.left(), t.key(), t.value(), right); } }
private static AVLTree put(Object key, Object value, AVLTree t) { if (t.isEmpty()) { return createNode(t, key, value, t); } int result = KEY_COMPARATOR.compare(key, t.key()); if (result == 0) { if (value.equals(t.value())) { return t; } return createNode(t.left(), key, value, t.right()); } else if (result < 0) { AVLTree left = put(key, value, t.left()); if (left == t.left()) { return t; } return balance(left, t.key(), t.value(), t.right()); } else { AVLTree right = put(key, value, t.right()); if (right == t.right()) { return t; } return balance(t.left(), t.key(), t.value(), right); } }
@SuppressWarnings("unchecked") @Nullable @Override public V get(K key) { Preconditions.checkNotNull(key); AVLTree t = this; while (!t.isEmpty()) { int c = KEY_COMPARATOR.compare(key, t.key()); if (c == 0) { return (V) t.value(); } else if (c < 0) { t = t.left(); } else { t = t.right(); } } return null; }