Bearsampp 2026.9.23
Loading...
Searching...
No Matches
class.cachemanager.php
Go to the documentation of this file.
1<?php
2/*
3 * Copyright (c) 2021-2026 Bearsampp
4 * License: GNU General Public License version 3 or later; see LICENSE.txt
5 * Website: https://bearsampp.com
6 * Github: https://github.com/Bearsampp
7 */
8
18{
20 private static $cacheDir;
21
23 private static $enabled = true;
24
26 private static $stats = [
27 'hits' => 0,
28 'misses' => 0,
29 'writes' => 0
30 ];
31
32 const CACHE_VERSION = '1.0';
33
42 public static function init(string $cacheDir): void
43 {
44 self::$cacheDir = $cacheDir;
45
46 // Create cache directory if needed
47 if (!is_dir(self::$cacheDir)) {
48 @mkdir(self::$cacheDir, 0755, true);
49 }
50
51 // Check if cache directory is writable
52 if (!is_writable(self::$cacheDir)) {
53 Log::warning('Cache directory not writable, caching disabled: ' . self::$cacheDir);
54 self::$enabled = false;
55 }
56 }
57
68 public static function load(
69 string $sourcePath,
70 callable $parser,
71 ?string $cacheKey = null
72 ) {
73 if (!self::$enabled || !self::$cacheDir) {
74 return call_user_func($parser, $sourcePath);
75 }
76
77 if ($cacheKey === null) {
78 $cacheKey = md5($sourcePath);
79 }
80
81 $cacheFile = self::getCacheFile($cacheKey);
82
83 // Try cache first (warm start optimization)
84 if (self::isCacheValid($sourcePath, $cacheFile)) {
85 $cached = @json_decode(file_get_contents($cacheFile), true);
86 if (is_array($cached)) {
87 self::$stats['hits']++;
88
89 return $cached;
90 }
91 }
92
93 // Cache miss or invalid - parse and save
94 self::$stats['misses']++;
95 $data = call_user_func($parser, $sourcePath);
96
97 if (is_array($data)) {
98 self::writeCache($cacheFile, $data);
99 }
100
101 return $data;
102 }
103
112 private static function isCacheValid(
113 string $sourcePath,
114 string $cacheFile
115 ): bool {
116 if (!file_exists($cacheFile) || !file_exists($sourcePath)) {
117 return false;
118 }
119
120 // Cache valid only if newer than source
121 return filemtime($cacheFile) > filemtime($sourcePath);
122 }
123
133 private static function writeCache(string $cacheFile, array $data): bool
134 {
135 if (!self::$enabled) {
136 return false;
137 }
138
139 $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
140 $written = @file_put_contents($cacheFile, $json);
141
142 if ($written !== false) {
143 self::$stats['writes']++;
144
145 return true;
146 }
147
148 Log::warning('Failed to write cache: ' . $cacheFile);
149
150 return false;
151 }
152
160 private static function getCacheFile(string $cacheKey): string
161 {
162 return self::$cacheDir . '/' . $cacheKey . '.cache';
163 }
164
173 public static function invalidate(string $sourcePath): void
174 {
175 if (!self::$enabled || !self::$cacheDir) {
176 return;
177 }
178
179 $cacheKey = md5($sourcePath);
180 $cacheFile = self::getCacheFile($cacheKey);
181
182 if (file_exists($cacheFile)) {
183 @unlink($cacheFile);
184 }
185 }
186
193 public static function clearAll(): int
194 {
195 if (!self::$enabled || !self::$cacheDir) {
196 return 0;
197 }
198
199 // Clear in-memory caches of related classes
200 if (class_exists('Module')) {
202 }
203
204 // Clear general cache if it exists
205 if (class_exists('Cache')) {
206 $cache = new Cache();
207 $cache->clear();
208 }
209
210 $files = @glob(self::$cacheDir . '/*.cache');
211 $deleted = 0;
212
213 if (is_array($files)) {
214 foreach ($files as $file) {
215 if (@unlink($file)) {
216 $deleted++;
217 }
218 }
219 }
220
221 return $deleted;
222 }
223
230 public static function getStats(): array
231 {
232 $files = @glob(self::$cacheDir . '/*.cache');
233 $totalSize = 0;
234 $oldestEntry = null;
235 $newestEntry = null;
236 $largestEntry = 0;
237
238 if (is_array($files)) {
239 foreach ($files as $file) {
240 $fileSize = @filesize($file);
241 if ($fileSize !== false) {
242 $totalSize += $fileSize;
243 if ($fileSize > $largestEntry) {
244 $largestEntry = $fileSize;
245 }
246 }
247 $fileMtime = @filemtime($file);
248 if ($fileMtime !== false) {
249 if ($oldestEntry === null || $fileMtime < $oldestEntry) {
250 $oldestEntry = $fileMtime;
251 }
252 if ($newestEntry === null || $fileMtime > $newestEntry) {
253 $newestEntry = $fileMtime;
254 }
255 }
256 }
257 }
258
259 return [
260 'enabled' => self::$enabled,
261 'cacheDir' => self::$cacheDir,
262 'filesCount' => count($files ?? []),
263 'totalSize' => $totalSize,
264 'oldestEntry' => $oldestEntry,
265 'newestEntry' => $newestEntry,
266 'largestEntry' => $largestEntry,
267 'cacheHits' => self::$stats['hits'],
268 'cacheMisses' => self::$stats['misses'],
269 'cachewrites' => self::$stats['writes'],
270 'hitRate' => (self::$stats['hits'] + self::$stats['misses']) > 0
271 ? round((self::$stats['hits'] / (self::$stats['hits'] + self::$stats['misses'])) * 100, 2)
272 : 0
273 ];
274 }
275
284 public static function setEnabled(bool $enable): void
285 {
286 self::$enabled = $enable;
287 }
288
294 public static function isEnabled(): bool
295 {
296 return self::$enabled;
297 }
298}
static load(string $sourcePath, callable $parser, ?string $cacheKey=null)
static invalidate(string $sourcePath)
static isCacheValid(string $sourcePath, string $cacheFile)
static setEnabled(bool $enable)
static getCacheFile(string $cacheKey)
static init(string $cacheDir)
static writeCache(string $cacheFile, array $data)
static warning($data, $file=null)
static clearMemoryCache()
if('@'. 'php_dir'.'@'=='@'. 'php_dir'.'@')
Definition helper.inc:2