List <IntervalNode> PerformStabbingQuery(IntervalNode node, IInterval <TPoint> interval) { var result = new List <IntervalNode>(); PerformStabbingQuery(node, interval, result); return(result); }
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); } }
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); } }
/// <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; } }
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); } }
/// <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; } }
public bool Add(char min, char max) { if (!(_root is null)) { return(false); } _root = new IntervalNode(); return(true); }
public bool Add(char min, char max) { if (_root == null) { _root = new IntervalNode(); return(true); } return(false); }
public bool Add(Interval interval) { if (rootNode == null) { rootNode = new IntervalNode(interval); return(true); } return(rootNode.Add(interval)); }
/// <summary> /// Resets the enumerator. /// </summary> public void Reset() { if (modificationsAtCreation != tree.modifications) { throw new InvalidOperationException("Collection was modified."); } current = startNode; hasVisitedCurrent = false; hasVisitedRight = false; }
/// <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(); }
IntervalNode GetLeftMostDescendantOrSelf(IntervalNode node) { if (node == null) { return(null); } while (node.Left != null) { node = node.Left; } return(node); }
/// <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); }
/// <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); }
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); } }
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)); } }
/// <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; }
/// <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); }
/// <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); } } } } }
void MoveToLeftMostDescendant() { current = GetLeftMostDescendantOrSelf(current); }
public IntervalNode(IntervalNode parent, int startIdx, int endIdx) { this.parent = parent; this.startIdx = startIdx; this.endIdx = endIdx; }
/// <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); }
/// <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); }