Ejemplo n.º 1
0
        public SpanSet <T> Add(Span span, T data)
        {
            if (this.DeleteZeroLengthSpans && (span.Length == 0))
            {
                return(this);
            }

            var newTrees = SpanTree <T> .Add(_trees, 0, span, data);

            return(new SpanSet <T>(this, newTrees));
        }
Ejemplo n.º 2
0
        internal static IEnumerable <SpanAndData <T> > GetSpansIntersecting(IReadOnlyList <SpanTree <T> > trees, Span span, int offset)
        {
            var first = SpanTree <T> .FirstEndIndexOnOrAfterPosition(trees, span.Start - offset);

            var last = SpanTree <T> .LastStartIndexBeforeOrOnPosition(trees, span.End - offset);

            for (int i = first; (i <= last); ++i)
            {
                var child = trees[i];
                if (child.Children.Count == 0)
                {
                    // Handle childless nodes as a special case (avoid the overhead of the foreach below)
                    yield return(new SpanAndData <T>(new Span(child.Span.Start + offset, child.Span.Length), child.Data));
                }
                else
                {
                    foreach (var c in child.GetSpansIntersecting(span, offset))
                    {
                        yield return(c);
                    }
                }
            }
        }
Ejemplo n.º 3
0
        internal static IReadOnlyList <SpanTree <T> > Add(IReadOnlyList <SpanTree <T> > trees, int offset, Span span, T data)
        {
            Assert(span.Start >= offset);
            span = new Span(span.Start - offset, span.Length);

            SpanTree <T>[] newTrees = null;

            var first = FirstStartIndexOnOrAfterPosition(trees, span.Start);

            Assert((first == trees.Count) || (span.Start <= trees[first].Span.Start));
            var last = LastEndIndexBeforeOrOnPosition(trees, first, trees.Count - 1, span.End);

            if (last < first)
            {
                Assert(last + 1 == first);
                // span doesn't contain any existing trees but might be contained by first or last

                if ((first < trees.Count) && (span.Start == trees[first].Span.Start))
                {
                    var tree = trees[first];
                    newTrees        = trees.Copy();
                    newTrees[first] = new SpanTree <T>(tree,
                                                       Add(tree.Children, tree.Span.Start,
                                                           span, data));
                }
                else if ((last >= 0) && (span.Start >= trees[last].Span.Start) && (span.End <= trees[last].Span.End))
                {
                    var tree = trees[last];
                    newTrees       = trees.Copy();
                    newTrees[last] = new SpanTree <T>(tree,
                                                      Add(tree.Children, tree.Span.Start,
                                                          span, data));
                }
                else
                {
                    newTrees = trees.InsertAt(first, new SpanTree <T>(span, data));
                }
            }
            else
            {
                Assert(span.End >= trees[last].Span.End);

                // trees [first ... last] are contained by the new span.
                // copy those nodes to a sublist which will become the children of the new span.
                var newChildren = new SpanTree <T> [1 + last - first];
                for (int i = first; (i <= last); ++i)
                {
                    var newChild = trees[i];
                    newChildren[i - first] = (span.Start == 0)
                                                ? newChild
                                                : new SpanTree <T>(new Span(newChild.Span.Start - span.Start, newChild.Span.Length), newChild.Data, newChild.Children);
                }

                var newTree = new SpanTree <T>(span, data, newChildren);

                newTrees = new SpanTree <T> [trees.Count - (last - first)];
                trees.CopyTo(0, newTrees, 0, first);
                newTrees[first] = newTree;
                trees.CopyTo(last + 1, newTrees, first + 1, trees.Count - (last + 1));
            }

            return(newTrees);
        }
Ejemplo n.º 4
0
 protected SpanTree(SpanTree <T> spanTree, IReadOnlyList <SpanTree <T> > children)
     : this(spanTree.Span, spanTree.Data, children)
 {
 }
Ejemplo n.º 5
0
 internal bool IsValid(int length)
 {
     return(SpanTree <T> .IsValid(_trees, length));
 }
Ejemplo n.º 6
0
 public IEnumerable <SpanAndData <T> > GetSpansIntersecting(Span span)
 {
     return(SpanTree <T> .GetSpansIntersecting(_trees, span, 0));
 }
Ejemplo n.º 7
0
 public IEnumerable <SpanAndData <T> > GetAllSpans()
 {
     return(SpanTree <T> .GetAllSpans(_trees, 0));
 }