private NodeBuilder ensureParent() { if (parent == null) { parent = new NodeBuilder(); parent.child = this; } if (parent.upperBound == null) parent.reset(EMPTY_BRANCH, upperBound, updateFunction, comparator); return parent; }
private NodeBuilder ascend() { ensureParent(); boolean isLeaf = isLeaf(copyFrom); if (buildKeyPosition > FAN_FACTOR) { // split current node and move the midpoint into parent, with the two halves as children int mid = buildKeyPosition / 2; parent.addExtraChild(buildFromRange(0, mid, isLeaf, true), buildKeys[mid]); parent.finishChild(buildFromRange(mid + 1, buildKeyPosition - (mid + 1), isLeaf, false)); } else { parent.finishChild(buildFromRange(0, buildKeyPosition, isLeaf, false)); } return parent; }
public <V> Object[] build(Iterable<V> source, UpdateFunction<V> updateF, int size) { assert updateF != null; NodeBuilder current = rootBuilder; // we descend only to avoid wasting memory; in update() we will often descend into existing trees // so here we want to descend also, so we don't have lg max(N) depth in both directions while ((size >>= FAN_SHIFT) > 0) current = current.ensureChild(); current.reset(EMPTY_LEAF, POSITIVE_INFINITY, updateF, null); for (V key : source) current.addNewKey(key); current = current.ascendToRoot(); Object[] r = current.toNode(); current.clear(); return r; } }
key = next; else if (i == copyFromKeyEnd && compareUpperBound(comparator, key, upperBound) >= 0) owns = false; copyKeys(i); replaceNextKey(key); addNewKey(key); copyKeys(i); copyKeys(i); replaceNextKey(key); copyChildren(i + 1); return null; copyKeys(i); copyChildren(i); ensureChild().reset(descendInto, newUpperBound, updateFunction, comparator); return child; copyKeys(copyFromKeyEnd); copyChildren(copyFromKeyEnd + 1); // since we know that there are exactly 1 more child nodes, than keys return ascend();
current.reset(btree, POSITIVE_INFINITY, updateF, comparator); rootBuilder.clear(); return null; NodeBuilder next = current.update(key); if (next == null) break; NodeBuilder next = current.finish(); if (next == null) break; assert current.isRoot(); Object[] r = current.toNode(); current.clear(); return r;
NodeBuilder finish() { assert copyFrom != null; int copyFromKeyEnd = getKeyEnd(copyFrom); if (buildKeyPosition + buildChildPosition > 0) { // only want to copy if we've already changed something, otherwise we'll return the original copyKeys(copyFromKeyEnd); if (!isLeaf(copyFrom)) copyChildren(copyFromKeyEnd + 1); } return isRoot() ? null : ascend(); }
private void ensureRoom(int nextBuildKeyPosition) { if (nextBuildKeyPosition < MAX_KEYS) return; // flush even number of items so we don't waste leaf space repeatedly Object[] flushUp = buildFromRange(0, FAN_FACTOR, isLeaf(copyFrom), true); ensureParent().addExtraChild(flushUp, buildKeys[FAN_FACTOR]); int size = FAN_FACTOR + 1; assert size <= buildKeyPosition : buildKeyPosition + "," + nextBuildKeyPosition; System.arraycopy(buildKeys, size, buildKeys, 0, buildKeyPosition - size); buildKeyPosition -= size; maxBuildKeyPosition = buildKeys.length; if (buildChildPosition > 0) { System.arraycopy(buildChildren, size, buildChildren, 0, buildChildPosition - size); buildChildPosition -= size; } }
NodeBuilder ensureChild() { if (child == null) { child = new NodeBuilder(); child.parent = this; } return child; } }
Object[] toNode() { assert buildKeyPosition <= FAN_FACTOR && (buildKeyPosition > 0 || copyFrom.length > 0) : buildKeyPosition; return buildFromRange(0, buildKeyPosition, isLeaf(copyFrom), false); }
key = next; else if (i == copyFromKeyEnd && compareUpperBound(comparator, key, upperBound) >= 0) owns = false; copyKeys(i); replaceNextKey(key); addNewKey(key); copyKeys(i); copyKeys(i); replaceNextKey(key); copyChildren(i + 1); return null; copyKeys(i); copyChildren(i); ensureChild().reset(descendInto, newUpperBound, updateFunction, comparator); return child; copyKeys(copyFromKeyEnd); copyChildren(copyFromKeyEnd + 1); // since we know that there are exactly 1 more child nodes, than keys return ascend();
NodeBuilder finish() { assert copyFrom != null; int copyFromKeyEnd = getKeyEnd(copyFrom); if (buildKeyPosition + buildChildPosition > 0) { // only want to copy if we've already changed something, otherwise we'll return the original copyKeys(copyFromKeyEnd); if (!isLeaf(copyFrom)) copyChildren(copyFromKeyEnd + 1); } return isRoot() ? null : ascend(); }
private void ensureRoom(int nextBuildKeyPosition) { if (nextBuildKeyPosition < MAX_KEYS) return; // flush even number of items so we don't waste leaf space repeatedly Object[] flushUp = buildFromRange(0, FAN_FACTOR, isLeaf(copyFrom), true); ensureParent().addExtraChild(flushUp, buildKeys[FAN_FACTOR]); int size = FAN_FACTOR + 1; assert size <= buildKeyPosition : buildKeyPosition + "," + nextBuildKeyPosition; System.arraycopy(buildKeys, size, buildKeys, 0, buildKeyPosition - size); buildKeyPosition -= size; maxBuildKeyPosition = buildKeys.length; if (buildChildPosition > 0) { System.arraycopy(buildChildren, size, buildChildren, 0, buildChildPosition - size); buildChildPosition -= size; } }
NodeBuilder ensureChild() { if (child == null) { child = new NodeBuilder(); child.parent = this; } return child; } }
Object[] toNode() { // we permit building empty trees as some constructions do not know in advance how many items they will contain assert buildKeyPosition <= FAN_FACTOR : buildKeyPosition; return buildFromRange(0, buildKeyPosition, isLeaf(copyFrom), false); }
key = next; else if (i == copyFromKeyEnd && compareUpperBound(comparator, key, upperBound) >= 0) owns = false; copyKeys(i); replaceNextKey(key); addNewKey(key); copyKeys(i); copyKeys(i); replaceNextKey(key); copyChildren(i + 1); return null; copyKeys(i); copyChildren(i); ensureChild().reset(descendInto, newUpperBound, updateFunction, comparator); return child; copyKeys(copyFromKeyEnd); copyChildren(copyFromKeyEnd + 1); // since we know that there are exactly 1 more child nodes, than keys return ascend();