MediaWiki  master
APCUBagOStuff.php
Go to the documentation of this file.
1 <?php
40  private $useIncrTTLArg;
41 
47  const KEY_SUFFIX = ':4';
48 
50  private static $CAS_MAX_ATTEMPTS = 100;
51 
52  public function __construct( array $params = [] ) {
53  $params['segmentationSize'] = $params['segmentationSize'] ?? INF;
54  parent::__construct( $params );
55  // The extension serializer is still buggy, unlike "php" and "igbinary"
56  $this->nativeSerialize = ( ini_get( 'apc.serializer' ) !== 'default' );
57  $this->useIncrTTLArg = version_compare( phpversion( 'apcu' ), '5.1.12', '>=' );
58  }
59 
60  protected function doGet( $key, $flags = 0, &$casToken = null ) {
61  $casToken = null;
62 
63  $blob = apcu_fetch( $key . self::KEY_SUFFIX );
64  $value = $this->nativeSerialize ? $blob : $this->unserialize( $blob );
65  if ( $value !== false ) {
66  $casToken = $blob; // don't bother hashing this
67  }
68 
69  return $value;
70  }
71 
72  protected function doSet( $key, $value, $exptime = 0, $flags = 0 ) {
73  return apcu_store(
74  $key . self::KEY_SUFFIX,
75  $this->nativeSerialize ? $value : $this->serialize( $value ),
76  $exptime
77  );
78  }
79 
80  protected function doAdd( $key, $value, $exptime = 0, $flags = 0 ) {
81  return apcu_add(
82  $key . self::KEY_SUFFIX,
83  $this->nativeSerialize ? $value : $this->serialize( $value ),
84  $exptime
85  );
86  }
87 
88  protected function doDelete( $key, $flags = 0 ) {
89  apcu_delete( $key . self::KEY_SUFFIX );
90 
91  return true;
92  }
93 
94  public function incr( $key, $value = 1, $flags = 0 ) {
95  // https://github.com/krakjoe/apcu/issues/166
96  for ( $i = 0; $i < self::$CAS_MAX_ATTEMPTS; ++$i ) {
97  $oldCount = apcu_fetch( $key . self::KEY_SUFFIX );
98  if ( !is_int( $oldCount ) ) {
99  return false;
100  }
101  $count = $oldCount + (int)$value;
102  if ( apcu_cas( $key . self::KEY_SUFFIX, $oldCount, $count ) ) {
103  return $count;
104  }
105  }
106 
107  return false;
108  }
109 
110  public function decr( $key, $value = 1, $flags = 0 ) {
111  // https://github.com/krakjoe/apcu/issues/166
112  if ( apcu_exists( $key . self::KEY_SUFFIX ) ) {
113  return apcu_dec( $key . self::KEY_SUFFIX, $value );
114  } else {
115  return false;
116  }
117  }
118 
119  public function incrWithInit( $key, $exptime, $value = 1, $init = null, $flags = 0 ) {
120  // Use apcu 5.1.12 $ttl argument if apcu_inc() will initialize to $init:
121  // https://www.php.net/manual/en/function.apcu-inc.php
122  if ( $value === $init && $this->useIncrTTLArg ) {
124  return apcu_inc( $key . self::KEY_SUFFIX, $value, $success, $exptime );
125  }
126 
127  for ( $i = 0; $i < self::$CAS_MAX_ATTEMPTS; ++$i ) {
128  $oldCount = apcu_fetch( $key . self::KEY_SUFFIX );
129  if ( $oldCount === false ) {
130  $count = (int)$init;
131  if ( apcu_add( $key . self::KEY_SUFFIX, $count, $exptime ) ) {
132  return $count;
133  }
134  } elseif ( !is_int( $oldCount ) ) {
135  return false;
136  } else {
137  $count = $oldCount + (int)$value;
138  if ( apcu_cas( $key . self::KEY_SUFFIX, $oldCount, $count ) ) {
139  return $count;
140  }
141  }
142  }
143 
144  return false;
145  }
146 }
doAdd( $key, $value, $exptime=0, $flags=0)
$success
static int $CAS_MAX_ATTEMPTS
Max attempts for implicit CAS operations.
doDelete( $key, $flags=0)
This is a wrapper for APCU&#39;s shared memory functions.
__construct(array $params=[])
doSet( $key, $value, $exptime=0, $flags=0)
bool $nativeSerialize
Whether to trust the APC implementation to serialization.
decr( $key, $value=1, $flags=0)
doGet( $key, $flags=0, &$casToken=null)
incrWithInit( $key, $exptime, $value=1, $init=null, $flags=0)
Storage medium specific cache for storing items (e.g.
incr( $key, $value=1, $flags=0)