Skip to content

Commit

Permalink
SONAR-8743 Handle only leak period when computing issues related meas…
Browse files Browse the repository at this point in the history
…ures
  • Loading branch information
julienlancelot committed Feb 9, 2017
1 parent a3f92a2 commit 01b74f8
Show file tree
Hide file tree
Showing 10 changed files with 282 additions and 500 deletions.
Expand Up @@ -32,7 +32,6 @@
import org.sonar.server.computation.task.projectanalysis.component.Component; import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.measure.Measure; import org.sonar.server.computation.task.projectanalysis.measure.Measure;
import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepository; import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepository;
import org.sonar.server.computation.task.projectanalysis.measure.MeasureVariations;
import org.sonar.server.computation.task.projectanalysis.metric.Metric; import org.sonar.server.computation.task.projectanalysis.metric.Metric;
import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository; import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository;
import org.sonar.server.computation.task.projectanalysis.period.Period; import org.sonar.server.computation.task.projectanalysis.period.Period;
Expand Down Expand Up @@ -83,16 +82,14 @@ public class IssueCounter extends IssueVisitor {
CRITICAL, CRITICAL_VIOLATIONS_KEY, CRITICAL, CRITICAL_VIOLATIONS_KEY,
MAJOR, MAJOR_VIOLATIONS_KEY, MAJOR, MAJOR_VIOLATIONS_KEY,
MINOR, MINOR_VIOLATIONS_KEY, MINOR, MINOR_VIOLATIONS_KEY,
INFO, INFO_VIOLATIONS_KEY INFO, INFO_VIOLATIONS_KEY);
);


private static final Map<String, String> SEVERITY_TO_NEW_METRIC_KEY = ImmutableMap.of( private static final Map<String, String> SEVERITY_TO_NEW_METRIC_KEY = ImmutableMap.of(
BLOCKER, NEW_BLOCKER_VIOLATIONS_KEY, BLOCKER, NEW_BLOCKER_VIOLATIONS_KEY,
CRITICAL, NEW_CRITICAL_VIOLATIONS_KEY, CRITICAL, NEW_CRITICAL_VIOLATIONS_KEY,
MAJOR, NEW_MAJOR_VIOLATIONS_KEY, MAJOR, NEW_MAJOR_VIOLATIONS_KEY,
MINOR, NEW_MINOR_VIOLATIONS_KEY, MINOR, NEW_MINOR_VIOLATIONS_KEY,
INFO, NEW_INFO_VIOLATIONS_KEY INFO, NEW_INFO_VIOLATIONS_KEY);
);


private static final Map<RuleType, String> TYPE_TO_METRIC_KEY = ImmutableMap.<RuleType, String>builder() private static final Map<RuleType, String> TYPE_TO_METRIC_KEY = ImmutableMap.<RuleType, String>builder()
.put(RuleType.CODE_SMELL, CoreMetrics.CODE_SMELLS_KEY) .put(RuleType.CODE_SMELL, CoreMetrics.CODE_SMELLS_KEY)
Expand Down Expand Up @@ -136,11 +133,13 @@ public void beforeComponent(Component component) {
@Override @Override
public void onIssue(Component component, DefaultIssue issue) { public void onIssue(Component component, DefaultIssue issue) {
currentCounters.add(issue); currentCounters.add(issue);
for (Period period : periodsHolder.getPeriods()) { if (!periodsHolder.hasPeriod()) {
// Add one second to not take into account issues created during current analysis return;
if (issue.creationDate().getTime() >= period.getSnapshotDate() + 1000L) { }
currentCounters.addOnPeriod(issue, period.getIndex()); Period period = periodsHolder.getPeriod();
} // Add one second to not take into account issues created during current analysis
if (issue.creationDate().getTime() >= period.getSnapshotDate() + 1000L) {
currentCounters.addOnPeriod(issue);
} }
} }


Expand Down Expand Up @@ -182,44 +181,34 @@ private void addMeasure(Component component, String metricKey, int value) {
} }


private void addMeasuresByPeriod(Component component) { private void addMeasuresByPeriod(Component component) {
if (!periodsHolder.getPeriods().isEmpty()) { if (!periodsHolder.hasPeriod()) {
Double[] unresolvedVariations = new Double[PeriodsHolder.MAX_NUMBER_OF_PERIODS]; return;
for (Period period : periodsHolder.getPeriods()) { }
unresolvedVariations[period.getIndex() - 1] = (double) currentCounters.counterForPeriod(period.getIndex()).unresolved; Double unresolvedVariations = (double) currentCounters.counterForPeriod().unresolved;
} measureRepository.add(component, metricRepository.getByKey(NEW_VIOLATIONS_KEY), Measure.newMeasureBuilder()
measureRepository.add(component, metricRepository.getByKey(NEW_VIOLATIONS_KEY), Measure.newMeasureBuilder() .setVariation(unresolvedVariations)
.setVariations(new MeasureVariations(unresolvedVariations)) .createNoValue());
.createNoValue());


for (Map.Entry<String, String> entry : SEVERITY_TO_NEW_METRIC_KEY.entrySet()) { for (Map.Entry<String, String> entry : SEVERITY_TO_NEW_METRIC_KEY.entrySet()) {
String severity = entry.getKey(); String severity = entry.getKey();
String metricKey = entry.getValue(); String metricKey = entry.getValue();
Double[] variations = new Double[PeriodsHolder.MAX_NUMBER_OF_PERIODS]; Multiset<String> bag = currentCounters.counterForPeriod().severityBag;
for (Period period : periodsHolder.getPeriods()) { Metric metric = metricRepository.getByKey(metricKey);
Multiset<String> bag = currentCounters.counterForPeriod(period.getIndex()).severityBag; measureRepository.add(component, metric, Measure.newMeasureBuilder()
variations[period.getIndex() - 1] = (double) bag.count(severity); .setVariation((double) bag.count(severity))
} .createNoValue());
Metric metric = metricRepository.getByKey(metricKey); }
measureRepository.add(component, metric, Measure.newMeasureBuilder()
.setVariations(new MeasureVariations(variations))
.createNoValue());
}


// waiting for Java 8 lambda in order to factor this loop with the previous one // waiting for Java 8 lambda in order to factor this loop with the previous one
// (see call currentCounters.counterForPeriod(period.getIndex()).xxx with xxx as severityBag or typeBag) // (see call currentCounters.counterForPeriod(period.getIndex()).xxx with xxx as severityBag or typeBag)
for (Map.Entry<RuleType, String> entry : TYPE_TO_NEW_METRIC_KEY.entrySet()) { for (Map.Entry<RuleType, String> entry : TYPE_TO_NEW_METRIC_KEY.entrySet()) {
RuleType type = entry.getKey(); RuleType type = entry.getKey();
String metricKey = entry.getValue(); String metricKey = entry.getValue();
Double[] variations = new Double[PeriodsHolder.MAX_NUMBER_OF_PERIODS]; Multiset<RuleType> bag = currentCounters.counterForPeriod().typeBag;
for (Period period : periodsHolder.getPeriods()) { Metric metric = metricRepository.getByKey(metricKey);
Multiset<RuleType> bag = currentCounters.counterForPeriod(period.getIndex()).typeBag; measureRepository.add(component, metric, Measure.newMeasureBuilder()
variations[period.getIndex() - 1] = (double) bag.count(type); .setVariation((double) bag.count(type))
} .createNoValue());
Metric metric = metricRepository.getByKey(metricKey);
measureRepository.add(component, metric, Measure.newMeasureBuilder()
.setVariations(new MeasureVariations(variations))
.createNoValue());
}
} }
} }


Expand Down Expand Up @@ -274,40 +263,33 @@ void add(DefaultIssue issue) {
} }


/** /**
* List of {@link Counter} for regular value and periods. * List of {@link Counter} for regular value and period.
*/ */
private static class Counters { private static class Counters {
private final Counter[] array = new Counter[1 + PeriodsHolder.MAX_NUMBER_OF_PERIODS]; private final Counter counter = new Counter();

private final Counter counterForPeriod = new Counter();
Counters() {
array[0] = new Counter();
for (int i = 1; i <= PeriodsHolder.MAX_NUMBER_OF_PERIODS; i++) {
array[i] = new Counter();
}
}


void add(@Nullable Counters other) { void add(@Nullable Counters other) {
if (other != null) { if (other != null) {
for (int i = 0; i < array.length; i++) { counter.add(other.counter);
array[i].add(other.array[i]); counterForPeriod.add(other.counterForPeriod);
}
} }
} }


void addOnPeriod(DefaultIssue issue, int periodIndex) { void addOnPeriod(DefaultIssue issue) {
array[periodIndex].add(issue); counterForPeriod.add(issue);
} }


void add(DefaultIssue issue) { void add(DefaultIssue issue) {
array[0].add(issue); counter.add(issue);
} }


Counter counter() { Counter counter() {
return array[0]; return counter;
} }


Counter counterForPeriod(int periodIndex) { Counter counterForPeriod() {
return array[periodIndex]; return counterForPeriod;
} }
} }
} }
Expand Up @@ -32,7 +32,6 @@
import org.sonar.server.computation.task.projectanalysis.component.Component; import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.measure.Measure; import org.sonar.server.computation.task.projectanalysis.measure.Measure;
import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepository; import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepository;
import org.sonar.server.computation.task.projectanalysis.measure.MeasureVariations;
import org.sonar.server.computation.task.projectanalysis.metric.Metric; import org.sonar.server.computation.task.projectanalysis.metric.Metric;
import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository; import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository;
import org.sonar.server.computation.task.projectanalysis.period.Period; import org.sonar.server.computation.task.projectanalysis.period.Period;
Expand Down Expand Up @@ -94,11 +93,9 @@ public void beforeComponent(Component component) {


@Override @Override
public void onIssue(Component component, DefaultIssue issue) { public void onIssue(Component component, DefaultIssue issue) {
if (issue.resolution() == null && issue.effortInMinutes() != null && !periodsHolder.getPeriods().isEmpty()) { if (issue.resolution() == null && issue.effortInMinutes() != null && periodsHolder.hasPeriod()) {
List<IssueChangeDto> changelog = changesByIssueUuid.get(issue.key()); List<IssueChangeDto> changelog = changesByIssueUuid.get(issue.key());
for (Period period : periodsHolder.getPeriods()) { counter.add(issue, periodsHolder.getPeriod(), changelog);
counter.add(issue, period, changelog);
}
} }
} }


Expand All @@ -113,8 +110,7 @@ public void afterComponent(Component component) {


private void computeMeasure(Component component, Metric metric, EffortSum effortSum) { private void computeMeasure(Component component, Metric metric, EffortSum effortSum) {
if (!effortSum.isEmpty) { if (!effortSum.isEmpty) {
MeasureVariations variations = new MeasureVariations(effortSum.sums); measureRepository.add(component, metric, Measure.newMeasureBuilder().setVariation(effortSum.newEffort).createNoValue());
measureRepository.add(component, metric, Measure.newMeasureBuilder().setVariations(variations).createNoValue());
} }
} }


Expand All @@ -139,13 +135,13 @@ void add(DefaultIssue issue, Period period, List<IssueChangeDto> changelog) {
long newEffort = calculator.calculate(issue, changelog, period); long newEffort = calculator.calculate(issue, changelog, period);
switch (issue.type()) { switch (issue.type()) {
case CODE_SMELL: case CODE_SMELL:
maintainabilitySum.add(period.getIndex(), newEffort); maintainabilitySum.add(newEffort);
break; break;
case BUG: case BUG:
reliabilitySum.add(period.getIndex(), newEffort); reliabilitySum.add(newEffort);
break; break;
case VULNERABILITY: case VULNERABILITY:
securitySum.add(period.getIndex(), newEffort); securitySum.add(newEffort);
break; break;
default: default:
throw new IllegalStateException(String.format("Unknown type '%s'", issue.type())); throw new IllegalStateException(String.format("Unknown type '%s'", issue.type()));
Expand All @@ -154,21 +150,19 @@ void add(DefaultIssue issue, Period period, List<IssueChangeDto> changelog) {
} }


private static class EffortSum { private static class EffortSum {
private final Double[] sums = new Double[PeriodsHolder.MAX_NUMBER_OF_PERIODS]; private Double newEffort;
private boolean isEmpty = true; private boolean isEmpty = true;


void add(int periodIndex, long newEffort) { void add(long newEffort) {
double previous = MoreObjects.firstNonNull(sums[periodIndex - 1], 0d); double previous = MoreObjects.firstNonNull(this.newEffort, 0d);
sums[periodIndex - 1] = previous + newEffort; this.newEffort = previous + newEffort;
isEmpty = false; isEmpty = false;
} }


void add(EffortSum other) { void add(EffortSum other) {
for (int i = 0; i < sums.length; i++) { Double otherValue = other.newEffort;
Double otherValue = other.sums[i]; if (otherValue != null) {
if (otherValue != null) { add(otherValue.longValue());
add(i + 1, otherValue.longValue());
}
} }
} }
} }
Expand Down

0 comments on commit 01b74f8

Please sign in to comment.