1 |
efrain |
1 |
/* Copyright (c) 2009 Facebook
|
|
|
2 |
*
|
|
|
3 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
4 |
* you may not use this file except in compliance with the License.
|
|
|
5 |
* You may obtain a copy of the License at
|
|
|
6 |
*
|
|
|
7 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
8 |
*
|
|
|
9 |
* Unless required by applicable law or agreed to in writing, software
|
|
|
10 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
11 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
12 |
* See the License for the specific language governing permissions and
|
|
|
13 |
* limitations under the License.
|
|
|
14 |
*/
|
|
|
15 |
|
|
|
16 |
/**
|
|
|
17 |
* Helper javascript functions for XHProf report tooltips.
|
|
|
18 |
*
|
|
|
19 |
* @author Kannan Muthukkaruppan
|
|
|
20 |
*/
|
|
|
21 |
|
|
|
22 |
// Take a string which is actually a number in comma separated format
|
|
|
23 |
// and return a string representing the absolute value of the number.
|
|
|
24 |
function stringAbs(x) {
|
|
|
25 |
return x.replace("-", "");
|
|
|
26 |
}
|
|
|
27 |
|
|
|
28 |
// Takes a number in comma-separated string format, and
|
|
|
29 |
// returns a boolean to indicate if the number is negative
|
|
|
30 |
// or not.
|
|
|
31 |
function isNegative(x) {
|
|
|
32 |
|
|
|
33 |
return (x.indexOf("-") == 0);
|
|
|
34 |
|
|
|
35 |
}
|
|
|
36 |
|
|
|
37 |
function addCommas(nStr)
|
|
|
38 |
{
|
|
|
39 |
nStr += '';
|
|
|
40 |
x = nStr.split('.');
|
|
|
41 |
x1 = x[0];
|
|
|
42 |
x2 = x.length > 1 ? '.' + x[1] : '';
|
|
|
43 |
var rgx = /(\d+)(\d{3})/;
|
|
|
44 |
while (rgx.test(x1)) {
|
|
|
45 |
x1 = x1.replace(rgx, '$1' + ',' + '$2');
|
|
|
46 |
}
|
|
|
47 |
return x1 + x2;
|
|
|
48 |
}
|
|
|
49 |
|
|
|
50 |
// Mouseover tips for parent rows in parent/child report..
|
|
|
51 |
function ParentRowToolTip(cell, metric)
|
|
|
52 |
{
|
|
|
53 |
var metric_val;
|
|
|
54 |
var parent_metric_val;
|
|
|
55 |
var parent_metric_pct_val;
|
|
|
56 |
var col_index;
|
|
|
57 |
var diff_text;
|
|
|
58 |
|
|
|
59 |
row = cell.parentNode;
|
|
|
60 |
tds = row.getElementsByTagName("td");
|
|
|
61 |
|
|
|
62 |
parent_func = tds[0].innerHTML; // name
|
|
|
63 |
|
|
|
64 |
if (diff_mode) {
|
|
|
65 |
diff_text = " diff ";
|
|
|
66 |
} else {
|
|
|
67 |
diff_text = "";
|
|
|
68 |
}
|
|
|
69 |
|
|
|
70 |
s = '<center>';
|
|
|
71 |
|
|
|
72 |
if (metric == "ct") {
|
|
|
73 |
parent_ct = tds[1].innerHTML; // calls
|
|
|
74 |
parent_ct_pct = tds[2].innerHTML;
|
|
|
75 |
|
|
|
76 |
func_ct = addCommas(func_ct);
|
|
|
77 |
|
|
|
78 |
if (diff_mode) {
|
|
|
79 |
s += 'There are ' + stringAbs(parent_ct) +
|
|
|
80 |
(isNegative(parent_ct) ? ' fewer ' : ' more ') +
|
|
|
81 |
' calls to ' + func_name + ' from ' + parent_func + '<br>';
|
|
|
82 |
|
|
|
83 |
text = " of diff in calls ";
|
|
|
84 |
} else {
|
|
|
85 |
text = " of calls ";
|
|
|
86 |
}
|
|
|
87 |
|
|
|
88 |
s += parent_ct_pct + text + '(' + parent_ct + '/' + func_ct + ') to '
|
|
|
89 |
+ func_name + ' are from ' + parent_func + '<br>';
|
|
|
90 |
} else {
|
|
|
91 |
|
|
|
92 |
// help for other metrics such as wall time, user cpu time, memory usage
|
|
|
93 |
col_index = metrics_col[metric];
|
|
|
94 |
parent_metric_val = tds[col_index].innerHTML;
|
|
|
95 |
parent_metric_pct_val = tds[col_index+1].innerHTML;
|
|
|
96 |
|
|
|
97 |
metric_val = addCommas(func_metrics[metric]);
|
|
|
98 |
|
|
|
99 |
s += parent_metric_pct_val + '(' + parent_metric_val + '/' + metric_val
|
|
|
100 |
+ ') of ' + metrics_desc[metric] +
|
|
|
101 |
(diff_mode ? ((isNegative(parent_metric_val) ?
|
|
|
102 |
" decrease" : " increase")) : "") +
|
|
|
103 |
' in ' + func_name + ' is due to calls from ' + parent_func + '<br>';
|
|
|
104 |
}
|
|
|
105 |
|
|
|
106 |
s += '</center>';
|
|
|
107 |
|
|
|
108 |
return s;
|
|
|
109 |
}
|
|
|
110 |
|
|
|
111 |
// Mouseover tips for child rows in parent/child report..
|
|
|
112 |
function ChildRowToolTip(cell, metric)
|
|
|
113 |
{
|
|
|
114 |
var metric_val;
|
|
|
115 |
var child_metric_val;
|
|
|
116 |
var child_metric_pct_val;
|
|
|
117 |
var col_index;
|
|
|
118 |
var diff_text;
|
|
|
119 |
|
|
|
120 |
row = cell.parentNode;
|
|
|
121 |
tds = row.getElementsByTagName("td");
|
|
|
122 |
|
|
|
123 |
child_func = tds[0].innerHTML; // name
|
|
|
124 |
|
|
|
125 |
if (diff_mode) {
|
|
|
126 |
diff_text = " diff ";
|
|
|
127 |
} else {
|
|
|
128 |
diff_text = "";
|
|
|
129 |
}
|
|
|
130 |
|
|
|
131 |
s = '<center>';
|
|
|
132 |
|
|
|
133 |
if (metric == "ct") {
|
|
|
134 |
|
|
|
135 |
child_ct = tds[1].innerHTML; // calls
|
|
|
136 |
child_ct_pct = tds[2].innerHTML;
|
|
|
137 |
|
|
|
138 |
s += func_name + ' called ' + child_func + ' ' + stringAbs(child_ct) +
|
|
|
139 |
(diff_mode ? (isNegative(child_ct) ? " fewer" : " more") : "" )
|
|
|
140 |
+ ' times.<br>';
|
|
|
141 |
s += 'This accounts for ' + child_ct_pct + ' (' + child_ct
|
|
|
142 |
+ '/' + total_child_ct
|
|
|
143 |
+ ') of function calls made by ' + func_name + '.';
|
|
|
144 |
|
|
|
145 |
} else {
|
|
|
146 |
|
|
|
147 |
// help for other metrics such as wall time, user cpu time, memory usage
|
|
|
148 |
col_index = metrics_col[metric];
|
|
|
149 |
child_metric_val = tds[col_index].innerHTML;
|
|
|
150 |
child_metric_pct_val = tds[col_index+1].innerHTML;
|
|
|
151 |
|
|
|
152 |
metric_val = addCommas(func_metrics[metric]);
|
|
|
153 |
|
|
|
154 |
if (child_func.indexOf("Exclusive Metrics") != -1) {
|
|
|
155 |
s += 'The exclusive ' + metrics_desc[metric] + diff_text
|
|
|
156 |
+ ' for ' + func_name
|
|
|
157 |
+ ' is ' + child_metric_val + " <br>";
|
|
|
158 |
|
|
|
159 |
s += "which is " + child_metric_pct_val + " of the inclusive "
|
|
|
160 |
+ metrics_desc[metric]
|
|
|
161 |
+ diff_text + " for " + func_name + " (" + metric_val + ").";
|
|
|
162 |
|
|
|
163 |
} else {
|
|
|
164 |
|
|
|
165 |
s += child_func + ' when called from ' + func_name
|
|
|
166 |
+ ' takes ' + stringAbs(child_metric_val)
|
|
|
167 |
+ (diff_mode ? (isNegative(child_metric_val) ? " less" : " more") : "")
|
|
|
168 |
+ " of " + metrics_desc[metric] + " <br>";
|
|
|
169 |
|
|
|
170 |
s += "which is " + child_metric_pct_val + " of the inclusive "
|
|
|
171 |
+ metrics_desc[metric]
|
|
|
172 |
+ diff_text + " for " + func_name + " (" + metric_val + ").";
|
|
|
173 |
}
|
|
|
174 |
}
|
|
|
175 |
|
|
|
176 |
s += '</center>';
|
|
|
177 |
|
|
|
178 |
return s;
|
|
|
179 |
}
|
|
|
180 |
|
|
|
181 |
$(document).ready(function() {
|
|
|
182 |
$('td[@metric]').tooltip(
|
|
|
183 |
{ bodyHandler: function() {
|
|
|
184 |
var type = $(this).attr('type');
|
|
|
185 |
var metric = $(this).attr('metric');
|
|
|
186 |
if (type == 'Parent') {
|
|
|
187 |
return ParentRowToolTip(this, metric);
|
|
|
188 |
} else if (type == 'Child') {
|
|
|
189 |
return ChildRowToolTip(this, metric);
|
|
|
190 |
}
|
|
|
191 |
},
|
|
|
192 |
showURL : false
|
|
|
193 |
});
|
|
|
194 |
var cur_params = {} ;
|
|
|
195 |
$.each(location.search.replace('?','').split('&'), function(i, x) {
|
|
|
196 |
var y = x.split('='); cur_params[y[0]] = y[1];
|
|
|
197 |
});
|
|
|
198 |
$('input.function_typeahead')
|
|
|
199 |
.autocomplete('typeahead.php', { extraParams : cur_params })
|
|
|
200 |
.result(function(event, item) {
|
|
|
201 |
cur_params['symbol'] = item;
|
|
|
202 |
location.search = '?' + jQuery.param(cur_params);
|
|
|
203 |
});
|
|
|
204 |
});
|