summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/Elastic/QueryEngine/TermsLookup/CachingTermsLookup.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/Elastic/QueryEngine/TermsLookup/CachingTermsLookup.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/Elastic/QueryEngine/TermsLookup/CachingTermsLookup.php393
1 files changed, 393 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/Elastic/QueryEngine/TermsLookup/CachingTermsLookup.php b/www/wiki/extensions/SemanticMediaWiki/src/Elastic/QueryEngine/TermsLookup/CachingTermsLookup.php
new file mode 100644
index 00000000..e43354e2
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/Elastic/QueryEngine/TermsLookup/CachingTermsLookup.php
@@ -0,0 +1,393 @@
+<?php
+
+namespace SMW\Elastic\QueryEngine\TermsLookup;
+
+use Onoi\Cache\Cache;
+use RuntimeException;
+use SMW\Elastic\QueryEngine\Condition;
+
+/**
+ * @license GNU GPL v2+
+ * @since 3.0
+ *
+ * @author mwjames
+ */
+class CachingTermsLookup extends TermsLookup {
+
+ /**
+ * Identifies the cache namespace
+ */
+ const CACHE_NAMESPACE = 'smw:elastic:lookup';
+
+ /**
+ * @var TermsLookup
+ */
+ private $termsLookup;
+
+ /**
+ * @var Cache
+ */
+ private $cache;
+
+ /**
+ * @var []
+ */
+ private $quick_cache = [];
+
+ /**
+ * @since 3.0
+ *
+ * @param TermsLookup $termsLookup
+ * @param Cache $cache
+ */
+ public function __construct( TermsLookup $termsLookup, Cache $cache ) {
+ $this->termsLookup = $termsLookup;
+ $this->cache = $cache;
+ }
+
+ /**
+ * @since 3.0
+ */
+ public function clear() {
+ $this->quick_cache = [];
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @return string
+ */
+ public static function makeCacheKey() {
+ return smwfCacheKey( self::CACHE_NAMESPACE, func_get_args() );
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param $type
+ * @param Parameters $parameters
+ *
+ * @return array
+ * @throws RuntimeException
+ */
+ public function lookup( $type, Parameters $parameters ) {
+
+ if ( $type === 'concept' ) {
+ return $this->concept_lookup( $parameters );
+ }
+
+ if ( $type === 'chain' ) {
+ return $this->chain_lookup( $parameters );
+ }
+
+ if ( $type === 'predef' ) {
+ return $this->predef_lookup( $parameters );
+ }
+
+ if ( $type === 'inverse' ) {
+ return $this->inverse_lookup( $parameters );
+ }
+
+ throw new RuntimeException( "$type is unknown!" );
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param Parameters $parameters
+ *
+ * @return array
+ */
+ public function concept_lookup( Parameters $parameters ) {
+
+ // @see Indexer::delete
+ $parameters->set( 'id', md5( $parameters->get( 'id' ) ) );
+ $id = $parameters->get( 'id' );
+ $parameters->set( 'count', 0 );
+
+ $threshold = $this->termsLookup->getOption(
+ 'concept.terms.lookup.result.size.index.write.threshold',
+ 100
+ );
+
+ $parameters->set( 'threshold', $threshold );
+
+ $key = $this->makeCacheKey(
+ $id,
+ $threshold,
+ $parameters->get( 'fingerprint' )
+ );
+
+ if ( isset( $this->quick_cache[$key] ) ) {
+ $parameters->set( 'query.info', $this->quick_cache[$key]['info'] );
+ return $this->quick_cache[$key]['params'];
+ }
+
+ if ( ( $count = $this->cache->fetch( $key ) ) !== false ) {
+
+ $info = [
+ 'cached_concept_lookup' => $parameters->get( 'query.string' ),
+ 'count' => $count,
+ 'isFromCache' => ['id' => $id ]
+ ];
+
+ $parameters->set( 'query.info', $info );
+
+ $params = $this->termsLookup->terms_filter(
+ '_id',
+ $this->termsLookup->path_filter( $id )
+ );
+
+ $this->quick_cache[$key] = [
+ 'params' => $params,
+ 'info' => $parameters->get( 'query.info' )
+ ];
+
+ return $params;
+ }
+
+ $ttl = $this->termsLookup->getOption(
+ 'concept.terms.lookup.cache.lifetime',
+ 60
+ );
+
+ $params = $this->termsLookup->concept_index_lookup(
+ $parameters
+ );
+
+ $count = $parameters->get( 'count' );
+
+ if ( $count >= $threshold ) {
+ $this->cache->save( $key, $count, $ttl );
+ }
+
+ $this->quick_cache[$key] = [
+ 'params' => $params,
+ 'info' => $parameters->get( 'query.info' )
+ ];
+
+ if ( isset( $params['type'] ) && isset( $params['id'] ) ) {
+ $params = $this->termsLookup->terms_filter(
+ '_id',
+ $this->termsLookup->path_filter( $params['id'] )
+ );
+ }
+
+ return $params;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param Parameters $parameters
+ *
+ * @return array
+ */
+ public function chain_lookup( Parameters $parameters ) {
+
+ $params = $parameters->get( 'params' );
+
+ if ( $params instanceof Condition ) {
+ $id = 'chain:' . md5( $params->__toString() );
+ } else {
+ $id = 'chain:' . md5( json_encode( $params ) );
+ }
+
+ $parameters->set( 'id', $id );
+ $parameters->set( 'count', 0 );
+
+ $threshold = $this->termsLookup->getOption(
+ 'subquery.terms.lookup.result.size.index.write.threshold',
+ 100
+ );
+
+ $parameters->set( 'threshold', $threshold );
+
+ $key = $this->makeCacheKey(
+ $id,
+ $threshold
+ );
+
+ if ( ( $count = $this->cache->fetch( $key ) ) !== false ) {
+
+ $info = [
+ 'cached_chain_lookup' => [
+ $parameters->get( 'property.key' ),
+ $parameters->get( 'query.string' )
+ ],
+ 'count' => $count,
+ 'isFromCache' => [ 'id' => $id ]
+ ];
+
+ $parameters->set( 'query.info', $info );
+
+ $params = $this->termsLookup->terms_filter(
+ $parameters->get( 'terms_filter.field' ),
+ $this->termsLookup->path_filter( $id )
+ );
+
+ return $params;
+ }
+
+ $ttl = $this->termsLookup->getOption(
+ 'subquery.terms.lookup.cache.lifetime',
+ 60
+ );
+
+ $params = $this->termsLookup->chain_index_lookup(
+ $parameters
+ );
+
+ $count = $parameters->get( 'count' );
+
+ if ( $count >= $threshold ) {
+ $this->cache->save( $key, $count, $ttl );
+ }
+
+ return $params;
+ }
+
+ /**
+ * `[[Has monolingual text:: <q>[[Text::two]] [[Language code::fr]]</q> ]] [[Has number::123]]`
+ *
+ * @since 3.0
+ *
+ * @param Parameters $parameters
+ *
+ * @return array
+ */
+ public function predef_lookup( Parameters $parameters ) {
+
+ $params = $parameters->get( 'params' );
+
+ if ( $params instanceof Condition ) {
+ $id = 'pre:' . md5( $params->__toString() );
+ } else {
+ $id = 'pre:' . md5( json_encode( $params ) );
+ }
+
+ $parameters->set( 'id', $id );
+ $parameters->set( 'count', 0 );
+
+ $threshold = $this->termsLookup->getOption(
+ 'subquery.terms.lookup.result.size.index.write.threshold',
+ 100
+ );
+
+ $parameters->set( 'threshold', $threshold );
+
+ $key = $this->makeCacheKey(
+ $id,
+ $threshold
+ );
+
+ if ( ( $count = $this->cache->fetch( $key ) ) !== false ) {
+
+ $info = [
+ 'cached_predefined_lookup' => $parameters->get( 'query.string' ),
+ 'count' => $count,
+ 'isFromCache' => [ 'id' => $id ]
+ ];
+
+ $parameters->set( 'query.info', $info );
+
+ $params = $this->termsLookup->terms_filter(
+ $parameters->get( 'field' ),
+ $this->termsLookup->path_filter( $id )
+ );
+
+ return $params;
+ }
+
+ $ttl = $this->termsLookup->getOption(
+ 'subquery.terms.lookup.cache.lifetime',
+ 60
+ );
+
+ $params = $this->termsLookup->predef_index_lookup(
+ $parameters
+ );
+
+ $count = $parameters->get( 'count' );
+
+ if ( $count >= $threshold ) {
+ $this->cache->save( $key, $count, $ttl );
+ }
+
+ return $params;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param Parameters $parameters
+ *
+ * @return array
+ */
+ public function inverse_lookup( Parameters $parameters ) {
+
+ $params = $parameters->get( 'params' );
+
+ if ( $params instanceof Condition ) {
+ $id = 'inv:' . md5( $parameters->get( 'field' ) . $params->__toString() );
+ } else {
+ $id = 'inv:' . md5( json_encode( [ $parameters->get( 'field' ), $params ] ) );
+ }
+
+ $parameters->set( 'id', $id );
+ $parameters->set( 'count', 0 );
+
+ $threshold = $this->termsLookup->getOption(
+ 'subquery.terms.lookup.result.size.index.write.threshold',
+ 100
+ );
+
+ $parameters->set( 'terms_filter.field', '_id' );
+ $parameters->set( 'threshold', $threshold );
+
+ $key = $this->makeCacheKey(
+ $id,
+ $threshold
+ );
+
+ if ( ( $count = $this->cache->fetch( $key ) ) !== false ) {
+
+ $info = [
+ 'cached_inverse_lookup' => [
+ $parameters->get( 'property.key' ),
+ $parameters->get( 'query.string' )
+ ],
+ 'count' => $count,
+ 'isFromCache' => [ 'id' => $id ]
+ ];
+
+ $parameters->set( 'query.info', $info );
+
+ // Return the _id field
+ $params = $this->termsLookup->terms_filter(
+ $parameters->get( 'terms_filter.field' ),
+ $this->termsLookup->path_filter( $id )
+ );
+
+ return $params;
+ }
+
+ $ttl = $this->termsLookup->getOption(
+ 'subquery.terms.lookup.cache.lifetime',
+ 60
+ );
+
+ $params = $this->termsLookup->inverse_index_lookup(
+ $parameters
+ );
+
+ $count = $parameters->get( 'count' );
+
+ if ( $count >= $threshold ) {
+ $this->cache->save( $key, $count, $ttl );
+ }
+
+ return $params;
+ }
+
+}