Movatterモバイル変換


[0]ホーム

URL:


MediaWiki master
MapCacheLRU.php
Go to the documentation of this file.
1<?php
21namespaceWikimedia\MapCacheLRU;
22
23use InvalidArgumentException;
24use UnexpectedValueException;
25useWikimedia\LightweightObjectStore\ExpirationAwareness;
26
38classMapCacheLRUimplementsExpirationAwareness {
40private $cache = [];
42private $timestamps = [];
44private $epoch;
45
47private $maxCacheKeys;
48
50private $wallClockOverride;
51
53privateconst RANK_TOP = 1.0;
54
56privateconst SIMPLE = 0;
58privateconst FIELDS = 1;
59
63publicfunction__construct(int $maxKeys ) {
64if ( $maxKeys <= 0 ) {
65thrownew InvalidArgumentException('$maxKeys must be above zero' );
66 }
67
68 $this->maxCacheKeys = $maxKeys;
69// Use the current time as the default "as of" timestamp of entries
70 $this->epoch = $this->getCurrentTime();
71 }
72
79publicstaticfunctionnewFromArray( array $values, $maxKeys ) {
80 $mapCache =newself( $maxKeys );
81 $mapCache->cache = ( count( $values ) > $maxKeys )
82 ? array_slice( $values, -$maxKeys,null,true )
83 : $values;
84
85return $mapCache;
86 }
87
92publicfunctiontoArray() {
93return $this->cache;
94 }
95
111publicfunctionset( $key, $value, $rank = self::RANK_TOP ) {
112if ( $this->has( $key ) ) {
113 $this->ping( $key );
114 } elseif ( count( $this->cache ) >= $this->maxCacheKeys ) {
115 $evictKey = array_key_first( $this->cache );
116 unset( $this->cache[$evictKey] );
117 unset( $this->timestamps[$evictKey] );
118 }
119
120if ( $rank < 1.0 && $rank > 0 ) {
121 $offset = intval( $rank * count( $this->cache ) );
122 $this->cache = array_slice( $this->cache, 0, $offset,true )
123 + [ $key => $value ]
124 + array_slice( $this->cache, $offset,null,true );
125 }else {
126 $this->cache[$key] = $value;
127 }
128
129 $this->timestamps[$key] = [
130 self::SIMPLE => $this->getCurrentTime(),
131 self::FIELDS => []
132 ];
133 }
134
143publicfunctionhas( $key, $maxAge = INF ) {
144if ( !is_int( $key ) && !is_string( $key ) ) {
145thrownew UnexpectedValueException(
146 __METHOD__ .': invalid key; must be string or integer.' );
147 }
148return array_key_exists( $key, $this->cache )
149 && (
150// Optimization: Avoid expensive getAge/getCurrentTime for common case (T275673)
151 $maxAge === INF
152 || $maxAge <= 0
153 || $this->getKeyAge( $key ) <= $maxAge
154 );
155 }
156
173publicfunctionget( $key, $maxAge = INF, $default = null ) {
174if ( !$this->has( $key, $maxAge ) ) {
175return $default;
176 }
177
178 $this->ping( $key );
179
180return $this->cache[$key];
181 }
182
189publicfunctionsetField( $key, $field, $value, $initRank = self::RANK_TOP ) {
190if ( $this->has( $key ) ) {
191 $this->ping( $key );
192
193if ( !is_array( $this->cache[$key] ) ) {
194 $type = get_debug_type( $this->cache[$key] );
195thrownew UnexpectedValueException("Cannot add field to non-array value ('$key' is $type)" );
196 }
197 }else {
198 $this->set( $key, [], $initRank );
199 }
200
201if ( !is_string( $field ) && !is_int( $field ) ) {
202thrownew UnexpectedValueException(
203 __METHOD__ .": invalid field for '$key'; must be string or integer." );
204 }
205
206 $this->cache[$key][$field] = $value;
207 $this->timestamps[$key][self::FIELDS][$field] = $this->getCurrentTime();
208 }
209
217publicfunctionhasField( $key, $field, $maxAge = INF ) {
218 $value = $this->get( $key );
219
220if ( !is_int( $field ) && !is_string( $field ) ) {
221thrownew UnexpectedValueException(
222 __METHOD__ .": invalid field for '$key'; must be string or integer." );
223 }
224return is_array( $value )
225 && array_key_exists( $field, $value )
226 && (
227 $maxAge === INF
228 || $maxAge <= 0
229 || $this->getKeyFieldAge( $key, $field ) <= $maxAge
230 );
231 }
232
240publicfunctiongetField( $key, $field, $maxAge = INF ) {
241if ( !$this->hasField( $key, $field, $maxAge ) ) {
242returnnull;
243 }
244
245return $this->cache[$key][$field];
246 }
247
252publicfunctiongetAllKeys() {
253return array_keys( $this->cache );
254 }
255
269publicfunctiongetWithSetCallback(
270 $key, callable $callback, $rank = self::RANK_TOP, $maxAge = INF
271 ) {
272if ( $this->has( $key, $maxAge ) ) {
273 $value = $this->get( $key );
274 }else {
275 $value = $callback();
276if ( $value !==false ) {
277 $this->set( $key, $value, $rank );
278 }
279 }
280
281return $value;
282 }
283
291publicfunctionmakeKey( ...$components ) {
292// Based on BagOStuff::makeKeyInternal, except without a required
293// $keygroup prefix. While MapCacheLRU can and is used as cache for
294// multiple groups of keys, it is equally common for the instance itself
295// to represent a single group, and thus have keys where the first component
296// can directly be a user-controlled variable.
297 $key ='';
298foreach ( $components as $i => $component ) {
299if ( $i > 0 ) {
300 $key .=':';
301 }
302 $key .= strtr( $component, ['%' =>'%25',':' =>'%3A' ] );
303 }
304return $key;
305 }
306
313publicfunctionclear( $keys =null ) {
314if ( func_num_args() == 0 ) {
315 $this->cache = [];
316 $this->timestamps = [];
317 }else {
318foreach ( (array)$keys as $key ) {
319 unset( $this->cache[$key] );
320 unset( $this->timestamps[$key] );
321 }
322 }
323 }
324
331publicfunctiongetMaxSize() {
332return $this->maxCacheKeys;
333 }
334
342publicfunctionsetMaxSize(int $maxKeys ) {
343if ( $maxKeys <= 0 ) {
344thrownew InvalidArgumentException('$maxKeys must be above zero' );
345 }
346
347 $this->maxCacheKeys = $maxKeys;
348while ( count( $this->cache ) > $this->maxCacheKeys ) {
349 $evictKey = array_key_first( $this->cache );
350 unset( $this->cache[$evictKey] );
351 unset( $this->timestamps[$evictKey] );
352 }
353 }
354
360privatefunction ping( $key ) {
361 $item = $this->cache[$key];
362 unset( $this->cache[$key] );
363 $this->cache[$key] = $item;
364 }
365
370privatefunction getKeyAge( $key ) {
371 $mtime = $this->timestamps[$key][self::SIMPLE] ?? $this->epoch;
372
373return ( $this->getCurrentTime() - $mtime );
374 }
375
381privatefunction getKeyFieldAge( $key, $field ) {
382 $mtime = $this->timestamps[$key][self::FIELDS][$field] ?? $this->epoch;
383
384return ( $this->getCurrentTime() - $mtime );
385 }
386
387publicfunction__serialize() {
388return [
389'entries' => $this->cache,
390'timestamps' => $this->timestamps,
391'maxCacheKeys' => $this->maxCacheKeys,
392 ];
393 }
394
395publicfunction__unserialize( $data ) {
396 $this->cache = $data['entries'] ?? [];
397 $this->timestamps = $data['timestamps'] ?? [];
398// Fallback needed for serializations prior to T218511
399 $this->maxCacheKeys = $data['maxCacheKeys'] ?? ( count( $this->cache ) + 1 );
400 $this->epoch = $this->getCurrentTime();
401 }
402
407protectedfunctiongetCurrentTime() {
408return $this->wallClockOverride ?: microtime(true );
409 }
410
415publicfunctionsetMockTime( &$time ) {
416 $this->wallClockOverride =& $time;
417 }
418}
419
421class_alias( MapCacheLRU::class,'MapCacheLRU' );
Wikimedia\MapCacheLRU\MapCacheLRU
Store key-value entries in a size-limited in-memory LRU cache.
DefinitionMapCacheLRU.php:38
Wikimedia\MapCacheLRU\MapCacheLRU\setMockTime
setMockTime(&$time)
DefinitionMapCacheLRU.php:415
Wikimedia\MapCacheLRU\MapCacheLRU\setMaxSize
setMaxSize(int $maxKeys)
Resize the maximum number of cache entries, removing older entries as needed.
DefinitionMapCacheLRU.php:342
Wikimedia\MapCacheLRU\MapCacheLRU\__unserialize
__unserialize( $data)
DefinitionMapCacheLRU.php:395
Wikimedia\MapCacheLRU\MapCacheLRU\newFromArray
static newFromArray(array $values, $maxKeys)
DefinitionMapCacheLRU.php:79
Wikimedia\MapCacheLRU\MapCacheLRU\makeKey
makeKey(... $components)
Format a cache key string.
DefinitionMapCacheLRU.php:291
Wikimedia\MapCacheLRU\MapCacheLRU\getWithSetCallback
getWithSetCallback( $key, callable $callback, $rank=self::RANK_TOP, $maxAge=INF)
Get an item with the given key, producing and setting it if not found.
DefinitionMapCacheLRU.php:269
Wikimedia\MapCacheLRU\MapCacheLRU\clear
clear( $keys=null)
Clear one or several cache entries, or all cache entries.
DefinitionMapCacheLRU.php:313
Wikimedia\MapCacheLRU\MapCacheLRU\getCurrentTime
getCurrentTime()
DefinitionMapCacheLRU.php:407
Wikimedia\MapCacheLRU\MapCacheLRU\__serialize
__serialize()
DefinitionMapCacheLRU.php:387
Wikimedia\MapCacheLRU\MapCacheLRU\toArray
toArray()
DefinitionMapCacheLRU.php:92
Wikimedia\MapCacheLRU\MapCacheLRU\getMaxSize
getMaxSize()
Get the maximum number of keys allowed.
DefinitionMapCacheLRU.php:331
Wikimedia\MapCacheLRU\MapCacheLRU\getAllKeys
getAllKeys()
DefinitionMapCacheLRU.php:252
Wikimedia\MapCacheLRU\MapCacheLRU\setField
setField( $key, $field, $value, $initRank=self::RANK_TOP)
DefinitionMapCacheLRU.php:189
Wikimedia\MapCacheLRU\MapCacheLRU\has
has( $key, $maxAge=INF)
Check if a key exists.
DefinitionMapCacheLRU.php:143
Wikimedia\MapCacheLRU\MapCacheLRU\hasField
hasField( $key, $field, $maxAge=INF)
DefinitionMapCacheLRU.php:217
Wikimedia\MapCacheLRU\MapCacheLRU\__construct
__construct(int $maxKeys)
DefinitionMapCacheLRU.php:63
Wikimedia\MapCacheLRU\MapCacheLRU\getField
getField( $key, $field, $maxAge=INF)
DefinitionMapCacheLRU.php:240
Wikimedia\LightweightObjectStore\ExpirationAwareness
Generic interface providing Time-To-Live constants for expirable object storage.
DefinitionExpirationAwareness.php:30
Wikimedia\MapCacheLRU
DefinitionMapCacheLRU.php:21

[8]ページ先頭

©2009-2025 Movatter.jp