/** * Compute the number of elements and sum of counts for every entry that * is strictly before <code>node</code>. */ @SuppressWarnings("WeakerAccess") public long headSum(int node) { final int left = tree.left(node); long sum = aggregatedCounts[left]; for (int n = node, p = tree.parent(node); p != IntAVLTree.NIL; n = p, p = tree.parent(n)) { if (n == tree.right(p)) { final int leftP = tree.left(p); sum += counts[p] + aggregatedCounts[leftP]; } } return sum; }
/** * Return the least node that is strictly greater than <code>node</code>. */ public final int next(int node) { final int right = right(node); if (right != NIL) { return first(right); } else { int parent = parent(node); while (parent != NIL && node == right(parent)) { node = parent; parent = parent(parent); } return parent; } }
/** * Return the highest node that is strictly less than <code>node</code>. */ public final int prev(int node) { final int left = left(node); if (left != NIL) { return last(left); } else { int parent = parent(node); while (parent != NIL && node == left(parent)) { node = parent; parent = parent(parent); } return parent; } }
/** Rotate left the subtree under <code>n</code> */ private void rotateLeft(int n) { final int r = right(n); final int lr = left(r); right(n, lr); if (lr != NIL) { parent(lr, n); } final int p = parent(n); parent(r, p); if (p == NIL) { root = r; } else if (left(p) == n) { left(p, r); } else { assert right(p) == n; right(p, r); } left(r, n); parent(n, r); fixAggregates(n); fixAggregates(parent(n)); }
/** Rotate right the subtree under <code>n</code> */ private void rotateRight(int n) { final int l = left(n); final int rl = right(l); left(n, rl); if (rl != NIL) { parent(rl, n); } final int p = parent(n); parent(l, p); if (p == NIL) { root = l; } else if (right(p) == n) { right(p, l); } else { assert left(p) == n; left(p, l); } right(l, n); parent(n, l); fixAggregates(n); fixAggregates(parent(n)); }
private void release(int node) { left(node, NIL); right(node, NIL); parent(node, NIL); nodeAllocator.release(node); }
private void swap(int node1, int node2) { final int parent1 = parent(node1); final int parent2 = parent(node2); if (parent1 != NIL) { if (node1 == left(parent1)) { root = node1; parent(node1, parent2); parent(node2, parent1); left(node1, left2); if (left2 != NIL) { parent(left2, node1); parent(left1, node2); right(node1, right2); if (right2 != NIL) { parent(right2, node1); parent(right1, node2);
private void rebalance(int node) { for (int n = node; n != NIL; ) { final int p = parent(n); fixAggregates(n); switch (balanceFactor(n)) { case -2: final int right = right(n); if (balanceFactor(right) == 1) { rotateRight(right); } rotateLeft(n); break; case 2: final int left = left(n); if (balanceFactor(left) == -1) { rotateLeft(left); } rotateRight(n); break; case -1: case 0: case 1: break; // ok default: throw new AssertionError(); } n = p; } }
/** * Update <code>node</code> with the current data. */ public void update(int node) { final int prev = prev(node); final int next = next(node); if ((prev == NIL || compare(prev) > 0) && (next == NIL || compare(next) < 0)) { // Update can be done in-place copy(node); for (int n = node; n != NIL; n = parent(n)) { fixAggregates(n); } } else { // TODO: it should be possible to find the new node position without // starting from scratch remove(node); add(); } }
/** * Compute the number of elements and sum of counts for every entry that * is strictly before <code>node</code>. */ public long headSum(int node) { final int left = tree.left(node); long sum = aggregatedCounts[left]; for (int n = node, p = tree.parent(node); p != IntAVLTree.NIL; n = p, p = tree.parent(n)) { if (n == tree.right(p)) { final int leftP = tree.left(p); sum += counts[p] + aggregatedCounts[leftP]; } } return sum; }
/** * Return the highest node that is strictly less than <code>node</code>. */ public final int prev(int node) { final int left = left(node); if (left != NIL) { return last(left); } else { int parent = parent(node); while (parent != NIL && node == left(parent)) { node = parent; parent = parent(parent); } return parent; } }
/** * Return the least node that is strictly greater than <code>node</code>. */ public final int next(int node) { final int right = right(node); if (right != NIL) { return first(right); } else { int parent = parent(node); while (parent != NIL && node == right(parent)) { node = parent; parent = parent(parent); } return parent; } }
/** Rotate right the subtree under <code>n</code> */ private void rotateRight(int n) { final int l = left(n); final int rl = right(l); left(n, rl); if (rl != NIL) { parent(rl, n); } final int p = parent(n); parent(l, p); if (p == NIL) { root = l; } else if (right(p) == n) { right(p, l); } else { assert left(p) == n; left(p, l); } right(l, n); parent(n, l); fixAggregates(n); fixAggregates(parent(n)); }
/** Rotate left the subtree under <code>n</code> */ private void rotateLeft(int n) { final int r = right(n); final int lr = left(r); right(n, lr); if (lr != NIL) { parent(lr, n); } final int p = parent(n); parent(r, p); if (p == NIL) { root = r; } else if (left(p) == n) { left(p, r); } else { assert right(p) == n; right(p, r); } left(r, n); parent(n, r); fixAggregates(n); fixAggregates(parent(n)); }
private void release(int node) { left(node, NIL); right(node, NIL); parent(node, NIL); nodeAllocator.release(node); }
/** * Update <code>node</code> with the current data. */ public void update(int node) { final int prev = prev(node); final int next = next(node); if ((prev == NIL || compare(prev) > 0) && (next == NIL || compare(next) < 0)) { // Update can be done in-place copy(node); for (int n = node; n != NIL; n = parent(n)) { fixAggregates(n); } } else { // TODO: it should be possible to find the new node position without // starting from scratch remove(node); add(); } }
private void rebalance(int node) { for (int n = node; n != NIL; ) { final int p = parent(n); fixAggregates(n); switch (balanceFactor(n)) { case -2: final int right = right(n); if (balanceFactor(right) == 1) { rotateRight(right); } rotateLeft(n); break; case 2: final int left = left(n); if (balanceFactor(left) == -1) { rotateLeft(left); } rotateRight(n); break; case -1: case 0: case 1: break; // ok default: throw new AssertionError(); } n = p; } }