Completed
Branch 0.4-dev (d27253)
by Evgenij
03:26
created

SpeedRateCounter::reset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * Async sockets
4
 *
5
 * @copyright Copyright (c) 2015-2017, Efimov Evgenij <[email protected]>
6
 *
7
 * This source file is subject to the MIT license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
namespace AsyncSockets\RequestExecutor\Metadata;
11
12
/**
13
 * Class SpeedRateCounter
14
 */
15
class SpeedRateCounter
16
{
17
    /**
18
     * Amount of processed bytes
19
     *
20
     * @var int
21
     */
22
    private $totalBytesProcessed;
23
24
    /**
25
     * Time when request is started
26
     *
27
     * @var double
28
     */
29
    private $initialTime;
30
31
    /**
32
     * Time of last measurement
33
     *
34
     * @var double
35
     */
36
    private $currentTime;
37
38
    /**
39
     * Time when speed felt below minimal
40
     *
41
     * @var double
42
     */
43
    private $slowStartTime;
44
45
    /**
46
     * Minimum allowed speed in bytes per second
47
     *
48
     * @var double
49
     */
50
    private $minSpeed;
51
52
    /**
53
     * Maximum duration of minimum speed in seconds
54
     *
55
     * @var double
56
     */
57
    private $maxDuration;
58
59
    /**
60
     * Current speed
61
     *
62
     * @var double
63
     */
64
    private $currentSpeed;
65
66
    /**
67
     * SpeedRateCounter constructor.
68
     *
69
     * @param double $minSpeed Minimum allowed speed in bytes per second
70
     * @param double $maxDuration Maximum duration of minimum speed in seconds
71
     */
72 89
    public function __construct($minSpeed, $maxDuration)
73
    {
74 89
        $this->minSpeed    = $minSpeed;
75 89
        $this->maxDuration = $maxDuration;
76 89
        $this->reset();
77 89
    }
78
79
    /**
80
     * Resets this counter
81
     *
82
     * @return void
83
     */
84 89
    public function reset()
85
    {
86 89
        $this->initialTime         = null;
87 89
        $this->currentTime         = null;
88 89
        $this->totalBytesProcessed = 0;
89 89
        $this->currentSpeed        = 0.0;
90 89
        $this->slowStartTime       = null;
91 89
    }
92
93
    /**
94
     * Process next measurement
95
     *
96
     * @param double $time Time in seconds
97
     * @param double $value Amount of received data in bytes
98
     *
99
     * @return void
100
     * @throws \OverflowException When speed is slower then desired
101
     */
102 89
    public function advance($time, $value)
103
    {
104 89
        $this->measure($time, $value);
105 89
        $this->currentSpeed = $this->getAverageSpeed();
106 89
        $skipCheck = $this->minSpeed === null ||
107 11
                     $this->maxDuration === null ||
108 10
                     $this->currentSpeed === null ||
109 89
                     $this->currentSpeed >= $this->minSpeed;
110
111 89
        if ($skipCheck) {
112 82
            $this->slowStartTime = null;
113 82
            return;
114
        }
115
116 10
        $this->slowStartTime = $this->slowStartTime !== null ? $this->slowStartTime : $time;
117
118 10
        if ($time - $this->slowStartTime > $this->maxDuration) {
119 2
            throw new \OverflowException();
120
        }
121 10
    }
122
123
    /**
124
     * Adds measure for counter
125
     *
126
     * @param double $time Time for given value in absolute timestamp
127
     * @param double $value A value
128
     *
129
     * @return void
130
     */
131 89
    private function measure($time, $value)
132
    {
133 89
        if ($this->initialTime === null) {
134 89
            $this->initialTime = $time;
135 89
        } else {
136 78
            $this->currentTime = $time;
137
        }
138
139 89
        $this->totalBytesProcessed += $value;
140 89
    }
141
142
    /**
143
     * Return average speed for measurements
144
     *
145
     * @return double|null
146
     */
147 89
    private function getAverageSpeed()
148
    {
149 89
        $timeElapsed = $this->currentTime - $this->initialTime;
150
151 89
        return $timeElapsed > 0 ? ($this->totalBytesProcessed / $timeElapsed) : 0.0;
152
    }
153
154
    /**
155
     * Return current speed in bytes per seconds
156
     *
157
     * @return float
158
     */
159 88
    public function getCurrentSpeed()
160
    {
161 88
        return $this->getAverageSpeed();
162
    }
163
164
    /**
165
     * Return duration of current slow speed
166
     *
167
     * @return double
168
     */
169 10
    public function getCurrentDuration()
170
    {
171 10
        return $this->slowStartTime !== null ? $this->currentTime - $this->slowStartTime : 0.0;
172
    }
173
}
174