Completed
Push — in-memory-cache2 ( de4787 )
by André
21:05
created

MetadataCachePool::set()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 3
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing MetadataCachePool class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
declare(strict_types=1);
10
11
namespace eZ\Publish\Core\Persistence\Cache\InMemory;
12
13
/**
14
 * InMemory Metadata Cache Pool.
15
 *
16
 * Burst cache for use on meta data only, meaning:
17
 * - data with in-frequently changes done on other threads/processes/requests
18
 * - when they do the system unlikely to crash from it
19
 *
20
 * Assuming cache is kept with low TTL (for up to slow request lengths like )
21
 *
22
 * E.g can be used for SPI data for Sections, ContentTypes, ObjectStates, ..
23
 * But not Content, Locations, (...).
24
 *
25
 * Design here is aligned with PSR-16 (but further simplified).
26
 *
27
 * @internal Only for use in eZ\Publish\Core\Persistence\Cache.
28
 */
29
class MetadataCachePool
30
{
31
    private const DEFAULT_CACHE_TTL = 4;
32
33
    /**
34
     * @var int Cache Time to Live, in seconds. This is only for how long we keep cache object around in-memory.
35
     */
36
    private $cacheTTL;
37
38
    /**
39
     * Cache objects by primary key.
40
     *
41
     * @TODO set to use WeakMap if present in __construct() ??
42
     *       https://secure.php.net/manual/en/class.weakmap.php
43
     *       At least very relevant for possible burst cache impl for Content.
44
     *
45
     * @var object[]
46
     */
47
    private $cache = [];
48
49
    /**
50
     * Secondary keys to primary key map.
51
     *
52
     * @var string[]
53
     */
54
    private $cacheSecondaryIndex = [];
55
56
    /**
57
     * @var int[] Timestamp for individual cache by primary key.
58
     */
59
    private $cacheTime = [];
60
61
    /**
62
     * Language Cache constructor.
63
     *
64
     * @param int $cacheTTL Seconds for the cache to live.
65
     */
66
    public function __construct(int $cacheTTL = self::DEFAULT_CACHE_TTL)
67
    {
68
        $this->cacheTTL = $cacheTTL;
69
    }
70
71
    /**
72
     * Returns a cache value.
73
     *
74
     * @param string $key Primary or secondary key to look for cache on.
75
     *
76
     * @return object|null Cache object if there is one and if not expired.
77
     */
78
    public function get($key): ?object
79
    {
80
        if (isset($this->cacheSecondaryIndex[$key])) {
81
            $key = $this->cacheSecondaryIndex[$key];
82
        }
83
84
        if (!isset($this->cache[$key])) {
85
            return null;
86
        }
87
88
        if ($this->cacheTime[$key] + $this->cacheTTL > time()) {
89
            $this->delete($key);
90
91
            return null;
92
        }
93
94
        return $this->cache[$key];
95
    }
96
97
    /**
98
     * Set object in in-memory cache.
99
     *
100
     * Should only set Cache hits here!
101
     *
102
     * @param string $key
103
     * @param object $object
104
     * @param array $secondaryIndexes
105
     */
106
    public function set(string $key, object $object, array $secondaryIndexes = []): void
107
    {
108
        $this->cache[$key] = $object;
109
        $this->cacheTime[$key] = time();
110
111
        foreach ($secondaryIndexes as $index) {
112
            $this->cacheSecondaryIndex[$index] = $key;
113
        }
114
    }
115
116
    /**
117
     * Removes multiple in-memory cache from the pool.
118
     *
119
     * @param string[] $keys An array of keys that should be removed from the pool.
0 ignored issues
show
Bug introduced by
There is no parameter named $keys. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
120
     */
121
    public function delete(string $key): void
122
    {
123
        unset($this->cache[$key], $this->cacheTime[$key]);
124
125
        if ($index = $this->cacheSecondaryIndex[$key] ?? null) {
126
            unset($this->cacheSecondaryIndex[$key], $this->cache[$index], $this->cacheTime[$index]);
127
        }
128
    }
129
130
    /**
131
     * Deletes all cache in the in-memory pool.
132
     */
133
    public function clear(): void
134
    {
135
        $this->cache = $this->cacheSecondaryIndex = $this->cacheTime = [];
136
    }
137
}
138