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->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_BE; // unreliable
47  $this->routingPrefix = $params['routingPrefix'] ?? '';
48  }
49 
58  public function makeKeyInternal( $keyspace, $components ) {
59  // Memcached keys have a maximum length of 255 characters. From that,
60  // subtract the number of characters we need for the keyspace and for
61  // the separator character needed for each argument. To handle some
62  // custom prefixes used by thing like WANObjectCache, limit to 205.
63  $charsLeft = 205 - strlen( $keyspace ) - count( $components );
64 
65  foreach ( $components as &$component ) {
66  $component = strtr( $component, ' ', '_' );
67 
68  // Make sure %, #, and non-ASCII chars are escaped
69  $component = preg_replace_callback(
70  '/[^\x21-\x22\x24\x26-\x39\x3b-\x7e]+/',
71  static function ( $m ) {
72  return rawurlencode( $m[0] );
73  },
74  $component
75  );
76 
77  // 33 = 32 characters for the MD5 + 1 for the '#' prefix.
78  if ( $charsLeft > 33 && strlen( $component ) > $charsLeft ) {
79  $component = '#' . md5( $component );
80  }
81 
82  $charsLeft -= strlen( $component );
83  }
84 
85  if ( $charsLeft < 0 ) {
86  return $keyspace . ':BagOStuff-long-key:##' . md5( implode( ':', $components ) );
87  }
88 
89  return $keyspace . ':' . implode( ':', $components );
90  }
91 
100  public function validateKeyEncoding( $key ) {
101  if ( preg_match( '/[^\x21-\x7e]+/', $key ) ) {
102  throw new Exception( "Key contains invalid characters: $key" );
103  }
104 
105  return $key;
106  }
107 
112  protected function validateKeyAndPrependRoute( $key ) {
113  $this->validateKeyEncoding( $key );
114 
115  if ( $this->routingPrefix === '' ) {
116  return $key;
117  }
118 
119  if ( $key[0] === '/' ) {
120  throw new RuntimeException( "Key '$key' already contains a route." );
121  }
122 
123  return $this->routingPrefix . $key;
124  }
125 
130  protected function stripRouteFromKey( $key ) {
131  if ( $this->routingPrefix === '' ) {
132  return $key;
133  }
134 
135  $prefixLength = strlen( $this->routingPrefix );
136  if ( substr( $key, 0, $prefixLength ) === $this->routingPrefix ) {
137  return substr( $key, $prefixLength );
138  }
139 
140  return $key;
141  }
142 
147  protected function fixExpiry( $exptime ) {
148  if ( $exptime < 0 ) {
149  // The PECL driver does not seem to like negative relative values
150  $expiresAt = $this->getCurrentTime() + $exptime;
151  } elseif ( $this->isRelativeExpiration( $exptime ) ) {
152  // TTLs higher than 30 days will be detected as absolute TTLs
153  // (UNIX timestamps), and will result in the cache entry being
154  // discarded immediately because the expiry is in the past.
155  // Clamp expires >30d at 30d, unless they're >=1e9 in which
156  // case they are likely to really be absolute (1e9 = 2011-09-09)
157  $expiresAt = min( $exptime, self::TTL_MONTH );
158  } else {
159  $expiresAt = $exptime;
160  }
161 
162  return (int)$expiresAt;
163  }
164 }
MemcachedBagOStuff\$routingPrefix
string $routingPrefix
Routing prefix appended to keys during operations.
Definition: MemcachedBagOStuff.php:31
MemcachedBagOStuff
Base class for memcached clients.
Definition: MemcachedBagOStuff.php:29
MemcachedBagOStuff\stripRouteFromKey
stripRouteFromKey( $key)
Definition: MemcachedBagOStuff.php:130
MemcachedBagOStuff\fixExpiry
fixExpiry( $exptime)
Definition: MemcachedBagOStuff.php:147
MediumSpecificBagOStuff
Storage medium specific cache for storing items (e.g.
Definition: MediumSpecificBagOStuff.php:34
MemcachedBagOStuff\validateKeyAndPrependRoute
validateKeyAndPrependRoute( $key)
Definition: MemcachedBagOStuff.php:112
MediumSpecificBagOStuff\isRelativeExpiration
isRelativeExpiration( $exptime)
Definition: MediumSpecificBagOStuff.php:836
MemcachedBagOStuff\makeKeyInternal
makeKeyInternal( $keyspace, $components)
Construct a cache key.
Definition: MemcachedBagOStuff.php:58
BagOStuff\getCurrentTime
getCurrentTime()
Definition: BagOStuff.php:804
BagOStuff\$keyspace
string $keyspace
Default keyspace; used by makeKey()
Definition: BagOStuff.php:103
MemcachedBagOStuff\validateKeyEncoding
validateKeyEncoding( $key)
Ensure that a key is safe to use (contains no control characters and no characters above the ASCII ra...
Definition: MemcachedBagOStuff.php:100
MemcachedBagOStuff\__construct
__construct(array $params)
Definition: MemcachedBagOStuff.php:42