Method.java
Home
/
src /
main /
java /
br /
ufrgs /
inf /
prosoft /
aplcache /
metadata /
Method.java
package br.ufrgs.inf.prosoft.aplcache.metadata;
import br.ufrgs.inf.prosoft.aplcache.flowchart.metrics.CacheabilityPatternDecider;
import java.util.*;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
public class Method {
private static final Logger LOGGER = Logger.getLogger(Method.class.getName());
private static final boolean TRACER_VERBOSE = System.getenv("TRACER_VERBOSE") != null && System.getenv("TRACER_VERBOSE").equals("true");
private final String name;
private final List<Occurrence> occurrences;
private List<GroupOfOccurrences> groupsOfOccurrences;
public Method(String name) {
this.name = name;
this.occurrences = new ArrayList<>();
}
public Method(String name, List<Occurrence> occurrences) {
this.name = name;
this.occurrences = occurrences;
}
public String getName() {
return name;
}
public Method addOccurrence(Occurrence occurrence) {
this.occurrences.add(occurrence);
return this;
}
public int getOccurrencesSize() {
return this.occurrences.size();
}
public Stream<Occurrence> occurrences() {
if (this.occurrences == null) throw new RuntimeException("Occurrences already consumed");
return this.occurrences.stream();
}
public Stream<GroupOfOccurrences> groupsOfOccurrences() {
return this.groupsOfOccurrences.stream();
}
private void groupByInput() {
LOGGER.log(Level.FINE, "Grouping by parameters {0} occurrences of {1}", new Object[]{this.name, this.occurrences.size()});
Map<String, GroupOfOccurrences> groupByParameter = new HashMap<>();
this.occurrences.stream().parallel().forEach(new Consumer<Occurrence>() {
private int i;
{
this.i = 0;
}
@Override
public void accept(Occurrence occurrence) {
if (TRACER_VERBOSE) {
System.out.print(".");
System.out.flush();
if (++this.i % 100 == 0) System.out.println();
}
String parameters = occurrence.getParametersSerialised();
synchronized (groupByParameter) {
try {
groupByParameter.get(parameters).addOccurrence(occurrence);
} catch (Exception e) {
GroupOfOccurrences groupOfOccurrences = new GroupOfOccurrences(parameters);
groupOfOccurrences.addOccurrence(occurrence);
groupByParameter.put(parameters, groupOfOccurrences);
}
}
}
});
this.groupsOfOccurrences = new ArrayList<>(groupByParameter.values());
}
public void removeSingleOccurrences() {
if (this.groupsOfOccurrences == null) groupByInput();
int initialCountOfOccurrences = this.groupsOfOccurrences.size();
this.groupsOfOccurrences.removeIf(groupOfOccurrences -> groupOfOccurrences.getOccurrencesSize() < 2);
int removedOccurrences = initialCountOfOccurrences - this.groupsOfOccurrences.size();
if (removedOccurrences > 0) LOGGER.log(Level.INFO, "\tRemoved {0} of {1} inputs from method {2}", new Object[]{removedOccurrences, initialCountOfOccurrences, this.name});
}
public void calculateMetrics() {
if (this.groupsOfOccurrences == null) groupByInput();
this.groupsOfOccurrences.sort(Comparator.comparingInt(GroupOfOccurrences::getOccurrencesSize));
this.groupsOfOccurrences.stream().parallel().forEach(GroupOfOccurrences::calculateMetrics);
}
public void calculateThresholds() {
this.groupsOfOccurrences.forEach(GroupOfOccurrences::calculateThresholds);
}
public void filterCacheableInputs() {
this.groupsOfOccurrences.removeIf(CacheabilityPatternDecider::isNotCacheable);
}
@Override
public String toString() {
return this.name;
}
}