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