internal override bool Visit(ProgressNode node, List <ProgressNode> unused, int unused2) { Tally += node.LinesRequiredMethod(_rawUi, _maxWidth); // We don't need to walk all the nodes, once it's larger than the max height, we should stop if (Tally > _maxHeight) { return(false); } return(true); }
internal override bool Visit(ProgressNode node, List <ProgressNode> listWhereFound, int indexWhereFound) { if (node.ActivityId == _idToFind && node.SourceId == _sourceIdToFind) { this.FoundNode = node; this.ListWhereFound = listWhereFound; this.IndexWhereFound = indexWhereFound; return(false); } return(true); }
internal override bool Visit(ProgressNode node, List <ProgressNode> listWhereFound, int indexWhereFound) { if (node.Age >= _oldestSoFar) { _oldestSoFar = node.Age; FoundNode = node; this.ListWhereFound = listWhereFound; this.IndexWhereFound = indexWhereFound; } return(true); }
private void EvictNode() { List <ProgressNode> listWhereFound = null; int indexWhereFound = -1; ProgressNode oldestNode = FindOldestLeafmostNode(out listWhereFound, out indexWhereFound); if (oldestNode == null) { // Well that's a surprise. There's got to be at least one node there that's older than 0. Debug.Assert(false, "Must be an old node in the tree somewhere"); // We'll just pick the root node, then. RemoveNode(_topLevelNodes, 0); } else { RemoveNode(listWhereFound, indexWhereFound); } }
internal static void VisitNodes(List <ProgressNode> nodes, NodeVisitor v) { if (nodes == null) { return; } for (int i = 0; i < nodes.Count; ++i) { ProgressNode node = (ProgressNode)nodes[i]; if (!v.Visit(node, nodes, i)) { return; } if (node.Children != null) { VisitNodes(node.Children, v); } } }
private ProgressNode FindOldestLeafmostNode(out List <ProgressNode> listWhereFound, out int indexWhereFound) { listWhereFound = null; indexWhereFound = -1; ProgressNode result = null; List <ProgressNode> treeToSearch = _topLevelNodes; do { result = FindOldestLeafmostNodeHelper(treeToSearch, out listWhereFound, out indexWhereFound); if (result == null || result.Children == null || result.Children.Count == 0) { break; } // search the subtree for the oldest child treeToSearch = result.Children; } while (true); return(result); }
/// <summary> /// Finds the oldest node with a given rendering style that is at least as old as a given age. /// </summary> /// <param name="nodes"> /// List of nodes to search. Child lists of each node in this list will also be searched. /// </param> /// <param name="oldestSoFar"></param> /// The minimum age of the node to be located. To find the oldest node, pass 0. /// <param name="style"> /// The rendering style of the node to be located. /// </param> /// <returns> /// The found node, or null if no suitable node was located. /// </returns> private ProgressNode FindOldestNodeOfGivenStyle(List <ProgressNode> nodes, int oldestSoFar, RenderStyle style) { if (nodes == null) { return(null); } ProgressNode found = null; for (int i = 0; i < nodes.Count; ++i) { ProgressNode node = (ProgressNode)nodes[i]; Debug.Assert(node != null, "nodes should not contain null elements"); if (node.Age >= oldestSoFar && node.Style == style) { found = node; oldestSoFar = found.Age; } if (node.Children != null) { ProgressNode child = FindOldestNodeOfGivenStyle(node.Children, oldestSoFar, style); if (child != null) { // In this universe, parents can be younger than their children. We found a child older than us. found = child; oldestSoFar = found.Age; } } } return(found); }
/// <summary> /// Update the data structures that represent the outstanding progress records reported so far. /// </summary> /// <param name="sourceId"> /// Identifier of the source of the event. This is used as part of the "key" for matching newly received records with /// records that have already been received. For a record to match (meaning that they refer to the same activity), both /// the source and activity identifiers need to match. /// </param> /// <param name="record"> /// The ProgressRecord received that will either update the status of an activity which we are already tracking, or /// represent a new activity that we need to track. /// </param> internal void Update(long sourceId, ProgressRecord record) { do { if (record.ParentActivityId == record.ActivityId) { // ignore malformed records. break; } List <ProgressNode> listWhereFound = null; int indexWhereFound = -1; ProgressNode foundNode = FindNodeById(sourceId, record.ActivityId, out listWhereFound, out indexWhereFound); if (foundNode != null) { if (record.RecordType == ProgressRecordType.Completed) { RemoveNodeAndPromoteChildren(listWhereFound, indexWhereFound); break; } if (record.ParentActivityId == foundNode.ParentActivityId) { // record is an update to an existing activity. Copy the record data into the found node, and // reset the age of the node. foundNode.Activity = record.Activity; foundNode.StatusDescription = record.StatusDescription; foundNode.CurrentOperation = record.CurrentOperation; foundNode.PercentComplete = Math.Min(record.PercentComplete, 100); foundNode.SecondsRemaining = record.SecondsRemaining; foundNode.Age = 0; break; } else { // The record's parent Id mismatches with that of the found node's. We interpret // this to mean that the activity represented by the record (and the found node) is // being "re-parented" elsewhere. So we remove the found node and treat the record // as a new activity. RemoveNodeAndPromoteChildren(listWhereFound, indexWhereFound); } } // At this point, the record's activity is not in the tree. So we need to add it. if (record.RecordType == ProgressRecordType.Completed) { // We don't track completion records that don't correspond to activities we're not // already tracking. break; } ProgressNode newNode = new ProgressNode(sourceId, record); // If we're adding a node, and we have no more space, then we need to pick a node to evict. while (_nodeCount >= maxNodeCount) { EvictNode(); } if (newNode.ParentActivityId >= 0) { ProgressNode parentNode = FindNodeById(newNode.SourceId, newNode.ParentActivityId); if (parentNode != null) { if (parentNode.Children == null) { parentNode.Children = new List <ProgressNode>(); } AddNode(parentNode.Children, newNode); break; } // The parent node is not in the tree. Make the new node's parent the root, // and add it to the tree. If the parent ever shows up, then the next time // we receive a record for this activity, the parent id's won't match, and the // activity will be properly re-parented. newNode.ParentActivityId = -1; } AddNode(_topLevelNodes, newNode); } while (false); // At this point the tree is up-to-date. Make a pass to age all of the nodes AgeNodesAndResetStyle(); }
internal override bool Visit(ProgressNode node, List <ProgressNode> unused, int unusedToo) { node.Age = Math.Min(node.Age + 1, Int32.MaxValue - 1); node.Style = RenderStyle.FullPlus; return(true); }
/// <summary> /// Called for each node in the tree. /// </summary> /// <param name="node"> /// The node being visited. /// </param> /// <param name="listWhereFound"> /// The list in which the node resides. /// </param> /// <param name="indexWhereFound"> /// The index into listWhereFound of the node. /// </param> /// <returns> /// true to continue visiting nodes, false if not. /// </returns> internal abstract bool Visit(ProgressNode node, List <ProgressNode> listWhereFound, int indexWhereFound);
/// <summary> /// Adds a node to the tree, first removing the oldest node if the tree is too large. /// </summary> /// <param name="nodes"> /// List in the tree where the node is to be added. /// </param> /// <param name="nodeToAdd"> /// Node to be added. /// </param> private void AddNode(List <ProgressNode> nodes, ProgressNode nodeToAdd) { nodes.Add(nodeToAdd); _nodeCount++; }