/**
  * Accepts a result set as sent out to the CategoryViewer::doCategoryQuery
  * hook.
  *
  * @param ResultWrapper|array $rows
  */
 public function loadMetadataBatch($rows)
 {
     $neededPosts = array();
     $neededWorkflows = array();
     foreach ($rows as $row) {
         if ($row->page_namespace != NS_TOPIC) {
             continue;
         }
         $uuid = UUID::create(strtolower($row->page_title));
         if ($uuid) {
             $alpha = $uuid->getAlphadecimal();
             $neededPosts[$alpha] = array('rev_type_id' => $uuid);
             $neededWorkflows[$alpha] = $uuid;
         }
     }
     if (!$neededPosts) {
         return;
     }
     $this->posts = $this->storage->findMulti('PostRevision', $neededPosts, array('sort' => 'rev_id', 'order' => 'DESC', 'limit' => 1));
     $workflows = $this->storage->getMulti('Workflow', $neededWorkflows);
     // @todo fixme: these should have come back with the apropriate array
     // key since we passed it in above, but didn't.
     foreach ($workflows as $workflow) {
         $this->workflows[$workflow->getId()->getAlphadecimal()] = $workflow;
     }
 }
 /**
  * Overwriting default writer because I want to use Flow storage methods so
  * the updates also affect cache, not just DB.
  *
  * @param array[] $updates
  */
 public function write(array $updates)
 {
     /*
      * from:
      * array(
      *     'primaryKey' => array( 'workflow_id' => $id ),
      *     'updates' => array( 'workflow_last_update_timestamp' => $timestamp ),
      * )
      * to:
      * array( $id => $timestamp );
      */
     $timestamps = array_combine($this->arrayColumn($this->arrayColumn($updates, 'primaryKey'), 'workflow_id'), $this->arrayColumn($this->arrayColumn($updates, 'changes'), 'workflow_last_update_timestamp'));
     /** @var UUID[] $uuids */
     $uuids = array_map(array('Flow\\Model\\UUID', 'create'), array_keys($timestamps));
     /** @var Workflow[] $workflows */
     $workflows = $this->storage->getMulti('Workflow', $uuids);
     foreach ($workflows as $workflow) {
         $timestamp = $timestamps[$workflow->getId()->getBinary()];
         $workflow->updateLastModified(UUID::getComparisonUUID($timestamp));
     }
     $this->storage->multiPut($workflows);
     // prevent memory from filling up
     $this->storage->clear();
     wfWaitForSlaves(false, false, $this->clusterName);
 }
 /**
  * Entry point for batch loading metadata for a variety of revisions
  * into the internal cache.
  *
  * @param AbstractRevision[]|ResultWrapper $results
  */
 protected function loadMetadataBatch($results)
 {
     // Batch load data related to a list of revisions
     $postIds = array();
     $workflowIds = array();
     $revisions = array();
     $previousRevisionIds = array();
     $collectionIds = array();
     foreach ($results as $result) {
         if ($result instanceof PostRevision) {
             // If top-level, then just get the workflow.
             // Otherwise we need to find the root post.
             $id = $result->getPostId();
             $alpha = $id->getAlphadecimal();
             if ($result->isTopicTitle()) {
                 $workflowIds[] = $id;
             } else {
                 $postIds[$alpha] = $id;
             }
             $this->postCache[$alpha] = $result;
         } elseif ($result instanceof Header) {
             $workflowIds[] = $result->getWorkflowId();
         } elseif ($result instanceof PostSummary) {
             // This would be the post id for the summary
             $id = $result->getSummaryTargetId();
             $postIds[$id->getAlphadecimal()] = $id;
         }
         $revisions[$result->getRevisionId()->getAlphadecimal()] = $result;
         if ($this->needsPreviousRevision($result)) {
             $previousRevisionIds[get_class($result)][] = $result->getPrevRevisionId();
         }
         $collection = $result->getCollection();
         $collectionIds[get_class($result)][] = $collection->getId();
     }
     // map from post Id to the related root post id
     $rootPostIds = array_filter($this->treeRepository->findRoots($postIds));
     $rootPostRequests = array();
     foreach ($rootPostIds as $postId) {
         $rootPostRequests[] = array('rev_type_id' => $postId);
     }
     // these tree identity maps are required for determining where a reply goes when
     //
     // replying to a specific post.
     $identityMap = $this->treeRepository->fetchSubtreeIdentityMap(array_unique($rootPostIds, SORT_REGULAR));
     $rootPostResult = $this->storage->findMulti('PostRevision', $rootPostRequests, array('SORT' => 'rev_id', 'ORDER' => 'DESC', 'LIMIT' => 1));
     $rootPosts = array();
     if (count($rootPostResult) > 0) {
         foreach ($rootPostResult as $found) {
             $root = reset($found);
             $rootPosts[$root->getPostId()->getAlphadecimal()] = $root;
             $revisions[$root->getRevisionId()->getAlphadecimal()] = $root;
         }
     }
     // Workflow IDs are the same as root post IDs
     // So any post IDs that *are* root posts + found root post IDs + header workflow IDs
     // should cover the lot.
     $workflows = $this->storage->getMulti('Workflow', array_merge($rootPostIds, $workflowIds));
     $workflows = $workflows ?: array();
     // preload all requested previous revisions
     foreach ($previousRevisionIds as $revisionType => $ids) {
         // get rid of null-values (for original revisions, without previous revision)
         $ids = array_filter($ids);
         /** @var AbstractRevision[] $found */
         $found = $this->storage->getMulti($revisionType, $ids);
         foreach ($found as $rev) {
             $revisions[$rev->getRevisionId()->getAlphadecimal()] = $rev;
         }
     }
     // preload all current versions
     foreach ($collectionIds as $revisionType => $ids) {
         $queries = array();
         foreach ($ids as $uuid) {
             $queries[] = array('rev_type_id' => $uuid);
         }
         $found = $this->storage->findMulti($revisionType, $queries, array('sort' => 'rev_id', 'order' => 'DESC', 'limit' => 1));
         /** @var AbstractRevision[] $result */
         foreach ($found as $result) {
             $rev = reset($result);
             $this->currentRevisionsCache[$rev->getCollectionId()->getAlphadecimal()] = $rev->getRevisionId();
             $revisions[$rev->getRevisionId()->getAlphadecimal()] = $rev;
         }
     }
     $this->revisionCache = array_merge($this->revisionCache, $revisions);
     $this->postCache = array_merge($this->postCache, $rootPosts);
     $this->rootPostIdCache = array_merge($this->rootPostIdCache, $rootPostIds);
     $this->workflowCache = array_merge($this->workflowCache, $workflows);
     $this->identityMap = array_merge($this->identityMap, $identityMap);
 }