Fix unnecessary duplicate read of refs/meta/config

During a miss ProjectCacheImpl runs the Loader to read the project's
refs/meta/config from its repository.  This new ProjectState was
immediately returned and checked against the ProjectCacheClock.  Since
the lastCheckTime was not initialized it never matched the clock.

By failing to match the clock the repository was immediately opened
a second time and its refs/meta/config ref was accessed again.

In a local filesystem case this may all happen quickly enough to not
show up as a significant runtime factor, but in a distributed system
like the one behind gerrit-review its easily 1.25% of the CPU time.

Change-Id: Ia3e83c41b7374783759883db68f4d69a8ee5e9a3
This commit is contained in:
Shawn Pearce
2016-06-18 13:30:22 -07:00
parent fd0ba728e5
commit 1fc13749c9
2 changed files with 15 additions and 5 deletions

View File

@@ -278,20 +278,26 @@ public class ProjectCacheImpl implements ProjectCache {
static class Loader extends CacheLoader<String, ProjectState> {
private final ProjectState.Factory projectStateFactory;
private final GitRepositoryManager mgr;
private final ProjectCacheClock clock;
@Inject
Loader(ProjectState.Factory psf, GitRepositoryManager g) {
Loader(ProjectState.Factory psf, GitRepositoryManager g, ProjectCacheClock clock) {
projectStateFactory = psf;
mgr = g;
this.clock = clock;
}
@Override
public ProjectState load(String projectName) throws Exception {
long now = clock.read();
Project.NameKey key = new Project.NameKey(projectName);
try (Repository git = mgr.openRepository(key)) {
ProjectConfig cfg = new ProjectConfig(key);
cfg.load(git);
return projectStateFactory.create(cfg);
ProjectState state = projectStateFactory.create(cfg);
state.initLastCheck(now);
return state;
}
}
}