-
Notifications
You must be signed in to change notification settings - Fork 650
/
StatementsVolatileCache.php
100 lines (81 loc) · 2.2 KB
/
StatementsVolatileCache.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?php
namespace Psalm\Internal\Provider;
use InvalidArgumentException;
use PhpParser\Node\Stmt;
use function array_key_exists;
use function array_search;
use function array_splice;
use function count;
use function is_null;
use function key;
use function reset;
/**
* @internal Owned by StatementsProvider
* @todo: track variables size instead
*/
final class StatementsVolatileCache
{
/**
* @var array<string, list<Stmt>>
*/
protected array $cache = [];
/**
* @var array<int, string>
*/
protected array $access = [];
protected int $max_size;
protected static ?StatementsVolatileCache $instance = null;
public function __construct(int $max_size = 4096)
{
$this->max_size = $max_size;
}
public static function getInstance(): StatementsVolatileCache
{
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function has(string $key): bool
{
return array_key_exists($key, $this->cache);
}
/**
* @return list<Stmt>
* @throws InvalidArgumentException
*/
public function get(string $key): array
{
if (! $this->has($key)) {
throw new InvalidArgumentException('Given $key does not exists');
}
$access_index = array_search($key, $this->access);
if (false !== $access_index) {
array_splice($this->access, $access_index, 1);
}
$this->access[] = $key;
return $this->cache[$key];
}
/**
* @param list<Stmt> $content
*/
public function set(string $key, array $content): void
{
if (count($this->cache) > $this->max_size) {
reset($this->access);
$oldest_key_index = key($this->access);
if (! is_null($oldest_key_index)) {
$oldest_key = $this->access[$oldest_key_index];
unset($this->cache[$oldest_key]);
unset($this->access[$oldest_key_index]);
}
}
$this->cache[$key] = $content;
$this->access[] = $key;
}
public function clearCache(): void
{
$this->cache = [];
$this->access = [];
}
}