Пример #1
0
        List <IntervalNode> PerformStabbingQuery(IntervalNode node, IInterval <TPoint> interval)
        {
            var result = new List <IntervalNode>();

            PerformStabbingQuery(node, interval, result);
            return(result);
        }
Пример #2
0
        void PerformStabbingQuery(IntervalNode node, IInterval <TPoint> interval, List <IntervalNode> result)
        {
            if (node == null)
            {
                return;
            }

            if (interval.Start.CompareTo(node.MaxEndPoint) > 0)
            {
                return;
            }

            if (node.Left != null)
            {
                PerformStabbingQuery(node.Left, interval, result);
            }

            if (DoIntervalsOverlap(node, interval))
            {
                result.Add(node);
            }

            if (interval.End.CompareTo(node.Start) < 0)
            {
                return;
            }

            if (node.Right != null)
            {
                PerformStabbingQuery(node.Right, interval, result);
            }
        }
Пример #3
0
        void PerformStabbingQuery(IntervalNode node, TPoint point, List <IntervalNode> result)
        {
            if (node == null)
            {
                return;
            }

            if (point.CompareTo(node.MaxEndPoint) > 0)
            {
                return;
            }

            if (node.Left != null)
            {
                PerformStabbingQuery(node.Left, point, result);
            }

            if (DoesIntervalContain(node, point))
            {
                result.Add(node);
            }

            if (point.CompareTo(node.Start) < 0)
            {
                return;
            }

            if (node.Right != null)
            {
                PerformStabbingQuery(node.Right, point, result);
            }
        }
Пример #4
0
        /// <summary>
        /// Adds the given item to the collection.
        /// </summary>
        /// <param name="item"></param>
        public void Add(TInterval item)
        {
            if (ReferenceEquals(item, null))
            {
                throw new ArgumentNullException("item");
            }

            var newNode = new IntervalNode(item);

            if (root == null)
            {
                SetRoot(newNode);
                Count = 1;
                modifications++;
                return;
            }

            IntervalNode node = root;

            while (true)
            {
                var startCmp = newNode.Start.CompareTo(node.Start);
                if (startCmp <= 0)
                {
                    if (startCmp == 0 && ReferenceEquals(node.Interval, newNode.Interval))
                    {
                        throw new InvalidOperationException("Cannot add the same item twice (object reference already exists in db)");
                    }

                    if (node.Left == null)
                    {
                        node.Left = newNode;
                        break;
                    }
                    node = node.Left;
                }
                else
                {
                    if (node.Right == null)
                    {
                        node.Right = newNode;
                        break;
                    }
                    node = node.Right;
                }
            }

            modifications++;
            Count++;

            // Restructure tree to be balanced
            node = newNode;
            while (node != null)
            {
                node.UpdateHeight();
                node.UpdateMaxEndPoint();
                Rebalance(node);
                node = node.Parent;
            }
        }
Пример #5
0
        void RotateRight(IntervalNode node)
        {
            var parent          = node.Parent;
            var isNodeLeftChild = node.IsLeftChild;

            // Make node.Left the new root of this sub tree (instead of node)
            var pivotNode = node.Left;

            node.Left       = pivotNode.Right;
            pivotNode.Right = node;

            if (parent != null)
            {
                if (isNodeLeftChild)
                {
                    parent.Left = pivotNode;
                }
                else
                {
                    parent.Right = pivotNode;
                }
            }
            else
            {
                SetRoot(pivotNode);
            }
        }
Пример #6
0
 /// <summary>
 /// Sets the root of the interval tree.
 /// </summary>
 /// <param name="node"></param>
 void SetRoot(IntervalNode node)
 {
     root = node;
     if (root != null)
     {
         root.Parent = null;
     }
 }
Пример #7
0
 public bool Add(char min, char max)
 {
     if (!(_root is null))
     {
         return(false);
     }
     _root = new IntervalNode();
     return(true);
 }
Пример #8
0
 public bool Add(char min, char max)
 {
     if (_root == null)
     {
         _root = new IntervalNode();
         return(true);
     }
     return(false);
 }
Пример #9
0
            public bool Add(Interval interval)
            {
                if (rootNode == null)
                {
                    rootNode = new IntervalNode(interval);
                    return(true);
                }

                return(rootNode.Add(interval));
            }
Пример #10
0
            /// <summary>
            /// Resets the enumerator.
            /// </summary>
            public void Reset()
            {
                if (modificationsAtCreation != tree.modifications)
                {
                    throw new InvalidOperationException("Collection was modified.");
                }

                current           = startNode;
                hasVisitedCurrent = false;
                hasVisitedRight   = false;
            }
Пример #11
0
            /// <summary>
            /// Initializes a new instance.
            /// </summary>
            /// <param name="tree"></param>
            public IntervalTreeEnumerator(IntervalTree <TInterval, TPoint> tree)
            {
                if (tree == null)
                {
                    throw new ArgumentNullException(nameof(tree));
                }

                this.tree = tree;
                modificationsAtCreation = tree.modifications;
                startNode = GetLeftMostDescendantOrSelf(tree.root);
                Reset();
            }
Пример #12
0
            IntervalNode GetLeftMostDescendantOrSelf(IntervalNode node)
            {
                if (node == null)
                {
                    return(null);
                }

                while (node.Left != null)
                {
                    node = node.Left;
                }

                return(node);
            }
Пример #13
0
        /// <summary>
        /// Recursive procedure to find nodes that belong to the interval
        /// </summary>
        /// <param name="level"></param>
        /// <param name="interval"></param>
        /// <returns></returns>
        private static List <IGraphNode> FindNodesInInterval(int level, IntervalNode interval)
        {
            List <IGraphNode> nodes = new List <IGraphNode>();

            if (level == 1)
            {
                nodes.AddRange(interval.Nodes);
            }
            else
            {
                foreach (IntervalNode intervalNode in interval.Nodes)
                {
                    nodes.AddRange(FindNodesInInterval(level - 1, intervalNode));
                }
            }

            return(nodes);
        }
Пример #14
0
            /// <summary>
            /// Moves to the next item in the tree.
            /// </summary>
            /// <returns></returns>
            public bool MoveNext()
            {
                if (modificationsAtCreation != tree.modifications)
                {
                    throw new InvalidOperationException("Collection was modified.");
                }

                if (tree.root == null)
                {
                    return(false);
                }

                // Visit this node
                if (!hasVisitedCurrent)
                {
                    hasVisitedCurrent = true;
                    return(true);
                }

                // Go right, visit the right's left most descendant (or the right node itself)
                if (!hasVisitedRight && current.Right != null)
                {
                    current = current.Right;
                    MoveToLeftMostDescendant();
                    hasVisitedCurrent = true;
                    hasVisitedRight   = false;
                    return(true);
                }

                // Move upward
                do
                {
                    var wasVisitingFromLeft = current.IsLeftChild;
                    current = current.Parent;
                    if (wasVisitingFromLeft)
                    {
                        hasVisitedCurrent = false;
                        hasVisitedRight   = false;
                        return(MoveNext());
                    }
                } while (current != null);

                return(false);
            }
Пример #15
0
 void Rebalance(IntervalNode node)
 {
     if (node.Balance > 1)
     {
         if (node.Left.Balance < 0)
         {
             RotateLeft(node.Left);
         }
         RotateRight(node);
     }
     else if (node.Balance < -1)
     {
         if (node.Right.Balance > 0)
         {
             RotateRight(node.Right);
         }
         RotateLeft(node);
     }
 }
Пример #16
0
                public bool Add(Interval interval)
                {
                    int comparision = Compare(Data, interval);

                    if (comparision == 0)
                    {
                        return(false); // the interval overlaps this node's interval
                    }
                    else if (comparision < 0)
                    {
                        // the interval does not overlap but happens before current event
                        // if no node at the left, then add the interval node and return true
                        // to indicate the booking was successful
                        if (Left == null)
                        {
                            Left = new IntervalNode(interval);
                            return(true);
                        }

                        // otherwise keep digging on the tree to insert on the left side.
                        return(Left.Add(interval));
                    }
                    else
                    {
                        // the interval does not overlap but happens after current event
                        // if no node at the right, then add the interval node and return true
                        // to indicate the booking was successful
                        if (Right == null)
                        {
                            Right = new IntervalNode(interval);
                            return(true);
                        }

                        // otherwise keep digging on the tree to insert on the right side
                        return(Right.Add(interval));
                    }
                }
Пример #17
0
 /// <summary>Обработка нового узла дерева выражения</summary>
 /// <param name="NewNode">Новый добавляемый узел</param>
 protected virtual void ProcessNewNode([NotNull] ref ExpressionTreeNode NewNode)
 {
     switch (NewNode)
     {
     case CharNode char_node:
     {
         switch (char_node.Value)
         {
         case '.' when NewNode.Parent is CharNode {
                 Value: '.'
         } :
             var value_node = NewNode[n => n.Parent].Last(n => !(n is OperatorNode) || n.Left is null);
             (NewNode["./."] ?? throw new InvalidOperationException("NewNode/. is null")).Right = null;
             var parent        = value_node.Parent;
             var interval_node = new IntervalNode(value_node);
             if (parent != null)
             {
                 parent.Right = interval_node;
             }
             NewNode = interval_node;
             break;
         }
         break;
     }
Пример #18
0
        /// <summary>
        /// Interval finding algorithm:
        ///
        /// 1. Establish a list H for header nodes and initialize it to e 0.
        /// 2. For h E H find l(h) as follows.
        /// 2.1 Put h in l(h) as the first element of l(h)
        /// 2.2 For any b ~ G for which r~l(b) rd l(h) add b to l(h).
        ///     Thus a node is added to an interval if and only if all of its
        ///     immediate predecessors are already in the interval.
        /// 2.3 Repeat 2.2 until no more nodes can be added to l(h).
        /// 3.1 Add to H all nodes in G which are not already in H and which
        ///     not in l(h) but which have immediate predecessors in l(h).
        ///     Therefore a node is added to H the first time any (but not all) of its
        ///     immediate predecessors are members of an interval.
        /// 3.2 Add l(h) to the set of intervals being developed.
        /// 4. Select the next unprocessed node in H and repeat steps 2,3,4.
        /// </summary>
        private static List <IGraphNode> FindIntervals(IList <IGraphNode> nodeList)
        {
            List <IGraphNode> intervals = new List <IGraphNode>();

            // 1. Establish a list of header nodes and initialize it to contain the root node.
            List <IGraphNode> headerNodes = new List <IGraphNode>();

            headerNodes.Add(nodeList[0]);

            // 2. For all call graph nodes in headerNodes find the interval as follows.
            for (int i = 0; i < headerNodes.Count; i++)
            {
                IGraphNode headerNode = headerNodes[i];

                // 2.1 Add the header node to the interval
                IntervalNode interval = new IntervalNode(headerNode);

                // 2.2 For any node b in the graph G for which ImmediatePredecessors(b) < I(h) add b to I(h).
                //     Thus a node is added to an interval if and only if all of its
                //     immediate predecessors are already in the interval.
                // 2.3 Repeat 2.2 until no more nodes can be added to I(h).
                for (int j = headerNode.DepthFirstSearchLastNumber + 1; j < nodeList.Count; j++)
                {
                    IGraphNode b = nodeList[j];
                    if (headerNodes.Contains(b))
                    {
                        continue;
                    }

                    if (interval.Contains(b))
                    {
                        continue;
                    }

                    bool add = true;
                    foreach (IGraphNode p in b.InEdges)
                    {
                        if (!interval.Contains(p))
                        {
                            add = false;
                        }
                    }

                    if (add)
                    {
                        interval.Add(b);
                    }
                }

                // 3.1 Add to H all nodes in G which are not already in H and which
                //     are not in I(h) but which have immediate predecessors in I(h).
                //     Therefore a node is added to H the first time any (but not all) of its
                //     immediate predecessors are members of an interval.
                for (int j = headerNode.DepthFirstSearchLastNumber + 1; j < nodeList.Count; j++)
                {
                    IGraphNode g = nodeList[j];
                    if (headerNodes.Contains(g))
                    {
                        continue;
                    }

                    if (interval.Contains(g))
                    {
                        continue;
                    }

                    foreach (IGraphNode ipg in g.InEdges)
                    {
                        if (interval.Contains(ipg))
                        {
                            headerNodes.Add(g);
                            break;
                        }
                    }
                }

                // 3.2 Add l(h) to the set of intervals being developed.
                intervals.Add(interval);

                // 4 Select the next unprocessed node in H and repeat steps 2,3,4.
            }

            PrintIntervals(intervals);

            return(intervals);
        }
Пример #19
0
        /// <summary>
        /// Loop structuring
        /// </summary>
        private void StructureLoops()
        {
            int level = 0;               // Derived Sequence Level

            // For all derived sequences of Gi
            foreach (List <IGraphNode> derivedSequence in _derivedSequence)
            {
                level++;

                // For all intervals Ii of Gi
                foreach (IntervalNode interval in derivedSequence)
                {
                    ICallGraphNode latchNode = null;

                    // Find the interval head (original block node in G1) and create
                    // list of nodes of interval Ii.
                    IntervalNode initInt = interval;
                    for (int i = 1; i < level; i++)
                    {
                        initInt = (IntervalNode)initInt.Nodes[0];
                    }

                    ICallGraphNode intervalHead = (ICallGraphNode)initInt.Nodes[0];

                    // Find nodes that belong to the interval (nodes from G1)
                    List <IGraphNode> intervalNodes = FindNodesInInterval(level, interval);

                    // Find the greatest enclosing back edge (if any)
                    for (int i = 0; i < intervalHead.InEdges.Count; i++)
                    {
                        ICallGraphNode pred = (ICallGraphNode)intervalHead.InEdges[i];
                        if (intervalNodes.Contains(pred) && (pred.DepthFirstSearchLastNumber >= intervalHead.DepthFirstSearchLastNumber))
                        {
                            if (latchNode == null)
                            {
                                latchNode = pred;
                            }
                            else
                            {
                                if (pred.DepthFirstSearchLastNumber > latchNode.DepthFirstSearchLastNumber)
                                {
                                    latchNode = pred;
                                }
                            }
                        }
                    }

                    // Find nodes in the loop and the type of loop
                    if (latchNode != null)
                    {
                        // Check latching node is at the same nesting level of case
                        // statements (if any) and that the node doesnt belong to
                        // another loop.
                        if ((latchNode.CaseHead == intervalHead.CaseHead) &&
                            (latchNode.LoopHead == null))
                        {
                            intervalHead.LatchNode = latchNode;
                            FindNodesInLoop(latchNode, intervalHead, intervalNodes);
                        }
                    }
                }
            }
        }
Пример #20
0
 void MoveToLeftMostDescendant()
 {
     current = GetLeftMostDescendantOrSelf(current);
 }
Пример #21
0
 public IntervalNode(IntervalNode parent, int startIdx, int endIdx)
 {
     this.parent   = parent;
     this.startIdx = startIdx;
     this.endIdx   = endIdx;
 }
Пример #22
0
 /// <summary>
 /// Returns <c>true</c> if the given interval overlaps with the other interval.
 /// </summary>
 /// <param name="interval"></param>
 /// <param name="other"></param>
 /// <returns></returns>
 bool DoIntervalsOverlap(IntervalNode interval, IInterval <TPoint> other)
 {
     return(interval.Start.CompareTo(other.End) <= 0 && interval.End.CompareTo(other.Start) >= 0);
 }
Пример #23
0
 public IntervalNode(IntervalNode parent, int startIdx, int endIdx)
 {
     this.parent   = parent;
     this.startIdx = startIdx;
     this.endIdx   = endIdx;
 }
Пример #24
0
 /// <summary>
 /// Returns <c>true</c> if the given interval contains the given point.
 /// </summary>
 /// <param name="interval"></param>
 /// <param name="point"></param>
 /// <returns></returns>
 bool DoesIntervalContain(IntervalNode interval, TPoint point)
 {
     return(point.CompareTo(interval.Start) >= 0 && point.CompareTo(interval.End) <= 0);
 }