Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Core\Cache;
|
Chris@0
|
4
|
Chris@0
|
5 /**
|
Chris@0
|
6 * Defines a chained cache implementation for combining multiple cache backends.
|
Chris@0
|
7 *
|
Chris@0
|
8 * Can be used to combine two or more backends together to behave as if they
|
Chris@0
|
9 * were a single backend.
|
Chris@0
|
10 *
|
Chris@0
|
11 * For example a slower, persistent storage engine could be combined with a
|
Chris@0
|
12 * faster, volatile storage engine. When retrieving items from cache, they will
|
Chris@0
|
13 * be fetched from the volatile backend first, only falling back to the
|
Chris@0
|
14 * persistent backend if an item is not available. An item not present in the
|
Chris@0
|
15 * volatile backend but found in the persistent one will be propagated back up
|
Chris@0
|
16 * to ensure fast retrieval on the next request. On cache sets and deletes, both
|
Chris@0
|
17 * backends will be invoked to ensure consistency.
|
Chris@0
|
18 *
|
Chris@0
|
19 * @see \Drupal\Core\Cache\ChainedFastBackend
|
Chris@0
|
20 *
|
Chris@0
|
21 * @ingroup cache
|
Chris@0
|
22 */
|
Chris@0
|
23 class BackendChain implements CacheBackendInterface, CacheTagsInvalidatorInterface {
|
Chris@0
|
24
|
Chris@0
|
25 /**
|
Chris@0
|
26 * Ordered list of CacheBackendInterface instances.
|
Chris@0
|
27 *
|
Chris@0
|
28 * @var array
|
Chris@0
|
29 */
|
Chris@0
|
30 protected $backends = [];
|
Chris@0
|
31
|
Chris@0
|
32 /**
|
Chris@0
|
33 * Constructs a DatabaseBackend object.
|
Chris@0
|
34 *
|
Chris@0
|
35 * @param string $bin
|
Chris@0
|
36 * The cache bin for which the object is created.
|
Chris@0
|
37 */
|
Chris@0
|
38 public function __construct($bin) {
|
Chris@0
|
39 }
|
Chris@0
|
40
|
Chris@0
|
41 /**
|
Chris@0
|
42 * Appends a cache backend to the cache chain.
|
Chris@0
|
43 *
|
Chris@0
|
44 * @param CacheBackendInterface $backend
|
Chris@0
|
45 * The cache backend to be appended to the cache chain.
|
Chris@0
|
46 *
|
Chris@0
|
47 * @return \Drupal\Core\Cache\BackendChain
|
Chris@0
|
48 * The called object.
|
Chris@0
|
49 */
|
Chris@0
|
50 public function appendBackend(CacheBackendInterface $backend) {
|
Chris@0
|
51 $this->backends[] = $backend;
|
Chris@0
|
52
|
Chris@0
|
53 return $this;
|
Chris@0
|
54 }
|
Chris@0
|
55
|
Chris@0
|
56 /**
|
Chris@0
|
57 * Prepends a cache backend to the cache chain.
|
Chris@0
|
58 *
|
Chris@0
|
59 * @param CacheBackendInterface $backend
|
Chris@0
|
60 * The backend to be prepended to the cache chain.
|
Chris@0
|
61 *
|
Chris@0
|
62 * @return \Drupal\Core\Cache\BackendChain
|
Chris@0
|
63 * The called object.
|
Chris@0
|
64 */
|
Chris@0
|
65 public function prependBackend(CacheBackendInterface $backend) {
|
Chris@0
|
66 array_unshift($this->backends, $backend);
|
Chris@0
|
67
|
Chris@0
|
68 return $this;
|
Chris@0
|
69 }
|
Chris@0
|
70
|
Chris@0
|
71 /**
|
Chris@0
|
72 * {@inheritdoc}
|
Chris@0
|
73 */
|
Chris@0
|
74 public function get($cid, $allow_invalid = FALSE) {
|
Chris@0
|
75 foreach ($this->backends as $index => $backend) {
|
Chris@0
|
76 if (($return = $backend->get($cid, $allow_invalid)) !== FALSE) {
|
Chris@0
|
77 // We found a result, propagate it to all missed backends.
|
Chris@0
|
78 if ($index > 0) {
|
Chris@0
|
79 for ($i = ($index - 1); 0 <= $i; --$i) {
|
Chris@0
|
80 $this->backends[$i]->set($cid, $return->data, $return->expire, $return->tags);
|
Chris@0
|
81 }
|
Chris@0
|
82 }
|
Chris@0
|
83
|
Chris@0
|
84 return $return;
|
Chris@0
|
85 }
|
Chris@0
|
86 }
|
Chris@0
|
87
|
Chris@0
|
88 return FALSE;
|
Chris@0
|
89 }
|
Chris@0
|
90
|
Chris@0
|
91 /**
|
Chris@0
|
92 * {@inheritdoc}
|
Chris@0
|
93 */
|
Chris@0
|
94 public function getMultiple(&$cids, $allow_invalid = FALSE) {
|
Chris@0
|
95 $return = [];
|
Chris@0
|
96
|
Chris@0
|
97 foreach ($this->backends as $index => $backend) {
|
Chris@0
|
98 $items = $backend->getMultiple($cids, $allow_invalid);
|
Chris@0
|
99
|
Chris@0
|
100 // Propagate the values that could be retrieved from the current cache
|
Chris@0
|
101 // backend to all missed backends.
|
Chris@0
|
102 if ($index > 0 && !empty($items)) {
|
Chris@0
|
103 for ($i = ($index - 1); 0 <= $i; --$i) {
|
Chris@0
|
104 foreach ($items as $cached) {
|
Chris@0
|
105 $this->backends[$i]->set($cached->cid, $cached->data, $cached->expire, $cached->tags);
|
Chris@0
|
106 }
|
Chris@0
|
107 }
|
Chris@0
|
108 }
|
Chris@0
|
109
|
Chris@0
|
110 // Append the values to the previously retrieved ones.
|
Chris@0
|
111 $return += $items;
|
Chris@0
|
112
|
Chris@0
|
113 if (empty($cids)) {
|
Chris@0
|
114 // No need to go further if we don't have any cid to fetch left.
|
Chris@0
|
115 break;
|
Chris@0
|
116 }
|
Chris@0
|
117 }
|
Chris@0
|
118
|
Chris@0
|
119 return $return;
|
Chris@0
|
120 }
|
Chris@0
|
121
|
Chris@0
|
122 /**
|
Chris@0
|
123 * {@inheritdoc}
|
Chris@0
|
124 */
|
Chris@0
|
125 public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = []) {
|
Chris@0
|
126 foreach ($this->backends as $backend) {
|
Chris@0
|
127 $backend->set($cid, $data, $expire, $tags);
|
Chris@0
|
128 }
|
Chris@0
|
129 }
|
Chris@0
|
130
|
Chris@0
|
131 /**
|
Chris@0
|
132 * {@inheritdoc}
|
Chris@0
|
133 */
|
Chris@0
|
134 public function setMultiple(array $items) {
|
Chris@0
|
135 foreach ($this->backends as $backend) {
|
Chris@0
|
136 $backend->setMultiple($items);
|
Chris@0
|
137 }
|
Chris@0
|
138 }
|
Chris@0
|
139
|
Chris@0
|
140 /**
|
Chris@0
|
141 * {@inheritdoc}
|
Chris@0
|
142 */
|
Chris@0
|
143 public function delete($cid) {
|
Chris@0
|
144 foreach ($this->backends as $backend) {
|
Chris@0
|
145 $backend->delete($cid);
|
Chris@0
|
146 }
|
Chris@0
|
147 }
|
Chris@0
|
148
|
Chris@0
|
149 /**
|
Chris@0
|
150 * {@inheritdoc}
|
Chris@0
|
151 */
|
Chris@0
|
152 public function deleteMultiple(array $cids) {
|
Chris@0
|
153 foreach ($this->backends as $backend) {
|
Chris@0
|
154 $backend->deleteMultiple($cids);
|
Chris@0
|
155 }
|
Chris@0
|
156 }
|
Chris@0
|
157
|
Chris@0
|
158 /**
|
Chris@0
|
159 * {@inheritdoc}
|
Chris@0
|
160 */
|
Chris@0
|
161 public function deleteAll() {
|
Chris@0
|
162 foreach ($this->backends as $backend) {
|
Chris@0
|
163 $backend->deleteAll();
|
Chris@0
|
164 }
|
Chris@0
|
165 }
|
Chris@0
|
166
|
Chris@0
|
167 /**
|
Chris@0
|
168 * {@inheritdoc}
|
Chris@0
|
169 */
|
Chris@0
|
170 public function invalidate($cid) {
|
Chris@0
|
171 foreach ($this->backends as $backend) {
|
Chris@0
|
172 $backend->invalidate($cid);
|
Chris@0
|
173 }
|
Chris@0
|
174 }
|
Chris@0
|
175
|
Chris@0
|
176 /**
|
Chris@0
|
177 * {@inheritdoc}
|
Chris@0
|
178 */
|
Chris@0
|
179 public function invalidateMultiple(array $cids) {
|
Chris@0
|
180 foreach ($this->backends as $backend) {
|
Chris@0
|
181 $backend->invalidateMultiple($cids);
|
Chris@0
|
182 }
|
Chris@0
|
183 }
|
Chris@0
|
184
|
Chris@0
|
185 /**
|
Chris@0
|
186 * {@inheritdoc}
|
Chris@0
|
187 */
|
Chris@0
|
188 public function invalidateTags(array $tags) {
|
Chris@0
|
189 foreach ($this->backends as $backend) {
|
Chris@0
|
190 if ($backend instanceof CacheTagsInvalidatorInterface) {
|
Chris@0
|
191 $backend->invalidateTags($tags);
|
Chris@0
|
192 }
|
Chris@0
|
193 }
|
Chris@0
|
194 }
|
Chris@0
|
195
|
Chris@0
|
196 /**
|
Chris@0
|
197 * {@inheritdoc}
|
Chris@0
|
198 */
|
Chris@0
|
199 public function invalidateAll() {
|
Chris@0
|
200 foreach ($this->backends as $backend) {
|
Chris@0
|
201 $backend->invalidateAll();
|
Chris@0
|
202 }
|
Chris@0
|
203 }
|
Chris@0
|
204
|
Chris@0
|
205 /**
|
Chris@0
|
206 * {@inheritdoc}
|
Chris@0
|
207 */
|
Chris@0
|
208 public function garbageCollection() {
|
Chris@0
|
209 foreach ($this->backends as $backend) {
|
Chris@0
|
210 $backend->garbageCollection();
|
Chris@0
|
211 }
|
Chris@0
|
212 }
|
Chris@0
|
213
|
Chris@0
|
214 /**
|
Chris@0
|
215 * {@inheritdoc}
|
Chris@0
|
216 */
|
Chris@0
|
217 public function removeBin() {
|
Chris@0
|
218 foreach ($this->backends as $backend) {
|
Chris@0
|
219 $backend->removeBin();
|
Chris@0
|
220 }
|
Chris@0
|
221 }
|
Chris@0
|
222
|
Chris@0
|
223 }
|