return res;
}
private void rebuildToCapacity(long newCapacity) {
Long2LongOpenHashMap newNode2count = new Long2LongOpenHashMap(MAP_INITIAL_SIZE, MAP_LOAD_FACTOR);
// rebuild to newLogCapacity.
// This means that our current tree becomes a leftmost subtree
// of the new tree.
// E.g. when rebuilding a tree with logCapacity = 2
// (i.e. storing values in 0..3) to logCapacity = 5 (i.e. 0..31):
// node 1 => 8 (+= 7 = 2^0*(2^3-1))
// nodes 2..3 => 16..17 (+= 14 = 2^1*(2^3-1))
// nodes 4..7 => 32..35 (+= 28 = 2^2*(2^3-1))
// This is easy to see if you draw it on paper.
// Process the keys by "layers" in the original tree.
long scaleR = newCapacity / capacity - 1;
Long[] keys = node2count.keySet().toArray(new Long[node2count.size()]);
Arrays.sort(keys);
long scaleL = 1;
for (long k : keys) {
while (scaleL <= k / 2) {
scaleL <<= 1;
}
newNode2count.put(k + scaleL * scaleR, node2count.get(k));
}
node2count = newNode2count;
capacity = newCapacity;
compressFully();
}