public override IMemTreeNode Free(int offset, int blocks) { if (leftChild.LastBlock > offset) // is this offset contained in the left subtree? { leftChild = leftChild.Free(offset, blocks); contiguousBlocks = (leftChild.ContiguousBlocks < rightChild.ContiguousBlocks) ? rightChild.ContiguousBlocks : leftChild.ContiguousBlocks; if (leftChild.LastBlock + 1 == rightChild.FirstBlock) { // left and right nodes have become contiguous, so merge them return(Merge()); } return(this); } else if (rightChild.FirstBlock < offset) //is this offset contained in the right subtree? { rightChild = rightChild.Free(offset, blocks); contiguousBlocks = (leftChild.ContiguousBlocks < rightChild.ContiguousBlocks) ? rightChild.ContiguousBlocks : leftChild.ContiguousBlocks; if (leftChild.LastBlock + 1 == rightChild.FirstBlock) { // left and right nodes have become contiguous, so merge them return(Merge()); } return(this); } else { // oh crap, not in either of them. Guess we'll have to handle this ourselves. // does the block to free lie adjacent ot the leftchild or rightchild? bool leftAdjacent, rightAdjacent; leftAdjacent = (offset - 1 == leftChild.LastBlock); rightAdjacent = (offset + blocks == rightChild.FirstBlock); if (leftAdjacent) { if (rightAdjacent) { // Adjacent to both right and left, so merge them into one. return(Merge()); } else { // Adjacent to left only, expand left leftChild.ExpandRightLeaf(blocks); contiguousBlocks = (leftChild.ContiguousBlocks < rightChild.ContiguousBlocks) ? rightChild.ContiguousBlocks : leftChild.ContiguousBlocks; return(this); } } else if (rightAdjacent) { // adjacent to right only, expand right; rightChild.ExpandLeftLeaf(blocks); contiguousBlocks = (leftChild.ContiguousBlocks < rightChild.ContiguousBlocks) ? rightChild.ContiguousBlocks : leftChild.ContiguousBlocks; return(this); } else { // adjacent to nothing, create new contentnode for the freed space, and a new index node to contain it. ContentNode newContentNode = new ContentNode() { FirstBlock = offset, LastBlock = offset + blocks - 1 }; IndexNode newIndexNode = null; if (IMemTreeNode.MergeDirection) { newIndexNode = new IndexNode(newContentNode, rightChild); // merging it into right subtree return(new IndexNode(leftChild, newIndexNode)); } else { newIndexNode = new IndexNode(leftChild, newContentNode); // merging it into left subtree return(new IndexNode(newIndexNode, rightChild)); } } } }
public override IMemTreeNode ExpandRightLeaf(int blocks) { rightChild.ExpandRightLeaf(blocks); contiguousBlocks = (leftChild.ContiguousBlocks < rightChild.ContiguousBlocks) ? rightChild.ContiguousBlocks : leftChild.ContiguousBlocks; return(this); }