| Current File : /home/jvzmxxx/wiki1/extensions/Flow/includes/Repository/MultiGetList.php |
<?php
namespace Flow\Repository;
use Flow\Data\BufferedCache;
use Flow\Model\UUID;
use Flow\Exception\InvalidParameterException;
class MultiGetList {
/**
* @var BufferedCache
*/
protected $cache;
/**
* @param BufferedCache $cache
*/
public function __construct( BufferedCache $cache ) {
$this->cache = $cache;
}
/**
* @param string $treeType
* @param array $ids
* @param callable $loadCallback
* @return array
* @throws InvalidParameterException
*/
public function get( $treeType, array $ids, $loadCallback ) {
$cacheKeys = array();
foreach ( $ids as $id ) {
if ( $id instanceof UUID ) {
$cacheId = $id;
} elseif ( is_scalar( $id ) ) {
$cacheId = UUID::create( $id );
} else {
$type = is_object( $id ) ? get_class( $id ) : gettype( $id );
throw new InvalidParameterException( 'Not scalar:' . $type, 'invalid-input' );
}
$cacheKeys[ TreeCacheKey::build( $treeType, $cacheId ) ] = $id;
}
return $this->getByKey( $cacheKeys, $loadCallback );
}
/**
* @param array $cacheKeys
* @param callable $loadCallback
* @return array
*/
public function getByKey( array $cacheKeys, $loadCallback ) {
if ( !$cacheKeys ) {
return array();
}
$result = array();
$multiRes = $this->cache->getMulti( array_keys( $cacheKeys ) );
if ( $multiRes === false ) {
// Falls through to query only backend
wfDebugLog( 'Flow', __METHOD__ . ': Failure querying memcache' );
} else {
// Memcached BagOStuff only returns found keys, but the redis bag
// returns false for not found keys.
$multiRes = array_filter(
$multiRes,
function( $val ) { return $val !== false; }
);
foreach ( $multiRes as $key => $value ) {
$idx = $cacheKeys[$key];
if ( $idx instanceof UUID ) {
$idx = $idx->getAlphadecimal();
}
$result[$idx] = $value;
unset( $cacheKeys[$key] );
}
}
if ( count( $cacheKeys ) === 0 ) {
return $result;
}
$res = call_user_func( $loadCallback, array_values( $cacheKeys ) );
if ( !$res ) {
// storage failure of some sort
return $result;
}
$invCacheKeys = array();
foreach ( $cacheKeys as $cacheKey => $id ) {
if ( $id instanceof UUID ) {
$id = $id->getAlphadecimal();
}
$invCacheKeys[$id] = $cacheKey;
}
foreach ( $res as $id => $row ) {
// If we failed contacting memcache a moment ago don't bother trying to
// push values either.
if ( $multiRes !== false ) {
$this->cache->set( $invCacheKeys[$id], $row );
}
$result[$id] = $row;
}
return $result;
}
}