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