Exemplo n.º 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));
        }
Exemplo n.º 2
0
 public ContextIntervalTree(IIntervalIntrospector <T> introspector)
     : base(introspector, values: null)
 {
     _edgeExclusivePredicate = ContainsEdgeExclusive;
     _edgeInclusivePredicate = ContainsEdgeInclusive;
     _containPredicate       = (value, start, end) => Contains(value, start, end, Introspector);
 }
Exemplo n.º 3
0
 public IntervalTree(IIntervalIntrospector <T> introspector, IEnumerable <T> values)
 {
     foreach (var value in values)
     {
         root = Insert(root, new Node(value), introspector);
     }
 }
Exemplo n.º 4
0
            internal void SetLeftRight(Node left, Node right, IIntervalIntrospector <T> introspector)
            {
                this.Left  = left;
                this.Right = right;

                this.Height = 1 + Math.Max(Height(left), Height(right));

                // We now must store the node that produces the maximum end. Since we might have tracking spans (or
                // something similar) defining our values of "end", we can't store the int itself.
                var thisEndValue  = GetEnd(this.Value, introspector);
                var leftEndValue  = MaxEndValue(left, introspector);
                var rightEndValue = MaxEndValue(right, introspector);

                if (thisEndValue >= leftEndValue && thisEndValue >= rightEndValue)
                {
                    MaxEndNode = this;
                }
                else if ((leftEndValue >= rightEndValue) && left != null)
                {
                    MaxEndNode = left.MaxEndNode;
                }
                else if (right != null)
                {
                    MaxEndNode = right.MaxEndNode;
                }
                else
                {
                    Contract.Fail("We have no MaxEndNode? Huh?");
                }
            }
Exemplo n.º 5
0
 public ContextIntervalTree(IIntervalIntrospector <T> introspector)
     : base(introspector)
 {
     this.edgeExclusivePredicate = ContainsEdgeExclusive;
     this.edgeInclusivePredicate = ContainsEdgeInclusive;
     this.containPredicate       = (value, start, end) => Contains(value, start, end, Introspector, skipZeroLengthIntervals: true);
 }
Exemplo n.º 6
0
        private static Node Balance(Node node, IIntervalIntrospector <T> introspector)
        {
            int balanceFactor = BalanceFactor(node);

            if (balanceFactor == -2)
            {
                int rightBalance = BalanceFactor(node.Right);
                if (rightBalance == -1)
                {
                    return(node.LeftRotation(introspector));
                }
                else
                {
                    Contract.Requires(rightBalance == 1);
                    return(node.InnerRightOuterLeftRotation(introspector));
                }
            }
            else if (balanceFactor == 2)
            {
                int leftBalance = BalanceFactor(node.Left);
                if (leftBalance == 1)
                {
                    return(node.RightRotation(introspector));
                }
                else
                {
                    Contract.Requires(leftBalance == -1);
                    return(node.InnerLeftOuterRightRotation(introspector));
                }
            }

            return(node);
        }
Exemplo n.º 7
0
            // Sample:
            //   1                  2
            //  / \              /     \
            // a   2            1       3
            //    / \     =>   / \     / \
            //   b   3        a   b   c   d
            //      / \
            //     c   d
            internal Node LeftRotation(IIntervalIntrospector <T> introspector)
            {
                var oldRight = this.Right;

                this.SetLeftRight(this.Left, this.Right.Left, introspector);
                oldRight.SetLeftRight(this, oldRight.Right, introspector);
                return(oldRight);
            }
Exemplo n.º 8
0
 public IntervalTree(IIntervalIntrospector <T> introspector, IEnumerable <T> values)
     : this(root : null)
 {
     foreach (var value in values)
     {
         root = Insert(root, new Node(introspector, value), introspector, inPlace : true);
     }
 }
        protected SimpleIntervalTree(IIntervalIntrospector <T> introspector, Node root) : base(root)
        {
            if (introspector == null)
            {
                throw new ArgumentNullException("introspector");
            }

            this.introspector = introspector;
        }
Exemplo n.º 10
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);
        }
Exemplo n.º 11
0
            // Sample:
            //     1              1              3
            //    / \            / \          /     \
            //   2   d          3   d        2       1
            //  / \     =>     / \     =>   / \     / \
            // a   3          2   c        a   b   c   d
            //    / \        / \
            //   b   c      a   b
            internal Node InnerLeftOuterRightRotation(IIntervalIntrospector <T> introspector)
            {
                var newTop  = this.Left.Right;
                var oldLeft = this.Left;

                this.SetLeftRight(this.Left.Right.Right, this.Right, introspector);
                oldLeft.SetLeftRight(oldLeft.Left, oldLeft.Right.Left, introspector);
                newTop.SetLeftRight(oldLeft, this, introspector);

                return(newTop);
            }
Exemplo n.º 12
0
        public SimpleIntervalTree(IIntervalIntrospector <T> introspector, IEnumerable <T> values)
        {
            _introspector = introspector;

            if (values != null)
            {
                foreach (var value in values)
                {
                    root = Insert(root, new Node(value), introspector);
                }
            }
        }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
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);
        }
Exemplo n.º 15
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);
        }
Exemplo n.º 16
0
 // Sample:
 //   1                  2
 //  / \              /     \
 // a   2            1       3
 //    / \     =>   / \     / \
 //   b   3        a   b   c   d
 //      / \
 //     c   d
 internal Node LeftRotation(bool inPlace, IIntervalIntrospector <T> introspector)
 {
     if (inPlace)
     {
         var oldRight = this.Right;
         this.SetLeftRight(this.Left, this.Right.Left, introspector);
         oldRight.SetLeftRight(this, oldRight.Right, introspector);
         return(oldRight);
     }
     else
     {
         var newLeft = this.With(
             this.Left,
             this.Right.Left,
             introspector);
         var newRight = this.Right.Right;
         return(this.Right.With(newLeft, newRight, introspector));
     }
 }
Exemplo n.º 17
0
            // Sample:
            //     1              1              3
            //    / \            / \          /     \
            //   2   d          3   d        2       1
            //  / \     =>     / \     =>   / \     / \
            // a   3          2   c        a   b   c   d
            //    / \        / \
            //   b   c      a   b
            internal Node InnerLeftOuterRightRotation(bool inPlace, IIntervalIntrospector <T> introspector)
            {
                if (inPlace)
                {
                    var newTop  = this.Left.Right;
                    var oldLeft = this.Left;

                    this.SetLeftRight(this.Left.Right.Right, this.Right, introspector);
                    oldLeft.SetLeftRight(oldLeft.Left, oldLeft.Right.Left, introspector);
                    newTop.SetLeftRight(oldLeft, this, introspector);

                    return(newTop);
                }
                else
                {
                    var temp = this.With(
                        this.Left.LeftRotation(inPlace, introspector),
                        this.Right,
                        introspector);
                    return(temp.RightRotation(inPlace, introspector));
                }
            }
Exemplo n.º 18
0
 public static SimpleIntervalTree <T> Create <T>(IIntervalIntrospector <T> introspector, params T[] values)
 {
     return(Create(introspector, (IEnumerable <T>)values));
 }
Exemplo n.º 19
0
            internal Node(IIntervalIntrospector <T> introspector, T value, Node left, Node right)
            {
                this.Value = value;

                SetLeftRight(left, right, introspector);
            }
Exemplo n.º 20
0
        protected static Node Insert(Node root, Node newNode, IIntervalIntrospector <T> introspector)
        {
            var newNodeStart = introspector.GetStart(newNode.Value);

            return(Insert(root, newNode, newNodeStart, introspector));
        }
Exemplo n.º 21
0
 public bool IntersectsWith(int position, IIntervalIntrospector <T> introspector)
 {
     return(GetIntersectingIntervals(position, 0, introspector).Any());
 }
Exemplo n.º 22
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));
                    }
                }
            }
        }
Exemplo n.º 23
0
 internal Node With(Node left, Node right, IIntervalIntrospector <T> introspector)
 {
     return(new Node(introspector, this.Value, left, right));
 }
Exemplo n.º 24
0
 internal Node(IIntervalIntrospector <T> introspector, T interval)
     : this(introspector, interval, left : null, right : null)
 {
 }
Exemplo n.º 25
0
 protected static int MaxEndValue(Node node, IIntervalIntrospector <T> arg)
 {
     return(node == null ? 0 : GetEnd(node.MaxEndNode.Value, arg));
 }
Exemplo n.º 26
0
 public SimpleIntervalTree(IIntervalIntrospector <T> introspector) : this(introspector, root : null)
 {
 }
Exemplo n.º 27
0
 public static SimpleIntervalTree <T> Create <T>(IIntervalIntrospector <T> introspector, IEnumerable <T> values = null)
 {
     return(new SimpleIntervalTree <T>(introspector, values));
 }
Exemplo n.º 28
0
 public IEnumerable <T> GetContainingIntervals(int start, int length, IIntervalIntrospector <T> introspector)
 {
     return(this.GetInOrderIntervals(start, length, s_containsTest, introspector));
 }
Exemplo n.º 29
0
 public IEnumerable <T> GetIntersectingIntervals(int start, int length, IIntervalIntrospector <T> introspector)
 {
     return(this.GetInOrderIntervals(start, length, s_intersectsWithTest, introspector));
 }
Exemplo n.º 30
0
 protected static int GetEnd(T value, IIntervalIntrospector <T> introspector)
 {
     return(introspector.GetStart(value) + introspector.GetLength(value));
 }