Ejemplo n.º 1
0
 internal void InnerReplace(RopeNode node, Int32 offset, T[] array, Int32 arrayIndex, Int32 length)
 {
     // 有bug 有空修复 todo
     if (length <= 0)
     {
         return;
     }
     if (node.IsLeaf)
     {
         node.GenerateContentsIfRequired();
         Array.Copy(array, arrayIndex, node._contents, offset, length);
     }
     else
     {
         if (offset < node.Left.Length)
         {
             Int32 leftSize = Math.Min(length, node.Left.Length - offset);
             InnerReplace(node.Left, offset, array, arrayIndex, leftSize);
             if (node.Left.Length < offset + length)
             {
                 Int32 rightSize = offset + length - node.Left.Length;
                 InnerReplace(node.Right, 0, array, arrayIndex + leftSize, rightSize);
             }
         }
         else
         {
             offset -= node.Left.Length;
             InnerReplace(node.Right, offset, array, arrayIndex, length);
         }
     }
 }
Ejemplo n.º 2
0
            internal RopeNode Clone()
            {
                var ret = new RopeNode();

                if (Parent != null)
                {
                    ret.Parent = Parent.Clone();
                }
                if (Left != null)
                {
                    ret.Left = Left.Clone();
                }
                if (Right != null)
                {
                    ret.Right = Right.Clone();
                }
                ret.Length = Length;
                ret.Height = Height;
                if (_contents != null)
                {
                    ret.GenerateContentsIfRequired();
                    Array.Copy(_contents, ret._contents, Length);
                }
                return(ret);
            }
Ejemplo n.º 3
0
        internal void InnerInsert(RopeNode node, Int32 offset, T[] array, Int32 arrayIndex, Int32 length)
        {
            if (length <= 0)
            {
                return;
            }
            if (node.IsLeaf && node.Length + length < RopeNode.NODE_SIZE)
            {
                // 一定为叶子节点
                node.GenerateContentsIfRequired();
                // 先数据后移
                for (int i = node.Length - 1; i >= offset; i--)
                {
                    node._contents[i + length] = node._contents[i];
                }
                // 再拷贝数据
                Array.Copy(array, arrayIndex, node._contents, offset, length);
                node.Length += length;
            }
            else if (node.IsLeaf)
            {
                // 叶子节点,且当前叶子节点存储不下的情况
                node.GenerateContentsIfRequired();

                /* 假设当前节点为A,创建新节点B,并创建新节点C,将B和A分别作为C的左右孩子,C节点替代A节点的位置
                 *       A                     C
                 *                ===>        / \
                 *                           B   A
                 */
                var a = node;
                var b = new RopeNode();
                b.GenerateContentsIfRequired();
                var c = new RopeNode();
                if (a.Parent != null)
                {
                    if (a.IsLeft)
                    {
                        a.Parent.Left = c;
                    }
                    else
                    {
                        a.Parent.Right = c;
                    }
                    c.Parent = a.Parent;
                }
                else
                {
                    _root = c;
                }
                c.Left   = b;
                b.Parent = c;
                c.Right  = a;
                a.Parent = c;
                // 将[0, offset)拷贝到左节点
                Int32 distributeLeft = offset;
                if (distributeLeft > 0)
                {
                    Array.Copy(a._contents, 0, b._contents, 0, distributeLeft);
                    // 将a后面的节点往前移动
                    for (int i = distributeLeft; i < a.Length; i++)
                    {
                        a._contents[i - distributeLeft] = a._contents[i];
                    }
                    a.Length -= distributeLeft;
                }
                Int32 rest = Math.Min(length, RopeNode.NODE_SIZE - distributeLeft);
                Array.Copy(array, arrayIndex, b._contents, distributeLeft, rest);
                b.Length    = distributeLeft + rest;
                arrayIndex += rest;
                length     -= rest;
                offset      = 0;
                InnerInsert(node, offset, array, arrayIndex, length);
                // 自平衡
                Rebalance(c);
            }
            else
            {
                node.Length += length;
                // 非叶子节点不存储数据,只用来二分
                if (offset < node.Left.Length)
                {
                    InnerInsert(node.Left, offset, array, arrayIndex, length);
                }
                else
                {
                    offset -= node.Left.Length;
                    InnerInsert(node.Right, offset, array, arrayIndex, length);
                }
                // 只有非叶子节点才需要重新平衡
                Rebalance(node);
            }
        }