public static void MergeLeaves(BplusNode left, BplusNode right, out bool DeleteRight) { DeleteRight = false; string[] allkeys = new string[left.Size*2]; long[] allseeks = new long[left.Size*2]; int index = 0; for (int i=0; i<left.Size; i++) { if (left.ChildKeys[i]==null) { break; } allkeys[index] = left.ChildKeys[i]; allseeks[index] = left.ChildBufferNumbers[i]; index++; } for (int i=0; i<right.Size; i++) { if (right.ChildKeys[i]==null) { break; } allkeys[index] = right.ChildKeys[i]; allseeks[index] = right.ChildBufferNumbers[i]; index++; } if (index<=left.Size) { left.Clear(); DeleteRight = true; for (int i=0; i<index; i++) { left.ChildKeys[i] = allkeys[i]; left.ChildBufferNumbers[i] = allseeks[i]; } right.Free(); left.Soil(); return; } left.Clear(); right.Clear(); left.Soil(); right.Soil(); int rightcontent = index/2; int leftcontent = index - rightcontent; int newindex = 0; for (int i=0; i<leftcontent; i++) { left.ChildKeys[i] = allkeys[newindex]; left.ChildBufferNumbers[i] = allseeks[newindex]; newindex++; } for (int i=0; i<rightcontent; i++) { right.ChildKeys[i] = allkeys[newindex]; right.ChildBufferNumbers[i] = allseeks[newindex]; newindex++; } }
public static void Merge(BplusNode left, string KeyBetween, BplusNode right, out string rightLeastKey, out bool DeleteRight) { //System.Diagnostics.Debug.WriteLine("\r\n<br> merging "+right.myBufferNumber+" ("+KeyBetween+") "+left.myBufferNumber); //System.Diagnostics.Debug.WriteLine(left.owner.toHtml()); rightLeastKey = null; // only if DeleteRight if (left.isLeaf || right.isLeaf) { if (!(left.isLeaf&&right.isLeaf)) { throw new BplusTreeException("can't merge leaf with non-leaf"); } MergeLeaves(left, right, out DeleteRight); rightLeastKey = right.ChildKeys[0]; return; } // merge non-leaves DeleteRight = false; string[] allkeys = new string[left.Size*2+1]; long[] allseeks = new long[left.Size*2+2]; BplusNode[] allMaterialized = new BplusNode[left.Size*2+2]; if (left.ChildBufferNumbers[0]==BplusTreeLong.NULLBUFFERNUMBER || right.ChildBufferNumbers[0]==BplusTreeLong.NULLBUFFERNUMBER) { throw new BplusTreeException("cannot merge empty non-leaf with non-leaf"); } int index = 0; allseeks[0] = left.ChildBufferNumbers[0]; allMaterialized[0] = left.MaterializedChildNodes[0]; for (int i=0; i<left.Size; i++) { if (left.ChildKeys[i]==null) { break; } allkeys[index] = left.ChildKeys[i]; allseeks[index+1] = left.ChildBufferNumbers[i+1]; allMaterialized[index+1] = left.MaterializedChildNodes[i+1]; index++; } allkeys[index] = KeyBetween; index++; allseeks[index] = right.ChildBufferNumbers[0]; allMaterialized[index] = right.MaterializedChildNodes[0]; int rightcount = 0; for (int i=0; i<right.Size; i++) { if (right.ChildKeys[i]==null) { break; } allkeys[index] = right.ChildKeys[i]; allseeks[index+1] = right.ChildBufferNumbers[i+1]; allMaterialized[index+1] = right.MaterializedChildNodes[i+1]; index++; rightcount++; } if (index<=left.Size) { // it will all fit in one node //System.Diagnostics.Debug.WriteLine("deciding to forget "+right.myBufferNumber+" into "+left.myBufferNumber); DeleteRight = true; for (int i=0; i<index; i++) { left.ChildKeys[i] = allkeys[i]; left.ChildBufferNumbers[i] = allseeks[i]; left.MaterializedChildNodes[i] = allMaterialized[i]; } left.ChildBufferNumbers[index] = allseeks[index]; left.MaterializedChildNodes[index] = allMaterialized[index]; left.reParentAllChildren(); left.Soil(); right.Free(); return; } // otherwise split the content between the nodes left.Clear(); right.Clear(); left.Soil(); right.Soil(); int leftcontent = index/2; int rightcontent = index-leftcontent-1; rightLeastKey = allkeys[leftcontent]; int outputindex = 0; for (int i=0; i<leftcontent; i++) { left.ChildKeys[i] = allkeys[outputindex]; left.ChildBufferNumbers[i] = allseeks[outputindex]; left.MaterializedChildNodes[i] = allMaterialized[outputindex]; outputindex++; } rightLeastKey = allkeys[outputindex]; left.ChildBufferNumbers[outputindex] = allseeks[outputindex]; left.MaterializedChildNodes[outputindex] = allMaterialized[outputindex]; outputindex++; rightcount = 0; for (int i=0; i<rightcontent; i++) { right.ChildKeys[i] = allkeys[outputindex]; right.ChildBufferNumbers[i] = allseeks[outputindex]; right.MaterializedChildNodes[i] = allMaterialized[outputindex]; outputindex++; rightcount++; } right.ChildBufferNumbers[rightcount] = allseeks[outputindex]; right.MaterializedChildNodes[rightcount] = allMaterialized[outputindex]; left.reParentAllChildren(); right.reParentAllChildren(); }