ExecutionSpeed::push()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 2
1
<?php
2
/*
3
 * This file is part of the Execution Speed package.
4
 *
5
 * (c) Bogdan Koval' <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
declare(strict_types = 1);
12
13
namespace Bogkov\ExecutionSpeed;
14
15
use InvalidArgumentException;
16
17
/**
18
 * Class ExecutionSpeed
19
 *
20
 * @package Bogkov\ExecutionSpeed
21
 */
22
class ExecutionSpeed
23
{
24
    const MIN_MAX = 5;
25
    const MIN_COEFFICIENT = 0.001;
26
27
    /**
28
     * @var array
29
     */
30
    protected $stack = [];
31
32
    /**
33
     * @var int
34
     */
35
    protected $max = 50;
36
37
    /**
38
     * ExecutionSpeed constructor
39
     *
40
     * @param int $max max
41
     *
42
     * @throws InvalidArgumentException
43
     */
44
    public function __construct(int $max = 50)
45
    {
46
        if (static::MIN_MAX > $max) {
47
            throw new InvalidArgumentException('Max must be more than ' . static::MIN_MAX);
48
        }
49
50
        $this->max = $max;
51
    }
52
53
    /**
54
     * @param int $count    count
55
     * @param int $duration duration
56
     *
57
     * @return void
58
     */
59
    public function push(int $count, int $duration)/*: void*/
60
    {
61
        \array_unshift(
62
            $this->stack,
63
            [
64
                $count => $duration,
65
            ]
66
        );
67
68
        $this->stack = \array_slice($this->stack, 0, $this->max);
69
    }
70
71
    /**
72
     * @param float $coefficient
73
     * @param int   $precision
74
     *
75
     * @return float
76
     */
77
    public function getSpeed(float $coefficient = 0.3, int $precision = 1): float
78
    {
79
        $coefficients = $this->getCoefficients($coefficient);
80
81
        $result = null;
82
83
        foreach ($this->stack as $index => $item) {
84
            $value = key($item) / current($item);
85
            $coefficient = $coefficients[$index];
86
87
            if (null !== $result) {
88
                $average = ($result + $value) / 2;
89
                $difference = $result - $average;
90
                $actualDifference = $difference - $difference * (1 - $coefficient);
91
                $value = $result - $actualDifference;
92
            }
93
94
            $result = $value;
95
        }
96
97
        return \round($result, $precision);
98
    }
99
100
    /**
101
     * @param float $coefficient coefficient
102
     *
103
     * @return array
104
     */
105
    protected function getCoefficients(float $coefficient): array
106
    {
107
        $value = 1;
108
109
        $coefficients = [
110
            $value,
111
        ];
112
113
        $max = $this->max;
114
        while (--$max > 0) {
115
            $value -= ($coefficient * $value);
116
117
            if (static::MIN_COEFFICIENT >= $value) {
118
                $value = static::MIN_COEFFICIENT;
119
            }
120
121
            $coefficients[] = $value;
122
        }
123
124
        return $coefficients;
125
    }
126
}