Example #1
0
        private static Node Insert(Node root, Node newNode, int newNodeStart, IIntervalIntrospector <T> introspector)
        {
            if (root == null)
            {
                return(newNode);
            }

            Node newLeft, newRight;

            if (newNodeStart < introspector.GetStart(root.Value))
            {
                newLeft  = Insert(root.Left, newNode, newNodeStart, introspector);
                newRight = root.Right;
            }
            else
            {
                newLeft  = root.Left;
                newRight = Insert(root.Right, newNode, newNodeStart, introspector);
            }

            root.SetLeftRight(newLeft, newRight, introspector);
            var newRoot = root;

            return(Balance(newRoot, introspector));
        }
Example #2
0
        private static bool IntersectsWith(T value, int start, int length, IIntervalIntrospector <T> introspector)
        {
            var otherStart = start;
            var otherEnd   = start + length;

            var thisEnd   = GetEnd(value, introspector);
            var thisStart = introspector.GetStart(value);

            return(otherStart <= thisEnd && otherEnd >= thisStart);
        }
Example #3
0
        protected static bool Contains(T value, int start, int length, IIntervalIntrospector <T> introspector)
        {
            var otherStart = start;
            var otherEnd   = start + length;

            var thisEnd   = GetEnd(value, introspector);
            var thisStart = introspector.GetStart(value);

            // make sure "Contains" test to be same as what TextSpan does
            if (length == 0)
            {
                return(thisStart <= otherStart && otherEnd < thisEnd);
            }

            return(thisStart <= otherStart && otherEnd <= thisEnd);
        }
Example #4
0
        private static bool IntersectsWith(T value, int start, int length, IIntervalIntrospector <T> introspector, bool skipZeroLengthIntervals)
        {
            var otherStart = start;
            var otherEnd   = start + length;

            var thisEnd   = GetEnd(value, introspector);
            var thisStart = introspector.GetStart(value);

            if (thisStart == thisEnd &&
                skipZeroLengthIntervals)
            {
                return(false);
            }

            return(otherStart <= thisEnd && otherEnd >= thisStart);
        }
Example #5
0
        private static bool OverlapsWith(T value, int start, int length, IIntervalIntrospector <T> introspector)
        {
            var otherStart = start;
            var otherEnd   = start + length;

            var thisEnd   = GetEnd(value, introspector);
            var thisStart = introspector.GetStart(value);

            if (length == 0)
            {
                return(thisStart < otherStart && otherStart < thisEnd);
            }

            int overlapStart = Math.Max(thisStart, otherStart);
            int overlapEnd   = Math.Min(thisEnd, otherEnd);

            return(overlapStart < overlapEnd);
        }
Example #6
0
        private IEnumerable <T> GetPreOrderIntervals(int start, int length, TestInterval testInterval, IIntervalIntrospector <T> introspector, bool skipZeroLengthIntervals)
        {
            if (root == null || GetEnd(root.MaxEndNode.Value, introspector) < start)
            {
                yield break;
            }

            int end        = start + length;
            var candidates = new Stack <Node>();

            candidates.Push(root);
            while (candidates.Count != 0)
            {
                var currentNode = candidates.Pop();

                // right children's starts will never be to the left of the parent's start
                // so we should consider right subtree
                // only if root's start overlaps with interval's End,
                if (introspector.GetStart(currentNode.Value) <= end)
                {
                    var right = currentNode.Right;
                    if (right != null && GetEnd(right.MaxEndNode.Value, introspector) >= start)
                    {
                        candidates.Push(right);
                    }
                }

                // only if left's maxVal overlaps with interval's start,
                // we should consider left subtree
                var left = currentNode.Left;
                if (left != null && GetEnd(left.MaxEndNode.Value, introspector) >= start)
                {
                    candidates.Push(left);
                }

                if (testInterval(currentNode.Value, start, length, introspector, skipZeroLengthIntervals))
                {
                    yield return(currentNode.Value);
                }
            }
        }
Example #7
0
 protected static int GetEnd(T value, IIntervalIntrospector <T> introspector)
 {
     return(introspector.GetStart(value) + introspector.GetLength(value));
 }
Example #8
0
        protected static Node Insert(Node root, Node newNode, IIntervalIntrospector <T> introspector)
        {
            var newNodeStart = introspector.GetStart(newNode.Value);

            return(Insert(root, newNode, newNodeStart, introspector));
        }
Example #9
0
        private IEnumerable <T> GetInOrderIntervals(int start, int length, TestInterval testInterval, IIntervalIntrospector <T> introspector)
        {
            if (root == null)
            {
                yield break;
            }

            var end = start + length;

            // The bool indicates if this is the first time we are seeing the node.
            var candidates = new Stack <ValueTuple <Node, bool> >();

            candidates.Push(ValueTuple.Create(root, true));

            while (candidates.Count > 0)
            {
                var currentTuple = candidates.Pop();
                var currentNode  = currentTuple.Item1;
                Debug.Assert(currentNode != null);

                var firstTime = currentTuple.Item2;

                if (!firstTime)
                {
                    // We're seeing this node for the second time (as we walk back up the left
                    // side of it).  Now see if it matches our test, and if so return it out.
                    if (testInterval(currentNode.Value, start, length, introspector))
                    {
                        yield return(currentNode.Value);
                    }
                }
                else
                {
                    // First time we're seeing this node.  In order to see the node 'in-order',
                    // we push the right side, then the node again, then the left side.  This
                    // time we mark the current node with 'false' to indicate that it's the
                    // second time we're seeing it the next time it comes around.

                    // right children's starts will never be to the left of the parent's start
                    // so we should consider right subtree only if root's start overlaps with
                    // interval's End,
                    if (introspector.GetStart(currentNode.Value) <= end)
                    {
                        var right = currentNode.Right;
                        if (right != null && GetEnd(right.MaxEndNode.Value, introspector) >= start)
                        {
                            candidates.Push(ValueTuple.Create(right, true));
                        }
                    }

                    candidates.Push(ValueTuple.Create(currentNode, false));

                    // only if left's maxVal overlaps with interval's start, we should consider
                    // left subtree
                    var left = currentNode.Left;
                    if (left != null && GetEnd(left.MaxEndNode.Value, introspector) >= start)
                    {
                        candidates.Push(ValueTuple.Create(left, true));
                    }
                }
            }
        }
Example #10
0
        private IList <T> GetInOrderIntervals(int start, int length, TestInterval testInterval, IIntervalIntrospector <T> introspector, bool skipZeroLengthIntervals)
        {
            List <T> result = null;

            if (root != null && GetEnd(root.MaxEndNode.Value, introspector) >= start)
            {
                int end        = start + length;
                var candidates = new Stack <Node>();

                var currentNode = root;
                while (true)
                {
                    if (currentNode != null)
                    {
                        candidates.Push(currentNode);

                        // only if left's maxVal overlaps with interval's start,
                        // we should consider left subtree
                        var left = currentNode.Left;
                        if (left != null && GetEnd(left.MaxEndNode.Value, introspector) >= start)
                        {
                            currentNode = left;
                            continue;
                        }

                        // current node has no meaning now, set it to null
                        currentNode = null;
                    }

                    if (candidates.Count == 0)
                    {
                        break;
                    }

                    currentNode = candidates.Pop();
                    if (testInterval(currentNode.Value, start, length, introspector, skipZeroLengthIntervals))
                    {
                        result = result ?? new List <T>();
                        result.Add(currentNode.Value);
                    }

                    // right children's starts will never be to the left of the parent's start
                    // so we should consider right subtree
                    // only if root's start overlaps with interval's End,
                    if (introspector.GetStart(currentNode.Value) <= end)
                    {
                        var right = currentNode.Right;
                        if (right != null && GetEnd(right.MaxEndNode.Value, introspector) >= start)
                        {
                            currentNode = right;
                            continue;
                        }
                    }

                    // set to null to get new one from stack
                    currentNode = null;
                }
            }

            return(result ?? SpecializedCollections.EmptyList <T>());
        }