aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-02-01 11:51:27 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-02-01 16:52:24 +0100
commited7a0167e3bfd31549213426a3bc3a101e2f4a9e (patch)
tree5ca3586dc754bd3a23d05823ad7ffb395403c6b2 /server
parent84d4f441879de01734bb9041fc0cdfbd461386ee (diff)
downloadsonarqube-ed7a0167e3bfd31549213426a3bc3a101e2f4a9e.tar.gz
sonarqube-ed7a0167e3bfd31549213426a3bc3a101e2f4a9e.zip
SONAR-7257 make SymbolsLineReader instantaneous
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/source/SymbolsLineReader.java77
1 files changed, 40 insertions, 37 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/source/SymbolsLineReader.java b/server/sonar-server/src/main/java/org/sonar/server/computation/source/SymbolsLineReader.java
index 71853f79bc4..8d519a863ab 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/source/SymbolsLineReader.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/source/SymbolsLineReader.java
@@ -19,17 +19,16 @@
*/
package org.sonar.server.computation.source;
+import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
-import java.io.Serializable;
+import com.google.common.collect.SetMultimap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.batch.protocol.output.BatchReport;
@@ -46,20 +45,20 @@ public class SymbolsLineReader implements LineReader {
private final Component file;
private final RangeOffsetConverter rangeOffsetConverter;
- private final List<BatchReport.Symbol> symbols;
private final Map<BatchReport.Symbol, Integer> idsBySymbol;
+ private final SetMultimap<Integer, BatchReport.Symbol> symbolsPerLine;
private boolean areSymbolsValid = true;
- public SymbolsLineReader(Component file, Iterator<BatchReport.Symbol> symbols, RangeOffsetConverter rangeOffsetConverter) {
+ public SymbolsLineReader(Component file, Iterator<BatchReport.Symbol> symbolIterator, RangeOffsetConverter rangeOffsetConverter) {
this.file = file;
this.rangeOffsetConverter = rangeOffsetConverter;
- this.symbols = Lists.newArrayList(symbols);
- // Sort symbols to have deterministic results and avoid false variation that would lead to an unnecessary update of the source files
- // data
- Collections.sort(this.symbols, new SymbolsComparator());
+ List<BatchReport.Symbol> symbols = Lists.newArrayList(symbolIterator);
+ // Sort symbols to have deterministic id generation
+ Collections.sort(symbols, SymbolsComparator.INSTANCE);
- this.idsBySymbol = createIdsBySymbolMap(this.symbols);
+ this.idsBySymbol = createIdsBySymbolMap(symbols);
+ this.symbolsPerLine = buildSymbolsPerLine(symbols);
}
@Override
@@ -77,19 +76,23 @@ public class SymbolsLineReader implements LineReader {
private void processSymbols(DbFileSources.Line.Builder lineBuilder) {
int line = lineBuilder.getLine();
- List<BatchReport.Symbol> lineSymbols = findSymbolsMatchingLine(line);
+
+ List<BatchReport.Symbol> lineSymbols = new ArrayList<>(this.symbolsPerLine.get(line));
+ // Sort symbols to have deterministic results and avoid false variation that would lead to an unnecessary update of the source files
+ // data
+ Collections.sort(lineSymbols, SymbolsComparator.INSTANCE);
+
+ StringBuilder symbolString = new StringBuilder();
for (BatchReport.Symbol lineSymbol : lineSymbols) {
int symbolId = idsBySymbol.get(lineSymbol);
- StringBuilder symbolString = new StringBuilder(lineBuilder.getSymbols());
appendSymbol(symbolString, lineSymbol.getDeclaration(), line, symbolId, lineBuilder.getSource());
for (BatchReport.TextRange range : lineSymbol.getReferenceList()) {
appendSymbol(symbolString, range, line, symbolId, lineBuilder.getSource());
}
-
- if (symbolString.length() > 0) {
- lineBuilder.setSymbols(symbolString.toString());
- }
+ }
+ if (symbolString.length() > 0) {
+ lineBuilder.setSymbols(symbolString.toString());
}
}
@@ -107,31 +110,12 @@ public class SymbolsLineReader implements LineReader {
}
}
- private List<BatchReport.Symbol> findSymbolsMatchingLine(int line) {
- List<BatchReport.Symbol> lineSymbols = new ArrayList<>();
- Set<BatchReport.Symbol> symbolsIndex = new HashSet<>();
- for (BatchReport.Symbol symbol : symbols) {
- if (matchLine(symbol.getDeclaration(), line) && !symbolsIndex.contains(symbol)) {
- lineSymbols.add(symbol);
- symbolsIndex.add(symbol);
- } else {
- for (BatchReport.TextRange range : symbol.getReferenceList()) {
- if (matchLine(range, line) && !symbolsIndex.contains(symbol)) {
- lineSymbols.add(symbol);
- symbolsIndex.add(symbol);
- }
- }
- }
- }
- return lineSymbols;
- }
-
private static boolean matchLine(BatchReport.TextRange range, int line) {
return range.getStartLine() <= line && range.getEndLine() >= line;
}
private static Map<BatchReport.Symbol, Integer> createIdsBySymbolMap(List<BatchReport.Symbol> symbols) {
- Map<BatchReport.Symbol, Integer> map = new HashMap<>();
+ Map<BatchReport.Symbol, Integer> map = new HashMap<>(symbols.size());
int symbolId = 1;
for (BatchReport.Symbol symbol : symbols) {
map.put(symbol, symbolId);
@@ -140,7 +124,26 @@ public class SymbolsLineReader implements LineReader {
return map;
}
- private static class SymbolsComparator implements Comparator<BatchReport.Symbol>, Serializable {
+ private static SetMultimap<Integer, BatchReport.Symbol> buildSymbolsPerLine(List<BatchReport.Symbol> symbols) {
+ SetMultimap<Integer, BatchReport.Symbol> res = HashMultimap.create();
+ for (BatchReport.Symbol symbol : symbols) {
+ putForTextRange(res, symbol, symbol.getDeclaration());
+ for (BatchReport.TextRange textRange : symbol.getReferenceList()) {
+ putForTextRange(res, symbol, textRange);
+ }
+ }
+ return res;
+ }
+
+ private static void putForTextRange(SetMultimap<Integer, BatchReport.Symbol> res, BatchReport.Symbol symbol, BatchReport.TextRange declaration) {
+ for (int i = declaration.getStartLine(); i <= declaration.getEndLine(); i++) {
+ res.put(i, symbol);
+ }
+ }
+
+ private enum SymbolsComparator implements Comparator<BatchReport.Symbol> {
+ INSTANCE;
+
@Override
public int compare(BatchReport.Symbol o1, BatchReport.Symbol o2) {
if (o1.getDeclaration().getStartLine() == o2.getDeclaration().getStartLine()) {