public void MoveLastHalfInto(TreeBranch dest) { int midpoint = children.Length / 2; // Check mutable CheckReadOnly(); dest.CheckReadOnly(); // Check this is full if (!IsFull) { throw new InvalidOperationException("Branch node is not full."); } // Check destination is empty if (!dest.IsEmpty) { throw new ArgumentException("Destination branch node is not empty."); } // Copy, Array.Copy(children, midpoint + 1, dest.children, 0, midpoint - 1); // New child count in each branch node. int newChildCount = MaxChildCount / 2; // Set the size of this and the destination node childrenCount = newChildCount; dest.childrenCount = newChildCount; }
public Key MergeLeft(TreeBranch right, Key midValue, int count) { // Check mutable CheckReadOnly(); // If we moving all from right, if (count == right.ChildCount) { // Move all the elements into this node, int destP = childrenCount * 5; int rightLen = (right.childrenCount * 5) - 2; Array.Copy(right.children, 0, children, destP, rightLen); children[destP - 2] = midValue.GetEncoded(1); children[destP - 1] = midValue.GetEncoded(2); // Update children_count childrenCount += right.childrenCount; return(null); } if (count < right.ChildCount) { right.CheckReadOnly(); // Shift elements from right to left // The amount to move that will leave the right node at min threshold int destP = ChildCount * 5; int rightLen = (count * 5) - 2; Array.Copy(right.children, 0, children, destP, rightLen); // Redistribute the right elements int rightRedist = (count * 5); // The midpoint value becomes the extent shifted off the end long newMidpointValue1 = right.children[rightRedist - 2]; long newMidpointValue2 = right.children[rightRedist - 1]; // Shift the right child Array.Copy(right.children, rightRedist, right.children, 0, right.children.Length - rightRedist); children[destP - 2] = midValue.GetEncoded(1); children[destP - 1] = midValue.GetEncoded(2); childrenCount += count; right.childrenCount -= count; // Return the new midpoint value return(new Key(newMidpointValue1, newMidpointValue2)); } throw new ApplicationException("count > right.size()"); }
public void MoveLastHalfInto(TreeBranch dest) { int midpoint = children.Length / 2; CheckReadOnly(); dest.CheckReadOnly(); // Check this is full if (!IsFull) throw new ApplicationException("Branch node is not full."); // Check destination is empty if (dest.ChildCount != 0) throw new ApplicationException("Destination branch node is not empty."); // Copy, Array.Copy(children, midpoint + 1, dest.children, 0, midpoint - 1); // New child count in each branch node. int new_child_count = MaxSize / 2; // Set the size of this and the destination node childCount = new_child_count; dest.childCount = new_child_count; }
public Key MergeLeft(TreeBranch right, Key mid_value, int count) { // Check mutable CheckReadOnly(); // If we moving all from right, if (count == right.ChildCount) { // Move all the elements into this node, int dest_p = childCount * 4; int right_len = (right.childCount * 4) - 2; Array.Copy(right.children, 0, children, dest_p, right_len); children[dest_p - 2] = mid_value.GetEncoded(1); children[dest_p - 1] = mid_value.GetEncoded(2); // Update children_count childCount += right.childCount; return null; } if (count < right.ChildCount) { right.CheckReadOnly(); // Shift elements from right to left // The amount to move that will leave the right node at min threshold int dest_p = ChildCount * 4; int right_len = (count * 4) - 2; Array.Copy(right.children, 0, children, dest_p, right_len); // Redistribute the right elements int right_redist = (count * 4); // The midpoint value becomes the extent shifted off the end long new_midpoint_value1 = right.children[right_redist - 2]; long new_midpoint_value2 = right.children[right_redist - 1]; // Shift the right child Array.Copy(right.children, right_redist, right.children, 0, right.children.Length - right_redist); children[dest_p - 2] = mid_value.GetEncoded(1); children[dest_p - 1] = mid_value.GetEncoded(2); childCount += count; right.childCount -= count; // Return the new midpoint value return new Key(new_midpoint_value1, new_midpoint_value2); } throw new ArgumentException("count > right.size()"); }
public Key Merge(TreeBranch right, Key midValue) { CheckReadOnly(); right.CheckReadOnly(); // How many elements in total? int total_elements = ChildCount + right.ChildCount; // If total elements is smaller than max size, if (total_elements <= MaxSize) { // Move all the elements into this node, int dest_p = childCount * 4; int right_len = (right.childCount * 4) - 2; Array.Copy(right.children, 0, children, dest_p, right_len); children[dest_p - 2] = midValue.GetEncoded(1); children[dest_p - 1] = midValue.GetEncoded(2); // Update children_count childCount += right.childCount; right.childCount = 0; return null; } else { long new_midpoint_value1, new_midpoint_value2; // Otherwise distribute between the nodes, int max_shift = (MaxSize + right.MaxSize) - total_elements; if (max_shift <= 2) { return midValue; } int min_threshold = MaxSize / 2; // final int half_total_elements = total_elements / 2; if (ChildCount < right.ChildCount) { // Shift elements from right to left // The amount to move that will leave the right node at min threshold int count = Math.Min(right.ChildCount - min_threshold, max_shift); int dest_p = ChildCount * 4; int right_len = (count * 4) - 2; Array.Copy(right.children, 0, children, dest_p, right_len); // Redistribute the right elements int right_redist = (count * 4); // The midpoint value becomes the extent shifted off the end new_midpoint_value1 = right.children[right_redist - 2]; new_midpoint_value2 = right.children[right_redist - 1]; // Shift the right child Array.Copy(right.children, right_redist, right.children, 0, right.children.Length - right_redist); children[dest_p - 2] = midValue.GetEncoded(1); children[dest_p - 1] = midValue.GetEncoded(2); childCount += count; right.childCount -= count; } else { // Shift elements from left to right // The amount to move that will leave the left node at min threshold int count = Math.Min(MaxSize - min_threshold, max_shift); // int count = Math.min(half_total_elements - right.size(), max_shift); // Make room for these elements int right_redist = (count * 4); Array.Copy(right.children, 0, right.children, right_redist, right.children.Length - right_redist); int src_p = (ChildCount - count) * 4; int left_len = (count * 4) - 2; Array.Copy(children, src_p, right.children, 0, left_len); right.children[right_redist - 2] = midValue.GetEncoded(1); right.children[right_redist - 1] = midValue.GetEncoded(2); // The midpoint value becomes the extent shifted off the end new_midpoint_value1 = children[src_p - 2]; new_midpoint_value2 = children[src_p - 1]; // Update children counts childCount -= count; right.childCount += count; } return new Key(new_midpoint_value1, new_midpoint_value2); } }
public void MoveLastHalfInto(TreeBranch dest) { int midpoint = children.Length/2; // Check mutable CheckReadOnly(); dest.CheckReadOnly(); // Check this is full if (!IsFull) throw new InvalidOperationException("Branch node is not full."); // Check destination is empty if (!dest.IsEmpty) throw new ArgumentException("Destination branch node is not empty."); // Copy, Array.Copy(children, midpoint + 1, dest.children, 0, midpoint - 1); // New child count in each branch node. int newChildCount = MaxChildCount/2; // Set the size of this and the destination node childrenCount = newChildCount; dest.childrenCount = newChildCount; }
public Key Merge(TreeBranch right, Key midValue) { // Check mutable CheckReadOnly(); right.CheckReadOnly(); // How many elements in total? int totalElements = ChildCount + right.ChildCount; // If total elements is smaller than max size, if (totalElements <= MaxChildCount) { // Move all the elements into this node, int destP = childrenCount*5; int rightLen = (right.childrenCount*5) - 2; Array.Copy(right.children, 0, children, destP, rightLen); children[destP - 2] = midValue.GetEncoded(1); children[destP - 1] = midValue.GetEncoded(2); // Update children_count childrenCount += right.childrenCount; right.childrenCount = 0; return null; } else { long newMidpointValue1, newMidpointValue2; // Otherwise distribute between the nodes, int maxShift = (MaxChildCount + right.MaxChildCount) - totalElements; if (maxShift <= 2) return midValue; int minThreshold = MaxChildCount/2; if (ChildCount < right.ChildCount) { // Shift elements from right to left // The amount to move that will leave the right node at min threshold int count = Math.Min(right.ChildCount - minThreshold, maxShift); int destP = ChildCount*5; int rightLen = (count*5) - 2; Array.Copy(right.children, 0, children, destP, rightLen); // Redistribute the right elements int rightRedist = (count*5); // The midpoint value becomes the extent shifted off the end newMidpointValue1 = right.children[rightRedist - 2]; newMidpointValue2 = right.children[rightRedist - 1]; // Shift the right child Array.Copy(right.children, rightRedist, right.children, 0, right.children.Length - rightRedist); children[destP - 2] = midValue.GetEncoded(1); children[destP - 1] = midValue.GetEncoded(2); childrenCount += count; right.childrenCount -= count; } else { // Shift elements from left to right // The amount to move that will leave the left node at min threshold int count = Math.Min(ChildCount - minThreshold, maxShift); // Make room for these elements int rightRedist = (count*5); Array.Copy(right.children, 0, right.children, rightRedist, right.children.Length - rightRedist); int srcP = (ChildCount - count)*5; int leftLen = (count*5) - 2; Array.Copy(children, srcP, right.children, 0, leftLen); right.children[rightRedist - 2] = midValue.GetEncoded(1); right.children[rightRedist - 1] = midValue.GetEncoded(2); // The midpoint value becomes the extent shifted off the end newMidpointValue1 = children[srcP - 2]; newMidpointValue2 = children[srcP - 1]; // Update children counts childrenCount -= count; right.childrenCount += count; } return new Key(newMidpointValue1, newMidpointValue2); } }
public Key Merge(TreeBranch right, Key midValue) { // Check mutable CheckReadOnly(); right.CheckReadOnly(); // How many elements in total? int totalElements = ChildCount + right.ChildCount; // If total elements is smaller than max size, if (totalElements <= MaxChildCount) { // Move all the elements into this node, int destP = childrenCount * 5; int rightLen = (right.childrenCount * 5) - 2; Array.Copy(right.children, 0, children, destP, rightLen); children[destP - 2] = midValue.GetEncoded(1); children[destP - 1] = midValue.GetEncoded(2); // Update children_count childrenCount += right.childrenCount; right.childrenCount = 0; return(null); } else { long newMidpointValue1, newMidpointValue2; // Otherwise distribute between the nodes, int maxShift = (MaxChildCount + right.MaxChildCount) - totalElements; if (maxShift <= 2) { return(midValue); } int minThreshold = MaxChildCount / 2; if (ChildCount < right.ChildCount) { // Shift elements from right to left // The amount to move that will leave the right node at min threshold int count = Math.Min(right.ChildCount - minThreshold, maxShift); int destP = ChildCount * 5; int rightLen = (count * 5) - 2; Array.Copy(right.children, 0, children, destP, rightLen); // Redistribute the right elements int rightRedist = (count * 5); // The midpoint value becomes the extent shifted off the end newMidpointValue1 = right.children[rightRedist - 2]; newMidpointValue2 = right.children[rightRedist - 1]; // Shift the right child Array.Copy(right.children, rightRedist, right.children, 0, right.children.Length - rightRedist); children[destP - 2] = midValue.GetEncoded(1); children[destP - 1] = midValue.GetEncoded(2); childrenCount += count; right.childrenCount -= count; } else { // Shift elements from left to right // The amount to move that will leave the left node at min threshold int count = Math.Min(ChildCount - minThreshold, maxShift); // Make room for these elements int rightRedist = (count * 5); Array.Copy(right.children, 0, right.children, rightRedist, right.children.Length - rightRedist); int srcP = (ChildCount - count) * 5; int leftLen = (count * 5) - 2; Array.Copy(children, srcP, right.children, 0, leftLen); right.children[rightRedist - 2] = midValue.GetEncoded(1); right.children[rightRedist - 1] = midValue.GetEncoded(2); // The midpoint value becomes the extent shifted off the end newMidpointValue1 = children[srcP - 2]; newMidpointValue2 = children[srcP - 1]; // Update children counts childrenCount -= count; right.childrenCount += count; } return(new Key(newMidpointValue1, newMidpointValue2)); } }