BTNode getChild(int index) throws IndexException { if (0 <= index && index < BTree.this.maxChildren) { long child = BTree.this.getChild(this.chunk, this.node, index); if (child != 0) return new BTNode(child); } return null; }
BTNode getChild(int index) throws IndexException { if (0 <= index && index < BTree.this.maxChildren) { long child = BTree.this.getChild(this.chunk, this.node, index); if (child != 0) return new BTNode(child); } return null; }
if (getChild(BTree.this.db.getChunk(node), node, i) != 0) { childCount++;
if (getChild(BTree.this.db.getChunk(node), node, i) != 0) { childCount++;
private void deallocateChildren(long record) { Chunk chunk = this.db.getChunk(record); // Copy all the children pointers to an array of longs so all the reads will happen on the same chunk // consecutively long[] children = new long[this.maxRecords + 1]; for (int idx = 0; idx < children.length; idx++) { children[idx] = getChild(chunk, record, idx); } this.db.free(record, Database.POOL_BTREE); chunk = null; for (long nextChild : children) { if (nextChild != 0) { deallocateChildren(nextChild); } } }
private void deallocateChildren(long record) { Chunk chunk = this.db.getChunk(record); // Copy all the children pointers to an array of longs so all the reads will happen on the same chunk // consecutively long[] children = new long[this.maxRecords + 1]; for (int idx = 0; idx < children.length; idx++) { children[idx] = getChild(chunk, record, idx); } this.db.free(record, Database.POOL_BTREE); chunk = null; for (long nextChild : children) { if (nextChild != 0) { deallocateChildren(nextChild); } } }
/** * Delete a section of node content - (key, (predecessor)child) pairs. Bounds checking * is not performed. To allow deletion of the final child (which has no corresponding key) * the routine behaves as though there were a corresponding key existing with value zero.<p> * Content is deleted and remaining content is moved leftward the appropriate amount. * @param node the node to delete content from * @param i the start index (inclusive) to delete from * @param length the length of the sequence to delete */ private void nodeContentDelete(BTNode node, int i, int length) { for (int index= i; index <= this.maxRecords; index++) { long newKey = (index + length) < node.keyCount ? getRecord(node.chunk, node.node, index + length) : 0; long newChild = (index + length) < node.keyCount + 1 ? getChild(node.chunk, node.node, index + length) : 0; if (index < this.maxRecords) { putRecord(node.chunk, node.node, index, newKey); } if (index < this.maxChildren) { putChild(node.chunk, node.node, index, newChild); } } }
/** * Delete a section of node content - (key, (predecessor)child) pairs. Bounds checking * is not performed. To allow deletion of the final child (which has no corresponding key) * the routine behaves as though there were a corresponding key existing with value zero.<p> * Content is deleted and remaining content is moved leftward the appropriate amount. * @param node the node to delete content from * @param i the start index (inclusive) to delete from * @param length the length of the sequence to delete */ private void nodeContentDelete(BTNode node, int i, int length) { for (int index= i; index <= this.maxRecords; index++) { long newKey = (index + length) < node.keyCount ? getRecord(node.chunk, node.node, index + length) : 0; long newChild = (index + length) < node.keyCount + 1 ? getChild(node.chunk, node.node, index + length) : 0; if (index < this.maxRecords) { putRecord(node.chunk, node.node, index, newKey); } if (index < this.maxChildren) { putChild(node.chunk, node.node, index, newChild); } } }
/** * Overwrite a section of the specified node (dst) with the specified section of the source * node. Bounds checking is not performed. To allow just copying of the final child (which has * no corresponding key) the routine behaves as though there were a corresponding key existing * with value zero.<p> * Copying from a node to itself is permitted. * @param src the node to read from * @param srcPos the initial index to read from (inclusive) * @param dst the node to write to * @param dstPos the initial index to write to (inclusive) * @param length the number of (key,(predecessor)child) nodes to write */ private void nodeContentCopy(BTNode src, int srcPos, BTNode dst, int dstPos, int length) { for (int i=length - 1; i >= 0; i--) { // this order is important when src == dst! int srcIndex = srcPos + i; int dstIndex = dstPos + i; if (srcIndex < src.keyCount + 1) { long srcChild = getChild(src.chunk, src.node, srcIndex); putChild(dst.chunk, dst.node, dstIndex, srcChild); if (srcIndex < src.keyCount) { long srcKey = getRecord(src.chunk, src.node, srcIndex); putRecord(dst.chunk, dst.node, dstIndex, srcKey); } } } }
/** * Overwrite a section of the specified node (dst) with the specified section of the source * node. Bounds checking is not performed. To allow just copying of the final child (which has * no corresponding key) the routine behaves as though there were a corresponding key existing * with value zero.<p> * Copying from a node to itself is permitted. * @param src the node to read from * @param srcPos the initial index to read from (inclusive) * @param dst the node to write to * @param dstPos the initial index to write to (inclusive) * @param length the number of (key,(predecessor)child) nodes to write */ private void nodeContentCopy(BTNode src, int srcPos, BTNode dst, int dstPos, int length) { for (int i=length - 1; i >= 0; i--) { // this order is important when src == dst! int srcIndex = srcPos + i; int dstIndex = dstPos + i; if (srcIndex < src.keyCount + 1) { long srcChild = getChild(src.chunk, src.node, srcIndex); putChild(dst.chunk, dst.node, dstIndex, srcChild); if (srcIndex < src.keyCount) { long srcKey = getRecord(src.chunk, src.node, srcIndex); putRecord(dst.chunk, dst.node, dstIndex, srcKey); } } } }
putRecord(dst.chunk, dst.node, dst.keyCount, midKey); long keySucc = kIndex + 1 == this.maxRecords ? 0 : getRecord(keyProvider.chunk, keyProvider.node, kIndex + 1); this.db.free(getChild(keyProvider.chunk, keyProvider.node, kIndex + 1), Database.POOL_BTREE); nodeContentDelete(keyProvider, kIndex + 1, 1); putRecord(keyProvider.chunk, keyProvider.node, kIndex, keySucc);
putRecord(dst.chunk, dst.node, dst.keyCount, midKey); long keySucc = kIndex + 1 == this.maxRecords ? 0 : getRecord(keyProvider.chunk, keyProvider.node, kIndex + 1); this.db.free(getChild(keyProvider.chunk, keyProvider.node, kIndex + 1), Database.POOL_BTREE); nodeContentDelete(keyProvider, kIndex + 1, 1); putRecord(keyProvider.chunk, keyProvider.node, kIndex, keySucc);
putRecord(newchunk, newnode, i, getRecord(chunk, node, this.medianRecord + 1 + i)); putRecord(chunk, node, this.medianRecord + 1 + i, 0); putChild(newchunk, newnode, i, getChild(chunk, node, this.medianRecord + 1 + i)); putChild(chunk, node, this.medianRecord + 1 + i, 0); putChild(newchunk, newnode, this.medianRecord, getChild(chunk, node, this.maxRecords)); putChild(chunk, node, this.maxRecords, 0); putChild(pChunk, parent, i + 2, getChild(pChunk, parent, i + 1)); long child = getChild(chunk, node, i); if (child != 0) {
if (getChild(node.chunk, node.node, 0) == 0) { append(child, rightKey, getChild(sibR.chunk, sibR.node, 0)); nodeContentDelete(sibR, 0, 1); putRecord(node.chunk, node.node, subtreeIndex, leftmostRightSiblingKey); prepend(child, leftKey, getChild(sibL.chunk, sibL.node, sibL.keyCount)); long rightmostLeftSiblingKey = getRecord(sibL.chunk, sibL.node, sibL.keyCount - 1); putRecord(sibL.chunk, sibL.node, sibL.keyCount - 1, 0);
putRecord(newchunk, newnode, i, getRecord(chunk, node, this.medianRecord + 1 + i)); putRecord(chunk, node, this.medianRecord + 1 + i, 0); putChild(newchunk, newnode, i, getChild(chunk, node, this.medianRecord + 1 + i)); putChild(chunk, node, this.medianRecord + 1 + i, 0); putChild(newchunk, newnode, this.medianRecord, getChild(chunk, node, this.maxRecords)); putChild(chunk, node, this.maxRecords, 0); putChild(pChunk, parent, i + 2, getChild(pChunk, parent, i + 1)); long child = getChild(chunk, node, i); if (child != 0) {
if (getChild(node.chunk, node.node, 0) == 0) { append(child, rightKey, getChild(sibR.chunk, sibR.node, 0)); nodeContentDelete(sibR, 0, 1); putRecord(node.chunk, node.node, subtreeIndex, leftmostRightSiblingKey); prepend(child, leftKey, getChild(sibL.chunk, sibL.node, sibL.keyCount)); long rightmostLeftSiblingKey = getRecord(sibL.chunk, sibL.node, sibL.keyCount - 1); putRecord(sibL.chunk, sibL.node, sibL.keyCount - 1, 0);