aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2015-10-05 10:31:49 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2015-10-05 10:48:02 +0200
commit1a8a6d5c91ddc8807c0f113ca4c470d8078bf721 (patch)
treee23676da173133209cd1352f705d3a33e7b9c138
parent478fa926c6c1bb6bc57355171a83919360fdc95e (diff)
downloadsonarqube-1a8a6d5c91ddc8807c0f113ca4c470d8078bf721.tar.gz
sonarqube-1a8a6d5c91ddc8807c0f113ca4c470d8078bf721.zip
SONAR-6397 Use a cache when reading SCM info to reduce db calls
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/scm/ScmInfoRepositoryImpl.java21
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/scm/ScmInfoRepositoryImplTest.java22
2 files changed, 41 insertions, 2 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/scm/ScmInfoRepositoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/scm/ScmInfoRepositoryImpl.java
index 7ac532af8aa..20a7e1d88b9 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/scm/ScmInfoRepositoryImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/scm/ScmInfoRepositoryImpl.java
@@ -20,6 +20,8 @@
package org.sonar.server.computation.scm;
import com.google.common.base.Optional;
+import java.util.HashMap;
+import java.util.Map;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.batch.protocol.output.BatchReport;
@@ -40,6 +42,8 @@ public class ScmInfoRepositoryImpl implements ScmInfoRepository {
private final DbClient dbClient;
private final SourceService sourceService;
+ private final Map<Component, ScmInfo> scmInfoCache = new HashMap<>();
+
public ScmInfoRepositoryImpl(BatchReportReader batchReportReader, DbClient dbClient, SourceService sourceService) {
this.batchReportReader = batchReportReader;
this.dbClient = dbClient;
@@ -49,17 +53,30 @@ public class ScmInfoRepositoryImpl implements ScmInfoRepository {
@Override
public Optional<ScmInfo> getScmInfo(Component component) {
checkNotNull(component, "Component cannot be bull");
+ initializeScmInfoForComponent(component);
+ return Optional.fromNullable(scmInfoCache.get(component));
+ }
+
+ private void initializeScmInfoForComponent(Component component) {
+ if (scmInfoCache.containsKey(component)) {
+ return;
+ }
+ Optional<ScmInfo> scmInfoOptional = getScmInfoForComponent(component);
+ scmInfoCache.put(component, scmInfoOptional.isPresent() ? scmInfoOptional.get() : null);
+ }
+
+ private Optional<ScmInfo> getScmInfoForComponent(Component component) {
BatchReport.Changesets changesets = batchReportReader.readChangesets(component.getReportAttributes().getRef());
if (changesets == null) {
LOGGER.trace("Reading SCM info from db for file '{}'", component);
- return getFromDb(component);
+ return getScmInfoFromDb(component);
} else {
LOGGER.trace("Reading SCM info from report for file '{}'", component);
return Optional.<ScmInfo>of(new ReportScmInfo(changesets));
}
}
- private Optional<ScmInfo> getFromDb(Component component){
+ private Optional<ScmInfo> getScmInfoFromDb(Component component) {
DbSession dbSession = dbClient.openSession(false);
try {
Optional<Iterable<DbFileSources.Line>> linesOpt = sourceService.getLines(dbSession, component.getUuid(), 1, Integer.MAX_VALUE);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/scm/ScmInfoRepositoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/scm/ScmInfoRepositoryImplTest.java
index 04c0166a372..6108f9f640d 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/scm/ScmInfoRepositoryImplTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/scm/ScmInfoRepositoryImplTest.java
@@ -24,6 +24,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
+import org.sonar.api.utils.log.LogTester;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
@@ -35,11 +36,15 @@ import org.sonar.server.source.SourceService;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.guava.api.Assertions.assertThat;
+import static org.sonar.api.utils.log.LoggerLevel.TRACE;
import static org.sonar.server.computation.component.ReportComponent.builder;
public class ScmInfoRepositoryImplTest {
@Rule
+ public LogTester logTester = new LogTester();
+
+ @Rule
public ExpectedException thrown = ExpectedException.none();
static final int FILE_REF = 1;
@@ -61,6 +66,8 @@ public class ScmInfoRepositoryImplTest {
ScmInfo scmInfo = underTest.getScmInfo(FILE).get();
assertThat(scmInfo.getAllChangesets()).hasSize(1);
+
+ assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from report for file 'ReportComponent{ref=1, key='FILE_KEY', type=FILE}'");
}
@Test
@@ -69,6 +76,8 @@ public class ScmInfoRepositoryImplTest {
ScmInfo scmInfo = underTest.getScmInfo(FILE).get();
assertThat(scmInfo.getAllChangesets()).hasSize(1);
+
+ assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from db for file 'ReportComponent{ref=1, key='FILE_KEY', type=FILE}'");
}
@Test
@@ -111,6 +120,19 @@ public class ScmInfoRepositoryImplTest {
underTest.getScmInfo(null);
}
+ @Test
+ public void load_scm_info_from_cache_when_already_read() throws Exception {
+ addChangesetInReport("john", 123456789L, "rev-1");
+ ScmInfo scmInfo = underTest.getScmInfo(FILE).get();
+ assertThat(scmInfo.getAllChangesets()).hasSize(1);
+
+ assertThat(logTester.logs(TRACE)).hasSize(1);
+ logTester.clear();
+
+ underTest.getScmInfo(FILE);
+ assertThat(logTester.logs(TRACE)).isEmpty();
+ }
+
private void addChangesetInDb(String author, Long date, String revision) {
DbFileSources.Data.Builder fileDataBuilder = DbFileSources.Data.newBuilder();
fileDataBuilder.addLinesBuilder()