Completed
Pull Request — master (#2)
by Joao
02:35
created

CachePool::getItem()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
c 0
b 0
f 0
rs 9.4285
cc 3
eloc 9
nc 3
nop 1
1
<?php
2
3
namespace ByJG\Cache\Psr6;
4
5
use ByJG\Cache\CacheEngineInterface;
6
use ByJG\Cache\Psr16\BaseCacheEngine;
7
use Psr\Cache\CacheItemInterface;
8
use Psr\Cache\CacheItemPoolInterface;
9
use Psr\Log\InvalidArgumentException;
10
use Psr\SimpleCache\CacheInterface;
11
12
class CachePool implements CacheItemPoolInterface
13
{
14
    /**
15
     * @var \Psr\SimpleCache\CacheInterface
16
     */
17
    protected $_cacheEngine;
18
19
    /**
20
     * @var CacheItem
21
     */
22
    protected $_lastCacheItem;
23
24
    /**
25
     * @var int
26
     */
27
    protected $bufferSize = 10;
28
29
    /**
30
     * @var CacheItem[]
31
     */
32
    protected $buffer = [];
33
34
    /**
35
     * @var array
36
     */
37
    protected $bufferKeys = [];
38
39
    /**
40
     * CachePool constructor.
41
     * 
42
     * @param BaseCacheEngine $_cacheEngine
43
     * @param int $bufferSize
44
     */
45
    public function __construct(BaseCacheEngine $_cacheEngine, $bufferSize = 10)
46
    {
47
        $this->_cacheEngine = $_cacheEngine;
48
        $this->bufferSize = intval($bufferSize);
49
    }
50
51
    /**
52
     * @return int
53
     */
54
    public function getBufferSize()
55
    {
56
        return $this->bufferSize;
57
    }
58
59
    /**
60
     * @param int $bufferSize
61
     */
62
    public function setBufferSize($bufferSize)
63
    {
64
        $this->bufferSize = $bufferSize;
65
    }
66
67
68
    /**
69
     * Add an element to buffer. If the buffer is full, the first element added will be removed 
70
     * 
71
     * @param CacheItem $cacheItem
72
     */
73
    protected function addElementToBuffer(CacheItem $cacheItem)
74
    {
75
        if ($this->bufferSize < 1) {
76
            return;
77
        }
78
79
        $key = $cacheItem->getKey();
80
        $this->buffer[$key] = $cacheItem;
81
82
        if (in_array($key, $this->bufferKeys)) {
83
            return;
84
        }
85
86
        array_push($this->bufferKeys, $key);
87
88
        if (count($this->bufferKeys) > $this->bufferSize) {
89
            $element = array_shift($this->bufferKeys);
90
            unset($this->buffer[$element]);
91
        }
92
    }
93
94
    /**
95
     * Remove a specific key from buffer
96
     * 
97
     * @param $key
98
     */
99
    protected function removeElementFromBuffer($key)
100
    {
101
        $result = array_search($key, $this->bufferKeys);
102
        if ($result === false) {
103
            return;
104
        }
105
106
        unset($this->buffer[$key]);
107
        unset($this->bufferKeys[$result]);
108
    }
109
110
    /**
111
     * Psr implementation of getItem()
112
     * 
113
     * @param string $key
114
     * @return CacheItem
115
     */
116
    public function getItem($key)
117
    {
118
        // Get the element from the buffer if still remains valid!
119
        if (in_array($key, $this->bufferKeys)) {
120
            $cacheItem = $this->buffer[$key];
121
            if ($cacheItem->getExpiresInSecs() > 1) {
122
                return $cacheItem;
123
            }
124
        }
125
        
126
        // Get the element from the cache!
127
        $result = $this->_cacheEngine->get($key);
128
        $cache = new CacheItem($key, $result, $result !== null);
129
130
        $this->addElementToBuffer($cache);
131
132
        return $cache;
133
    }
134
135
    /**
136
     * Psr implementation of getItems()
137
     * 
138
     * @param array $keys
139
     * @return array
140
     */
141
    public function getItems(array $keys = array())
142
    {
143
        $result = [];
144
        foreach ($keys as $key) {
145
            $result[] = $this->getItem($key);
146
        }
147
148
        return $result;
149
    }
150
151
    /**
152
     * Psr implementation of hasItems()
153
     * 
154
     * @param string $key
155
     * @return bool
156
     */
157
    public function hasItem($key)
158
    {
159
        return $this->getItem($key)->isHit();
160
    }
161
162
    /**
163
     * Psr implementation of clear()
164
     */
165
    public function clear()
166
    {
167
        $this->bufferKeys = [];
168
        $this->buffer = [];
169
    }
170
171
    /**
172
     * Psr implementation of deleteItem()
173
     *
174
     * @param string $key
175
     * @return bool
176
     */
177
    public function deleteItem($key)
178
    {
179
        return $this->deleteItems([$key]);
180
    }
181
182
    /**
183
     * Psr Implementation of deleteItems()
184
     * 
185
     * @param array $keys
186
     * @return bool
187
     */
188
    public function deleteItems(array $keys)
189
    {
190
        foreach ($keys as $key) {
191
            $this->_cacheEngine->delete($key);
192
            $this->removeElementFromBuffer($key);
193
        }
194
        
195
        return true;
196
    }
197
198
    /**
199
     * @param CacheItemInterface $item
200
     * @return bool
201
     */
202
    public function save(CacheItemInterface $item)
203
    {
204
        if (!($item instanceof CacheItem)) {
205
            throw new InvalidArgumentException('The cache item must be an implementation of \ByJG\Cache\Psr\CacheItem');
206
        }
207
        
208
        if ($item->getExpiresInSecs() < 1) {
209
            throw new InvalidArgumentException('Object has expired!');
210
        }
211
        
212
        $this->_cacheEngine->set($item->getKey(), $item->get(), $item->getExpiresInSecs());
213
        $this->addElementToBuffer($item);
214
        
215
        return true;
216
    }
217
218
    /**
219
     * @var CacheItem[]
220
     */
221
    protected $deferredItem = [];
222
223
    /**
224
     * Psr Implementation of saveDeferred()
225
     * 
226
     * @param CacheItemInterface $item
227
     * @return bool
228
     */
229
    public function saveDeferred(CacheItemInterface $item)
230
    {
231
        $this->deferredItem[] = $item;
232
        return true;
233
    }
234
235
    /**
236
     * Psr implementation of commit()
237
     */
238
    public function commit()
239
    {
240
        foreach ($this->deferredItem as $item) {
241
            $this->save($item);
242
        }
243
        
244
        $this->deferredItem = [];
245
    }
246
247
    public function isAvailable()
248
    {
249
        return $this->_cacheEngine->isAvailable();
250
    }
251
}
252