| OLD | NEW |
| (Empty) | |
| 1 <!DOCTYPE html> |
| 2 <!-- |
| 3 Copyright 2014 The Chromium Authors. All rights reserved. |
| 4 Use of this source code is governed by a BSD-style license that can be |
| 5 found in the LICENSE file. |
| 6 --> |
| 7 <html> |
| 8 <head> |
| 9 <script> |
| 10 function rnd(max) { |
| 11 return Math.round(Math.random()*max); |
| 12 } |
| 13 |
| 14 function gen() { |
| 15 var dirs1=['usr1', 'etc1', 'var1']; |
| 16 var dirs2=['aaa2', 'bbb2', 'ccc2', 'ddd2', 'eee2', 'fff2', 'ggg2', 'hhh2', '
frobozz2', 'kazaam2', 'shazam2']; |
| 17 var dirs3=['iii3', 'jjj3', 'kkk3', 'lll3', 'mmm3', 'nnn3', 'ooo3', 'ppp3', '
wonderllama3', 'excelsior3', 'src3']; |
| 18 var filenames=['awesome.cc', 'rad.h', 'tubular.cxx', 'cool.cc', 'groovy.h',
'excellent.c', 'gnarly.h', 'green.C', 'articulate.cc']; |
| 19 //All possible types (we only see a subset in practice): 'ABbCDdGgiNpRrSsTtU
uVvWw-?'; |
| 20 var nm_symbol_types = 'trd'; |
| 21 var minSize = 4; |
| 22 var maxSize = 10000; |
| 23 var numGen = 300000; |
| 24 var text = 'var nm_data=[\n'; |
| 25 var vtablePercent = 5; |
| 26 for (var x=0; x<numGen; x++) { |
| 27 var path = '/' + dirs1[rnd(dirs1.length - 1)] + '/' + dirs2[rnd(dirs2.le
ngth - 1)] + '/' + dirs3[rnd(dirs3.length - 1)] + '/' + filenames[rnd(filenames.
length - 1)]; |
| 28 var isVtable = Math.floor((Math.random()*100)+1) <= vtablePercent ? true
: false; |
| 29 var size = rnd(maxSize); |
| 30 var symbol_name; |
| 31 var type; |
| 32 if (!isVtable) { |
| 33 symbol_name = 'sym' + x.toString(16); |
| 34 type = nm_symbol_types.charAt(rnd(nm_symbol_types.length - 1)); |
| 35 } else { |
| 36 symbol_name = 'vtable for ' + x.toString(16); |
| 37 type = '@' |
| 38 } |
| 39 // {'n': 'longgggsymbol1', 't': 'b', 's': 1000, 'p': '/usr/local/foo/foo
.cc'}, |
| 40 text = text + "{'n': '" + symbol_name + "', 't': '" + type + "', 's': "
+ size + ", 'p': '" + path + "'},\n"; |
| 41 } |
| 42 text += '];'; |
| 43 |
| 44 eval(text); |
| 45 var treeified = to_d3_tree(nm_data); |
| 46 generateDownloadLink('tree_data=' + JSON.stringify(treeified)); |
| 47 } |
| 48 |
| 49 function generateDownloadLink(content) { |
| 50 var blob = new Blob([content], {type: 'text/plain'}); |
| 51 var link = document.createElement('a'); |
| 52 link.download = 'generated-content.txt'; |
| 53 link.href = window.URL.createObjectURL(blob); |
| 54 link.textContent = 'Download ready, click here.'; |
| 55 link.dataset.downloadurl = ['text/plain', link.download, link.href].join(':'
); |
| 56 link.onclick = function(e) { |
| 57 if ('disabled' in this.dataset) { return false; } |
| 58 link.dataset.disabled = true; |
| 59 setTimeout(function() { window.URL.revokeObjectURL(link.href); }, 1500); |
| 60 }; |
| 61 document.getElementById('linkcontainer').innerHTML = ''; |
| 62 document.getElementById('linkcontainer').appendChild(link); |
| 63 } |
| 64 |
| 65 /** |
| 66 * This function takes in an array of nm records and converts them into a |
| 67 * hierarchical data structure suitable for use in a d3-base treemap layout. |
| 68 * Leaves are individual symbols. The parents of the leaves are logical |
| 69 * groupings by common symbol-type (for BSS, read-only data, code, etc). |
| 70 * Above this, each node represents part of a filesystem path relative |
| 71 * to the parent node. The root node has the name '/', and represents |
| 72 * a root (though not necessarily THE root) of a file system traversal. |
| 73 * The root node also has a special property, 'maxDepth', to which is bound |
| 74 * the deepest level of nesting that was found during conversion: for the |
| 75 * record at path /a/b/c/d.foo, the maxDepth will be 6; the file 'd.foo' |
| 76 * is at depth 4, the type-bucket is depth 5 and the symbols are depth 6. |
| 77 */ |
| 78 function to_d3_tree(records) { |
| 79 var result = {'n': '/', 'children': [], 'k': 'p'}; |
| 80 var maxDepth = 0; |
| 81 //{'n': 'symbol1', 't': 'b', 's': 1000, 'p': '/usr/local/foo/foo.cc'}, |
| 82 for (index in records) { |
| 83 var record = records[index]; |
| 84 var parts = record.p.split("/"); |
| 85 var node = result; |
| 86 var depth = 0; |
| 87 // Walk the tree and find the file that is named by the "location" |
| 88 // field of the record. We create any intermediate nodes required. |
| 89 // This is directly analogous to "mkdir -p". |
| 90 while(parts.length > 0) { |
| 91 var part = parts.shift(); |
| 92 if (part.length == 0) continue; |
| 93 depth++; |
| 94 node = _mk_child(node, part, record.s); |
| 95 node.k = 'p'; // p for path |
| 96 } |
| 97 node.lastPathElement = true; |
| 98 |
| 99 // 'node' is now the file node. Find the symbol-type bucket. |
| 100 node = _mk_child(node, record.t, record.s); |
| 101 node.t = record.t; |
| 102 node.k = 'b'; // b for bucket |
| 103 depth++; |
| 104 // 'node' is now the symbol-type bucket. Make the child entry. |
| 105 node = _mk_child(node, record.n, record.s); |
| 106 delete node.children; |
| 107 node.value = record.s; |
| 108 node.t = record.t; |
| 109 node.k = 's'; // s for symbol |
| 110 depth++; |
| 111 |
| 112 maxDepth = Math.max(maxDepth, depth); |
| 113 } |
| 114 result.maxDepth = maxDepth; |
| 115 return result; |
| 116 } |
| 117 |
| 118 /** |
| 119 * Given a node and a name, return the child within node.children whose |
| 120 * name matches the specified name. If necessary, a new child node is |
| 121 * created and appended to node.children. |
| 122 * If this method creates a new node, the 'name' attribute is set to the |
| 123 * specified name and the 'children' attribute is an empty array, and |
| 124 * total_size is the specified size. Otherwise, the existing node is |
| 125 * returned and its total_size value is incremented by the specified size. |
| 126 */ |
| 127 function _mk_child(node, name, size) { |
| 128 var child = undefined; |
| 129 for (child_index in node.children) { |
| 130 if (node.children[child_index].n == name) { |
| 131 child = node.children[child_index]; |
| 132 } |
| 133 } |
| 134 if (child === undefined) { |
| 135 child = {'n': name, 'children': []}; |
| 136 node.children.push(child); |
| 137 } |
| 138 return child; |
| 139 } |
| 140 </script> |
| 141 </head> |
| 142 <body style='white-space: pre; font-family: monospace;'> |
| 143 This script generates sample data for use in D3SymbolTreeMap, and can be used |
| 144 for testing. |
| 145 <input type=button onclick='gen();' value='Generate data'></input> |
| 146 <div id='linkcontainer'></div> |
| 147 </body> |
| 148 </html> |
| OLD | NEW |