Stat   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 38
c 1
b 0
f 1
dl 0
loc 86
rs 10
wmc 18

8 Methods

Rating   Name   Duplication   Size   Complexity  
A addTrace() 0 5 2
A __construct() 0 5 1
A calculateEntryTotals() 0 9 3
A clearCurrentSamples() 0 6 2
A updateTotalSampleCount() 0 3 1
A updateStat() 0 9 2
A sort() 0 13 4
A addFrame() 0 14 3
1
<?php
2
3
/**
4
 * This file is part of the sj-i/ package.
5
 *
6
 * (c) sji <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace PhpProfiler\Inspector\Output\TopLike;
15
16
use PhpProfiler\Lib\PhpProcessReader\CallFrame;
17
use PhpProfiler\Lib\PhpProcessReader\CallTrace;
18
19
final class Stat
20
{
21
    /** @param array<string, FunctionEntry> $function_entries */
22
    public function __construct(
23
        public array $function_entries = [],
24
        public int $sample_count = 0,
25
        public int $total_count = 0,
26
    ) {
27
    }
28
29
    public function addTrace(CallTrace $call_trace): void
30
    {
31
        $this->sample_count++;
32
        foreach ($call_trace->call_frames as $frame_number => $call_frame) {
33
            $this->addFrame($call_frame, $frame_number === 0);
34
        }
35
    }
36
37
    private function addFrame(CallFrame $call_frame, bool $is_first_frame): void
38
    {
39
        $name = $call_frame->getFullyQualifiedFunctionName();
40
        if (!isset($this->function_entries[$name])) {
41
            $this->function_entries[$name] = new FunctionEntry(
42
                $name,
43
                $call_frame->file_name,
44
                $call_frame->getLineno(),
45
            );
46
        }
47
        if ($is_first_frame) {
48
            $this->function_entries[$name]->count_exclusive++;
49
        }
50
        $this->function_entries[$name]->count_inclusive++;
51
    }
52
53
    public function updateStat(): void
54
    {
55
        if (count($this->function_entries) === 0) {
56
            return;
57
        }
58
59
        $this->calculateEntryTotals();
60
        $this->sort();
61
        $this->updateTotalSampleCount();
62
    }
63
64
65
    public function sort(): void
66
    {
67
        \uasort($this->function_entries, function (FunctionEntry $a, FunctionEntry $b) {
68
            if ($b->count_exclusive === $a->count_exclusive) {
69
                if ($b->count_inclusive === $a->count_inclusive) {
70
                    if ($b->total_count_exclusive === $a->total_count_exclusive) {
71
                        return $b->total_count_inclusive <=> $a->total_count_inclusive;
72
                    }
73
                    return $b->total_count_exclusive <=> $a->total_count_exclusive;
74
                }
75
                return $b->count_inclusive <=> $a->count_inclusive;
76
            }
77
            return $b->count_exclusive <=> $a->count_exclusive;
78
        });
79
    }
80
81
    public function calculateEntryTotals(): void
82
    {
83
        foreach ($this->function_entries as $function_entry) {
84
            $function_entry->total_count_exclusive += $function_entry->count_exclusive;
85
            $function_entry->total_count_inclusive += $function_entry->count_inclusive;
86
            $function_entry->percent_exclusive =
87
                $this->sample_count < 1
88
                ? 0.0
89
                : 100.0 * $function_entry->count_exclusive / $this->sample_count
90
            ;
91
        }
92
    }
93
94
    public function updateTotalSampleCount(): void
95
    {
96
        $this->total_count += $this->sample_count;
97
    }
98
99
    public function clearCurrentSamples(): void
100
    {
101
        $this->sample_count = 0;
102
        foreach ($this->function_entries as $function_entry) {
103
            $function_entry->count_exclusive = 0;
104
            $function_entry->count_inclusive = 0;
105
        }
106
    }
107
}
108