Changeset View
Changeset View
Standalone View
Standalone View
src/applications/people/query/PhabricatorPeopleQuery.php
| Show All 17 Lines | final class PhabricatorPeopleQuery | ||||
| private $nameLike; | private $nameLike; | ||||
| private $nameTokens; | private $nameTokens; | ||||
| private $needPrimaryEmail; | private $needPrimaryEmail; | ||||
| private $needProfile; | private $needProfile; | ||||
| private $needProfileImage; | private $needProfileImage; | ||||
| private $needAvailability; | private $needAvailability; | ||||
| private $needBadges; | private $needBadges; | ||||
| private $cacheKeys = array(); | |||||
| public function withIDs(array $ids) { | public function withIDs(array $ids) { | ||||
| $this->ids = $ids; | $this->ids = $ids; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function withPHIDs(array $phids) { | public function withPHIDs(array $phids) { | ||||
| $this->phids = $phids; | $this->phids = $phids; | ||||
| ▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | public function needAvailability($need) { | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function needBadges($need) { | public function needBadges($need) { | ||||
| $this->needBadges = $need; | $this->needBadges = $need; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| public function needUserSettings($need) { | |||||
| $cache_key = PhabricatorUserPreferencesCacheType::KEY_PREFERENCES; | |||||
| if ($need) { | |||||
| $this->cacheKeys[$cache_key] = true; | |||||
| } else { | |||||
| unset($this->cacheKeys[$cache_key]); | |||||
| } | |||||
| return $this; | |||||
| } | |||||
| public function newResultObject() { | public function newResultObject() { | ||||
| return new PhabricatorUser(); | return new PhabricatorUser(); | ||||
| } | } | ||||
| protected function loadPage() { | protected function loadPage() { | ||||
| $table = new PhabricatorUser(); | $table = new PhabricatorUser(); | ||||
| $data = $this->loadStandardPageRows($table); | $data = $this->loadStandardPageRows($table); | ||||
| ▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | if ($this->needAvailability) { | ||||
| } | } | ||||
| } | } | ||||
| if ($rebuild) { | if ($rebuild) { | ||||
| $this->rebuildAvailabilityCache($rebuild); | $this->rebuildAvailabilityCache($rebuild); | ||||
| } | } | ||||
| } | } | ||||
| $this->fillUserCaches($users); | |||||
| return $users; | return $users; | ||||
| } | } | ||||
| protected function shouldGroupQueryResultRows() { | protected function shouldGroupQueryResultRows() { | ||||
| if ($this->nameTokens) { | if ($this->nameTokens) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 227 Lines • ▼ Show 20 Lines | foreach ($rebuild as $phid => $user) { | ||||
| // Never TTL the cache to longer than the maximum range we examined. | // Never TTL the cache to longer than the maximum range we examined. | ||||
| $availability_ttl = min($availability_ttl, $max_range); | $availability_ttl = min($availability_ttl, $max_range); | ||||
| $user->writeAvailabilityCache($availability, $availability_ttl); | $user->writeAvailabilityCache($availability, $availability_ttl); | ||||
| $user->attachAvailability($availability); | $user->attachAvailability($availability); | ||||
| } | } | ||||
| } | } | ||||
| private function fillUserCaches(array $users) { | |||||
| if (!$this->cacheKeys) { | |||||
| return; | |||||
| } | |||||
| $user_map = mpull($users, null, 'getPHID'); | |||||
| $keys = array_keys($this->cacheKeys); | |||||
| $hashes = array(); | |||||
| foreach ($keys as $key) { | |||||
| $hashes[] = PhabricatorHash::digestForIndex($key); | |||||
| } | |||||
| // First, pull any available caches. If we wanted to be particularly clever | |||||
| // we could do this with JOINs in the main query. | |||||
| $cache_table = new PhabricatorUserCache(); | |||||
| $cache_conn = $cache_table->establishConnection('r'); | |||||
| $cache_data = queryfx_all( | |||||
| $cache_conn, | |||||
| 'SELECT cacheKey, userPHID, cacheData FROM %T | |||||
| WHERE cacheIndex IN (%Ls) AND userPHID IN (%Ls)', | |||||
| $cache_table->getTableName(), | |||||
| $hashes, | |||||
| array_keys($user_map)); | |||||
| $need = array(); | |||||
| $cache_data = igroup($cache_data, 'userPHID'); | |||||
| foreach ($user_map as $user_phid => $user) { | |||||
| $raw_rows = idx($cache_data, $user_phid, array()); | |||||
| if (!$raw_rows) { | |||||
| continue; | |||||
| } | |||||
| $raw_data = ipull($raw_rows, 'cacheData', 'cacheKey'); | |||||
| foreach ($keys as $key) { | |||||
| if (isset($raw_data[$key]) || array_key_exists($key, $raw_data)) { | |||||
| continue; | |||||
| } | |||||
| $need[$key][$user_phid] = $user; | |||||
| } | |||||
| $user->attachRawCacheData($raw_data); | |||||
| } | |||||
| // If we missed any cache values, bulk-construct them now. This is | |||||
| // usually much cheaper than generating them on-demand for each user | |||||
| // record. | |||||
| if (!$need) { | |||||
| return; | |||||
| } | |||||
| $writes = array(); | |||||
| foreach ($need as $cache_key => $need_users) { | |||||
| $type = PhabricatorUserCacheType::getCacheTypeForKey($cache_key); | |||||
| if (!$type) { | |||||
| continue; | |||||
| } | |||||
| $data = $type->newValueForUsers($cache_key, $need_users); | |||||
| foreach ($data as $user_phid => $value) { | |||||
| $raw_value = $type->getValueForStorage($value); | |||||
| $data[$user_phid] = $raw_value; | |||||
| $writes[] = array( | |||||
| 'userPHID' => $user_phid, | |||||
| 'key' => $cache_key, | |||||
| 'type' => $type, | |||||
| 'value' => $raw_value, | |||||
| ); | |||||
| } | |||||
| foreach ($need_users as $user_phid => $user) { | |||||
| if (isset($data[$user_phid]) || array_key_exists($user_phid, $data)) { | |||||
| $user->attachRawCacheData( | |||||
| array( | |||||
| $cache_key => $data[$user_phid], | |||||
| )); | |||||
| } | |||||
| } | |||||
| } | |||||
| PhabricatorUserCache::writeCaches($writes); | |||||
| } | |||||
| } | } | ||||