diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2019-07-30 15:44:51 -0500 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2019-09-04 20:21:04 +0200 |
commit | 1d02b47100a7193552b794235ed49ab83a2a3192 (patch) | |
tree | e4cc0997e84f97ab31a9feed902800e11c9f6838 | |
parent | 013bb7998af335ca734d7362d1be0162f5752f95 (diff) | |
download | sonarqube-1d02b47100a7193552b794235ed49ab83a2a3192.tar.gz sonarqube-1d02b47100a7193552b794235ed49ab83a2a3192.zip |
Use arrays instead of Map for SCM info
7 files changed, 68 insertions, 70 deletions
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/DbScmInfo.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/DbScmInfo.java index 9caaa10301a..eef809a7d4d 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/DbScmInfo.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/DbScmInfo.java @@ -20,8 +20,7 @@ package org.sonar.ce.task.projectanalysis.scm; import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.List; import java.util.Optional; import java.util.function.Function; import javax.annotation.Nonnull; @@ -43,23 +42,26 @@ class DbScmInfo implements ScmInfo { this.fileHash = fileHash; } - public static Optional<DbScmInfo> create(Iterable<DbFileSources.Line> lines, String fileHash) { + public static Optional<DbScmInfo> create(List<DbFileSources.Line> lines, String fileHash) { LineToChangeset lineToChangeset = new LineToChangeset(); - Map<Integer, Changeset> lineChanges = new LinkedHashMap<>(); + Changeset[] lineChanges = new Changeset[lines.size()]; + + boolean lineAdded = false; for (DbFileSources.Line line : lines) { Changeset changeset = lineToChangeset.apply(line); if (changeset == null) { continue; } - lineChanges.put(line.getLine(), changeset); + lineChanges[line.getLine() - 1] = changeset; + lineAdded = true; } - if (lineChanges.isEmpty()) { + if (!lineAdded) { return Optional.empty(); } return Optional.of(new DbScmInfo(new ScmInfoImpl(lineChanges), fileHash)); } - + public String fileHash() { return fileHash; } @@ -80,12 +82,12 @@ class DbScmInfo implements ScmInfo { } @Override - public Map<Integer, Changeset> getAllChangesets() { + public Changeset[] getAllChangesets() { return delegate.getAllChangesets(); } /** - * Transforms {@link org.sonar.db.protobuf.DbFileSources.Line} into {@link Changeset} + * Transforms {@link org.sonar.db.protobuf.DbFileSources.Line} into {@link Changeset} */ private static class LineToChangeset implements Function<DbFileSources.Line, Changeset> { private final Changeset.Builder builder = Changeset.newChangesetBuilder(); @@ -96,8 +98,8 @@ class DbScmInfo implements ScmInfo { public Changeset apply(@Nonnull DbFileSources.Line input) { if (input.hasScmDate()) { Changeset cs = builder - .setRevision(input.hasScmRevision() ? input.getScmRevision() : null) - .setAuthor(input.hasScmAuthor() ? input.getScmAuthor() : null) + .setRevision(input.hasScmRevision() ? input.getScmRevision().intern() : null) + .setAuthor(input.hasScmAuthor() ? input.getScmAuthor().intern() : null) .setDate(input.getScmDate()) .build(); if (cache.containsKey(cs)) { diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/GeneratedScmInfo.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/GeneratedScmInfo.java index 0656564c669..71ed37e721a 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/GeneratedScmInfo.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/GeneratedScmInfo.java @@ -19,29 +19,26 @@ */ package org.sonar.ce.task.projectanalysis.scm; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - import static com.google.common.base.Preconditions.checkState; public class GeneratedScmInfo implements ScmInfo { private final ScmInfoImpl delegate; - public GeneratedScmInfo(Map<Integer, Changeset> changesets) { - delegate = new ScmInfoImpl(changesets); + public GeneratedScmInfo(Changeset[] lineChangeset) { + delegate = new ScmInfoImpl(lineChangeset); } - public static ScmInfo create(long analysisDate, Set<Integer> lines) { - checkState(!lines.isEmpty(), "No changesets"); + public static ScmInfo create(long analysisDate, int lines) { + checkState(lines > 0, "No changesets"); Changeset changeset = Changeset.newChangesetBuilder() .setDate(analysisDate) .build(); - Map<Integer, Changeset> changesets = lines.stream() - .collect(Collectors.toMap(x -> x, i -> changeset)); - return new GeneratedScmInfo(changesets); + Changeset[] lineChangeset = new Changeset[lines]; + for (int i = 0; i < lines; i++) { + lineChangeset[i] = changeset; + } + return new GeneratedScmInfo(lineChangeset); } public static ScmInfo create(long analysisDate, int[] matches, ScmInfo dbScmInfo) { @@ -49,14 +46,14 @@ public class GeneratedScmInfo implements ScmInfo { .setDate(analysisDate) .build(); - Map<Integer, Changeset> dbChangesets = dbScmInfo.getAllChangesets(); - Map<Integer, Changeset> changesets = new LinkedHashMap<>(matches.length); + Changeset[] dbChangesets = dbScmInfo.getAllChangesets(); + Changeset[] changesets = new Changeset[matches.length]; for (int i = 0; i < matches.length; i++) { if (matches[i] > 0) { - changesets.put(i + 1, dbChangesets.get(matches[i])); + changesets[i] = dbChangesets[matches[i]]; } else { - changesets.put(i + 1, changeset); + changesets[i] = changeset; } } return new GeneratedScmInfo(changesets); @@ -78,7 +75,7 @@ public class GeneratedScmInfo implements ScmInfo { } @Override - public Map<Integer, Changeset> getAllChangesets() { + public Changeset[] getAllChangesets() { return delegate.getAllChangesets(); } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ReportScmInfo.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ReportScmInfo.java index 2c73d320cd9..8de0b9c45eb 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ReportScmInfo.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ReportScmInfo.java @@ -20,13 +20,9 @@ package org.sonar.ce.task.projectanalysis.scm; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.IntStream; import javax.annotation.concurrent.Immutable; -import org.sonar.core.util.stream.MoreCollectors; import org.sonar.scanner.protocol.output.ScannerReport; import static com.google.common.base.Preconditions.checkState; @@ -43,13 +39,17 @@ class ReportScmInfo implements ScmInfo { ReportScmInfo(ScannerReport.Changesets changesets) { requireNonNull(changesets); this.delegate = convertToScmInfo(changesets); - checkState(!delegate.getAllChangesets().isEmpty(), "Report has no changesets"); } private static ScmInfo convertToScmInfo(ScannerReport.Changesets changesets) { - return new ScmInfoImpl(IntStream.rangeClosed(1, changesets.getChangesetIndexByLineCount()) - .boxed() - .collect(Collectors.toMap(x -> x, new LineIndexToChangeset(changesets), MoreCollectors.mergeNotSupportedMerger(), LinkedHashMap::new))); + Changeset[] lineChangesets = new Changeset[changesets.getChangesetIndexByLineCount()]; + LineIndexToChangeset lineIndexToChangeset = new LineIndexToChangeset(changesets); + + for (int i = 0; i < changesets.getChangesetIndexByLineCount(); i++) { + lineChangesets[i] = lineIndexToChangeset.apply(i); + } + + return new ScmInfoImpl(lineChangesets); } @Override @@ -68,7 +68,7 @@ class ReportScmInfo implements ScmInfo { } @Override - public Map<Integer, Changeset> getAllChangesets() { + public Changeset[] getAllChangesets() { return this.delegate.getAllChangesets(); } @@ -79,12 +79,12 @@ class ReportScmInfo implements ScmInfo { public LineIndexToChangeset(ScannerReport.Changesets changesets) { this.changesets = changesets; - changesetCache = new HashMap<>(changesets.getChangesetCount()); + this.changesetCache = new HashMap<>(changesets.getChangesetCount()); } @Override public Changeset apply(Integer lineNumber) { - int changesetIndex = changesets.getChangesetIndexByLine(lineNumber - 1); + int changesetIndex = changesets.getChangesetIndexByLine(lineNumber); return changesetCache.computeIfAbsent(changesetIndex, idx -> convert(changesets.getChangeset(changesetIndex), lineNumber)); } @@ -92,8 +92,8 @@ class ReportScmInfo implements ScmInfo { checkState(isNotEmpty(changeset.getRevision()), "Changeset on line %s must have a revision", line); checkState(changeset.getDate() != 0, "Changeset on line %s must have a date", line); return builder - .setRevision(changeset.getRevision()) - .setAuthor(isNotEmpty(changeset.getAuthor()) ? changeset.getAuthor() : null) + .setRevision(changeset.getRevision().intern()) + .setAuthor(isNotEmpty(changeset.getAuthor()) ? changeset.getAuthor().intern() : null) .setDate(changeset.getDate()) .build(); } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfo.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfo.java index bbb9a5d2fea..6c52c0509e3 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfo.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfo.java @@ -47,6 +47,6 @@ public interface ScmInfo { /** * Return all ChangeSets, in order, for all lines that have changesets. */ - Map<Integer, Changeset> getAllChangesets(); + Changeset[] getAllChangesets(); } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoImpl.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoImpl.java index ce4e20b63aa..46416371552 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoImpl.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoImpl.java @@ -19,25 +19,25 @@ */ package org.sonar.ce.task.projectanalysis.scm; -import java.util.Collections; +import java.util.Arrays; import java.util.Comparator; -import java.util.Map; import javax.annotation.concurrent.Immutable; -import static com.google.common.base.Preconditions.checkState; +import org.sonar.api.utils.Preconditions; @Immutable public class ScmInfoImpl implements ScmInfo { private final Changeset latestChangeset; - private final Map<Integer, Changeset> lineChangesets; + private final Changeset[] lineChangesets; - public ScmInfoImpl(Map<Integer, Changeset> lineChangesets) { - checkState(!lineChangesets.isEmpty(), "A ScmInfo must have at least one Changeset and does not support any null one"); - this.lineChangesets = Collections.unmodifiableMap(lineChangesets); + public ScmInfoImpl(Changeset[] lineChangesets) { + Preconditions.checkNotNull(lineChangesets); + Preconditions.checkState(lineChangesets.length > 0, "ScmInfo cannot be empty"); + this.lineChangesets = lineChangesets; this.latestChangeset = computeLatestChangeset(lineChangesets); } - private static Changeset computeLatestChangeset(Map<Integer, Changeset> lineChangesets) { - return lineChangesets.values().stream().max(Comparator.comparingLong(Changeset::getDate)) + private static Changeset computeLatestChangeset(Changeset[] lineChangesets) { + return Arrays.stream(lineChangesets).max(Comparator.comparingLong(Changeset::getDate)) .orElseThrow(() -> new IllegalStateException("Expecting at least one Changeset to be present")); } @@ -48,7 +48,7 @@ public class ScmInfoImpl implements ScmInfo { @Override public Changeset getChangesetForLine(int lineNumber) { - Changeset changeset = lineChangesets.get(lineNumber); + Changeset changeset = lineChangesets[lineNumber - 1]; if (changeset != null) { return changeset; } @@ -57,11 +57,11 @@ public class ScmInfoImpl implements ScmInfo { @Override public boolean hasChangesetForLine(int lineNumber) { - return lineChangesets.containsKey(lineNumber); + return lineNumber - 1 < lineChangesets.length && lineChangesets[lineNumber - 1] != null; } @Override - public Map<Integer, Changeset> getAllChangesets() { + public Changeset[] getAllChangesets() { return lineChangesets; } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoRepositoryImpl.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoRepositoryImpl.java index 03c9e38771a..6788e59dd18 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoRepositoryImpl.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoRepositoryImpl.java @@ -19,21 +19,19 @@ */ package org.sonar.ce.task.projectanalysis.scm; -import java.util.HashMap; +import java.util.Arrays; import java.util.Map; import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.IntStream; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; -import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.ce.task.projectanalysis.batch.BatchReportReader; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.Component.Status; import org.sonar.ce.task.projectanalysis.source.SourceHashRepository; import org.sonar.ce.task.projectanalysis.source.SourceLinesDiff; +import org.sonar.scanner.protocol.output.ScannerReport; +import vlsi.utils.CompactHashMap; import static java.util.Objects.requireNonNull; @@ -42,14 +40,14 @@ public class ScmInfoRepositoryImpl implements ScmInfoRepository { private static final Logger LOGGER = Loggers.get(ScmInfoRepositoryImpl.class); private final BatchReportReader scannerReportReader; - private final Map<Component, Optional<ScmInfo>> scmInfoCache = new HashMap<>(); + private final Map<Component, Optional<ScmInfo>> scmInfoCache = new CompactHashMap<>(); private final ScmInfoDbLoader scmInfoDbLoader; private final AnalysisMetadataHolder analysisMetadata; private final SourceLinesDiff sourceLinesDiff; private final SourceHashRepository sourceHashRepository; public ScmInfoRepositoryImpl(BatchReportReader scannerReportReader, AnalysisMetadataHolder analysisMetadata, ScmInfoDbLoader scmInfoDbLoader, - SourceLinesDiff sourceLinesDiff, SourceHashRepository sourceHashRepository) { + SourceLinesDiff sourceLinesDiff, SourceHashRepository sourceHashRepository) { this.scannerReportReader = scannerReportReader; this.analysisMetadata = analysisMetadata; this.scmInfoDbLoader = scmInfoDbLoader; @@ -93,14 +91,14 @@ public class ScmInfoRepositoryImpl implements ScmInfoRepository { if (file.getFileAttributes().getLines() == 0) { return Optional.empty(); } - Set<Integer> newOrChangedLines = IntStream.rangeClosed(1, file.getFileAttributes().getLines()).boxed().collect(Collectors.toSet()); - return Optional.of(GeneratedScmInfo.create(analysisMetadata.getAnalysisDate(), newOrChangedLines)); + return Optional.of(GeneratedScmInfo.create(analysisMetadata.getAnalysisDate(), file.getFileAttributes().getLines())); } private static ScmInfo removeAuthorAndRevision(ScmInfo info) { - Map<Integer, Changeset> cleanedScmInfo = info.getAllChangesets().entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, e -> removeAuthorAndRevision(e.getValue()))); - return new ScmInfoImpl(cleanedScmInfo); + Changeset[] changesets = Arrays.stream(info.getAllChangesets()) + .map(ScmInfoRepositoryImpl::removeAuthorAndRevision) + .toArray(Changeset[]::new); + return new ScmInfoImpl(changesets); } private static Changeset removeAuthorAndRevision(Changeset changeset) { diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepository.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepository.java index 20386f3576c..55ea56c0349 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepository.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/NewLinesRepository.java @@ -76,16 +76,17 @@ public class NewLinesRepository { } ScmInfo scmInfo = scmInfoOpt.get(); - Map<Integer, Changeset> allChangesets = scmInfo.getAllChangesets(); + Changeset[] allChangesets = scmInfo.getAllChangesets(); Set<Integer> lines = new HashSet<>(); // in SLB/PRs, we consider changes introduced in this analysis as new, hence subtracting 1. long referenceDate = analysisMetadataHolder.isSLBorPR() ? analysisMetadataHolder.getAnalysisDate() - 1 : periodHolder.getPeriod().getSnapshotDate(); - for (Map.Entry<Integer, Changeset> e : allChangesets.entrySet()) { - if (isLineInPeriod(e.getValue().getDate(), referenceDate)) { - lines.add(e.getKey()); + for (int i=0; i<allChangesets.length; i++) { + if (isLineInPeriod(allChangesets[i].getDate(), referenceDate)) { + lines.add(i+1); } } + return Optional.of(lines); } |