Files
michaelschiemer/src/Framework/Database/Cache/SimpleCacheStrategy.php

139 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Database\Cache;
/**
* Einfache Cache-Strategy als Fallback wenn kein Framework-Cache verfügbar
*/
final class SimpleCacheStrategy implements CacheStrategy
{
private array $cache = [];
private array $expiry = [];
private array $stats = [
'hits' => 0,
'misses' => 0,
'sets' => 0,
'deletes' => 0,
'invalidations' => 0,
];
public function __construct(
private readonly string $keyPrefix = 'db_query:'
) {}
public function set(QueryCacheKey $key, array $value, int $ttlSeconds): bool
{
$keyString = $this->keyPrefix . $key->toString();
$this->cache[$keyString] = $value;
$this->expiry[$keyString] = time() + $ttlSeconds;
$this->stats['sets']++;
return true;
}
public function get(QueryCacheKey $key): ?array
{
$keyString = $this->keyPrefix . $key->toString();
// Prüfe Ablauf
if (isset($this->expiry[$keyString]) && time() > $this->expiry[$keyString]) {
$this->delete($key);
$this->stats['misses']++;
return null;
}
if (isset($this->cache[$keyString])) {
$this->stats['hits']++;
return $this->cache[$keyString];
}
$this->stats['misses']++;
return null;
}
public function has(QueryCacheKey $key): bool
{
return $this->get($key) !== null;
}
public function delete(QueryCacheKey $key): bool
{
$keyString = $this->keyPrefix . $key->toString();
$existed = isset($this->cache[$keyString]);
unset($this->cache[$keyString], $this->expiry[$keyString]);
if ($existed) {
$this->stats['deletes']++;
}
return $existed;
}
public function invalidatePattern(string $pattern): int
{
$deleted = 0;
foreach (array_keys($this->cache) as $keyString) {
if (fnmatch($pattern, $keyString)) {
unset($this->cache[$keyString], $this->expiry[$keyString]);
$deleted++;
}
}
$this->stats['invalidations'] += $deleted;
return $deleted;
}
public function clear(): void
{
$count = count($this->cache);
$this->cache = [];
$this->expiry = [];
$this->stats['invalidations'] += $count;
}
public function getStats(): array
{
return array_merge($this->stats, [
'size' => count($this->cache),
'memory_usage' => $this->estimateMemoryUsage(),
'hit_ratio' => $this->calculateHitRatio(),
'cache_type' => 'SimpleCacheStrategy'
]);
}
private function estimateMemoryUsage(): int
{
return memory_get_usage() - memory_get_usage(true); // Grobe Schätzung
}
private function calculateHitRatio(): float
{
$total = $this->stats['hits'] + $this->stats['misses'];
return $total > 0 ? ($this->stats['hits'] / $total) : 0.0;
}
/**
* Bereinigt abgelaufene Einträge
*/
public function cleanup(): int
{
$currentTime = time();
$cleaned = 0;
foreach ($this->expiry as $keyString => $expiry) {
if ($currentTime > $expiry) {
unset($this->cache[$keyString], $this->expiry[$keyString]);
$cleaned++;
}
}
return $cleaned;
}
}