Example #1
0
        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;
        }
Example #2
0
        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()");
        }
Example #3
0
        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;
        }
Example #4
0
        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()");
        }
Example #5
0
        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);
            }
        }
Example #6
0
        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;
        }
Example #7
0
        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);
            }
        }
Example #8
0
        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));
            }
        }