import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import static org.sonar.server.computation.filemove.FileMoveDetectionStep.MIN_REQUIRED_SCORE;
-class MatchesByScore implements ScoreMatrix.ScoreMatrixVisitor, Iterable<List<Match>> {
- private final ScoreMatrix scoreMatrix;
- private final List<Match>[] matches;
- private int totalMatches = 0;
-
- private MatchesByScore(ScoreMatrix scoreMatrix) {
- this.scoreMatrix = scoreMatrix;
- this.matches = new List[Math.max(MIN_REQUIRED_SCORE, scoreMatrix.getMaxScore()) - MIN_REQUIRED_SCORE];
- }
+abstract class MatchesByScore implements Iterable<List<Match>> {
public static MatchesByScore create(ScoreMatrix scoreMatrix) {
- MatchesByScore res = new MatchesByScore(scoreMatrix);
+ if (scoreMatrix.getMaxScore() < MIN_REQUIRED_SCORE) {
+ return EmptyMatchesByScore.INSTANCE;
+ }
+ MatchesByScoreImpl res = new MatchesByScoreImpl(scoreMatrix);
res.populate();
return res;
}
- private void populate() {
- scoreMatrix.accept(this);
- }
+ public abstract int getSize();
+
+ private static final class MatchesByScoreImpl extends MatchesByScore implements ScoreMatrix.ScoreMatrixVisitor {
+ private final ScoreMatrix scoreMatrix;
+ private final List<Match>[] matches;
+ private int totalMatches = 0;
- @Override
- public void visit(String dbFileKey, String reportFileKey, int score) {
- if (!isAcceptableScore(score)) {
- return;
+ private MatchesByScoreImpl(ScoreMatrix scoreMatrix) {
+ this.scoreMatrix = scoreMatrix;
+ this.matches = new List[scoreMatrix.getMaxScore() - MIN_REQUIRED_SCORE + 1];
}
- int index = score - MIN_REQUIRED_SCORE - 1;
- if (matches[index] == null) {
- matches[index] = new ArrayList<>(1);
+ private void populate() {
+ scoreMatrix.accept(this);
+ }
+
+ @Override
+ public void visit(String dbFileKey, String reportFileKey, int score) {
+ if (!isAcceptableScore(score)) {
+ return;
+ }
+
+ int index = score - MIN_REQUIRED_SCORE;
+ if (matches[index] == null) {
+ matches[index] = new ArrayList<>(1);
+ }
+ Match match = new Match(dbFileKey, reportFileKey);
+ matches[index].add(match);
+ totalMatches++;
}
- Match match = new Match(dbFileKey, reportFileKey);
- matches[index].add(match);
- totalMatches++;
- }
- private static boolean isAcceptableScore(int score) {
- return score >= MIN_REQUIRED_SCORE;
- }
- public int getSize() {
- return totalMatches;
+ private static boolean isAcceptableScore(int score) {
+ return score >= MIN_REQUIRED_SCORE;
+ }
+
+ @Override
+ public int getSize() {
+ return totalMatches;
+ }
+
+ @Override
+ public Iterator<List<Match>> iterator() {
+ return Arrays.asList(matches).iterator();
+ }
}
- @Override
- public Iterator<List<Match>> iterator() {
- return Arrays.asList(matches).iterator();
+ private static class EmptyMatchesByScore extends MatchesByScore {
+ private static final EmptyMatchesByScore INSTANCE = new EmptyMatchesByScore();
+
+ @Override
+ public int getSize() {
+ return 0;
+ }
+
+ @Override
+ public Iterator<List<Match>> iterator() {
+ return Collections.<List<Match>>emptyList().iterator();
+ }
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.filemove;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.junit.Test;
+
+import static com.google.common.collect.ImmutableSet.of;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.computation.filemove.FileMoveDetectionStep.MIN_REQUIRED_SCORE;
+
+public class MatchesByScoreTest {
+
+ private static final List<Match> NO_MATCH = null;
+
+ @Test
+ public void creates_returns_always_the_same_instance_of_maxScore_is_less_than_min_required_score() {
+ Set<String> doesNotMatterDbFileKeys = Collections.emptySet();
+ Map<String, FileSimilarity.File> doesNotMatterReportFiles = Collections.emptyMap();
+ int[][] doesNotMatterScores = new int[0][0];
+
+ ScoreMatrix scoreMatrix1 = new ScoreMatrix(doesNotMatterDbFileKeys, doesNotMatterReportFiles, doesNotMatterScores, MIN_REQUIRED_SCORE - 1);
+ MatchesByScore matchesByScore = MatchesByScore.create(scoreMatrix1);
+
+ assertThat(matchesByScore.getSize()).isEqualTo(0);
+ assertThat(matchesByScore).isEmpty();
+
+ ScoreMatrix scoreMatrix2 = new ScoreMatrix(doesNotMatterDbFileKeys, doesNotMatterReportFiles, doesNotMatterScores, MIN_REQUIRED_SCORE - 5);
+ assertThat(MatchesByScore.create(scoreMatrix2)).isSameAs(matchesByScore);
+ }
+
+ @Test
+ public void creates_supports_score_with_same_value_as_min_required_score() {
+ int maxScore = 92;
+ int[][] scores = {
+ {maxScore},
+ {8},
+ {85},
+ };
+ MatchesByScore matchesByScore = MatchesByScore.create(new ScoreMatrix(
+ of("A", "B", "C"), ImmutableMap.of("1", fileOf("1")), scores, maxScore));
+
+ assertThat(matchesByScore.getSize()).isEqualTo(2);
+ assertThat(Lists.newArrayList(matchesByScore)).isEqualTo(Arrays.asList(
+ ImmutableList.of(new Match("C", "1")), // 85
+ NO_MATCH,
+ NO_MATCH,
+ NO_MATCH,
+ NO_MATCH,
+ NO_MATCH,
+ NO_MATCH,
+ ImmutableList.of(new Match("A", "1")) // 92
+ ));
+ }
+
+ private static FileSimilarity.File fileOf(String key) {
+ return new FileSimilarity.File("path of " + key, null, null);
+ }
+}