Skip to content
Snippets Groups Projects

Benchmarking initial

Files

package nl.tudelft.ewi.auta.core.benchmarking;
import nl.tudelft.ewi.auta.common.model.entity.Entity;
import nl.tudelft.ewi.auta.common.model.entity.EntityLevel;
import nl.tudelft.ewi.auta.common.model.entity.ProjectEntity;
import nl.tudelft.ewi.auta.common.model.metric.IntegerMetric;
import nl.tudelft.ewi.auta.common.model.metric.MetricName;
import org.springframework.stereotype.Service;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Service
public class Benchmarker {
/**
* The list of entities for which the benchmarker will calculate the weight as the sum of their
* children entities.
*/
private static final Set<EntityLevel> GET_WEIGHT_FROM_CHILDREN = Set.of(
EntityLevel.PROJECT,
EntityLevel.MODULE
);
/**
* Gets the total weight from a project entity.
* @param projectEntity the project entity to calculte the total weight with
* @return the total project weight
* @throws InvalidEntityWeightException if something goes wrong when calculating the total
* weight
*/
private Double getTotalWeight(final Entity projectEntity) throws InvalidEntityWeightException {
return this.getWeight(projectEntity);
}
/**
* Gets the weight from an entity.
* @param entity the entity to weigh
* @return the weight of the entity
* @throws InvalidEntityWeightException if the weight is invalid
*/
private Double getWeight(final Entity entity) throws InvalidEntityWeightException {
if (GET_WEIGHT_FROM_CHILDREN.contains(entity.getLevel())) {
var sum = 0d;
for (var child : entity.getChildren()) {
sum += this.getWeight(child);
}
return sum;
}
var linesOfCode = entity.getMetricList().stream()
.filter(m -> m.getName().equals(MetricName.LINES_OF_CODE))
.findFirst();
if (linesOfCode.isPresent()) {
return Double.valueOf(((IntegerMetric) linesOfCode.get()).getValue());
}
throw new InvalidEntityWeightException();
}
/**
* Gets the relative weight of an entity.
* @param entity the entity to calculate the relative weight with
* @param projectEntity the project entity to use
* @return the relative weight of the entity
*/
private Double getRelativeWeight(final Entity entity, final ProjectEntity projectEntity) {
Double totalWeight = this.getTotalWeight(projectEntity);
if (totalWeight <= 0.d) {
throw new InvalidEntityWeightException("Project entity cannot have weight <= 0");
}
return this.getWeight(entity) / totalWeight;
}
/**
* Aggregates all metrics of a certain type into a Map of value -> total relative weights.
* @param projectEntity the project entity to use
* @param name the name of the metric
* @param level the level of the entity to analyze (filters all other entities)
* @return a map of value -> total relative weights
* @throws MissingMetricException if an entity unexpectedly does not contain the metric which
* @throws IllegalArgumentException if the project entity is missing
* is to be aggregated
*/
public Map<Integer, Double> aggregate(@Nullable final ProjectEntity projectEntity,
final MetricName name, final EntityLevel level)
throws MissingMetricException, IllegalArgumentException {
if (projectEntity == null) {
throw new IllegalArgumentException("Project entity cannot be null");
}
Map<Integer, Double> aggregatedMetrics = new HashMap<>();
//Filters children by level
var allFilteredChildren = projectEntity.getAllChildren().stream()
.filter(e -> e.getLevel().equals(level))
.collect(Collectors.toSet());
//Gets the correct metric name. Throws an exception if the metric could not be found.
allFilteredChildren.forEach(
c -> {
var metric = c.getMetricList().stream()
.filter(m -> m.getName().equals(name))
.findFirst()
.orElseThrow(MissingMetricException::new);
var oldValue = aggregatedMetrics.getOrDefault((Integer) metric.getValue(), 0.d);
aggregatedMetrics.put(
(Integer) metric.getValue(),
oldValue + this.getRelativeWeight(c, projectEntity)
);
}
);
return aggregatedMetrics;
}
}
Loading