AccountState: Parse project watches and general preferences lazily

When an account is loaded with AccountConfig it loads the watch config
and the preference config, but defers parsing them until project watches
and general preferences are accessed. At the moment they are accessed to
create AccountState but we can defer parsing them further until a
caller of AccountState really needs them. Most callers that load
accounts via the AccountCache don't need project watches and general
preferences and hence they can save the parsing effort when the account
is not cached yet.

It's intentional that external IDs are not lazily loaded. External IDs
are retrieved from the external ID cache and hence getting them should
be cheap. Loading them lazily would be a problem because at the point
when the external IDs are accessed the external ID cache may no longer
have the external IDs for that SHA1. Populating the external ID cache
with external IDs for an old SHA1 may drop the external IDs for current
SHA1 from the cache and as result there would be an increased amount of
evictions and loads from the external ID cache.

Change-Id: I9b9949088c838b2e3f85a1c792ee64e2ab3c3f8d
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2018-01-12 09:33:20 +01:00
parent 5486aa8515
commit 2246836c51
7 changed files with 99 additions and 84 deletions

View File

@@ -18,12 +18,10 @@ import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.account.AccountState;
@@ -43,14 +41,7 @@ public class AccountFieldTest extends GerritBaseTests {
String metaId = "0e39795bb25dc914118224995c53c5c36923a461";
account.setMetaId(metaId);
List<String> values =
toStrings(
AccountField.REF_STATE.get(
new AccountState(
allUsersName,
account,
ImmutableSet.of(),
ImmutableMap.of(),
GeneralPreferencesInfo.defaults())));
toStrings(AccountField.REF_STATE.get(AccountState.forAccount(allUsersName, account)));
assertThat(values).hasSize(1);
String expectedValue =
allUsersName.get() + ":" + RefNames.refsUsers(account.getId()) + ":" + metaId;
@@ -78,12 +69,7 @@ public class AccountFieldTest extends GerritBaseTests {
List<String> values =
toStrings(
AccountField.EXTERNAL_ID_STATE.get(
new AccountState(
null,
account,
ImmutableSet.of(extId1, extId2),
ImmutableMap.of(),
GeneralPreferencesInfo.defaults())));
AccountState.forAccount(null, account, ImmutableSet.of(extId1, extId2))));
String expectedValue1 = extId1.key().sha1().name() + ":" + extId1.blobId().name();
String expectedValue2 = extId2.key().sha1().name() + ":" + extId2.blobId().name();
assertThat(values).containsExactly(expectedValue1, expectedValue2);

View File

@@ -21,10 +21,7 @@ import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
@@ -385,11 +382,6 @@ public class FromAddressGeneratorProviderTest {
final Account account = new Account(userId, TimeUtil.nowTs());
account.setFullName(name);
account.setPreferredEmail(email);
return new AccountState(
new AllUsersName(AllUsersNameProvider.DEFAULT),
account,
ImmutableSet.of(),
ImmutableMap.of(),
GeneralPreferencesInfo.defaults());
return AccountState.forAccount(new AllUsersName(AllUsersNameProvider.DEFAULT), account);
}
}