diff options
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/CachedPropertyValuesPrefetcher.php')
-rw-r--r-- | www/wiki/extensions/SemanticMediaWiki/src/CachedPropertyValuesPrefetcher.php | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/CachedPropertyValuesPrefetcher.php b/www/wiki/extensions/SemanticMediaWiki/src/CachedPropertyValuesPrefetcher.php new file mode 100644 index 00000000..873a887f --- /dev/null +++ b/www/wiki/extensions/SemanticMediaWiki/src/CachedPropertyValuesPrefetcher.php @@ -0,0 +1,177 @@ +<?php + +namespace SMW; + +use Onoi\BlobStore\BlobStore; +use SMWQuery as Query; + +/** + * This class should be accessed via ApplicationFactory::getCachedPropertyValuesPrefetcher + * to ensure a singleton instance. + * + * The purpose of this class is to give fragmented access to frequent (hence + * cacheable) property values to ensure that the store is only used for when a + * match can not be found and so freeing up the capacities that can equally be + * served from a persistent cache instance. + * + * It is expected that as soon as the "on.before.semanticdata.update.complete" + * event has been emitted that matchable cache entries are purged for the + * subject in question. + * + * @license GNU GPL v2+ + * @since 2.4 + * + * @author mwjames + */ +class CachedPropertyValuesPrefetcher { + + /** + * @var string + */ + const VERSION = '0.4.1'; + + /** + * Namespace occupied by the BlobStore + */ + const CACHE_NAMESPACE = 'smw:pvp:store'; + + /** + * @var Store + */ + private $store; + + /** + * @var BlobStore + */ + private $blobStore; + + /** + * @var boolean + */ + private $disableCache = false; + + /** + * @since 2.4 + * + * @param Store $store + * @param BlobStore $blobStore + */ + public function __construct( Store $store, BlobStore $blobStore ) { + $this->store = $store; + $this->blobStore = $blobStore; + } + + /** + * @since 2.4 + */ + public function resetCacheBy( DIWikiPage $subject ) { + $this->blobStore->delete( $this->getRootHashFrom( $subject ) ); + } + + /** + * @since 3.0 + * + * @param boolean $disableCache + */ + public function disableCache( $disableCache ) { + $this->disableCache = (bool)$disableCache; + } + + /** + * @since 2.4 + * + * @param DIWikiPage $subject + * @param DIProperty $property + * @param RequestOptions|null $requestOptions + * + * @return array + */ + public function getPropertyValues( DIWikiPage $subject, DIProperty $property, RequestOptions $requestOptions = null ) { + + // Items are collected as part of the subject hash so that any request is + // stored with that entity identifier allowing it to be evicted entirely + // when the subject is changed. + // + // The key on the other hand represent an individual request identifier + // that is stored as part of the overall cache item but making distinct + // requests possible, yet is fetched as part of the overall subject to + // minimize cache fragmentation and a better eviction strategy. + $key = $property->getKey() . + ':' . $subject->getSubobjectName() . + ':' . ( $requestOptions !== null ? md5( $requestOptions->getHash() ) : null ); + + $container = $this->blobStore->read( + $this->getRootHashFrom( $subject ) + ); + + if ( $this->disableCache === false && $container->has( $key ) ) { + return $container->get( $key ); + } + + $dataItems = $this->store->getPropertyValues( + $subject, + $property, + $requestOptions + ); + + $container->set( $key, $dataItems ); + + $this->blobStore->save( + $container + ); + + return $dataItems; + } + + /** + * @since 2.4 + * + * @param Query $query + * + * @return array + */ + public function queryPropertyValuesFor( Query $query ) { + return $this->store->getQueryResult( $query )->getResults(); + } + + /** + * @since 2.4 + * + * @return BlobStore + */ + public function getBlobStore() { + return $this->blobStore; + } + + /** + * @since 2.4 + * + * @return Store + */ + public function getStore() { + return $this->store; + } + + /** + * @since 2.4 + * + * @param DIWikiPage $subject + * + * @return string + */ + public function getRootHashFrom( DIWikiPage $subject ) { + return md5( $subject->asBase()->getHash() . self::VERSION ); + } + + /** + * @since 2.4 + * + * @param string $hash + * + * @return string + */ + public function createHashFromString( $hash ) { + return md5( $hash . self::VERSION ); + } + +} |