Localisation updates from https://translatewiki.net.
[mediawiki.git] / includes / libs / objectcache / CachedBagOStuff.php
blobe6f6e06dc14f0ae5e9850e56886b7ce37d2bdca6
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
18 * @file
20 namespace Wikimedia\ObjectCache;
22 /**
23 * Wrap any BagOStuff and add an in-process memory cache to it.
25 * The differences between CachedBagOStuff and MultiWriteBagOStuff are:
26 * - CachedBagOStuff supports only one "backend".
27 * - There's a flag for writes to only go to the in-memory cache.
28 * - The in-memory cache is always updated.
29 * - Locks go to the backend cache (with MultiWriteBagOStuff, it would wind
30 * up going to the HashBagOStuff used for the in-memory cache).
32 * @newable
33 * @ingroup Cache
35 class CachedBagOStuff extends BagOStuff {
36 /** @var BagOStuff */
37 protected $store;
38 /** @var HashBagOStuff */
39 protected $procCache;
41 /**
42 * @stable to call
44 * @param BagOStuff $backend Permanent backend to use
45 * @param array $params Parameters for HashBagOStuff
47 public function __construct( BagOStuff $backend, $params = [] ) {
48 $params['keyspace'] = $backend->keyspace;
49 parent::__construct( $params );
51 $this->store = $backend;
52 $this->procCache = new HashBagOStuff( $params );
54 $this->attrMap = $backend->attrMap;
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;
63 $value = $this->store->proxyCall(
64 __FUNCTION__,
65 self::ARG0_KEY,
66 self::RES_NONKEY,
67 func_get_args(),
68 $this
70 $this->set( $key, $value, self::TTL_INDEFINITE, self::WRITE_CACHE_ONLY );
72 return $value;
75 public function getMulti( array $keys, $flags = 0 ) {
76 $valueByKeyCached = [];
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;
88 $valueByKeyFetched = $this->store->proxyCall(
89 __FUNCTION__,
90 self::ARG0_KEYARR,
91 self::RES_KEYMAP,
92 [ $keysFetch, $flags ],
93 $this
95 $this->setMulti( $valueByKeyFetched, self::TTL_INDEFINITE, self::WRITE_CACHE_ONLY );
97 return $valueByKeyCached + $valueByKeyFetched;
100 public function set( $key, $value, $exptime = 0, $flags = 0 ) {
101 $this->procCache->set( $key, $value, $exptime, $flags );
103 if ( $this->fieldHasFlags( $flags, self::WRITE_CACHE_ONLY ) ) {
104 return true;
107 return $this->store->proxyCall(
108 __FUNCTION__,
109 self::ARG0_KEY,
110 self::RES_NONKEY,
111 func_get_args(),
112 $this
116 public function delete( $key, $flags = 0 ) {
117 $this->procCache->delete( $key, $flags );
119 if ( $this->fieldHasFlags( $flags, self::WRITE_CACHE_ONLY ) ) {
120 return true;
123 return $this->store->proxyCall(
124 __FUNCTION__,
125 self::ARG0_KEY,
126 self::RES_NONKEY,
127 func_get_args(),
128 $this
132 public function add( $key, $value, $exptime = 0, $flags = 0 ) {
133 if ( $this->get( $key ) === false ) {
134 return $this->set( $key, $value, $exptime, $flags );
137 // key already set
138 return false;
141 // These just call the backend (tested elsewhere)
142 // @codeCoverageIgnoreStart
144 public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
145 $this->procCache->delete( $key );
147 return $this->store->proxyCall(
148 __FUNCTION__,
149 self::ARG0_KEY,
150 self::RES_NONKEY,
151 func_get_args(),
152 $this
156 public function changeTTL( $key, $exptime = 0, $flags = 0 ) {
157 $this->procCache->delete( $key );
159 return $this->store->proxyCall(
160 __FUNCTION__,
161 self::ARG0_KEY,
162 self::RES_NONKEY,
163 func_get_args(),
164 $this
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
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
188 public function deleteObjectsExpiringBefore(
189 $timestamp,
190 ?callable $progress = null,
191 $limit = INF,
192 ?string $tag = null
194 $this->procCache->deleteObjectsExpiringBefore( $timestamp, $progress, $limit, $tag );
196 return $this->store->proxyCall(
197 __FUNCTION__,
198 self::ARG0_NONKEY,
199 self::RES_NONKEY,
200 func_get_args(),
201 $this
205 public function setMulti( array $valueByKey, $exptime = 0, $flags = 0 ) {
206 $this->procCache->setMulti( $valueByKey, $exptime, $flags );
208 if ( $this->fieldHasFlags( $flags, self::WRITE_CACHE_ONLY ) ) {
209 return true;
212 return $this->store->proxyCall(
213 __FUNCTION__,
214 self::ARG0_KEYMAP,
215 self::RES_NONKEY,
216 func_get_args(),
217 $this
221 public function deleteMulti( array $keys, $flags = 0 ) {
222 $this->procCache->deleteMulti( $keys, $flags );
224 if ( $this->fieldHasFlags( $flags, self::WRITE_CACHE_ONLY ) ) {
225 return true;
228 return $this->store->proxyCall(
229 __FUNCTION__,
230 self::ARG0_KEYARR,
231 self::RES_NONKEY,
232 func_get_args(),
233 $this
237 public function changeTTLMulti( array $keys, $exptime, $flags = 0 ) {
238 $this->procCache->changeTTLMulti( $keys, $exptime, $flags );
240 if ( $this->fieldHasFlags( $flags, self::WRITE_CACHE_ONLY ) ) {
241 return true;
244 return $this->store->proxyCall(
245 __FUNCTION__,
246 self::ARG0_KEYARR,
247 self::RES_NONKEY,
248 func_get_args(),
249 $this
253 public function incrWithInit( $key, $exptime, $step = 1, $init = null, $flags = 0 ) {
254 $this->procCache->delete( $key );
256 return $this->store->proxyCall(
257 __FUNCTION__,
258 self::ARG0_KEY,
259 self::RES_NONKEY,
260 func_get_args(),
261 $this
265 public function setMockTime( &$time ) {
266 parent::setMockTime( $time );
267 $this->procCache->setMockTime( $time );
268 $this->store->setMockTime( $time );
271 // @codeCoverageIgnoreEnd
274 /** @deprecated class alias since 1.43 */
275 class_alias( CachedBagOStuff::class, 'CachedBagOStuff' );