21 use RunningStat\RunningStat;
65 $this->config = array_merge( [
70 $this->hieraData = $this->
pruneData( $data );
114 return array_pad( explode(
'==>', $key, 2 ), -2,
null );
125 if ( !$this->config[
'include'] ) {
129 $want = array_fill_keys( $this->config[
'include'],
true );
130 $want[
'main()'] =
true;
133 foreach ( $data
as $key => $stats ) {
135 if ( isset( $want[$parent] ) || isset( $want[$child] ) ) {
136 $keep[$key] = $stats;
161 if ( $this->inclusive ===
null ) {
162 $main = $this->hieraData[
'main()'];
163 $hasCpu = isset( $main[
'cpu'] );
164 $hasMu = isset( $main[
'mu'] );
165 $hasAlloc = isset( $main[
'alloc'] );
167 $this->inclusive = [];
168 foreach ( $this->hieraData
as $key => $stats ) {
170 if ( !isset( $this->inclusive[$child] ) ) {
171 $this->inclusive[$child] = [
173 'wt' =>
new RunningStat(),
176 $this->inclusive[$child][
'cpu'] =
new RunningStat();
179 $this->inclusive[$child][
'mu'] =
new RunningStat();
180 $this->inclusive[$child][
'pmu'] =
new RunningStat();
183 $this->inclusive[$child][
'alloc'] =
new RunningStat();
184 $this->inclusive[$child][
'free'] =
new RunningStat();
188 $this->inclusive[$child][
'ct'] += $stats[
'ct'];
189 foreach ( $stats
as $stat =>
$value ) {
190 if ( $stat ===
'ct' ) {
194 if ( !isset( $this->inclusive[$child][$stat] ) ) {
199 for ( $i = 0; $i < $stats[
'ct']; $i++ ) {
200 $this->inclusive[$child][$stat]->addObservation(
209 foreach ( $this->inclusive
as $func => $stats ) {
211 if (
$value instanceof RunningStat ) {
213 $percent = ( isset( $main[
$name] ) && $main[
$name] )
214 ? 100 * $total / $main[
$name]
216 $this->inclusive[$func][
$name] = [
222 'percent' => $percent,
228 uasort( $this->inclusive, self::makeSortFunction(
229 $this->config[
'sort'],
'total'
251 foreach ( $this->
complete as $func => $stats ) {
252 foreach ( $stats
as $stat =>
$value ) {
253 if ( $stat ===
'ct' ) {
260 $this->
complete[$func][
'calls'] = [];
261 $this->
complete[$func][
'subcalls'] = [];
264 foreach ( $this->hieraData
as $key => $stats ) {
266 if ( $parent !==
null ) {
268 $this->
complete[$child][
'calls'][$parent] = $stats;
269 $this->
complete[$parent][
'subcalls'][$child] = $stats;
272 if ( isset( $this->
complete[$parent] ) ) {
274 foreach ( $stats
as $stat =>
$value ) {
275 if ( $stat ===
'ct' ) {
279 if ( !isset( $this->
complete[$parent][$stat] ) ) {
289 uasort( $this->
complete, self::makeSortFunction(
290 $this->config[
'sort'],
'exclusive'
305 if ( isset( $edges[$function][
'calls'] ) ) {
306 return array_keys( $edges[$function][
'calls'] );
321 if ( isset( $edges[$function][
'subcalls'] ) ) {
322 return array_keys( $edges[$function][
'subcalls'] );
337 $func => $this->hieraData[$func],
343 foreach ( $callees
as $callee ) {
344 $call =
"{$func}==>{$callee}";
345 if ( $maxCall ===
null ||
346 $this->hieraData[$call][$metric] >
347 $this->hieraData[$maxCall][$metric]
349 $maxCallee = $callee;
353 if ( $maxCall !==
null ) {
354 $path[$maxCall] = $this->hieraData[$maxCall];
370 return function ( $a, $b )
use ( $key, $sub ) {
371 if ( isset( $a[$key] ) && isset( $b[$key] ) ) {
375 $valA = is_array( $a[$key] ) ? $a[$key][$sub] : $a[$key];
376 $valB = is_array( $b[$key] ) ? $b[$key][$sub] : $b[$key];
377 return $valB - $valA;
380 return isset( $a[$key] ) ? -1 : 1;