private function tryFindMatchResultFor($hash, $dataValue)
 {
     $descriptionFactory = $this->queryFactory->newDescriptionFactory();
     $contextPage = $dataValue->getContextPage();
     // Exclude the current page from the result match to check whether another
     // page matches the condition and if so then the value can no longer be
     // assigned and is not unique
     $description = $descriptionFactory->newConjunction(array($descriptionFactory->newFromDataValue($dataValue), $descriptionFactory->newValueDescription($contextPage, null, SMW_CMP_NEQ)));
     $query = $this->queryFactory->newQuery($description);
     $query->setLimit(1);
     $dataItems = $this->cachedPropertyValuesPrefetcher->queryPropertyValuesFor($query);
     if (!is_array($dataItems) || $dataItems === array()) {
         // No other assignments were found therefore it is assumed that at
         // the time of the query request, the "contextPage" holds a unique
         // value for the property
         $page = $contextPage;
     } else {
         $page = end($dataItems);
     }
     // Create a linked list so that when the subject is altered or deleted
     // the related uniqueness container can be removed as well
     $blobStore = $this->cachedPropertyValuesPrefetcher->getBlobStore();
     $container = $blobStore->read($this->cachedPropertyValuesPrefetcher->getRootHashFrom($page));
     $container->addToLinkedList($hash);
     $blobStore->save($container);
     return $page;
 }
 /**
  * @since 2.4
  *
  * @param DIProperty|null $property
  */
 public function fetchCachedConversionData(DIProperty $property = null)
 {
     if ($property === null || ($propertyDiWikiPage = $property->getDiWikiPage()) === null) {
         return;
     }
     $blobStore = $this->cachedPropertyValuesPrefetcher->getBlobStore();
     // Ensure that when the property page is altered the cache gets
     // evicted
     $hash = $this->cachedPropertyValuesPrefetcher->getRootHashFrom($propertyDiWikiPage);
     $container = $blobStore->read($hash);
     $key = '--conv';
     if ($container->has($key)) {
         $data = $container->get($key);
         $this->unitIds = $data['ids'];
         $this->unitFactors = $data['factors'];
         $this->mainUnit = $data['main'];
         $this->prefixalUnitPreference = $data['prefix'];
         return;
     }
     $this->fetchConversionData($property);
     if ($this->errors !== array()) {
         return;
     }
     $data = array('ids' => $this->unitIds, 'factors' => $this->unitFactors, 'main' => $this->mainUnit, 'prefix' => $this->prefixalUnitPreference);
     $container->set($key, $data);
     $blobStore->save($container);
 }
 /**
  * We try to cache anything to avoid unnecessary store connections or DB
  * lookups. For cases where a property was changed, the EventDipatcher will
  * receive a 'property.specification.change' event (emitted as soon as the content of
  * a property page was altered) with PropertySpecificationLookup::resetCacheBy
  * being invoked to remove the cache entry for that specific property.
  *
  * @since 2.4
  *
  * @param DIProperty $property
  * @param mixed|null $linker
  * @param string $languageCode
  *
  * @return string
  */
 public function getPropertyDescriptionBy(DIProperty $property, $linker = null, $languageCode = '')
 {
     // Take the linker into account (Special vs. in page rendering etc.)
     $languageCode = $languageCode === '' ? $this->languageCode : $languageCode;
     $key = '--pdesc:' . $languageCode . ':' . ($linker === null ? '0' : '1');
     $blobStore = $this->cachedPropertyValuesPrefetcher->getBlobStore();
     $container = $blobStore->read($this->cachedPropertyValuesPrefetcher->getRootHashFrom($property->getCanonicalDiWikiPage()));
     if ($container->has($key)) {
         return $container->get($key);
     }
     $localPropertyDescription = $this->tryToFindLocalPropertyDescription($property, $linker, $languageCode);
     // If a local property description wasn't available for a predefined property
     // the try to find a system translation
     if (trim($localPropertyDescription) === '' && !$property->isUserDefined()) {
         $localPropertyDescription = $this->getPredefinedPropertyDescription($property, $linker, $languageCode);
     }
     $container->set($key, $localPropertyDescription);
     $blobStore->save($container);
     return $localPropertyDescription;
 }