Beispiel #1
0
        internal static RopeNode <T> Concat(RopeNode <T> left, RopeNode <T> right)
        {
            if (left.length == 0)
            {
                return(right);
            }
            if (right.length == 0)
            {
                return(left);
            }

            if (left.length + right.length <= NodeSize)
            {
                left = left.CloneIfShared();
                // left is guaranteed to be leaf node after cloning:
                // - it cannot be function node (due to clone)
                // - it cannot be concat node (too short)
                right.CopyTo(0, left.contents, left.length, right.length);
                left.length += right.length;
                return(left);
            }
            else
            {
                RopeNode <T> concatNode = new RopeNode <T>();
                concatNode.left   = left;
                concatNode.right  = right;
                concatNode.length = left.length + right.length;
                concatNode.Rebalance();
                return(concatNode);
            }
        }
Beispiel #2
0
        void MergeIfPossible()
        {
            Debug.Assert(!isShared);

            if (this.length <= NodeSize)
            {
                // Convert this concat node to leaf node.
                // We know left and right cannot be concat nodes (they would have merged already),
                // but they could be function nodes.
                this.height = 0;
                int lengthOnLeftSide = this.left.length;
                if (this.left.isShared)
                {
                    this.contents = new T[NodeSize];
                    left.CopyTo(0, this.contents, 0, lengthOnLeftSide);
                }
                else
                {
                    // must be a leaf node: function nodes are always marked shared
                    Debug.Assert(this.left.contents != null);
                    // steal buffer from left side
                    this.contents = this.left.contents;
                                        #if DEBUG
                    // In debug builds, explicitly mark left node as 'damaged' - but no one else should be using it
                    // because it's not shared.
                    this.left.contents = Empty <T> .Array;
                                        #endif
                }
                this.left = null;
                right.CopyTo(0, this.contents, lengthOnLeftSide, this.right.length);
                this.right = null;
            }
        }
Beispiel #3
0
 /// <summary>
 /// Copies the a part of the rope into the specified array.
 /// Runs in O(lg N + M).
 /// </summary>
 /// <remarks>
 /// This method counts as a read access and may be called concurrently to other read accesses.
 /// </remarks>
 public void CopyTo(int index, T[] array, int arrayIndex, int count)
 {
     VerifyRange(index, count);
     VerifyArrayWithRange(array, arrayIndex, count);
     root.CopyTo(index, array, arrayIndex, count);
 }