initial commit

This commit is contained in:
boris
2025-09-30 09:24:25 +01:00
committed by boris
parent a783a12c97
commit c7770ea03b
4695 changed files with 525784 additions and 0 deletions

30
vendor/symfony/stopwatch/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,30 @@
CHANGELOG
=========
7.2
---
* Add method `getLastPeriod()` to `StopwatchEvent`
* Add `getRootSectionEvents()` method and `ROOT` constant to `Stopwatch`
5.2
---
* Add `name` argument to the `StopWatchEvent` constructor, accessible via a new `StopwatchEvent::getName()`
5.0.0
-----
* Removed support for passing `null` as 1st (`$id`) argument of `Section::get()` method, pass a valid child section identifier instead.
4.4.0
-----
* Deprecated passing `null` as 1st (`$id`) argument of `Section::get()` method, pass a valid child section identifier instead.
3.4.0
-----
* added the `Stopwatch::reset()` method
* allowed to measure sub-millisecond times by introducing an argument to the
constructor of `Stopwatch`

19
vendor/symfony/stopwatch/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2004-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

42
vendor/symfony/stopwatch/README.md vendored Normal file
View File

@@ -0,0 +1,42 @@
Stopwatch Component
===================
The Stopwatch component provides a way to profile code.
Getting Started
---------------
```bash
composer require symfony/stopwatch
```
```php
use Symfony\Component\Stopwatch\Stopwatch;
$stopwatch = new Stopwatch();
// optionally group events into sections (e.g. phases of the execution)
$stopwatch->openSection();
// starts event named 'eventName'
$stopwatch->start('eventName');
// ... run your code here
// optionally, start a new "lap" time
$stopwatch->lap('foo');
// ... run your code here
$event = $stopwatch->stop('eventName');
$stopwatch->stopSection('phase_1');
```
Resources
---------
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)
in the [main Symfony repository](https://github.com/symfony/symfony)

155
vendor/symfony/stopwatch/Section.php vendored Normal file
View File

@@ -0,0 +1,155 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Stopwatch;
/**
* Stopwatch section.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Section
{
/**
* @var StopwatchEvent[]
*/
private array $events = [];
private ?string $id = null;
/**
* @var Section[]
*/
private array $children = [];
/**
* @param float|null $origin Set the origin of the events in this section, use null to set their origin to their start time
* @param bool $morePrecision If true, time is stored as float to keep the original microsecond precision
*/
public function __construct(
private ?float $origin = null,
private bool $morePrecision = false,
) {
}
/**
* Returns the child section.
*/
public function get(string $id): ?self
{
foreach ($this->children as $child) {
if ($id === $child->getId()) {
return $child;
}
}
return null;
}
/**
* Creates or re-opens a child section.
*
* @param string|null $id Null to create a new section, the identifier to re-open an existing one
*/
public function open(?string $id): self
{
if (null === $id || null === $session = $this->get($id)) {
$session = $this->children[] = new self(microtime(true) * 1000, $this->morePrecision);
}
return $session;
}
public function getId(): ?string
{
return $this->id;
}
/**
* Sets the session identifier.
*
* @return $this
*/
public function setId(string $id): static
{
$this->id = $id;
return $this;
}
/**
* Starts an event.
*/
public function startEvent(string $name, ?string $category): StopwatchEvent
{
if (!isset($this->events[$name])) {
$this->events[$name] = new StopwatchEvent($this->origin ?: microtime(true) * 1000, $category, $this->morePrecision, $name);
}
return $this->events[$name]->start();
}
/**
* Checks if the event was started.
*/
public function isEventStarted(string $name): bool
{
return isset($this->events[$name]) && $this->events[$name]->isStarted();
}
/**
* Stops an event.
*
* @throws \LogicException When the event has not been started
*/
public function stopEvent(string $name): StopwatchEvent
{
if (!isset($this->events[$name])) {
throw new \LogicException(\sprintf('Event "%s" is not started.', $name));
}
return $this->events[$name]->stop();
}
/**
* Stops then restarts an event.
*
* @throws \LogicException When the event has not been started
*/
public function lap(string $name): StopwatchEvent
{
return $this->stopEvent($name)->start();
}
/**
* Returns a specific event by name.
*
* @throws \LogicException When the event is not known
*/
public function getEvent(string $name): StopwatchEvent
{
if (!isset($this->events[$name])) {
throw new \LogicException(\sprintf('Event "%s" is not known.', $name));
}
return $this->events[$name];
}
/**
* Returns the events from this section.
*
* @return StopwatchEvent[]
*/
public function getEvents(): array
{
return $this->events;
}
}

163
vendor/symfony/stopwatch/Stopwatch.php vendored Normal file
View File

@@ -0,0 +1,163 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Stopwatch;
use Symfony\Contracts\Service\ResetInterface;
// Help opcache.preload discover always-needed symbols
class_exists(Section::class);
/**
* Stopwatch provides a way to profile code.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Stopwatch implements ResetInterface
{
public const ROOT = '__root__';
/**
* @var Section[]
*/
private array $sections;
/**
* @var Section[]
*/
private array $activeSections;
/**
* @param bool $morePrecision If true, time is stored as float to keep the original microsecond precision
*/
public function __construct(
private bool $morePrecision = false,
) {
$this->reset();
}
/**
* @return Section[]
*/
public function getSections(): array
{
return $this->sections;
}
/**
* Creates a new section or re-opens an existing section.
*
* @param string|null $id The id of the session to re-open, null to create a new one
*
* @throws \LogicException When the section to re-open is not reachable
*/
public function openSection(?string $id = null): void
{
$current = end($this->activeSections);
if (null !== $id && null === $current->get($id)) {
throw new \LogicException(\sprintf('The section "%s" has been started at an other level and cannot be opened.', $id));
}
$this->start('__section__.child', 'section');
$this->activeSections[] = $current->open($id);
$this->start('__section__');
}
/**
* Stops the last started section.
*
* The id parameter is used to retrieve the events from this section.
*
* @see getSectionEvents()
*
* @throws \LogicException When there's no started section to be stopped
*/
public function stopSection(string $id): void
{
$this->stop('__section__');
if (1 == \count($this->activeSections)) {
throw new \LogicException('There is no started section to stop.');
}
$this->sections[$id] = array_pop($this->activeSections)->setId($id);
$this->stop('__section__.child');
}
/**
* Starts an event.
*/
public function start(string $name, ?string $category = null): StopwatchEvent
{
return end($this->activeSections)->startEvent($name, $category);
}
/**
* Checks if the event was started.
*/
public function isStarted(string $name): bool
{
return end($this->activeSections)->isEventStarted($name);
}
/**
* Stops an event.
*/
public function stop(string $name): StopwatchEvent
{
return end($this->activeSections)->stopEvent($name);
}
/**
* Stops then restarts an event.
*/
public function lap(string $name): StopwatchEvent
{
return end($this->activeSections)->stopEvent($name)->start();
}
/**
* Returns a specific event by name.
*/
public function getEvent(string $name): StopwatchEvent
{
return end($this->activeSections)->getEvent($name);
}
/**
* Gets all events for a given section.
*
* @return StopwatchEvent[]
*/
public function getSectionEvents(string $id): array
{
return isset($this->sections[$id]) ? $this->sections[$id]->getEvents() : [];
}
/**
* Gets all events for the root section.
*
* @return StopwatchEvent[]
*/
public function getRootSectionEvents(): array
{
return $this->sections[self::ROOT]->getEvents() ?? [];
}
/**
* Resets the stopwatch to its original state.
*/
public function reset(): void
{
$this->sections = $this->activeSections = [self::ROOT => new Section(null, $this->morePrecision)];
}
}

View File

@@ -0,0 +1,238 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Stopwatch;
/**
* Represents an Event managed by Stopwatch.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class StopwatchEvent
{
/**
* @var StopwatchPeriod[]
*/
private array $periods = [];
private float $origin;
private string $category;
/**
* @var float[]
*/
private array $started = [];
private string $name;
/**
* @param float $origin The origin time in milliseconds
* @param string|null $category The event category or null to use the default
* @param bool $morePrecision If true, time is stored as float to keep the original microsecond precision
* @param string|null $name The event name or null to define the name as default
*/
public function __construct(
float $origin,
?string $category = null,
private bool $morePrecision = false,
?string $name = null,
) {
$this->origin = $this->formatTime($origin);
$this->category = \is_string($category) ? $category : 'default';
$this->name = $name ?? 'default';
}
/**
* Gets the category.
*/
public function getCategory(): string
{
return $this->category;
}
/**
* Gets the origin in milliseconds.
*/
public function getOrigin(): float
{
return $this->origin;
}
/**
* Starts a new event period.
*
* @return $this
*/
public function start(): static
{
$this->started[] = $this->getNow();
return $this;
}
/**
* Stops the last started event period.
*
* @return $this
*
* @throws \LogicException When stop() is called without a matching call to start()
*/
public function stop(): static
{
if (!\count($this->started)) {
throw new \LogicException('stop() called but start() has not been called before.');
}
$this->periods[] = new StopwatchPeriod(array_pop($this->started), $this->getNow(), $this->morePrecision);
return $this;
}
/**
* Checks if the event was started.
*/
public function isStarted(): bool
{
return (bool) $this->started;
}
/**
* Stops the current period and then starts a new one.
*
* @return $this
*/
public function lap(): static
{
return $this->stop()->start();
}
/**
* Stops all non already stopped periods.
*/
public function ensureStopped(): void
{
while (\count($this->started)) {
$this->stop();
}
}
/**
* Gets all event periods.
*
* @return StopwatchPeriod[]
*/
public function getPeriods(): array
{
return $this->periods;
}
/**
* Gets the last event period.
*/
public function getLastPeriod(): ?StopwatchPeriod
{
if ([] === $this->periods) {
return null;
}
return $this->periods[array_key_last($this->periods)];
}
/**
* Gets the relative time of the start of the first period in milliseconds.
*/
public function getStartTime(): int|float
{
if (isset($this->periods[0])) {
return $this->periods[0]->getStartTime();
}
if ($this->started) {
return $this->started[0];
}
return 0;
}
/**
* Gets the relative time of the end of the last period in milliseconds.
*/
public function getEndTime(): int|float
{
$count = \count($this->periods);
return $count ? $this->periods[$count - 1]->getEndTime() : 0;
}
/**
* Gets the duration of the events in milliseconds (including all periods).
*/
public function getDuration(): int|float
{
$periods = $this->periods;
$left = \count($this->started);
for ($i = $left - 1; $i >= 0; --$i) {
$periods[] = new StopwatchPeriod($this->started[$i], $this->getNow(), $this->morePrecision);
}
$total = 0;
foreach ($periods as $period) {
$total += $period->getDuration();
}
return $total;
}
/**
* Gets the max memory usage of all periods in bytes.
*/
public function getMemory(): int
{
$memory = 0;
foreach ($this->periods as $period) {
if ($period->getMemory() > $memory) {
$memory = $period->getMemory();
}
}
return $memory;
}
/**
* Return the current time relative to origin in milliseconds.
*/
protected function getNow(): float
{
return $this->formatTime(microtime(true) * 1000 - $this->origin);
}
/**
* Formats a time.
*/
private function formatTime(float $time): float
{
return round($time, 1);
}
/**
* Gets the event name.
*/
public function getName(): string
{
return $this->name;
}
public function __toString(): string
{
return \sprintf('%s/%s: %.2F MiB - %d ms', $this->getCategory(), $this->getName(), $this->getMemory() / 1024 / 1024, $this->getDuration());
}
}

View File

@@ -0,0 +1,73 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Stopwatch;
/**
* Represents a Period for an Event.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class StopwatchPeriod
{
private int|float $start;
private int|float $end;
private int $memory;
/**
* @param int|float $start The relative time of the start of the period (in milliseconds)
* @param int|float $end The relative time of the end of the period (in milliseconds)
* @param bool $morePrecision If true, time is stored as float to keep the original microsecond precision
*/
public function __construct(int|float $start, int|float $end, bool $morePrecision = false)
{
$this->start = $morePrecision ? (float) $start : (int) $start;
$this->end = $morePrecision ? (float) $end : (int) $end;
$this->memory = memory_get_usage(true);
}
/**
* Gets the relative time of the start of the period in milliseconds.
*/
public function getStartTime(): int|float
{
return $this->start;
}
/**
* Gets the relative time of the end of the period in milliseconds.
*/
public function getEndTime(): int|float
{
return $this->end;
}
/**
* Gets the time spent in this period in milliseconds.
*/
public function getDuration(): int|float
{
return $this->end - $this->start;
}
/**
* Gets the memory usage in bytes.
*/
public function getMemory(): int
{
return $this->memory;
}
public function __toString(): string
{
return \sprintf('%.2F MiB - %d ms', $this->getMemory() / 1024 / 1024, $this->getDuration());
}
}

29
vendor/symfony/stopwatch/composer.json vendored Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "symfony/stopwatch",
"type": "library",
"description": "Provides a way to profile code",
"keywords": [],
"homepage": "https://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"require": {
"php": ">=8.2",
"symfony/service-contracts": "^2.5|^3"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Stopwatch\\": "" },
"exclude-from-classmap": [
"/Tests/"
]
},
"minimum-stability": "dev"
}