chore: complete update
This commit is contained in:
138
src/Framework/Database/Cache/SimpleCacheStrategy.php
Normal file
138
src/Framework/Database/Cache/SimpleCacheStrategy.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user