Allow to get all external IDs by account and email

If many external IDs need to be looked up by account or email it is more
efficient to retrieve all external IDs from the external ID cache at
once instead of retrieving them from the external ID cache one by one in
a loop. This is because each cache lookup reads the SHA1 of the external
IDs branch to ensure that the cached data is still up-to-date.

The new methods are not used by Gerrit core but can be useful for
plugins. Within Google we have a concrete need for them.

Change-Id: Iaad11fc71b64197a896342920f206d33b363c6d8
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2017-08-02 15:45:43 +02:00
parent fdbfe277e4
commit bcc6bdd106
4 changed files with 46 additions and 12 deletions

View File

@@ -89,8 +89,18 @@ public class DisabledExternalIdCache implements ExternalIdCache {
throw new UnsupportedOperationException();
}
@Override
public ImmutableSetMultimap<Account.Id, ExternalId> allByAccount() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public ImmutableSetMultimap<String, ExternalId> byEmails(String... emails) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public ImmutableSetMultimap<String, ExternalId> allByEmail() throws IOException {
throw new UnsupportedOperationException();
}
}

View File

@@ -82,8 +82,12 @@ interface ExternalIdCache {
Set<ExternalId> byAccount(Account.Id accountId) throws IOException;
ImmutableSetMultimap<Account.Id, ExternalId> allByAccount() throws IOException;
ImmutableSetMultimap<String, ExternalId> byEmails(String... emails) throws IOException;
ImmutableSetMultimap<String, ExternalId> allByEmail() throws IOException;
default ImmutableSet<ExternalId> byEmail(String email) throws IOException {
return byEmails(email).get(email);
}

View File

@@ -218,24 +218,34 @@ class ExternalIdCacheImpl implements ExternalIdCache {
@Override
public Set<ExternalId> byAccount(Account.Id accountId) throws IOException {
try {
return extIdsByAccount.get(externalIdReader.readRevision()).byAccount().get(accountId);
} catch (ExecutionException e) {
throw new IOException("Cannot list external ids by account", e);
}
return get().byAccount().get(accountId);
}
@Override
public ImmutableSetMultimap<Account.Id, ExternalId> allByAccount() throws IOException {
return get().byAccount();
}
@Override
public ImmutableSetMultimap<String, ExternalId> byEmails(String... emails) throws IOException {
AllExternalIds allExternalIds = get();
ImmutableSetMultimap.Builder<String, ExternalId> byEmails = ImmutableSetMultimap.builder();
for (String email : emails) {
byEmails.putAll(email, allExternalIds.byEmail().get(email));
}
return byEmails.build();
}
@Override
public ImmutableSetMultimap<String, ExternalId> allByEmail() throws IOException {
return get().byEmail();
}
private AllExternalIds get() throws IOException {
try {
AllExternalIds allExternalIds = extIdsByAccount.get(externalIdReader.readRevision());
ImmutableSetMultimap.Builder<String, ExternalId> byEmails = ImmutableSetMultimap.builder();
for (String email : emails) {
byEmails.putAll(email, allExternalIds.byEmail().get(email));
}
return byEmails.build();
return extIdsByAccount.get(externalIdReader.readRevision());
} catch (ExecutionException e) {
throw new IOException("Cannot list external ids by email", e);
throw new IOException("Cannot load external ids", e);
}
}

View File

@@ -75,6 +75,11 @@ public class ExternalIds {
return byAccount(accountId).stream().filter(e -> e.key().isScheme(scheme)).collect(toSet());
}
/** Returns all external IDs by account. */
public ImmutableSetMultimap<Account.Id, ExternalId> allByAccount() throws IOException {
return externalIdCache.allByAccount();
}
/**
* Returns the external ID with the given email.
*
@@ -109,4 +114,9 @@ public class ExternalIds {
public ImmutableSetMultimap<String, ExternalId> byEmails(String... emails) throws IOException {
return externalIdCache.byEmails(emails);
}
/** Returns all external IDs by email. */
public ImmutableSetMultimap<String, ExternalId> allByEmail() throws IOException {
return externalIdCache.allByEmail();
}
}