MediaWiki  master
HashBagOStuff.php
Go to the documentation of this file.
1 <?php
33  protected $bag = [];
35  protected $maxCacheKeys;
36 
38  private $token;
39 
41  private static $casCounter = 0;
42 
43  public const KEY_VAL = 0;
44  public const KEY_EXP = 1;
45  public const KEY_CAS = 2;
46 
54  public function __construct( $params = [] ) {
55  $params['segmentationSize'] = $params['segmentationSize'] ?? INF;
56  parent::__construct( $params );
57 
58  $this->token = microtime( true ) . ':' . mt_rand();
59  $this->maxCacheKeys = $params['maxKeys'] ?? INF;
60  if ( $this->maxCacheKeys <= 0 ) {
61  throw new InvalidArgumentException( '$maxKeys parameter must be above zero' );
62  }
63  }
64 
65  protected function doGet( $key, $flags = 0, &$casToken = null ) {
66  $casToken = null;
67 
68  if ( !$this->hasKey( $key ) || $this->expire( $key ) ) {
69  return false;
70  }
71 
72  // Refresh key position for maxCacheKeys eviction
73  $temp = $this->bag[$key];
74  unset( $this->bag[$key] );
75  $this->bag[$key] = $temp;
76 
77  $casToken = $this->bag[$key][self::KEY_CAS];
78 
79  return $this->bag[$key][self::KEY_VAL];
80  }
81 
82  protected function doSet( $key, $value, $exptime = 0, $flags = 0 ) {
83  // Refresh key position for maxCacheKeys eviction
84  unset( $this->bag[$key] );
85  $this->bag[$key] = [
86  self::KEY_VAL => $value,
87  self::KEY_EXP => $this->getExpirationAsTimestamp( $exptime ),
88  self::KEY_CAS => $this->token . ':' . ++self::$casCounter
89  ];
90 
91  if ( count( $this->bag ) > $this->maxCacheKeys ) {
92  reset( $this->bag );
93  $evictKey = key( $this->bag );
94  unset( $this->bag[$evictKey] );
95  }
96 
97  return true;
98  }
99 
100  protected function doAdd( $key, $value, $exptime = 0, $flags = 0 ) {
101  if ( $this->hasKey( $key ) && !$this->expire( $key ) ) {
102  return false; // key already set
103  }
104 
105  return $this->doSet( $key, $value, $exptime, $flags );
106  }
107 
108  protected function doDelete( $key, $flags = 0 ) {
109  unset( $this->bag[$key] );
110 
111  return true;
112  }
113 
114  public function incr( $key, $value = 1, $flags = 0 ) {
115  $n = $this->get( $key );
116  if ( $this->isInteger( $n ) ) {
117  $n = max( $n + (int)$value, 0 );
118  $this->bag[$key][self::KEY_VAL] = $n;
119 
120  return $n;
121  }
122 
123  return false;
124  }
125 
126  public function decr( $key, $value = 1, $flags = 0 ) {
127  return $this->incr( $key, -$value, $flags );
128  }
129 
133  public function clear() {
134  $this->bag = [];
135  }
136 
141  protected function expire( $key ) {
142  $et = $this->bag[$key][self::KEY_EXP];
143  if ( $et == self::TTL_INDEFINITE || $et > $this->getCurrentTime() ) {
144  return false;
145  }
146 
147  $this->doDelete( $key );
148 
149  return true;
150  }
151 
152  public function setNewPreparedValues( array $valueByKey ) {
153  // Do not bother with serialization as this class does not serialize values
154  $sizes = [];
155  foreach ( $valueByKey as $value ) {
156  $sizes[] = $this->guessSerialValueSize( $value );
157  }
158 
159  return $sizes;
160  }
161 
169  public function hasKey( $key ) {
170  return isset( $this->bag[$key] );
171  }
172 }
HashBagOStuff\KEY_EXP
const KEY_EXP
Definition: HashBagOStuff.php:44
MediumSpecificBagOStuff\isInteger
isInteger( $value)
Check if a value is an integer.
Definition: MediumSpecificBagOStuff.php:878
HashBagOStuff\$bag
mixed[] $bag
Definition: HashBagOStuff.php:33
HashBagOStuff\expire
expire( $key)
Definition: HashBagOStuff.php:141
HashBagOStuff\setNewPreparedValues
setNewPreparedValues(array $valueByKey)
Prepare values for storage and get their serialized sizes, or, estimate those sizes.
Definition: HashBagOStuff.php:152
MediumSpecificBagOStuff\guessSerialValueSize
guessSerialValueSize( $value, $depth=0, &$loops=0)
Estimate the size of a variable once serialized.
Definition: MediumSpecificBagOStuff.php:996
HashBagOStuff
Simple store for keeping values in an associative array for the current process.
Definition: HashBagOStuff.php:31
HashBagOStuff\decr
decr( $key, $value=1, $flags=0)
Decrease stored value of $key by $value while preserving its TTL.
Definition: HashBagOStuff.php:126
HashBagOStuff\$token
string $token
CAS token prefix for this instance.
Definition: HashBagOStuff.php:38
HashBagOStuff\doGet
doGet( $key, $flags=0, &$casToken=null)
Definition: HashBagOStuff.php:65
HashBagOStuff\KEY_CAS
const KEY_CAS
Definition: HashBagOStuff.php:45
HashBagOStuff\hasKey
hasKey( $key)
Does this bag have a non-null value for the given key?
Definition: HashBagOStuff.php:169
HashBagOStuff\incr
incr( $key, $value=1, $flags=0)
Increase stored value of $key by $value while preserving its TTL.
Definition: HashBagOStuff.php:114
HashBagOStuff\clear
clear()
Clear all values in cache.
Definition: HashBagOStuff.php:133
MediumSpecificBagOStuff\getExpirationAsTimestamp
getExpirationAsTimestamp( $exptime)
Convert an optionally relative timestamp to an absolute time.
Definition: MediumSpecificBagOStuff.php:838
MediumSpecificBagOStuff
Storage medium specific cache for storing items (e.g.
Definition: MediumSpecificBagOStuff.php:34
HashBagOStuff\KEY_VAL
const KEY_VAL
Definition: HashBagOStuff.php:43
HashBagOStuff\$casCounter
static int $casCounter
CAS token counter.
Definition: HashBagOStuff.php:41
HashBagOStuff\$maxCacheKeys
int $maxCacheKeys
Max entries allowed.
Definition: HashBagOStuff.php:35
HashBagOStuff\doSet
doSet( $key, $value, $exptime=0, $flags=0)
Set an item.
Definition: HashBagOStuff.php:82
HashBagOStuff\__construct
__construct( $params=[])
Definition: HashBagOStuff.php:54
HashBagOStuff\doAdd
doAdd( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.
Definition: HashBagOStuff.php:100
BagOStuff\getCurrentTime
getCurrentTime()
Definition: BagOStuff.php:565
HashBagOStuff\doDelete
doDelete( $key, $flags=0)
Delete an item.
Definition: HashBagOStuff.php:108