Skip to content

Commit e109c6c

Browse files
committed
feat!: FileLocator caching
1 parent edfa0b5 commit e109c6c

File tree

2 files changed

+171
-4
lines changed

2 files changed

+171
-4
lines changed

system/Autoloader/FileLocator.php

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace CodeIgniter\Autoloader;
1313

14+
use CodeIgniter\Cache\FileLocatorCache;
15+
1416
/**
1517
* Allows loading non-class files in a namespaced manner.
1618
* Works with Helpers, Views, etc.
@@ -26,9 +28,40 @@ class FileLocator
2628
*/
2729
protected $autoloader;
2830

29-
public function __construct(Autoloader $autoloader)
31+
/**
32+
* Cache
33+
*
34+
* [method => data]
35+
* E.g.,
36+
* [
37+
* 'search' => [$path => $foundPaths],
38+
* ]
39+
*/
40+
protected array $cache = [];
41+
42+
/**
43+
* Is the cache updated?
44+
*/
45+
protected bool $cacheUpdated = false;
46+
47+
private ?FileLocatorCache $locatorCache;
48+
49+
public function __construct(Autoloader $autoloader, ?FileLocatorCache $cache = null)
50+
{
51+
$this->autoloader = $autoloader;
52+
$this->locatorCache = $cache;
53+
54+
if ($cache !== null) {
55+
$this->locatorCache->setLocator($this);
56+
$this->locatorCache->load();
57+
}
58+
}
59+
60+
public function __destruct()
3061
{
31-
$this->autoloader = $autoloader;
62+
if ($this->locatorCache !== null) {
63+
$this->locatorCache->save();
64+
}
3265
}
3366

3467
/**
@@ -119,6 +152,10 @@ public function locateFile(string $file, ?string $folder = null, string $ext = '
119152
*/
120153
public function getClassname(string $file): string
121154
{
155+
if (isset($this->cache['getClassname'][$file])) {
156+
return $this->cache['getClassname'][$file];
157+
}
158+
122159
$php = file_get_contents($file);
123160
$tokens = token_get_all($php);
124161
$dlm = false;
@@ -154,7 +191,12 @@ public function getClassname(string $file): string
154191
return '';
155192
}
156193

157-
return $namespace . '\\' . $className;
194+
$fullClassname = $namespace . '\\' . $className;
195+
196+
$this->cache['getClassname'][$file] = $fullClassname;
197+
$this->cacheUpdated = true;
198+
199+
return $fullClassname;
158200
}
159201

160202
/**
@@ -172,6 +214,10 @@ public function getClassname(string $file): string
172214
*/
173215
public function search(string $path, string $ext = 'php', bool $prioritizeApp = true): array
174216
{
217+
if (isset($this->cache['search'][$path])) {
218+
return $this->cache['search'][$path];
219+
}
220+
175221
$path = $this->ensureExt($path, $ext);
176222

177223
$foundPaths = [];
@@ -197,7 +243,42 @@ public function search(string $path, string $ext = 'php', bool $prioritizeApp =
197243
}
198244

199245
// Remove any duplicates
200-
return array_unique($foundPaths);
246+
$foundPaths = array_unique($foundPaths);
247+
248+
$this->cache['search'][$path] = $foundPaths;
249+
$this->cacheUpdated = true;
250+
251+
return $foundPaths;
252+
}
253+
254+
/**
255+
* Gets cache
256+
*
257+
* @internal For caching only
258+
*/
259+
public function getCache(): array
260+
{
261+
return $this->cache;
262+
}
263+
264+
/**
265+
* Sets cache
266+
*
267+
* @internal For caching only
268+
*/
269+
public function setCache(array $data): void
270+
{
271+
$this->cache = $data;
272+
}
273+
274+
/**
275+
* Is the cache updated?
276+
*
277+
* @internal For caching only
278+
*/
279+
public function isCacheUpdated(): bool
280+
{
281+
return $this->cacheUpdated;
201282
}
202283

203284
/**
@@ -223,6 +304,10 @@ protected function ensureExt(string $path, string $ext): string
223304
*/
224305
protected function getNamespaces()
225306
{
307+
if (isset($this->cache['getNamespaces'])) {
308+
return $this->cache['getNamespaces'];
309+
}
310+
226311
$namespaces = [];
227312

228313
// Save system for last
@@ -248,6 +333,9 @@ protected function getNamespaces()
248333

249334
$namespaces[] = $system;
250335

336+
$this->cache['getNamespaces'] = $namespaces;
337+
$this->cacheUpdated = true;
338+
251339
return $namespaces;
252340
}
253341

@@ -259,6 +347,10 @@ protected function getNamespaces()
259347
*/
260348
public function findQualifiedNameFromPath(string $path)
261349
{
350+
if (isset($this->cache['findQualifiedNameFromPath'][$path])) {
351+
return $this->cache['findQualifiedNameFromPath'][$path];
352+
}
353+
262354
$path = realpath($path) ?: $path;
263355

264356
if (! is_file($path)) {
@@ -285,6 +377,9 @@ public function findQualifiedNameFromPath(string $path)
285377

286378
// Check if this exists
287379
if (class_exists($className)) {
380+
$this->cache['findQualifiedNameFromPath'][$path] = $className;
381+
$this->cacheUpdated = true;
382+
288383
return $className;
289384
}
290385
}

system/Cache/FileLocatorCache.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CodeIgniter 4 framework.
5+
*
6+
* (c) CodeIgniter Foundation <[email protected]>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace CodeIgniter\Cache;
13+
14+
use CodeIgniter\Autoloader\FileLocator;
15+
use CodeIgniter\Cache\FactoriesCache\FileVarExportHandler;
16+
17+
final class FileLocatorCache
18+
{
19+
/**
20+
* @var CacheInterface|FileVarExportHandler
21+
*/
22+
private $cache;
23+
24+
private FileLocator $locator;
25+
26+
/**
27+
* @param CacheInterface|FileVarExportHandler|null $cache
28+
*/
29+
public function __construct($cache = null)
30+
{
31+
$this->cache = $cache ?? new FileVarExportHandler();
32+
}
33+
34+
public function setLocator(FileLocator $fileLocator): void
35+
{
36+
$this->locator = $fileLocator;
37+
}
38+
39+
public function save(): void
40+
{
41+
if (! $this->locator->isCacheUpdated()) {
42+
return;
43+
}
44+
45+
$data = $this->locator->getCache();
46+
47+
$this->cache->save($this->getCacheKey(), $data, 3600 * 24);
48+
}
49+
50+
private function getCacheKey(): string
51+
{
52+
return 'FileLocatorCache';
53+
}
54+
55+
public function load(): bool
56+
{
57+
$key = $this->getCacheKey();
58+
59+
if (! $data = $this->cache->get($key)) {
60+
return false;
61+
}
62+
63+
$this->locator->setCache($data);
64+
65+
return true;
66+
}
67+
68+
public function delete(): void
69+
{
70+
$this->cache->delete($this->getCacheKey());
71+
}
72+
}

0 commit comments

Comments
 (0)