//================================================== void updateTreeNodes(allocTreeNode node) { for (int i = 0; i < node.Nodes.Count; i++) { allocTreeNode knode = node.Nodes[i] as allocTreeNode; if (knode == null) { continue; } updateTreeNodes(knode); } node.accumulatedSamples.Clear(); node.accumulateSamples(node.accumulatedSamples); node.Text = node.getFullText(); node.mFiltered = checkFilter(node); if (mFilterColorOnly.Checked) { if (node.mFiltered) { node.ForeColor = Color.Blue; } else { node.ForeColor = Color.LightGray; } } }
//================================================== void removeFilteredNodes(allocTreeNode node) { if (mFilterColorOnly.Checked) { return; } if (node == null) { return; } List <allocTreeNode> removeList = new List <allocTreeNode>(); foreach (allocTreeNode n in node.Nodes) { removeFilteredNodes(n); if (!n.mFiltered) { removeList.Add(n); } } foreach (allocTreeNode r in removeList) { r.Remove(); } }
//================================================== void sortTreeNodes(allocTreeNode node) { //stupid bubble sort for (int i = 0; i < node.Nodes.Count; i++) { allocTreeNode knode = node.Nodes[i] as allocTreeNode; if (knode == null) { continue; } int targetAmt = knode.getInclusiveMemory(); for (int j = i; j < node.Nodes.Count; j++) { allocTreeNode tnode = node.Nodes[j] as allocTreeNode; if (knode == null) { continue; } int nextAmt = tnode.getInclusiveMemory(); if (nextAmt > targetAmt) { TreeNode tn = node.Nodes[i]; node.Nodes[i] = node.Nodes[j]; node.Nodes[j] = tn; targetAmt = nextAmt; } } } for (int i = 0; i < node.Nodes.Count; i++) { allocTreeNode knode = node.Nodes[i] as allocTreeNode; if (knode == null) { continue; } sortTreeNodes(knode); } }
//================================================== public string toClipboardString(bool includeParents, bool includeKids) { string outString = ""; if (includeParents) { Stack <string> parentStrings = new Stack <string>(); //walk parents of me. allocTreeNode parent = (allocTreeNode)this.Parent; while (parent != null) { parentStrings.Push(parent.getFileLineFunctionText() + ":" + " [" + MemoryNumber.convert(getInclusiveMemory()) + "]"); parent = (allocTreeNode)parent.Parent; } parentStrings.Pop();//we don't care about the topmost entry while (parentStrings.Count != 0) { outString += parentStrings.Pop() + "\n"; } } outString += getFullText(); if (includeKids) { for (int i = 0; i < Nodes.Count; i++) { allocTreeNode knode = Nodes[i] as allocTreeNode; if (knode == null) { continue; } outString += "\n" + knode.toClipboardString(false, includeKids); } } return(outString); }
//================================================== private void copyThisNodesChildrenOnlyToolStripMenuItem_Click(object sender, EventArgs e) { TreeNode selNode = treeView1.SelectedNode; if (selNode == null) { return; } allocTreeNode atn = selNode as allocTreeNode; if (atn == null) { return; } Clipboard.SetDataObject(atn.toClipboardStringOneLevel(), true); }
//================================================== void populateTreeView(memStatsXML fsXML) { allocTreeNode tnRootNode = new allocTreeNode(); tnRootNode.function = "ALL"; tnRootNode.file = ""; tnRootNode.line = ""; tnRootNode.allocSize = 0; for (int allocIndex = 0; allocIndex < fsXML.allocations.Count; allocIndex++) { allocXML alloc = fsXML.allocations[allocIndex]; int allocSize = int.Parse(alloc.size); int stackIndex = 0; allocTreeNode lastNode = tnRootNode; bool added = false; while (stackIndex < alloc.stack.Count) { bool found = false; for (int i = 0; i < lastNode.Nodes.Count; i++) { allocTreeNode node = lastNode.Nodes[i] as allocTreeNode; if (node == null) { continue; } if (node.function == alloc.stack[stackIndex].function) { lastNode = node; stackIndex++; found = true; break; } } //we didn't find ourselves at this node, add us. if (!found) { added = true; allocTreeNode atn = new allocTreeNode(); atn.function = alloc.stack[stackIndex].function; atn.file = alloc.stack[stackIndex].file; atn.line = alloc.stack[stackIndex].line; atn.allocSize = allocSize; atn.samples = new List <allocTreeSampleData>(); foreach (sizeSampleXML sample in alloc.sizeSamples) { allocTreeSampleData sampleData = new allocTreeSampleData(); sampleData.size = Int32.Parse(sample.size); sampleData.sampleIndex = Int32.Parse(sample.sample); atn.samples.Add(sampleData); } atn.samples.Sort(SortBySamples); lastNode.Nodes.Add(atn); stackIndex++; lastNode = (allocTreeNode)lastNode.Nodes[lastNode.Nodes.Count - 1]; } } //if we never added, then this is a duplicate path, so add our memory to the leaf node if (!added) { lastNode.allocSize += allocSize; } } updateTreeNodes(tnRootNode); removeFilteredNodes(tnRootNode); sortTreeNodes(tnRootNode); treeView1.Nodes.Clear(); treeView1.Nodes.Add(tnRootNode); }
//================================================== bool checkFilter(allocTreeNode node) { if (mFilterLarge.Checked) { if (node.allocSize < 1024 * 10) // 10kb { return(false); } } if ((mFilterIncreasing.Checked) || mFilterIncreasingNonTrivial.Checked) { int filterVal = 0; if (mFilterIncreasingNonTrivial.Checked) { filterVal = 1024; } int minVal = 0; bool growth = false; if (node.samples != null) { foreach (allocTreeSampleData asd in node.accumulatedSamples) { if (minVal == 0) { minVal = asd.size; } else if (asd.size > (minVal + filterVal)) { growth = true; break; } } if (!growth) { return(false); } } } if (mFilterAlwaysIncreasing.Checked) { int filterVal = 0; int lastVal = 0; bool growth = false; if (node.samples != null) { foreach (allocTreeSampleData asd in node.accumulatedSamples) { if (lastVal == 0) { lastVal = asd.size; } else if (asd.size > (lastVal + filterVal)) { lastVal = asd.size; } else { return(false); } } return(true); } } return(true); }