Full text search in memory for review suggestions
This change also makes it possible to configure maximum displayed reviewers. On some Gerrit instances the full name is formatted like: <given name> <surname> and email like: <given name>.<surname>@... This would make it impossible to get reviewer suggestions from surnames. Since gwtorm doesn't support sql LIKE there is no straight forward way of filtering on substring in the DB. Hence this in memory approach. For performance reasons this implementation differs from the default implementation in that it does not look at the email_address in account_external_ids but only at the preferred_email of accounts. The default implementation does only look for 10 matches and afterwards filters out the acconts that are not allowed to view the change. Configuration: suggest.maxSuggestedReviewers Maximum number of suggested reviewers (default 10). suggest.fullTextSearch Enable full text search (default "false"). suggest.fullTextSearchMaxMatches Maximum number of matches to be checked for accessability when using full text search (default 100). Change-Id: Ia4c3a15263783bc144e66a05854c3915392095b5
This commit is contained in:
committed by
Edwin Kempin
parent
2501e548e2
commit
42d9d297d5
@@ -57,7 +57,8 @@ import java.util.Set;
|
||||
public class SuggestReviewers implements RestReadView<ChangeResource> {
|
||||
|
||||
private static final String MAX_SUFFIX = "\u9fa5";
|
||||
private static final int MAX = 10;
|
||||
private static final int DEFAULT_MAX_SUGGESTED = 10;
|
||||
private static final int DEFAULT_MAX_MATCHES = 100;
|
||||
|
||||
private final AccountInfo.Loader.Factory accountLoaderFactory;
|
||||
private final AccountControl.Factory accountControlFactory;
|
||||
@@ -72,11 +73,17 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
|
||||
private final int maxAllowed;
|
||||
private int limit;
|
||||
private String query;
|
||||
private boolean useFullTextSearch;
|
||||
private final int fullTextMaxMatches;
|
||||
private final int maxSuggestedReviewers;
|
||||
private final ReviewerSuggestionCache reviewerSuggestionCache;
|
||||
|
||||
@Option(name = "--limit", aliases = {"-n"}, metaVar = "CNT",
|
||||
usage = "maximum number of reviewers to list")
|
||||
public void setLimit(int l) {
|
||||
this.limit = l <= 0 ? MAX : Math.min(l, MAX);
|
||||
this.limit =
|
||||
l <= 0 ? maxSuggestedReviewers : Math.min(l,
|
||||
maxSuggestedReviewers);
|
||||
}
|
||||
|
||||
@Option(name = "--query", aliases = {"-q"}, metaVar = "QUERY",
|
||||
@@ -95,7 +102,8 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
|
||||
Provider<CurrentUser> currentUser,
|
||||
Provider<ReviewDb> dbProvider,
|
||||
@GerritServerConfig Config cfg,
|
||||
GroupBackend groupBackend) {
|
||||
GroupBackend groupBackend,
|
||||
ReviewerSuggestionCache reviewerSuggestionCache) {
|
||||
this.accountLoaderFactory = accountLoaderFactory;
|
||||
this.accountControlFactory = accountControlFactory;
|
||||
this.accountCache = accountCache;
|
||||
@@ -104,12 +112,18 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
|
||||
this.identifiedUserFactory = identifiedUserFactory;
|
||||
this.currentUser = currentUser;
|
||||
this.groupBackend = groupBackend;
|
||||
|
||||
this.reviewerSuggestionCache = reviewerSuggestionCache;
|
||||
this.maxSuggestedReviewers =
|
||||
cfg.getInt("suggest", "maxSuggestedReviewers", DEFAULT_MAX_SUGGESTED);
|
||||
this.fullTextMaxMatches =
|
||||
cfg.getInt("suggest", "fullTextSearchMaxMatches",
|
||||
DEFAULT_MAX_MATCHES);
|
||||
String suggest = cfg.getString("suggest", null, "accounts");
|
||||
if ("OFF".equalsIgnoreCase(suggest)
|
||||
|| "false".equalsIgnoreCase(suggest)) {
|
||||
this.suggestAccounts = false;
|
||||
} else {
|
||||
this.useFullTextSearch = cfg.getBoolean("suggest", "fullTextSearch", false);
|
||||
this.suggestAccounts = (av != AccountVisibility.NONE);
|
||||
}
|
||||
|
||||
@@ -134,7 +148,12 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
|
||||
}
|
||||
|
||||
VisibilityControl visibilityControl = getVisibility(rsrc);
|
||||
List<AccountInfo> suggestedAccounts = suggestAccount(visibilityControl);
|
||||
List<AccountInfo> suggestedAccounts;
|
||||
if (useFullTextSearch) {
|
||||
suggestedAccounts = suggestAccountFullTextSearch(visibilityControl);
|
||||
} else {
|
||||
suggestedAccounts = suggestAccount(visibilityControl);
|
||||
}
|
||||
accountLoaderFactory.create(true).fill(suggestedAccounts);
|
||||
|
||||
List<SuggestedReviewerInfo> reviewer = Lists.newArrayList();
|
||||
@@ -220,6 +239,42 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
|
||||
return Lists.newArrayList(r.values());
|
||||
}
|
||||
|
||||
private List<AccountInfo> suggestAccountFullTextSearch(
|
||||
VisibilityControl visibilityControl) throws OrmException {
|
||||
String str = query.toLowerCase();
|
||||
LinkedHashMap<Account.Id, AccountInfo> accountMap = Maps.newLinkedHashMap();
|
||||
List<Account> fullNameMatches = Lists.newArrayListWithCapacity(fullTextMaxMatches);
|
||||
List<Account> emailMatches = Lists.newArrayListWithCapacity(fullTextMaxMatches);
|
||||
for (Account a : reviewerSuggestionCache.get()) {
|
||||
if (a.getFullName() != null
|
||||
&& a.getFullName().toLowerCase().contains(str)) {
|
||||
fullNameMatches.add(a);
|
||||
} else if (a.getPreferredEmail() != null
|
||||
&& emailMatches.size() < fullTextMaxMatches
|
||||
&& a.getPreferredEmail().toLowerCase().contains(str)) {
|
||||
emailMatches.add(a);
|
||||
}
|
||||
if (fullNameMatches.size() >= fullTextMaxMatches) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (Account a : fullNameMatches) {
|
||||
addSuggestion(accountMap, a, new AccountInfo(a.getId()), visibilityControl);
|
||||
if (accountMap.size() >= limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (accountMap.size() < limit) {
|
||||
for (Account a : emailMatches) {
|
||||
addSuggestion(accountMap, a, new AccountInfo(a.getId()), visibilityControl);
|
||||
if (accountMap.size() >= limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Lists.newArrayList(accountMap.values());
|
||||
}
|
||||
|
||||
private void addSuggestion(Map<Account.Id, AccountInfo> map, Account account,
|
||||
AccountInfo info, VisibilityControl visibilityControl)
|
||||
throws OrmException {
|
||||
|
||||
Reference in New Issue
Block a user