示例#1
0
        private static IEnumerator <T> Enumerate(RopeNode <T> node)
        {
            Stack <RopeNode <T> > stack = new Stack <RopeNode <T> >();

            while (node != null)
            {
                // go to leftmost node, pushing the right parts that we'll have to visit later
                while (node.contents == null)
                {
                    if (node.height == 0)
                    {
                        // go down into function nodes
                        node = node.GetContentNode();
                        continue;
                    }
                    Debug.Assert(node.right != null);
                    stack.Push(node.right);
                    node = node.left;
                }
                // yield contents of leaf node
                for (int i = 0; i < node.length; i++)
                {
                    yield return(node.contents[i]);
                }
                // go up to the next node not visited yet
                if (stack.Count > 0)
                {
                    node = stack.Pop();
                }
                else
                {
                    node = null;
                }
            }
        }
示例#2
0
文件: CharRope.cs 项目: dnGrep/dnGrep
 internal static void WriteTo(this RopeNode <char> node, int index, TextWriter output, int count)
 {
     if (node.height == 0)
     {
         if (node.contents == null)
         {
             // function node
             node.GetContentNode().WriteTo(index, output, count);
         }
         else
         {
             // leaf node: append data
             output.Write(node.contents, index, count);
         }
     }
     else
     {
         // concat node: do recursive calls
         if (index + count <= node.left.length)
         {
             node.left.WriteTo(index, output, count);
         }
         else if (index >= node.left.length)
         {
             node.right.WriteTo(index - node.left.length, output, count);
         }
         else
         {
             int amountInLeft = node.left.length - index;
             node.left.WriteTo(index, output, amountInLeft);
             node.right.WriteTo(0, output, count - amountInLeft);
         }
     }
 }
示例#3
0
 void GoToLeftMostLeaf()
 {
     while (currentNode.contents == null)
     {
         if (currentNode.height == 0)
         {
             // this is a function node - move to its contained rope
             currentNode = currentNode.GetContentNode();
             continue;
         }
         Debug.Assert(currentNode.right != null);
         stack.Push(currentNode.right);
         currentNode = currentNode.left;
     }
     Debug.Assert(currentNode.height == 0);
 }
示例#4
0
 internal override RopeNode <T> GetContentNode()
 {
     lock (this)
     {
         if (this.cachedResults == null)
         {
             if (this.initializer == null)
             {
                 throw new InvalidOperationException("Trying to load this node recursively; or: a previous call to a rope initializer failed.");
             }
             Func <Rope <T> > initializerCopy = this.initializer;
             this.initializer = null;
             Rope <T> resultRope = initializerCopy();
             if (resultRope == null)
             {
                 throw new InvalidOperationException("Rope initializer returned null.");
             }
             RopeNode <T> resultNode = resultRope.root;
             resultNode.Publish(); // result is shared between returned rope and the rope containing this function node
             if (resultNode.length != this.length)
             {
                 throw new InvalidOperationException("Rope initializer returned rope with incorrect length.");
             }
             if (resultNode.height == 0 && resultNode.contents == null)
             {
                 // ResultNode is another function node.
                 // We want to guarantee that GetContentNode() never returns function nodes, so we have to
                 // go down further in the tree.
                 this.cachedResults = resultNode.GetContentNode();
             }
             else
             {
                 this.cachedResults = resultNode;
             }
         }
         return(this.cachedResults);
     }
 }