PageRenderTime 52ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/web/modules/contrib/devel/webprofiler/src/Stopwatch.php

https://gitlab.com/andecode/theme-spark
PHP | 609 lines | 192 code | 76 blank | 341 comment | 13 complexity | 44d02c28b3fd1afcec04c2eb59515d33 MD5 | raw file
  1. <?php
  2. namespace Drupal\webprofiler {
  3. use Symfony\Component\Stopwatch\Stopwatch as SymfonyStopwatch;
  4. /**
  5. * Class Stopwatch.
  6. */
  7. class Stopwatch extends SymfonyStopwatch {
  8. }
  9. }
  10. namespace Symfony\Component\Stopwatch {
  11. /**
  12. * Class Stopwatch.
  13. */
  14. class Stopwatch {
  15. /**
  16. * @var Section[]
  17. */
  18. private $sections;
  19. /**
  20. * @var array
  21. */
  22. private $activeSections;
  23. /**
  24. * @inheritdoc
  25. */
  26. public function __construct() {
  27. $this->sections = $this->activeSections = ['__root__' => new Section('__root__')];
  28. }
  29. /**
  30. * Creates a new section or re-opens an existing section.
  31. *
  32. * @param string|null $id
  33. * The id of the session to re-open, null to create a new one.
  34. *
  35. * @throws \LogicException
  36. * When the section to re-open is not reachable.
  37. */
  38. public function openSection($id = NULL) {
  39. $current = end($this->activeSections);
  40. if (NULL !== $id && NULL === $current->get($id)) {
  41. throw new \LogicException(sprintf('The section "%s" has been started at an other level and can not be opened.', $id));
  42. }
  43. $this->start('__section__.child', 'section');
  44. $this->activeSections[] = $current->open($id);
  45. $this->start('__section__');
  46. }
  47. /**
  48. * Stops the last started section.
  49. *
  50. * The id parameter is used to retrieve the events from this section.
  51. *
  52. * @param string $id
  53. * The identifier of the section.
  54. *
  55. * @throws \LogicException
  56. * When there's no started section to be stopped.
  57. *
  58. * @see getSectionEvents
  59. */
  60. public function stopSection($id) {
  61. $this->stop('__section__');
  62. if (1 == count($this->activeSections)) {
  63. throw new \LogicException('There is no started section to stop.');
  64. }
  65. $this->sections[$id] = array_pop($this->activeSections)->setId($id);
  66. $this->stop('__section__.child');
  67. }
  68. /**
  69. * Starts an event.
  70. *
  71. * @param string $name
  72. * The event name.
  73. * @param string $category
  74. * The event category.
  75. *
  76. * @return \Symfony\Component\Stopwatch\StopwatchEvent
  77. * A StopwatchEvent instance
  78. */
  79. public function start($name, $category = NULL) {
  80. return end($this->activeSections)->startEvent($name, $category);
  81. }
  82. /**
  83. * Checks if the named event was started.
  84. *
  85. * @param string $name
  86. * The event name.
  87. *
  88. * @return bool
  89. * True if the event was started.
  90. */
  91. public function isStarted($name) {
  92. return end($this->activeSections)->isEventStarted($name);
  93. }
  94. /**
  95. * Stops an event.
  96. *
  97. * @param string $name
  98. * The event name.
  99. *
  100. * @return \Symfony\Component\Stopwatch\StopwatchEvent
  101. * A StopwatchEvent instance
  102. */
  103. public function stop($name) {
  104. return end($this->activeSections)->stopEvent($name);
  105. }
  106. /**
  107. * Stops then restarts an event.
  108. *
  109. * @param string $name
  110. * The event name.
  111. *
  112. * @return \Symfony\Component\Stopwatch\StopwatchEvent
  113. * A StopwatchEvent instance
  114. */
  115. public function lap($name) {
  116. return end($this->activeSections)->stopEvent($name)->start();
  117. }
  118. /**
  119. * Gets all events for a given section.
  120. *
  121. * @param string $id
  122. * A section identifier.
  123. *
  124. * @return \Symfony\Component\Stopwatch\StopwatchEvent[]
  125. * An array of StopwatchEvent instances
  126. */
  127. public function getSectionEvents($id) {
  128. return isset($this->sections[$id]) ? $this->sections[$id]->getEvents() : [];
  129. }
  130. }
  131. /**
  132. * @internal This class is for internal usage only
  133. *
  134. * Original author Fabien Potencier <fabien@symfony.com>
  135. */
  136. class Section {
  137. /**
  138. * @var \Symfony\Component\Stopwatch\StopwatchEvent[]
  139. */
  140. private $events = [];
  141. /**
  142. * @var null|float
  143. */
  144. private $origin;
  145. /**
  146. * @var string
  147. */
  148. private $id;
  149. /**
  150. * @var Section[]
  151. */
  152. private $children = [];
  153. /**
  154. * Constructor.
  155. *
  156. * @param float|null $origin
  157. * Set the origin of the events in this section, use null to set their
  158. * origin to their start time.
  159. */
  160. public function __construct($origin = NULL) {
  161. $this->origin = is_numeric($origin) ? $origin : NULL;
  162. }
  163. /**
  164. * Returns the child section.
  165. *
  166. * @param string $id
  167. * The child section identifier.
  168. *
  169. * @return Section|null
  170. * The child section or null when none found
  171. */
  172. public function get($id) {
  173. foreach ($this->children as $child) {
  174. if ($id === $child->getId()) {
  175. return $child;
  176. }
  177. }
  178. return NULL;
  179. }
  180. /**
  181. * Creates or re-opens a child section.
  182. *
  183. * @param string|null $id
  184. * Null to create a new section, the identifier to re-open an existing
  185. * one.
  186. *
  187. * @return Section
  188. * A child section
  189. */
  190. public function open($id) {
  191. if (NULL === $session = $this->get($id)) {
  192. $session = $this->children[] = new self(microtime(TRUE) * 1000);
  193. }
  194. return $session;
  195. }
  196. /**
  197. * @return string
  198. * The identifier of the section
  199. */
  200. public function getId() {
  201. return $this->id;
  202. }
  203. /**
  204. * Sets the session identifier.
  205. *
  206. * @param string $id
  207. * The session identifier.
  208. *
  209. * @return Section
  210. * The current section
  211. */
  212. public function setId($id) {
  213. $this->id = $id;
  214. return $this;
  215. }
  216. /**
  217. * Starts an event.
  218. *
  219. * @param string $name
  220. * The event name.
  221. * @param string $category
  222. * The event category.
  223. *
  224. * @return \Symfony\Component\Stopwatch\StopwatchEvent
  225. * The event
  226. */
  227. public function startEvent($name, $category) {
  228. if (!isset($this->events[$name])) {
  229. $this->events[$name] = new StopwatchEvent($this->origin ?: microtime(TRUE) * 1000, $category);
  230. }
  231. return $this->events[$name]->start();
  232. }
  233. /**
  234. * Checks if an event was started.
  235. *
  236. * @param string $name
  237. * The event name.
  238. *
  239. * @return bool
  240. * True if the specified event was started.
  241. */
  242. public function isEventStarted($name) {
  243. return isset($this->events[$name]) && $this->events[$name]->isStarted();
  244. }
  245. /**
  246. * Stops an event.
  247. *
  248. * @param string $name
  249. * The event name.
  250. *
  251. * @return \Symfony\Component\Stopwatch\StopwatchEvent
  252. * The event.
  253. *
  254. * @throws \LogicException
  255. * When the event has not been started.
  256. */
  257. public function stopEvent($name) {
  258. if (!isset($this->events[$name])) {
  259. throw new \LogicException(sprintf('Event "%s" is not started.', $name));
  260. }
  261. return $this->events[$name]->stop();
  262. }
  263. /**
  264. * Stops then restarts an event.
  265. *
  266. * @param string $name
  267. * The event name.
  268. *
  269. * @return \Symfony\Component\Stopwatch\StopwatchEvent
  270. * The event.
  271. *
  272. * @throws \LogicException
  273. * When the event has not been started.
  274. */
  275. public function lap($name) {
  276. return $this->stopEvent($name)->start();
  277. }
  278. /**
  279. * Returns the events from this section.
  280. *
  281. * @return \Symfony\Component\Stopwatch\StopwatchEvent[]
  282. * An array of StopwatchEvent instances
  283. */
  284. public function getEvents() {
  285. return $this->events;
  286. }
  287. }
  288. /**
  289. * Class StopwatchEvent.
  290. */
  291. class StopwatchEvent {
  292. /**
  293. * @var \Symfony\Component\Stopwatch\StopwatchPeriod[]
  294. */
  295. private $periods = [];
  296. /**
  297. * @var float
  298. */
  299. private $origin;
  300. /**
  301. * @var string
  302. */
  303. private $category;
  304. /**
  305. * @var float[]
  306. */
  307. private $started = [];
  308. /**
  309. * Constructor.
  310. *
  311. * @param float $origin
  312. * The origin time in milliseconds.
  313. * @param string|null $category
  314. * The event category or null to use the default.
  315. *
  316. * @throws \InvalidArgumentException
  317. * When the raw time is not valid.
  318. */
  319. public function __construct($origin, $category = NULL) {
  320. $this->origin = $this->formatTime($origin);
  321. $this->category = is_string($category) ? $category : 'default';
  322. }
  323. /**
  324. * Gets the category.
  325. *
  326. * @return string
  327. * The category.
  328. */
  329. public function getCategory() {
  330. return $this->category;
  331. }
  332. /**
  333. * Gets the origin.
  334. *
  335. * @return float
  336. * The origin in milliseconds.
  337. */
  338. public function getOrigin() {
  339. return $this->origin;
  340. }
  341. /**
  342. * Starts a new event period.
  343. *
  344. * @return \Symfony\Component\Stopwatch\StopwatchEvent
  345. * The event.
  346. */
  347. public function start() {
  348. $this->started[] = $this->getNow();
  349. return $this;
  350. }
  351. /**
  352. * Stops the last started event period.
  353. *
  354. * @return \Symfony\Component\Stopwatch\StopwatchEvent
  355. * The event.
  356. *
  357. * @throws \LogicException
  358. * When stop() is called without a matching call to start().
  359. */
  360. public function stop() {
  361. if (!count($this->started)) {
  362. throw new \LogicException('stop() called but start() has not been called before.');
  363. }
  364. $this->periods[] = new StopwatchPeriod(array_pop($this->started), $this->getNow());
  365. return $this;
  366. }
  367. /**
  368. * Checks if this event was started.
  369. *
  370. * @return bool
  371. * True if this event was started.
  372. */
  373. public function isStarted() {
  374. return !empty($this->started);
  375. }
  376. /**
  377. * Stops the current period and then starts a new one.
  378. *
  379. * @return \Symfony\Component\Stopwatch\StopwatchEvent
  380. * The event.
  381. */
  382. public function lap() {
  383. return $this->stop()->start();
  384. }
  385. /**
  386. * Stops all non already stopped periods.
  387. */
  388. public function ensureStopped() {
  389. while (count($this->started)) {
  390. $this->stop();
  391. }
  392. }
  393. /**
  394. * Gets all event periods.
  395. *
  396. * @return \Symfony\Component\Stopwatch\StopwatchPeriod[]
  397. * An array of StopwatchPeriod instances.
  398. */
  399. public function getPeriods() {
  400. return $this->periods;
  401. }
  402. /**
  403. * Gets the relative time of the start of the first period.
  404. *
  405. * @return int
  406. * The time (in milliseconds).
  407. */
  408. public function getStartTime() {
  409. return isset($this->periods[0]) ? $this->periods[0]->getStartTime() : 0;
  410. }
  411. /**
  412. * Gets the relative time of the end of the last period.
  413. *
  414. * @return int
  415. * The time (in milliseconds).
  416. */
  417. public function getEndTime() {
  418. return ($count = count($this->periods)) ? $this->periods[$count - 1]->getEndTime() : 0;
  419. }
  420. /**
  421. * Gets the duration of the events (including all periods).
  422. *
  423. * @return int
  424. * The duration (in milliseconds).
  425. */
  426. public function getDuration() {
  427. $total = 0;
  428. foreach ($this->periods as $period) {
  429. $total += $period->getDuration();
  430. }
  431. return $total;
  432. }
  433. /**
  434. * Gets the max memory usage of all periods.
  435. *
  436. * @return int
  437. * The memory usage (in bytes).
  438. */
  439. public function getMemory() {
  440. $memory = 0;
  441. foreach ($this->periods as $period) {
  442. if ($period->getMemory() > $memory) {
  443. $memory = $period->getMemory();
  444. }
  445. }
  446. return $memory;
  447. }
  448. /**
  449. * Return the current time relative to origin.
  450. *
  451. * @return float
  452. * Time in ms.
  453. */
  454. protected function getNow() {
  455. return $this->formatTime(microtime(TRUE) * 1000 - $this->origin);
  456. }
  457. /**
  458. * Formats a time.
  459. *
  460. * @param int|float $time
  461. * A raw time.
  462. *
  463. * @return float
  464. * The formatted time.
  465. *
  466. * @throws \InvalidArgumentException
  467. * When the raw time is not valid.
  468. */
  469. private function formatTime($time) {
  470. if (!is_numeric($time)) {
  471. throw new \InvalidArgumentException('The time must be a numerical value');
  472. }
  473. return round($time, 1);
  474. }
  475. }
  476. /**
  477. * Class StopwatchPeriod.
  478. */
  479. class StopwatchPeriod {
  480. private $start;
  481. private $end;
  482. private $memory;
  483. /**
  484. * Constructor.
  485. *
  486. * @param int $start
  487. * The relative time of the start of the period (in milliseconds)
  488. * @param int $end
  489. * The relative time of the end of the period (in milliseconds)
  490. */
  491. public function __construct($start, $end) {
  492. $this->start = (integer) $start;
  493. $this->end = (integer) $end;
  494. $this->memory = memory_get_usage(TRUE);
  495. }
  496. /**
  497. * Gets the relative time of the start of the period.
  498. *
  499. * @return int
  500. * The time (in milliseconds).
  501. */
  502. public function getStartTime() {
  503. return $this->start;
  504. }
  505. /**
  506. * Gets the relative time of the end of the period.
  507. *
  508. * @return int
  509. * The time (in milliseconds).
  510. */
  511. public function getEndTime() {
  512. return $this->end;
  513. }
  514. /**
  515. * Gets the time spent in this period.
  516. *
  517. * @return int
  518. * The period duration (in milliseconds).
  519. */
  520. public function getDuration() {
  521. return $this->end - $this->start;
  522. }
  523. /**
  524. * Gets the memory usage.
  525. *
  526. * @return int
  527. * The memory usage (in bytes).
  528. */
  529. public function getMemory() {
  530. return $this->memory;
  531. }
  532. }
  533. }