internal void SetKeyToLeft(Key key, int childIndex) { CheckReadOnly(); if (childIndex >= ChildCount) { throw new ArgumentOutOfRangeException("childIndex", "Key request out of bounds."); } children[(childIndex * 5) - 2] = key.GetEncoded(1); children[(childIndex * 5) - 1] = key.GetEncoded(2); }
public void Set(NodeId child1, long child1Count, Key key, NodeId child2, long child2Count) { CheckReadOnly(); // Set the values children[0] = child1.High; children[1] = child1.Low; children[2] = child1Count; children[3] = key.GetEncoded(1); children[4] = key.GetEncoded(2); children[5] = child2.High; children[6] = child2.Low; children[7] = child2Count; // Increase the child count. childrenCount += 2; }
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 Insert(NodeId child1, long child1Count, Key key, NodeId child2, long child2Count, int n) { CheckReadOnly(); // Shift the array by 5 int p1 = (n * 5) + 3; int p2 = (n * 5) + 8; Array.Copy(children, p1, children, p2, children.Length - p2); // Insert the values children[p1 - 3] = child1.High; children[p1 - 2] = child1.Low; children[p1 - 1] = child1Count; children[p1 + 0] = key.GetEncoded(1); children[p1 + 1] = key.GetEncoded(2); children[p1 + 2] = child2.High; children[p1 + 3] = child2.Low; children[p1 + 4] = child2Count; // Increase the child count. ++childrenCount; }
internal void SetKeyValueToLeft(Key k, int child_i) { SetKeyValueToLeft(k.GetEncoded(1), k.GetEncoded(2), child_i); }
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); } }
internal void SetKeyToLeft(Key key, int childIndex) { CheckReadOnly(); if (childIndex >= ChildCount) throw new ArgumentOutOfRangeException("childIndex", "Key request out of bounds."); children[(childIndex*5) - 2] = key.GetEncoded(1); children[(childIndex*5) - 1] = key.GetEncoded(2); }
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 void Insert(NodeId child1, long child1Count, Key key, NodeId child2, long child2Count, int n) { CheckReadOnly(); // Shift the array by 5 int p1 = (n*5) + 3; int p2 = (n*5) + 8; Array.Copy(children, p1, children, p2, children.Length - p2); // Insert the values children[p1 - 3] = child1.High; children[p1 - 2] = child1.Low; children[p1 - 1] = child1Count; children[p1 + 0] = key.GetEncoded(1); children[p1 + 1] = key.GetEncoded(2); children[p1 + 2] = child2.High; children[p1 + 3] = child2.Low; children[p1 + 4] = child2Count; // Increase the child count. ++childrenCount; }
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)); } }