MediaWiki master
CachedBagOStuff.php
Go to the documentation of this file.
1<?php
24namespace Wikimedia\ObjectCache;
25
41 protected $store;
43 protected $procCache;
44
51 public function __construct( BagOStuff $backend, $params = [] ) {
52 $params['keyspace'] = $backend->keyspace;
53 parent::__construct( $params );
54
55 $this->store = $backend;
56 $this->procCache = new HashBagOStuff( $params );
57
58 $this->attrMap = $backend->attrMap;
59 }
60
61 public function get( $key, $flags = 0 ) {
62 $value = $this->procCache->get( $key, $flags );
63 if ( $value !== false || $this->procCache->hasKey( $key ) ) {
64 return $value;
65 }
66
67 $value = $this->store->proxyCall(
68 __FUNCTION__,
69 self::ARG0_KEY,
70 self::RES_NONKEY,
71 func_get_args(),
72 $this
73 );
74 $this->set( $key, $value, self::TTL_INDEFINITE, self::WRITE_CACHE_ONLY );
75
76 return $value;
77 }
78
79 public function getMulti( array $keys, $flags = 0 ) {
80 $valueByKeyCached = [];
81
82 $keysFetch = [];
83 foreach ( $keys as $key ) {
84 $value = $this->procCache->get( $key, $flags );
85 if ( $value === false && !$this->procCache->hasKey( $key ) ) {
86 $keysFetch[] = $key;
87 } else {
88 $valueByKeyCached[$key] = $value;
89 }
90 }
91
92 $valueByKeyFetched = $this->store->proxyCall(
93 __FUNCTION__,
94 self::ARG0_KEYARR,
95 self::RES_KEYMAP,
96 [ $keysFetch, $flags ],
97 $this
98 );
99 $this->setMulti( $valueByKeyFetched, self::TTL_INDEFINITE, self::WRITE_CACHE_ONLY );
100
101 return $valueByKeyCached + $valueByKeyFetched;
102 }
103
104 public function set( $key, $value, $exptime = 0, $flags = 0 ) {
105 $this->procCache->set( $key, $value, $exptime, $flags );
106
107 if ( $this->fieldHasFlags( $flags, self::WRITE_CACHE_ONLY ) ) {
108 return true;
109 }
110
111 return $this->store->proxyCall(
112 __FUNCTION__,
113 self::ARG0_KEY,
114 self::RES_NONKEY,
115 func_get_args(),
116 $this
117 );
118 }
119
120 public function delete( $key, $flags = 0 ) {
121 $this->procCache->delete( $key, $flags );
122
123 if ( $this->fieldHasFlags( $flags, self::WRITE_CACHE_ONLY ) ) {
124 return true;
125 }
126
127 return $this->store->proxyCall(
128 __FUNCTION__,
129 self::ARG0_KEY,
130 self::RES_NONKEY,
131 func_get_args(),
132 $this
133 );
134 }
135
136 public function add( $key, $value, $exptime = 0, $flags = 0 ) {
137 if ( $this->get( $key ) === false ) {
138 return $this->set( $key, $value, $exptime, $flags );
139 }
140
141 // key already set
142 return false;
143 }
144
145 // These just call the backend (tested elsewhere)
146 // @codeCoverageIgnoreStart
147
148 public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
149 $this->procCache->delete( $key );
150
151 return $this->store->proxyCall(
152 __FUNCTION__,
153 self::ARG0_KEY,
154 self::RES_NONKEY,
155 func_get_args(),
156 $this
157 );
158 }
159
160 public function changeTTL( $key, $exptime = 0, $flags = 0 ) {
161 $this->procCache->delete( $key );
162
163 return $this->store->proxyCall(
164 __FUNCTION__,
165 self::ARG0_KEY,
166 self::RES_NONKEY,
167 func_get_args(),
168 $this
169 );
170 }
171
172 public function lock( $key, $timeout = 6, $exptime = 6, $rclass = '' ) {
173 return $this->store->proxyCall(
174 __FUNCTION__,
175 self::ARG0_KEY,
176 self::RES_NONKEY,
177 func_get_args(),
178 $this
179 );
180 }
181
182 public function unlock( $key ) {
183 return $this->store->proxyCall(
184 __FUNCTION__,
185 self::ARG0_KEY,
186 self::RES_NONKEY,
187 func_get_args(),
188 $this
189 );
190 }
191
193 $timestamp,
194 callable $progress = null,
195 $limit = INF,
196 string $tag = null
197 ) {
198 $this->procCache->deleteObjectsExpiringBefore( $timestamp, $progress, $limit, $tag );
199
200 return $this->store->proxyCall(
201 __FUNCTION__,
202 self::ARG0_NONKEY,
203 self::RES_NONKEY,
204 func_get_args(),
205 $this
206 );
207 }
208
209 public function setMulti( array $valueByKey, $exptime = 0, $flags = 0 ) {
210 $this->procCache->setMulti( $valueByKey, $exptime, $flags );
211
212 if ( $this->fieldHasFlags( $flags, self::WRITE_CACHE_ONLY ) ) {
213 return true;
214 }
215
216 return $this->store->proxyCall(
217 __FUNCTION__,
218 self::ARG0_KEYMAP,
219 self::RES_NONKEY,
220 func_get_args(),
221 $this
222 );
223 }
224
225 public function deleteMulti( array $keys, $flags = 0 ) {
226 $this->procCache->deleteMulti( $keys, $flags );
227
228 if ( $this->fieldHasFlags( $flags, self::WRITE_CACHE_ONLY ) ) {
229 return true;
230 }
231
232 return $this->store->proxyCall(
233 __FUNCTION__,
234 self::ARG0_KEYARR,
235 self::RES_NONKEY,
236 func_get_args(),
237 $this
238 );
239 }
240
241 public function changeTTLMulti( array $keys, $exptime, $flags = 0 ) {
242 $this->procCache->changeTTLMulti( $keys, $exptime, $flags );
243
244 if ( $this->fieldHasFlags( $flags, self::WRITE_CACHE_ONLY ) ) {
245 return true;
246 }
247
248 return $this->store->proxyCall(
249 __FUNCTION__,
250 self::ARG0_KEYARR,
251 self::RES_NONKEY,
252 func_get_args(),
253 $this
254 );
255 }
256
257 public function incrWithInit( $key, $exptime, $step = 1, $init = null, $flags = 0 ) {
258 $this->procCache->delete( $key );
259
260 return $this->store->proxyCall(
261 __FUNCTION__,
262 self::ARG0_KEY,
263 self::RES_NONKEY,
264 func_get_args(),
265 $this
266 );
267 }
268
269 public function setMockTime( &$time ) {
270 parent::setMockTime( $time );
271 $this->procCache->setMockTime( $time );
272 $this->store->setMockTime( $time );
273 }
274
275 // @codeCoverageIgnoreEnd
276}
277
279class_alias( CachedBagOStuff::class, 'CachedBagOStuff' );
array $params
The job parameters.
Class representing a cache/ephemeral data store.
Definition BagOStuff.php:88
get( $key, $flags=0)
Get an item.
const WRITE_CACHE_ONLY
Bitfield constants for set()/merge(); these are only advisory.
Wrapper around a BagOStuff that caches data in memory.
setMulti(array $valueByKey, $exptime=0, $flags=0)
Set a batch of items.
changeTTL( $key, $exptime=0, $flags=0)
Change the expiration on an item.
lock( $key, $timeout=6, $exptime=6, $rclass='')
Acquire an advisory lock on a key string, exclusive to the caller.
unlock( $key)
Release an advisory lock on a key string.
deleteMulti(array $keys, $flags=0)
Delete a batch of items.
incrWithInit( $key, $exptime, $step=1, $init=null, $flags=0)
Increase the value of the given key (no TTL change) if it exists or create it otherwise.
merge( $key, callable $callback, $exptime=0, $attempts=10, $flags=0)
Merge changes into the existing cache value (possibly creating a new one)
getMulti(array $keys, $flags=0)
Get a batch of items.
deleteObjectsExpiringBefore( $timestamp, callable $progress=null, $limit=INF, string $tag=null)
Delete all objects expiring before a certain date.
add( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.
changeTTLMulti(array $keys, $exptime, $flags=0)
Change the expiration of multiple items.
__construct(BagOStuff $backend, $params=[])
Simple store for keeping values in an associative array for the current process.