* @ingroup Cache
*/
class APCBagOStuff extends BagOStuff {
-
/**
* @var string String to append to each APC key. This may be changed
* whenever the handling of values is changed, to prevent existing code
**/
const KEY_SUFFIX = ':1';
- public function get( $key, &$casToken = null ) {
+ public function get( $key, &$casToken = null, $flags = 0 ) {
$val = apc_fetch( $key . self::KEY_SUFFIX );
$casToken = $val;
const ERR_UNREACHABLE = 2; // can't connect
const ERR_UNEXPECTED = 3; // response gave some error
+ /** Bitfield constants for get()/getMulti() */
+ const READ_LATEST = 1; // use latest data for replicated stores
+
public function __construct( array $params = array() ) {
if ( isset( $params['logger'] ) ) {
$this->setLogger( $params['logger'] );
* Get an item with the given key. Returns false if it does not exist.
* @param string $key
* @param mixed $casToken [optional]
+ * @param integer $flags Bitfield; supports READ_LATEST [optional]
* @return mixed Returns false on failure
*/
- abstract public function get( $key, &$casToken = null );
+ abstract public function get( $key, &$casToken = null, $flags = 0 );
/**
* Set an item.
return false;
}
- /* *** Emulated functions *** */
-
/**
* Get an associative array containing the item for each of the keys that have items.
* @param array $keys List of strings
+ * @param integer $flags Bitfield; supports READ_LATEST [optional]
* @return array
*/
- public function getMulti( array $keys ) {
+ public function getMulti( array $keys, $flags = 0 ) {
$res = array();
foreach ( $keys as $key ) {
$val = $this->get( $key );
* @ingroup Cache
*/
class EmptyBagOStuff extends BagOStuff {
- public function get( $key, &$casToken = null ) {
+ public function get( $key, &$casToken = null, $flags = 0 ) {
return false;
}
return true;
}
- public function get( $key, &$casToken = null ) {
+ public function get( $key, &$casToken = null, $flags = 0 ) {
if ( !isset( $this->bag[$key] ) ) {
return false;
}
$this->readStore->setDebug( $debug );
}
- public function get( $key, &$casToken = null ) {
- return $this->readStore->get( $key, $casToken );
+ public function get( $key, &$casToken = null, $flags = 0 ) {
+ return ( $flags & self::READ_LATEST )
+ ? $this->writeStore->get( $key, $casToken, $flags )
+ : $this->readStore->get( $key, $casToken, $flags );
}
- public function getMulti( array $keys ) {
- return $this->readStore->getMulti( $keys );
+ public function getMulti( array $keys, $flags = 0 ) {
+ return ( $flags & self::READ_LATEST )
+ ? $this->writeStore->getMulti( $keys, $flags )
+ : $this->readStore->getMulti( $keys, $flags );
}
public function set( $key, $value, $exptime = 0 ) {
* @ingroup Cache
*/
class WinCacheBagOStuff extends BagOStuff {
-
- /**
- * Get a value from the WinCache object cache
- *
- * @param string $key Cache key
- * @param int $casToken [optional] Cas token
- * @return mixed
- */
- public function get( $key, &$casToken = null ) {
+ public function get( $key, &$casToken = null, $flags = 0 ) {
$val = wincache_ucache_get( $key );
$casToken = $val;
return $val;
}
- /**
- * Store a value in the WinCache object cache
- *
- * @param string $key Cache key
- * @param mixed $value Value to store
- * @param int $expire Expiration time
- * @return bool
- */
public function set( $key, $value, $expire = 0 ) {
$result = wincache_ucache_set( $key, serialize( $value ), $expire );
return ( is_array( $result ) && $result === array() ) || $result;
}
- /**
- * Store a value in the WinCache object cache, race condition-safe
- *
- * @param int $casToken Cas token
- * @param string $key Cache key
- * @param int $value Object to store
- * @param int $exptime Expiration time
- * @return bool
- */
protected function cas( $casToken, $key, $value, $exptime = 0 ) {
return wincache_ucache_cas( $key, $casToken, serialize( $value ) );
}
- /**
- * Remove a value from the WinCache object cache
- *
- * @param string $key Cache key
- * @return bool
- */
public function delete( $key ) {
wincache_ucache_delete( $key );
* @ingroup Cache
*/
class XCacheBagOStuff extends BagOStuff {
- /**
- * Get a value from the XCache object cache
- *
- * @param string $key Cache key
- * @param mixed $casToken Cas token
- * @return mixed
- */
- public function get( $key, &$casToken = null ) {
+ public function get( $key, &$casToken = null, $flags = 0 ) {
$val = xcache_get( $key );
if ( is_string( $val ) ) {
return $val;
}
- /**
- * Store a value in the XCache object cache
- *
- * @param string $key Cache key
- * @param mixed $value Object to store
- * @param int $expire Expiration time
- * @return bool
- */
public function set( $key, $value, $expire = 0 ) {
if ( !$this->isInteger( $value ) ) {
$value = serialize( $value );
return true;
}
- /**
- * Remove a value from the XCache object cache
- *
- * @param string $key Cache key
- * @return bool
- */
public function delete( $key ) {
xcache_unset( $key );
return true;
return $params;
}
- /**
- * @param string $key
- * @param mixed $casToken [optional]
- * @return mixed
- */
- public function get( $key, &$casToken = null ) {
+ public function get( $key, &$casToken = null, $flags = 0 ) {
return $this->client->get( $this->encodeKey( $key ), $casToken );
}
$this->client->addServers( $servers );
}
- /**
- * @param string $key
- * @param float $casToken [optional]
- * @return mixed
- */
- public function get( $key, &$casToken = null ) {
+ public function get( $key, &$casToken = null, $flags = 0 ) {
$this->debugLog( "get($key)" );
$result = $this->client->get( $this->encodeKey( $key ), null, $casToken );
$result = $this->checkResult( $key, $result );
return $result;
}
- /**
- * @param array $keys
- * @return array
- */
- public function getMulti( array $keys ) {
+ public function getMulti( array $keys, $flags = 0 ) {
$this->debugLog( 'getMulti(' . implode( ', ', $keys ) . ')' );
$callback = array( $this, 'encodeKey' );
$result = $this->client->getMulti( array_map( $callback, $keys ) );
$this->client->set_debug( $debug );
}
- /**
- * @param array $keys
- * @return array
- */
- public function getMulti( array $keys ) {
+ public function getMulti( array $keys, $flags = 0 ) {
$callback = array( $this, 'encodeKey' );
return $this->client->get_multi( array_map( $callback, $keys ) );
}
$this->doWrite( 'setDebug', $debug );
}
- /**
- * @param string $key
- * @param mixed $casToken [optional]
- * @return bool|mixed
- */
- public function get( $key, &$casToken = null ) {
+ public function get( $key, &$casToken = null, $flags = 0 ) {
foreach ( $this->caches as $cache ) {
- $value = $cache->get( $key );
+ $value = $cache->get( $key, null, $flags = 0 );
if ( $value !== false ) {
return $value;
}
* The word "cache" has two main dictionary meanings, and both
* are used in this factory class. They are:
* - a) A place to store copies or computations on existing data
- * for higher access speeds (the computer science definition)
+ * for higher access speeds (the computer science definition)
* - b) A place to store lightweight data that is not canonically
- * stored anywhere else (e.g. a "hoard" of objects)
+ * stored anywhere else (e.g. a "hoard" of objects)
+ *
+ * The former should always use strongly consistent stores, so callers don't
+ * have to deal with stale reads. The later may be eventually consistent, but
+ * callers can use BagOStuff:READ_LATEST to see the latest available data.
*
* @ingroup Cache
*/
* In general, this means avoiding updates on idempotent HTTP requests and
* avoiding an assumption of perfect serializability (or accepting anomalies).
* Reads may be eventually consistent or data might rollback as nodes flap.
+ * Callers can use BagOStuff:READ_LATEST to see the latest available data.
*
- * @since 1.26
* @return BagOStuff
+ * @since 1.26
*/
static function getMainStashInstance() {
global $wgMainStash;
}
}
- public function get( $key, &$casToken = null ) {
+ public function get( $key, &$casToken = null, $flags = 0 ) {
list( $server, $conn ) = $this->getConnection( $key );
if ( !$conn ) {
return $result;
}
- public function getMulti( array $keys ) {
+ public function getMulti( array $keys, $flags = 0 ) {
$batches = array();
$conns = array();
}
}
- /**
- * @param string $key
- * @param mixed $casToken [optional]
- * @return mixed
- */
- public function get( $key, &$casToken = null ) {
+ public function get( $key, &$casToken = null, $flags = 0 ) {
$values = $this->getMulti( array( $key ) );
if ( array_key_exists( $key, $values ) ) {
$casToken = $values[$key];
return false;
}
- /**
- * @param array $keys
- * @return array
- */
- public function getMulti( array $keys ) {
+ public function getMulti( array $keys, $flags = 0 ) {
$values = array(); // array of (key => value)
$keysByTable = array();