Passed
Push — master ( de2315...d20eef )
by Alec
02:19
created

EventCounter::trim()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 4
nc 4
nop 0
crap 4
1
<?php
2
/**
3
 * User: alec
4
 * Date: 03.11.18
5
 * Time: 10:26
6
 */
7
declare(strict_types=1);
8
9
namespace AlecRabbit\Event;
10
11
class EventCounter
12
{
13
    protected const DEFAULT_NAME = 'default';
14
    protected const DEFAULT_LENGTH = 3600;
15
    protected const DEFAULT_GROUP_BY = 60;
16
17
    /** @var array */
18
    protected $events = [];
19
20
    /** @var int */
21
    protected $length;
22
23
    /** @var string */
24
    protected $name;
25
26
    /** @var int|null */
27
    protected $groupBy;
28
29
    /** @var int */
30
    protected $lastTimestamp;
31
32
    /** @var bool */
33
    private $relativeMode;
34
35
    /**
36
     * EventCounter constructor.
37
     * @param int|null $length Time length in seconds e.g. 3600 => 1 hour
38
     * @param int|null $groupBy Group by period of time in seconds e.g. 60 => 1 min
39
     * @param bool|null $relativeMode
40
     */
41 3
    public function __construct(?int $length = null, ?int $groupBy = null, ?bool $relativeMode = null)
42
    {
43 3
        $this->name = static::DEFAULT_NAME;
44 3
        $this->length = $length ?? static::DEFAULT_LENGTH;
45 3
        $this->groupBy = $groupBy;
46 3
        $this->relativeMode = $relativeMode ?? false;
47 3
        $this->lastTimestamp = 0;
48 3
    }
49
50
    /**
51
     * @param int|null $time
52
     */
53 3
    public function addEvent(?int $time = null): void
54
    {
55 3
        $this->lastTimestamp = $time = $time ?? time();
56 3
        if (null !== $this->groupBy) {
57 2
            $time = base_timestamp($time, $this->groupBy);
58
        }
59
        // Is there any event during [$time] period? If not initialize with 0
60 3
        $this->events[$time] = $this->events[$time] ?? 0;
61 3
        $this->events[$time]++;
62 3
        $this->trim();
63 3
    }
64
65 3
    private function trim(): void
66
    {
67 3
        $time = $this->relativeMode ? $this->lastTimestamp : time();
68 3
        $threshold = $time - $this->length;
69 3
        if (null !== ($key = array_key_first($this->events)) && ($key <= $threshold)) {
70 1
            unset($this->events[$key]);
71
        }
72 3
    }
73
74
    /**
75
     * @param bool|null $reset
76
     * @return int
77
     */
78 3
    public function getCalculatedEvents(?bool $reset = null): int
79
    {
80 3
        $r = 0;
81 3
        if (0 < ($sum = (int)array_sum($this->events))) {
82 3
            $r = $sum;
83
        }
84 3
        if ($reset) {
85 2
            $this->events = [];
86
        }
87 3
        return $r;
88
    }
89
90
    /**
91
     * @return string
92
     */
93 1
    public function getName(): string
94
    {
95 1
        return $this->name;
96
    }
97
98
    /**
99
     * @param string $name
100
     * @return EventCounter
101
     */
102 1
    public function setName(string $name): EventCounter
103
    {
104 1
        $this->name = $name;
105 1
        return $this;
106
    }
107
108
    /**
109
     * Set to this mode to count events by timestamps.
110
     *
111
     * @param bool $relative
112
     * @return EventCounter
113
     */
114 2
    public function setRelativeMode(bool $relative = true): EventCounter
115
    {
116 2
        $this->relativeMode = $relative;
117 2
        return $this;
118
    }
119
120
    /**
121
     * @return array
122
     */
123 3
    public function getEvents(): array
124
    {
125 3
        return $this->events;
126
    }
127
}
128