Exponential 5.x Kernel 7.5.40 Exponential New Stack (Symfony-based) Kernel — PHP Class Reference

InMemoryCache.php
Go to the documentation of this file.
1 <?php
2
7 declare(strict_types=1);
8
9 namespace eZ\Publish\Core\Persistence\Cache\InMemory;
10
27 class InMemoryCache
28 {
30 private $ttl;
31
33 private $limit;
34
36 private $enabled;
37
43 private $cache = [];
44
46 private $cacheExpiryTime = [];
47
49 private $cacheAccessCount = [];
50
56 private $cacheIndex = [];
57
65 public function __construct(int $ttl = 300, int $limit = 100, bool $enabled = true)
66 {
67 $this->ttl = $ttl / 1000;
68 $this->limit = $limit;
69 $this->enabled = $enabled;
70 }
71
77 public function setEnabled(bool $enabled = true): bool
78 {
79 $was = $this->enabled;
80 $this->enabled = $enabled;
81
82 return $was;
83 }
84
92 public function get(string $key)
93 {
94 if ($this->enabled === false) {
95 return null;
96 }
97
98 $index = $this->cacheIndex[$key] ?? $key;
99 if (!isset($this->cache[$index]) || $this->cacheExpiryTime[$index] < microtime(true)) {
100 return null;
101 }
102
103 ++$this->cacheAccessCount[$index];
104
105 return $this->cache[$index];
106 }
107
117 public function setMulti(array $objects, callable $objectIndexes, string $listIndex = null): void
118 {
119 // If objects accounts for more then 20% of our limit, assume it's bulk load and skip saving in-memory
120 if ($this->enabled === false || \count($objects) >= $this->limit / 5) {
121 return;
122 }
123
124 // check if we will reach limit by adding these objects, if so remove old cache
125 if (\count($this->cache) + \count($objects) >= $this->limit) {
126 $this->vacuum();
127 }
128
129 $expiryTime = microtime(true) + $this->ttl;
130 // if set add objects to cache on list index (typically a "all" key)
131 if ($listIndex) {
132 $this->cache[$listIndex] = $objects;
133 $this->cacheExpiryTime[$listIndex] = $expiryTime;
134 $this->cacheAccessCount[$listIndex] = 0;
135 }
136
137 foreach ($objects as $object) {
138 // Skip if there are no indexes
139 if (!$indexes = $objectIndexes($object)) {
140 continue;
141 }
142
143 $key = \array_shift($indexes);
144 $this->cache[$key] = $object;
145 $this->cacheExpiryTime[$key] = $expiryTime;
146 $this->cacheAccessCount[$key] = 0;
147
148 foreach ($indexes as $index) {
149 $this->cacheIndex[$index] = $key;
150 }
151 }
152 }
153
159 public function deleteMulti(array $keys): void
160 {
161 if ($this->enabled === false) {
162 return;
163 }
164
165 foreach ($keys as $index) {
166 if ($key = $this->cacheIndex[$index] ?? null) {
167 unset($this->cacheIndex[$index]);
168 } else {
169 $key = $index;
170 }
171
172 unset($this->cache[$key], $this->cacheExpiryTime[$key], $this->cacheAccessCount[$key]);
173 }
174 }
175
179 public function clear(): void
180 {
181 // On purpose does not check if enabled, in case of prior phase being enabled we clear cache when someone asks.
182 $this->cache = $this->cacheIndex = $this->cacheExpiryTime = $this->cacheAccessCount = [];
183 }
184
191 private function vacuum(): void
192 {
193 // To not having to call this too often, we aim to clear 33% of cache values in bulk
194 $deleteTarget = (int) ($this->limit / 3);
195
196 // First we flip the cacheAccessCount and sort so order is first by access (LFU) then secondly by order (FIFO)
197 $groupedAccessCount = [];
198 foreach ($this->cacheAccessCount as $key => $accessCount) {
199 $groupedAccessCount[$accessCount][] = $key;
200 }
201 \ksort($groupedAccessCount, SORT_NUMERIC);
202
203 // Merge the resulting sorted array of arrays to flatten the result
204 foreach (\array_merge(...$groupedAccessCount) as $key) {
205 unset($this->cache[$key], $this->cacheExpiryTime[$key], $this->cacheAccessCount[$key]);
206 --$deleteTarget;
207
208 if ($deleteTarget <= 0) {
209 break;
210 }
211 }
212
213 // Cleanup secondary indexes for missing primary keys
214 foreach ($this->cacheIndex as $index => $key) {
215 if (!isset($this->cache[$key])) {
216 unset($this->cacheIndex[$index]);
217 }
218 }
219 }
220 }
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache
Simple internal In-Memory Cache Pool.
Definition: InMemoryCache.php:28
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\$ttl
$ttl
Definition: InMemoryCache.php:30
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\$cacheExpiryTime
$cacheExpiryTime
Definition: InMemoryCache.php:46
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\deleteMulti
deleteMulti(array $keys)
Removes multiple in-memory cache from the pool.
Definition: InMemoryCache.php:159
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\$enabled
$enabled
Definition: InMemoryCache.php:36
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\__construct
__construct(int $ttl=300, int $limit=100, bool $enabled=true)
In Memory Cache constructor.
Definition: InMemoryCache.php:65
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\setEnabled
setEnabled(bool $enabled=true)
Definition: InMemoryCache.php:77
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\setMulti
setMulti(array $objects, callable $objectIndexes, string $listIndex=null)
Set object in in-memory cache.
Definition: InMemoryCache.php:117
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\$cacheAccessCount
$cacheAccessCount
Definition: InMemoryCache.php:49
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\$cache
$cache
Definition: InMemoryCache.php:43
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\$cacheIndex
$cacheIndex
Definition: InMemoryCache.php:56
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\$limit
$limit
Definition: InMemoryCache.php:33
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\vacuum
vacuum()
Call to reduce cache items when $limit has been reached.
Definition: InMemoryCache.php:191
eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache\clear
clear()
Deletes all cache in the in-memory pool.
Definition: InMemoryCache.php:179
eZ\Publish\Core\Persistence\Cache\InMemory
Definition: InMemoryCache.php:9
Copyright © 1998 – 2026 7x. All rights reserved. Licensed under the GNU GPLv2+.