/**
  * Returns a list of entities a given site is subscribed to.
  *
  * This implementations combines the results of queries to both of the lookups
  * provided to the constructor.
  *
  * @param string $siteId Site ID of the client site.
  * @param EntityId[]|null $entityIds The entities we are interested in, or null for "any".
  *
  * @return EntityId[] a list of entity IDs the client wiki is subscribed to.
  *         The result is limited to entity ids also present in $entityIds, if given.
  */
 public function getSubscriptions($siteId, array $entityIds)
 {
     if (empty($entityIds)) {
         return array();
     }
     $primarySubscriptions = $this->reIndexEntityIds($this->primary->getSubscriptions($siteId, $entityIds));
     $entityIds = array_diff($this->reIndexEntityIds($entityIds), $primarySubscriptions);
     if (empty($entityIds)) {
         return $primarySubscriptions;
     }
     $secondarySubscriptions = $this->reIndexEntityIds($this->secondary->getSubscriptions($siteId, $entityIds));
     $subscriptions = array_merge($primarySubscriptions, $secondarySubscriptions);
     return $subscriptions;
 }
 /**
  * Filters a list of changes, removing changes not relevant to the given client wiki.
  *
  * Currently, we keep EntityChanges for entities the client wiki is subscribed to, or
  * that modify a sitelink to the client wiki.
  *
  * @param string $siteID The client wiki's global site identifier, as used by sitelinks.
  * @param Change[] $changes The list of changes to filter.
  * @param int $limit The max number of changes to return
  *
  * @return array( $batch, $seen ), where $batch is the filtered list of Change objects,
  *         and $seen if the ID of the last change considered for the batch
  *         (even if that was filtered out), for use as a continuation marker.
  */
 private function filterChanges($siteID, $changes, $limit)
 {
     // collect all item IDs mentioned in the changes
     $entitySet = array();
     foreach ($changes as $change) {
         if (!$change instanceof EntityChange) {
             continue;
         }
         $id = $change->getEntityId();
         $idString = $id->getSerialization();
         $entitySet[$idString] = $id;
     }
     $this->trace("Checking sitelinks to {$siteID} for " . count($entitySet) . " entities.");
     $subscribedEntities = $this->subscriptionLookup->getSubscriptions($siteID, $entitySet);
     $subscribedEntities = $this->reIndexEntityIds($subscribedEntities);
     $this->trace("Retaining changes for " . count($subscribedEntities) . " relevant entities.");
     // find all changes that relate to an item that has a sitelink to $siteID.
     $filteredChanges = array();
     $numberOfChangesFound = 0;
     $lastIdSeen = 0;
     foreach ($changes as $change) {
         if (!$change instanceof EntityChange) {
             continue;
         }
         $lastIdSeen = $change->getId();
         $idString = $change->getEntityId()->getSerialization();
         // The change is relevant if it alters any sitelinks referring to $siteID,
         // or the item currently links to $siteID.
         if (isset($subscribedEntities[$idString]) || $this->isRelevantChange($change, $siteID)) {
             $filteredChanges[] = $change;
             $numberOfChangesFound++;
         }
         if ($numberOfChangesFound >= $limit) {
             break;
         }
     }
     $this->trace("Found " . count($filteredChanges) . " changes for items with relevant sitelinks.");
     return array($filteredChanges, $lastIdSeen);
 }