Passed
Pull Request — 0.9.x (#272)
by Nikita
11:35
created

SpeedscopeCommand::getTraceIterator()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the reliforp/reli-prof 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 Reli\Command\Converter;
15
16
use Reli\Converter\ParsedCallTrace;
17
use Reli\Converter\PhpSpyCompatibleParser;
18
use Symfony\Component\Console\Command\Command;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Command\Command was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use Symfony\Component\Console\Input\InputInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Input\InputInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Symfony\Component\Console\Output\OutputInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Output\OutputInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
22
final class SpeedscopeCommand extends Command
23
{
24
    public function configure(): void
25
    {
26
        $this->setName('converter:speedscope')
27
            ->setDescription('convert traces to the speedscope file format')
28
        ;
29
    }
30
31
    public function execute(InputInterface $input, OutputInterface $output): int
32
    {
33
        $parser = new PhpSpyCompatibleParser();
34
        $output->write(
35
            json_encode(
36
                $this->collectFrames(
37
                    $parser->parseFile(STDIN)
38
                )
39
            )
40
        );
41
        return 0;
42
    }
43
44
    /** @param iterable<ParsedCallTrace> $call_frames */
45
    private function collectFrames(iterable $call_frames): array
46
    {
47
        $mapper = fn (array $value): string => \json_encode($value);
48
        $trace_map = [];
49
        $result_frames = [];
50
        $sampled_stacks = [];
51
        $counter = 0;
52
        foreach ($call_frames as $frames) {
53
            $sampled_stack = [];
54
            foreach ($frames->call_frames as $call_frame) {
55
                    $frame = [
56
                    'name' => $call_frame->function_name,
57
                    'file' => $call_frame->file_name,
58
                    'line' => $call_frame->lineno,
59
                    ];
60
                    $mapper_key = $mapper($frame);
61
                    if (!isset($trace_map[$mapper_key])) {
62
                        $result_frames[] = $frame;
63
                        $trace_map[$mapper_key] = array_key_last($result_frames);
64
                    }
65
                    $sampled_stack[] = $trace_map[$mapper_key];
66
            }
67
            $sampled_stacks[] = \array_reverse($sampled_stack);
68
            $counter++;
69
        }
70
        return [
71
            "\$schema" => "https://www.speedscope.app/file-format-schema.json",
72
            'shared' => [
73
                'frames' => $result_frames,
74
            ],
75
            'profiles' => [[
76
                'type' => 'sampled',
77
                'name' => 'php profile',
78
                'unit' => 'none',
79
                'startValue' => 0,
80
                'endValue' => $counter,
81
                'samples' => $sampled_stacks,
82
                'weights' => array_fill(0, count($sampled_stacks), 1),
83
            ]]
84
        ];
85
    }
86
}
87