From 9d19a0a8b19e3883109a69b534f136934ba8c719 Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 1 Aug 2012 14:57:07 -0700 Subject: [PATCH] Limit results returned by typeahead query in response to user searches Summary: Currently, on secure.phabricator.com, if you type "e" we generate about 600 users and ship them over the wire. This takes ~300ms. Instead, limit the results to a superset of what the client will actually show. Test Plan: Ran user typeahead queries, tweaked limit to 1. Reviewers: vrana, btrahan Reviewed By: vrana CC: aran Differential Revision: https://secure.phabricator.com/D3121 --- ...torTypeaheadCommonDatasourceController.php | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php b/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php index 6532cedc1e..bfcae45282 100644 --- a/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php +++ b/src/applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php @@ -114,13 +114,48 @@ final class PhabricatorTypeaheadCommonDatasourceController 'phid'); if ($query) { - $conn_r = id(new PhabricatorUser())->establishConnection('r'); + // This is an arbitrary limit which is just larger than any limit we + // actually use in the application. + + // TODO: The datasource should pass this in the query. + $limit = 15; + + $user_table = new PhabricatorUser(); + $conn_r = $user_table->establishConnection('r'); $ids = queryfx_all( $conn_r, - 'SELECT DISTINCT userID FROM %T WHERE token LIKE %>', - PhabricatorUser::NAMETOKEN_TABLE, - $query); - $ids = ipull($ids, 'userID'); + 'SELECT id FROM %T WHERE username LIKE %> + ORDER BY username ASC LIMIT %d', + $user_table->getTableName(), + $query, + $limit); + $ids = ipull($ids, 'id'); + + if (count($ids) < $limit) { + // If we didn't find enough username hits, look for real name hits. + // We need to pull the entire pagesize so that we end up with the + // right number of items if this query returns many duplicate IDs + // that we've already selected. + + $realname_ids = queryfx_all( + $conn_r, + 'SELECT DISTINCT userID FROM %T WHERE token LIKE %> + ORDER BY token ASC LIMIT %d', + PhabricatorUser::NAMETOKEN_TABLE, + $query, + $limit); + $realname_ids = ipull($realname_ids, 'userID'); + $ids = array_merge($ids, $realname_ids); + + $ids = array_unique($ids); + $ids = array_slice($ids, 0, $limit); + } + + // Always add the logged-in user because some tokenizers autosort them + // first. They'll be filtered out on the client side if they don't + // match the query. + $ids[] = $request->getUser()->getID(); + if ($ids) { $users = id(new PhabricatorUser())->loadColumnsWhere( $columns,