Files
michaelschiemer/src/Framework/Discovery/Results/DiscoveryRegistry.php
Michael Schiemer 55a330b223 Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
2025-08-11 20:13:26 +02:00

196 lines
5.6 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Discovery\Results;
use Countable;
/**
* Central registry that coordinates the smaller specialized registries
* This replaces the monolithic DiscoveryResults with a composition of lightweight registries
*
* MEMORY OPTIMIZATION: Implements __serialize/__unserialize to prevent cache memory explosion
*/
final readonly class DiscoveryRegistry implements Countable
{
public function __construct(
public AttributeRegistry $attributes = new AttributeRegistry(),
public InterfaceRegistry $interfaces = new InterfaceRegistry(),
public TemplateRegistry $templates = new TemplateRegistry(),
) {
}
// === Memory Management ===
/**
* Optimize all registries for memory efficiency
*/
public function optimize(): void
{
$this->attributes->optimize();
$this->interfaces->optimize();
$this->templates->optimize();
}
/**
* Clear all caches to free memory
*/
public function clearCaches(): void
{
$this->attributes->clearCache();
$this->interfaces->clearCache();
$this->templates->clearCache();
}
/**
* Get comprehensive memory statistics
*/
public function getMemoryStats(): array
{
$attributeStats = $this->attributes->getMemoryStats();
$interfaceStats = $this->interfaces->getMemoryStats();
$templateStats = $this->templates->getMemoryStats();
return [
'total_estimated_bytes' => $attributeStats['estimated_bytes'] + $interfaceStats['estimated_bytes'] + $templateStats['estimated_bytes'],
'attributes' => $attributeStats,
'interfaces' => $interfaceStats,
'templates' => $templateStats,
];
}
public function isEmpty(): bool
{
return count($this) === 0;
}
public function count(): int
{
return count($this->attributes) +
count($this->interfaces) +
count($this->templates);
}
/**
* Create a lightweight version with only essential data
*/
public function createLightweight(): self
{
// Keep only commonly accessed attributes
$essentialAttributes = new AttributeRegistry();
$importantTypes = [
'App\\Framework\\Attributes\\Route',
'App\\Framework\\DI\\Initializer',
'App\\Framework\\Core\\Events\\OnEvent',
'App\\Framework\\Http\\MiddlewarePriorityAttribute',
];
foreach ($importantTypes as $type) {
if ($this->attributes->has($type)) {
foreach ($this->attributes->get($type) as $data) {
$essentialAttributes->add($type, $data);
}
}
}
return new self(
attributes: $essentialAttributes,
interfaces: $this->interfaces,
templates: new TemplateRegistry() // Skip templates in lightweight version
);
}
// === Factory Methods ===
public static function empty(): self
{
return new self();
}
/**
* Convert to array for cache serialization
*/
public function toArray(): array
{
return [
'attributes' => $this->attributes->toArray(),
'interfaces' => $this->interfaces->toArray(),
'templates' => $this->templates->toArray(),
];
}
public function __serialize(): array
{
return $this->toArray();
}
/**
* Custom deserialization using fromArray() method
*/
public function __unserialize(array $data): void
{
$restored = self::fromArray($data);
$this->attributes = $restored->attributes;
$this->interfaces = $restored->interfaces;
$this->templates = $restored->templates;
}
/**
* Create DiscoveryRegistry from array data (for cache deserialization)
* Uses direct constructor instantiation with data injection
*/
public static function fromArray(array $data): self
{
// Verwende die fromArray Factory-Methoden der Registry-Klassen
// Diese laden automatisch als nicht-optimiert für Datenintegrität
return new self(
attributes: isset($data['attributes'])
? AttributeRegistry::fromArray($data['attributes'])
: new AttributeRegistry(),
interfaces: isset($data['interfaces'])
? InterfaceRegistry::fromArray($data['interfaces'])
: new InterfaceRegistry(),
templates: isset($data['templates'])
? TemplateRegistry::fromArray($data['templates'])
: new TemplateRegistry()
);
}
/**
* Merge multiple registries efficiently
*/
public function merge(self $other): self
{
$mergedAttributes = new AttributeRegistry();
// Copy all attributes from both registries
foreach ($this->attributes->getAllTypes() as $type) {
foreach ($this->attributes->get($type) as $mapping) {
$mergedAttributes->add($type, $mapping);
}
}
foreach ($other->attributes->getAllTypes() as $type) {
foreach ($other->attributes->get($type) as $mapping) {
$mergedAttributes->add($type, $mapping);
}
}
$merged = new self(
attributes: $mergedAttributes,
interfaces: $this->interfaces->merge($other->interfaces),
templates: $this->templates->merge($other->templates)
);
$merged->optimize();
return $merged;
}
public function getFileCount(): int
{
return $this->count();
}
}