MediaWiki  master
MemcachedBagOStuff.php
Go to the documentation of this file.
1 <?php
31  protected $routingPrefix;
32 
42  public function __construct( array $params ) {
43  $params['segmentationSize'] = $params['segmentationSize'] ?? 917504; // < 1MiB
44  parent::__construct( $params );
45 
46  $this->routingPrefix = $params['routingPrefix'] ?? '';
47 
48  // ...and does not use special disk-cache plugins
50  }
51 
60  public function makeKeyInternal( $keyspace, $components ) {
61  // Memcached keys have a maximum length of 255 characters. From that,
62  // subtract the number of characters we need for the keyspace and for
63  // the separator character needed for each argument. To handle some
64  // custom prefixes used by thing like WANObjectCache, limit to 205.
65  $charsLeft = 205 - strlen( $keyspace ) - count( $components );
66 
67  foreach ( $components as &$component ) {
68  $component = strtr( $component, ' ', '_' );
69 
70  // Make sure %, #, and non-ASCII chars are escaped
71  $component = preg_replace_callback(
72  '/[^\x21-\x22\x24\x26-\x39\x3b-\x7e]+/',
73  static function ( $m ) {
74  return rawurlencode( $m[0] );
75  },
76  $component
77  );
78 
79  // 33 = 32 characters for the MD5 + 1 for the '#' prefix.
80  if ( $charsLeft > 33 && strlen( $component ) > $charsLeft ) {
81  $component = '#' . md5( $component );
82  }
83 
84  $charsLeft -= strlen( $component );
85  }
86 
87  if ( $charsLeft < 0 ) {
88  return $keyspace . ':BagOStuff-long-key:##' . md5( implode( ':', $components ) );
89  }
90 
91  return $keyspace . ':' . implode( ':', $components );
92  }
93 
102  public function validateKeyEncoding( $key ) {
103  if ( preg_match( '/[^\x21-\x7e]+/', $key ) ) {
104  throw new Exception( "Key contains invalid characters: $key" );
105  }
106 
107  return $key;
108  }
109 
114  protected function validateKeyAndPrependRoute( $key ) {
115  $this->validateKeyEncoding( $key );
116 
117  if ( $this->routingPrefix === '' ) {
118  return $key;
119  }
120 
121  if ( $key[0] === '/' ) {
122  throw new RuntimeException( "Key '$key' already contains a route." );
123  }
124 
125  return $this->routingPrefix . $key;
126  }
127 
132  protected function stripRouteFromKey( $key ) {
133  if ( $this->routingPrefix === '' ) {
134  return $key;
135  }
136 
137  $prefixLength = strlen( $this->routingPrefix );
138  if ( substr( $key, 0, $prefixLength ) === $this->routingPrefix ) {
139  return substr( $key, $prefixLength );
140  }
141 
142  return $key;
143  }
144 
149  protected function fixExpiry( $exptime ) {
150  if ( $exptime < 0 ) {
151  // The PECL driver does not seem to like negative relative values
152  $expiresAt = $this->getCurrentTime() + $exptime;
153  } elseif ( $this->isRelativeExpiration( $exptime ) ) {
154  // TTLs higher than 30 days will be detected as absolute TTLs
155  // (UNIX timestamps), and will result in the cache entry being
156  // discarded immediately because the expiry is in the past.
157  // Clamp expires >30d at 30d, unless they're >=1e9 in which
158  // case they are likely to really be absolute (1e9 = 2011-09-09)
159  $expiresAt = min( $exptime, self::TTL_MONTH );
160  } else {
161  $expiresAt = $exptime;
162  }
163 
164  return (int)$expiresAt;
165  }
166 
167  protected function doIncrWithInit( $key, $exptime, $step, $init, $flags ) {
168  if ( $flags & self::WRITE_BACKGROUND ) {
169  return $this->doIncrWithInitAsync( $key, $exptime, $step, $init );
170  } else {
171  return $this->doIncrWithInitSync( $key, $exptime, $step, $init );
172  }
173  }
174 
182  abstract protected function doIncrWithInitAsync( $key, $exptime, $step, $init );
183 
191  abstract protected function doIncrWithInitSync( $key, $exptime, $step, $init );
192 }
string $keyspace
Default keyspace; used by makeKey()
Definition: BagOStuff.php:101
getCurrentTime()
Definition: BagOStuff.php:834
Storage medium specific cache for storing items (e.g.
Base class for memcached clients.
doIncrWithInit( $key, $exptime, $step, $init, $flags)
validateKeyEncoding( $key)
Ensure that a key is safe to use (contains no control characters and no characters above the ASCII ra...
__construct(array $params)
doIncrWithInitSync( $key, $exptime, $step, $init)
makeKeyInternal( $keyspace, $components)
Construct a cache key.
string $routingPrefix
Routing prefix appended to keys during operations.
doIncrWithInitAsync( $key, $exptime, $step, $init)
const QOS_DURABILITY_SERVICE
Data is lost once the service storing the data restarts.
const ATTR_DURABILITY
Durability of writes; see QOS_DURABILITY_* (higher means stronger)