PocketMine-MP 5.15.1 git-5ef247620a7c6301a849b54e5ef1009217729fc8
TimingsRecord.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\timings;
25
28use function floor;
29use function spl_object_id;
30
36final class TimingsRecord{
41 private static array $records = [];
42
43 private static ?self $currentRecord = null;
44
48 public static function reset() : void{
49 foreach(self::$records as $record){
50 $record->handler->reset();
51 }
52 self::$records = [];
53 self::$currentRecord = null;
54 }
55
60 public static function getAll() : array{ return self::$records; }
61
62 public static function tick(bool $measure = true) : void{
63 if($measure){
64 foreach(self::$records as $record){
65 if($record->curCount > 0){
66 if($record->curTickTotal > Server::TARGET_NANOSECONDS_PER_TICK){
67 $record->violations += (int) floor($record->curTickTotal / Server::TARGET_NANOSECONDS_PER_TICK);
68 }
69 $record->curTickTotal = 0;
70 $record->curCount = 0;
71 $record->ticksActive++;
72 }
73 }
74 }else{
75 foreach(self::$records as $record){
76 $record->totalTime -= $record->curTickTotal;
77 $record->count -= $record->curCount;
78
79 $record->curTickTotal = 0;
80 $record->curCount = 0;
81 }
82 }
83 }
84
85 private int $count = 0;
86 private int $curCount = 0;
87 private int $start = 0;
88 private int $totalTime = 0;
89 private int $curTickTotal = 0;
90 private int $violations = 0;
91 private int $ticksActive = 0;
92 private int $peakTime = 0;
93
94 public function __construct(
95 //I'm not the biggest fan of this cycle, but it seems to be the most effective way to avoid leaking anything.
96 private TimingsHandler $handler,
97 private ?TimingsRecord $parentRecord
98 ){
99 self::$records[spl_object_id($this)] = $this;
100 }
101
102 public function getId() : int{ return spl_object_id($this); }
103
104 public function getParentId() : ?int{ return $this->parentRecord?->getId(); }
105
106 public function getTimerId() : int{ return spl_object_id($this->handler); }
107
108 public function getName() : string{ return $this->handler->getName(); }
109
110 public function getGroup() : string{ return $this->handler->getGroup(); }
111
112 public function getCount() : int{ return $this->count; }
113
114 public function getCurCount() : int{ return $this->curCount; }
115
116 public function getStart() : float{ return $this->start; }
117
118 public function getTotalTime() : float{ return $this->totalTime; }
119
120 public function getCurTickTotal() : float{ return $this->curTickTotal; }
121
122 public function getViolations() : int{ return $this->violations; }
123
124 public function getTicksActive() : int{ return $this->ticksActive; }
125
126 public function getPeakTime() : int{ return $this->peakTime; }
127
128 public function startTiming(int $now) : void{
129 $this->start = $now;
130 self::$currentRecord = $this;
131 }
132
133 public function stopTiming(int $now) : void{
134 if($this->start == 0){
135 return;
136 }
137 if(self::$currentRecord !== $this){
138 if(self::$currentRecord === null){
139 //timings may have been stopped while this timer was running
140 return;
141 }
142
143 throw new AssumptionFailedError("stopTiming() called on a non-current timer");
144 }
145 self::$currentRecord = $this->parentRecord;
146 $diff = $now - $this->start;
147 $this->totalTime += $diff;
148 $this->curTickTotal += $diff;
149 ++$this->curCount;
150 ++$this->count;
151 $this->start = 0;
152 if($diff > $this->peakTime){
153 $this->peakTime = $diff;
154 }
155 }
156
157 public static function getCurrentRecord() : ?self{
158 return self::$currentRecord;
159 }
160}