/**
  * All queries must be against the same index. Results are equivalent to
  * array_map, maintaining order and key relationship between input $queries
  * and $result.
  *
  * @param array $queries
  * @param array $options
  * @return array|null  null is query failure.  empty array is no result.  array is success
  */
 public function findMulti(array $queries, array $options = array())
 {
     if (!$queries) {
         return array();
     }
     $keys = array_keys(reset($queries));
     if (isset($options['sort']) && !is_array($options['sort'])) {
         $options['sort'] = ObjectManager::makeArray($options['sort']);
     }
     try {
         $index = $this->getIndexFor($keys, $options);
         $res = $index->findMulti($queries, $options);
     } catch (NoIndexException $e) {
         if (array_search('topic_root_id', $keys)) {
             wfDebugLog('Flow', __METHOD__ . ': ' . json_encode($keys) . ' : ' . json_encode($options) . ' : ' . json_encode(array_map('get_class', $this->indexes)));
             \MWExceptionHandler::logException($e);
         } else {
             wfDebugLog('FlowDebug', __METHOD__ . ': ' . $e->getMessage());
         }
         $res = $this->storage->findMulti($queries, $this->convertToDbOptions($options));
     }
     if ($res === null) {
         return null;
     }
     $output = array();
     foreach ($res as $index => $queryOutput) {
         foreach ($queryOutput as $k => $v) {
             if ($v) {
                 $output[$index][$k] = $this->load($v);
             }
         }
     }
     return $output;
 }
 /**
  * Query persistent storage for data not found in cache.  Note that this
  * does not use the query options because an individual bucket contents is
  * based on constructor options, and not query options.  Query options merely
  * change what part of the bucket is returned(or if the query has to fail over
  * to direct from storage due to being beyond the set of cached values).
  *
  * @param array $queries
  * @return array
  */
 protected function backingStoreFindMulti(array $queries)
 {
     // query backing store
     $options = $this->queryOptions();
     $stored = $this->storage->findMulti($queries, $options);
     $results = array();
     // map store results to cache key
     foreach ($stored as $idx => $rows) {
         if (!$rows) {
             // Nothing found,  should we cache failures as well as success?
             continue;
         }
         $results[$idx] = $rows;
         unset($queries[$idx]);
     }
     if (count($queries) !== 0) {
         // Log something about not finding everything?
     }
     return $results;
 }
 public function findDescendants(array $queries, array $options = array())
 {
     $data = $this->postRevisionStorage->findMulti($queries, $options);
     $summary = $this->postSummaryStorage->findMulti($queries, $options);
     if ($summary) {
         if ($data) {
             foreach ($summary as $key => $rows) {
                 if (isset($data[$key])) {
                     $data[$key] += $rows;
                     // Failing to sort is okay, we'd rather display unordered
                     // result than showing an error page with exception
                     krsort($data[$key]);
                 } else {
                     $data[$key] = $rows;
                 }
             }
         } else {
             $data = $summary;
         }
     }
     return $data;
 }