MediaWiki  master
HashBagOStuff.php
Go to the documentation of this file.
1 <?php
34  protected $bag = [];
36  protected $maxCacheKeys;
37 
39  private $token;
40 
42  private static $casCounter = 0;
43 
44  public const KEY_VAL = 0;
45  public const KEY_EXP = 1;
46  public const KEY_CAS = 2;
47 
55  public function __construct( $params = [] ) {
56  $params['segmentationSize'] = $params['segmentationSize'] ?? INF;
57  parent::__construct( $params );
58 
59  $this->token = microtime( true ) . ':' . mt_rand();
60  $maxKeys = $params['maxKeys'] ?? INF;
61  if ( $maxKeys !== INF && ( !is_int( $maxKeys ) || $maxKeys <= 0 ) ) {
62  throw new InvalidArgumentException( '$maxKeys parameter must be above zero' );
63  }
64  $this->maxCacheKeys = $maxKeys;
65 
67  }
68 
69  protected function doGet( $key, $flags = 0, &$casToken = null ) {
70  $getToken = ( $casToken === self::PASS_BY_REF );
71  $casToken = null;
72 
73  if ( !$this->hasKey( $key ) || $this->expire( $key ) ) {
74  return false;
75  }
76 
77  // Refresh key position for maxCacheKeys eviction
78  $temp = $this->bag[$key];
79  unset( $this->bag[$key] );
80  $this->bag[$key] = $temp;
81 
82  if ( $getToken ) {
83  $casToken = $this->bag[$key][self::KEY_CAS];
84  }
85 
86  return $this->bag[$key][self::KEY_VAL];
87  }
88 
89  protected function doSet( $key, $value, $exptime = 0, $flags = 0 ) {
90  // Refresh key position for maxCacheKeys eviction
91  unset( $this->bag[$key] );
92  $this->bag[$key] = [
93  self::KEY_VAL => $value,
94  self::KEY_EXP => $this->getExpirationAsTimestamp( $exptime ),
95  self::KEY_CAS => $this->token . ':' . ++self::$casCounter
96  ];
97 
98  if ( count( $this->bag ) > $this->maxCacheKeys ) {
99  reset( $this->bag );
100  $evictKey = key( $this->bag );
101  unset( $this->bag[$evictKey] );
102  }
103 
104  return true;
105  }
106 
107  protected function doAdd( $key, $value, $exptime = 0, $flags = 0 ) {
108  if ( $this->hasKey( $key ) && !$this->expire( $key ) ) {
109  return false; // key already set
110  }
111 
112  return $this->doSet( $key, $value, $exptime, $flags );
113  }
114 
115  protected function doDelete( $key, $flags = 0 ) {
116  unset( $this->bag[$key] );
117 
118  return true;
119  }
120 
121  public function incr( $key, $value = 1, $flags = 0 ) {
122  $n = $this->get( $key );
123  if ( $this->isInteger( $n ) ) {
124  $n = max( $n + (int)$value, 0 );
125  $this->bag[$key][self::KEY_VAL] = $n;
126 
127  return $n;
128  }
129 
130  return false;
131  }
132 
133  public function decr( $key, $value = 1, $flags = 0 ) {
134  return $this->incr( $key, -$value, $flags );
135  }
136 
140  public function clear() {
141  $this->bag = [];
142  }
143 
148  protected function expire( $key ) {
149  $et = $this->bag[$key][self::KEY_EXP];
150  if ( $et == self::TTL_INDEFINITE || $et > $this->getCurrentTime() ) {
151  return false;
152  }
153 
154  $this->doDelete( $key );
155 
156  return true;
157  }
158 
159  public function setNewPreparedValues( array $valueByKey ) {
160  // Do not bother with serialization as this class does not serialize values
161  $sizes = [];
162  foreach ( $valueByKey as $value ) {
163  $sizes[] = $this->guessSerialValueSize( $value );
164  }
165 
166  return $sizes;
167  }
168 
176  public function hasKey( $key ) {
177  return isset( $this->bag[$key] );
178  }
179 
180  public function makeKeyInternal( $keyspace, $components ) {
181  return $this->genericKeyFromComponents( $keyspace, ...$components );
182  }
183 
184  protected function convertGenericKey( $key ) {
185  return $key; // short-circuit; already uses "generic" keys
186  }
187 }
HashBagOStuff\KEY_EXP
const KEY_EXP
Definition: HashBagOStuff.php:45
Wikimedia\LightweightObjectStore\StorageAwareness\QOS_DURABILITY_SCRIPT
const QOS_DURABILITY_SCRIPT
Data is lost at the end of the current web request or CLI script.
Definition: StorageAwareness.php:53
MediumSpecificBagOStuff\isInteger
isInteger( $value)
Check if a value is an integer.
Definition: MediumSpecificBagOStuff.php:953
HashBagOStuff\$bag
mixed[] $bag
Definition: HashBagOStuff.php:34
HashBagOStuff\expire
expire( $key)
Definition: HashBagOStuff.php:148
HashBagOStuff\setNewPreparedValues
setNewPreparedValues(array $valueByKey)
Make a "generic" reversible cache key from the given components.
Definition: HashBagOStuff.php:159
MediumSpecificBagOStuff\guessSerialValueSize
guessSerialValueSize( $value, $depth=0, &$loops=0)
Estimate the size of a variable once serialized.
Definition: MediumSpecificBagOStuff.php:1056
HashBagOStuff
Simple store for keeping values in an associative array for the current process.
Definition: HashBagOStuff.php:32
HashBagOStuff\decr
decr( $key, $value=1, $flags=0)
Decrease stored value of $key by $value while preserving its TTL.
Definition: HashBagOStuff.php:133
HashBagOStuff\$token
string $token
CAS token prefix for this instance.
Definition: HashBagOStuff.php:39
HashBagOStuff\doGet
doGet( $key, $flags=0, &$casToken=null)
Definition: HashBagOStuff.php:69
HashBagOStuff\KEY_CAS
const KEY_CAS
Definition: HashBagOStuff.php:46
HashBagOStuff\makeKeyInternal
makeKeyInternal( $keyspace, $components)
Make a cache key for the given keyspace and components.
Definition: HashBagOStuff.php:180
HashBagOStuff\hasKey
hasKey( $key)
Does this bag have a non-null value for the given key?
Definition: HashBagOStuff.php:176
BagOStuff\genericKeyFromComponents
genericKeyFromComponents(... $components)
At a minimum, there must be a keyspace and collection name component.
Definition: BagOStuff.php:662
HashBagOStuff\incr
incr( $key, $value=1, $flags=0)
Increase stored value of $key by $value while preserving its TTL.
Definition: HashBagOStuff.php:121
HashBagOStuff\clear
clear()
Clear all values in cache.
Definition: HashBagOStuff.php:140
MediumSpecificBagOStuff\getExpirationAsTimestamp
getExpirationAsTimestamp( $exptime)
Convert an optionally relative timestamp to an absolute time.
Definition: MediumSpecificBagOStuff.php:913
HashBagOStuff\convertGenericKey
convertGenericKey( $key)
Convert a "generic" reversible cache key into one for this cache.
Definition: HashBagOStuff.php:184
MediumSpecificBagOStuff
Storage medium specific cache for storing items (e.g.
Definition: MediumSpecificBagOStuff.php:34
HashBagOStuff\KEY_VAL
const KEY_VAL
Definition: HashBagOStuff.php:44
HashBagOStuff\$casCounter
static int $casCounter
CAS token counter.
Definition: HashBagOStuff.php:42
HashBagOStuff\doSet
doSet( $key, $value, $exptime=0, $flags=0)
Set an item.
Definition: HashBagOStuff.php:89
HashBagOStuff\__construct
__construct( $params=[])
Definition: HashBagOStuff.php:55
HashBagOStuff\$maxCacheKeys
int double $maxCacheKeys
Max entries allowed, INF for unlimited.
Definition: HashBagOStuff.php:36
HashBagOStuff\doAdd
doAdd( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.
Definition: HashBagOStuff.php:107
Wikimedia\LightweightObjectStore\StorageAwareness\ATTR_DURABILITY
const ATTR_DURABILITY
Durability of writes; see QOS_DURABILITY_* (higher means stronger)
Definition: StorageAwareness.php:45
BagOStuff\getCurrentTime
getCurrentTime()
Definition: BagOStuff.php:781
BagOStuff\$keyspace
string $keyspace
Default keyspace; used by makeKey()
Definition: BagOStuff.php:103
HashBagOStuff\doDelete
doDelete( $key, $flags=0)
Delete an item.
Definition: HashBagOStuff.php:115