public static List <FCallStack> GetHighlightedCallStacks(TreeView CallGraphTreeView) { List <FCallStack> Results = new List <FCallStack>(); Worklist.Clear(); foreach (TreeNode node in CallGraphTreeView.Nodes) { Worklist.Add(node); } while (Worklist.Count > 0) { TreeNode node = Worklist[Worklist.Count - 1]; Worklist.RemoveAt(Worklist.Count - 1); if (node.BackColor != Color.Transparent) { FNodePayload payload = ( FNodePayload )node.Tag; Results.AddRange(payload.CallStacks); } else { // Only search children if this node isn't highlighted. // This makes the search go faster, and means that we don't // have to worry about duplicate callstacks in the list. foreach (TreeNode childNode in node.Nodes) { Worklist.Add(childNode); } } } return(Results); }
private static void UpdateNodeText(TreeNode RootNode) { // Compile a list of all nodes in the graph without recursion. List <TreeNode> TreeNodes = new List <TreeNode>(); TreeNodes.Add(RootNode); int NodeIndex = 0; while (NodeIndex < TreeNodes.Count) { foreach (TreeNode Node in TreeNodes[NodeIndex].Nodes) { TreeNodes.Add(Node); } NodeIndex++; } // Iterate over all nodes and prepend size in KByte. foreach (TreeNode Node in TreeNodes) { // Some nodes like root node won't have a tag. if (Node.Tag != null) { FNodePayload Payload = Node.Tag as FNodePayload; string size = MainWindow.FormatSizeString(Payload.AllocationSize); Node.Text = size + " " + Payload.AllocationCount + " Allocations " + Node.Text; } // Count down work remaining. NodeIndex--; } }
private static TreeNode UpdateNodeAndPayload(TreeNode ParentNode, int AddressIndex, FCallStackAllocationInfo AllocationInfo) { FCallStack CallStack = FStreamInfo.GlobalInstance.CallStackArray[AllocationInfo.CallStackIndex]; // Iterate over existing nodes to see whether there is a match. foreach (TreeNode Node in ParentNode.Nodes) { FNodePayload Payload = (FNodePayload)Node.Tag; // If there is a match, update the allocation size and return the current node. if (FStreamInfo.GlobalInstance.CallStackAddressArray[Payload.AddressIndex].FunctionIndex == FStreamInfo.GlobalInstance.CallStackAddressArray[AddressIndex].FunctionIndex) { Payload.AllocationSize += AllocationInfo.Size; Payload.AllocationCount += AllocationInfo.Count; Payload.CallStacks.Add(CallStack); // Return current node as parent for next iteration. return(Node); } } // If we made it here it means that we need to add a new node. string NodeName = FStreamInfo.GlobalInstance.NameArray[FStreamInfo.GlobalInstance.CallStackAddressArray[AddressIndex].FunctionIndex]; TreeNode NewNode = new TreeNode(NodeName); // Create payload for the node and associate it. FNodePayload NewPayload = new FNodePayload(AddressIndex, AllocationInfo.Size, AllocationInfo.Count, CallStack); NewNode.Tag = NewPayload; // Add to parent node and return new node as subsequent parent. ParentNode.Nodes.Add(NewNode); return(NewNode); }
private static int HighlightAllNodesAux(TreeView CallGraphTreeView, TreeNodeCollection TreeNodes, FNodeSearchState SearchState, ref TreeNode FirstResult) { int ResultCount = 0; for (int NodeIndex = 0; NodeIndex < TreeNodes.Count; NodeIndex++) { TreeNode N = TreeNodes[NodeIndex]; bool bNodeMatch = false; if (SearchRegex != null) { bNodeMatch = SearchRegex.Match(N.Text).Success; } else { if (bMatchCase) { bNodeMatch = N.Text.IndexOf(SearchText, StringComparison.InvariantCulture) != -1; } else { bNodeMatch = N.Text.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) != -1; } } if (bNodeMatch) { if (FirstResult == null) { FirstResult = N; } N.BackColor = Color.CornflowerBlue; N.EnsureVisible(); ResultCount++; FNodePayload payload = ( FNodePayload )N.Tag; if (!SearchState.CallStacks.Contains(payload.CallStacks[0])) { // if one callstack from this node is new, then all must be, due to the way the graph is arranged // and the order in which it is searched SearchState.CallStacks.AddRange(payload.CallStacks); SearchState.AllocationCount += payload.AllocationCount; SearchState.AllocationSize += payload.AllocationSize; } } ResultCount += HighlightAllNodesAux(CallGraphTreeView, N.Nodes, SearchState, ref FirstResult); } return(ResultCount); }
public int Compare(object ObjectA, object ObjectB) { // We sort by size, which requires payload. TreeNode NodeA = ObjectA as TreeNode; TreeNode NodeB = ObjectB as TreeNode; FNodePayload PayloadA = NodeA.Tag as FNodePayload; FNodePayload PayloadB = NodeB.Tag as FNodePayload; // Can only sort if there is payload. if (PayloadA != null && PayloadB != null) { // Sort by size, descending. return(Math.Sign(PayloadB.AllocationCount - PayloadA.AllocationCount)); } // Treat missing payload as unsorted else { return(0); } }
public static List <string> GetHighlightedNodesAsStrings(TreeView CallGraphTreeView) { List <string> Results = new List <string>(); Worklist.Clear(); foreach (TreeNode node in CallGraphTreeView.Nodes) { Worklist.Add(node); } while (Worklist.Count > 0) { TreeNode Node = Worklist[Worklist.Count - 1]; Worklist.RemoveAt(Worklist.Count - 1); if (Node.BackColor != Color.Transparent) { FNodePayload Payload = ( FNodePayload )Node.Tag; if (Payload != null) { string FunctionName = FStreamInfo.GlobalInstance.NameArray[FStreamInfo.GlobalInstance.CallStackAddressArray[Payload.AddressIndex].FunctionIndex]; int AllocationCount = Payload.AllocationCount; long AllocationSize = Payload.AllocationSize; Results.Add(FunctionName + "," + AllocationCount + "," + AllocationSize); } } else { // Only search children if this node isn't highlighted. // This makes the search go faster, and means that we don't // have to worry about duplicate callstacks in the list. foreach (TreeNode childNode in Node.Nodes) { Worklist.Add(childNode); } } } return(Results); }
private static TreeNode UpdateNodeAndPayload( TreeNode ParentNode, int AddressIndex, FCallStackAllocationInfo AllocationInfo ) { FCallStack CallStack = FStreamInfo.GlobalInstance.CallStackArray[AllocationInfo.CallStackIndex]; // Iterate over existing nodes to see whether there is a match. foreach( TreeNode Node in ParentNode.Nodes ) { FNodePayload Payload = (FNodePayload) Node.Tag; // If there is a match, update the allocation size and return the current node. if( FStreamInfo.GlobalInstance.CallStackAddressArray[Payload.AddressIndex].FunctionIndex == FStreamInfo.GlobalInstance.CallStackAddressArray[AddressIndex].FunctionIndex ) { Payload.AllocationSize += AllocationInfo.Size; Payload.AllocationCount += AllocationInfo.Count; Payload.CallStacks.Add(CallStack); // Return current node as parent for next iteration. return Node; } } // If we made it here it means that we need to add a new node. string NodeName = FStreamInfo.GlobalInstance.NameArray[FStreamInfo.GlobalInstance.CallStackAddressArray[AddressIndex].FunctionIndex]; TreeNode NewNode = new TreeNode( NodeName ); // Create payload for the node and associate it. FNodePayload NewPayload = new FNodePayload(AddressIndex, AllocationInfo.Size, AllocationInfo.Count, CallStack); NewNode.Tag = NewPayload; // Add to parent node and return new node as subsequent parent. ParentNode.Nodes.Add( NewNode ); return NewNode; }