1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace MatthiasMullie\Scrapbook\Buffered\Utils; |
4
|
|
|
|
5
|
|
|
use MatthiasMullie\Scrapbook\Adapters\MemoryStore; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* This is a helper class for BufferedStore & TransactionalStore, which buffer |
9
|
|
|
* real cache requests in memory. |
10
|
|
|
* The memory-part can easily be handled by MemoryStore. There's just 1 gotcha: |
11
|
|
|
* when an item is to be deleted (but not yet committed), it needs to be deleted |
12
|
|
|
* from the MemoryStore too, but we need to be able to make a distinction |
13
|
|
|
* between "this is deleted" and "this value is not known in this memory cache, |
14
|
|
|
* fall back to real cache". |
15
|
|
|
* |
16
|
|
|
* This is where this class comes in to play: we'll add an additional "expired" |
17
|
|
|
* method, which allows BufferedStore to just expire the keys that are supposed |
18
|
|
|
* to be deleted (instead of deleting them) - then we can keep track of when |
19
|
|
|
* a key is just not known, or known-but-deleted (=expired) |
20
|
|
|
* |
21
|
|
|
* @author Matthias Mullie <[email protected]> |
22
|
|
|
* @copyright Copyright (c) 2014, Matthias Mullie. All rights reserved |
23
|
|
|
* @license LICENSE MIT |
24
|
|
|
*/ |
25
|
|
|
class Buffer extends MemoryStore |
26
|
|
|
{ |
27
|
|
|
/** |
28
|
|
|
* Make items publicly available - if we create a collection from this, |
29
|
|
|
* that collection will need to be able to access these items to determine |
30
|
|
|
* if something has expired. |
31
|
|
|
* |
32
|
|
|
* @var array |
33
|
|
|
*/ |
34
|
|
|
public $items = array(); |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Checks if a value exists in cache and is not yet expired. |
38
|
|
|
* Contrary to default MemoryStore, expired items must *not* be deleted |
39
|
|
|
* from memory: we need to remember that they were expired, so we don't |
40
|
|
|
* reach out to real cache (only to get nothing, since it's expired...). |
41
|
|
|
* |
42
|
|
|
* @param string $key |
43
|
|
|
* |
44
|
|
|
* @return bool |
45
|
|
|
*/ |
46
|
|
|
protected function exists($key) |
47
|
|
|
{ |
48
|
|
|
if (!array_key_exists($key, $this->items)) { |
49
|
|
|
// key not in cache |
50
|
|
|
return false; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
$expire = $this->items[$key][1]; |
54
|
|
|
if (0 !== $expire && $expire < time()) { |
55
|
|
|
// not permanent & already expired |
56
|
|
|
return false; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
$this->lru($key); |
60
|
|
|
|
61
|
|
|
return true; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Check if a key existed in local storage, but is now expired. |
66
|
|
|
* |
67
|
|
|
* Because our local buffer is also just a real cache, expired items will |
68
|
|
|
* just return nothing, which will lead us to believe no such item exists in |
69
|
|
|
* that local cache, and we'll reach out to the real cache (where the value |
70
|
|
|
* may not yet have been expired because that may have been part of an |
71
|
|
|
* uncommitted write) |
72
|
|
|
* So we'll want to know when a value is in local cache, but expired! |
73
|
|
|
* |
74
|
|
|
* @param string $key |
75
|
|
|
* |
76
|
|
|
* @return bool |
77
|
|
|
*/ |
78
|
|
|
public function expired($key) |
79
|
|
|
{ |
80
|
|
|
if (false !== $this->get($key)) { |
81
|
|
|
// returned a value, clearly not yet expired |
82
|
|
|
return false; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
// a known item, not returned by get, is expired |
86
|
|
|
return array_key_exists($key, $this->items); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* {@inheritdoc} |
91
|
|
|
*/ |
92
|
|
|
public function getCollection($name) |
93
|
|
|
{ |
94
|
|
|
return new BufferCollection($this, $name); |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
|