aplcache
Changes
pom.xml 5(+0 -5)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/FlowchartWorkFlow.java 397(+55 -342)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/model/MethodEntry.java 60(+0 -60)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/CacheabilityMetrics.java 93(+13 -80)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/CacheabilityPatternDecider.java 99(+22 -77)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/Stats.java 92(+24 -68)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/Thresholds.java 217(+217 -0)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/GroupOfOccurrences.java 73(+73 -0)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/LogTrace.java 95(+0 -95)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/Method.java 103(+103 -0)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/MethodInfoConcrete.java 24(+0 -24)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/Occurrence.java 88(+49 -39)
src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/OccurrenceConcrete.java 32(+32 -0)
Details
pom.xml 5(+0 -5)
diff --git a/pom.xml b/pom.xml
index bbae100..ab23205 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,11 +16,6 @@
<dependencies>
<dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.7.21</version>
- </dependency>
- <dependency>
<groupId>org.ehcache</groupId>
<artifactId>sizeof</artifactId>
<version>0.3.0</version>
diff --git a/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/FlowchartWorkFlow.java b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/FlowchartWorkFlow.java
index c796197..497dc70 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/FlowchartWorkFlow.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/FlowchartWorkFlow.java
@@ -1,362 +1,75 @@
package br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.CacheDecider;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.model.MethodEntry;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.model.MethodStats;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.stats.CacheabilityMetrics;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.stats.CacheabilityPatternDecider;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.LogTrace;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.MethodInfo;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.PrintWriter;
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
+import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.stats.Thresholds;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.Method;
+import java.util.Collection;
+import java.util.Iterator;
import java.util.logging.Level;
-import java.util.stream.Collectors;
-
-public class FlowchartWorkFlow {
-
- Logger logger = LoggerFactory.getLogger(FlowchartWorkFlow.class);
-
- private final long population;
- protected HashMap<MethodInfo, MethodStats> methodsInfoMap;
-
- private CacheDecider decider;
-
- private double sumMissRatio;
- private double sumHitRatio;
- private double sumExecutionTime;
- private double sumShareability;
- private double sumFrequency;
- private List<Double> hitRatios = new ArrayList<>();
- private List<Double> missRatios = new ArrayList<>();
- private List<Long> executionTimes = new ArrayList<>();
- private List<Double> shareabilities = new ArrayList<>();
- private List<Long> frequencies = new ArrayList<>();
-
- public FlowchartWorkFlow(List<LogTrace> logList) {
- this.decider = new CacheabilityPatternDecider(logList.size(), this);
- this.methodsInfoMap = countOccurrences(logList);
- this.population = logList.size();
-
- logger.debug(methodsInfoMap.size() + " unique method calls identified from " + logList.size() + " original traces");
-
- logger.debug("Average ExecutionTime: " + getAverageExecutionTime());
- logger.debug("Average HitRatio: " + getAverageHitRatio());
- logger.debug("Average MissRatio: " + getAverageMissRatio());
- logger.debug("Average shareability: " + getAverageShareability());
- logger.debug("StdDv ExecutionTime: " + getStdDevExecutionTimeRatio());
- logger.debug("StdDv HitRatio: " + getStdDevHitRatio());
- logger.debug("StdDv MissRatio: " + getStdDevMissRatio());
- logger.debug("StdDv shareability: " + getStdDevShareability());
- logger.debug("StdDv frequency: " + getStdDevFrequency());
-
- int k = 0;
- logger.debug("Using " + k + " stdDev to calculate thresholds...");
- logger.debug("Threshold ExecutionTime: " + expensivenessThreshold(k));
- logger.debug("Threshold HitRatio: " + hitThreshold(k));
- logger.debug("Threshold MissRatio: " + missThreshold(k));
- logger.debug("Threshold Shareability: " + shareabilityThreshold(k));
- logger.debug("Threshold frequency: " + frequencyThreshold(k));
- }
-
- public Set<MethodEntry> filterCacheableMethods(long expiryTime) {
- logger.debug("Deciding if methods are cacheable...");
-
- Set<MethodEntry> cacheableMethods = getMethodsInfoMap().keySet().stream()
- .filter(mi -> decider.isCacheable(mi, getMethodsInfoMap().get(mi)))
- .map(mi -> new MethodEntry(mi, getMethodsInfoMap().get(mi), System.currentTimeMillis() + expiryTime))
- .collect(Collectors.toSet());
-
- logger.info(cacheableMethods.size() + " cacheable methods detected. Printing files...");
-
- //TODO remove: print all unique methods and metrics to csv file
- try (PrintWriter pw = new PrintWriter(new File("allmethods.csv"))) {
- pw.write("isStaticData,changeMoreThanUsed,usedByManyRequests,isUserSpecific,isCacheSizeLarge,isDataSizeLarge,isExpensive,signature,numberOfSameOccurrences,numberOfDifferentReturnOccurrences,totalOccurrences,sameOccurrencesAverageExecutionTime,sameOccurrencesTotalExecutionTime,hitRatio,missRatio\n");
- getMethodsInfoMap().keySet().stream().forEach(mi -> pw.write(CacheabilityMetrics.allMetricsToString(mi, getMethodsInfoMap().get(mi), this, getMethodsInfoMap().size()) + "," + new MethodEntry(mi, getMethodsInfoMap().get(mi), System.currentTimeMillis() + expiryTime).getMethodInfo().getSignature() + "," + new MethodEntry(mi, getMethodsInfoMap().get(mi), System.currentTimeMillis() + expiryTime).getMethodStats().toCSV() + '\n'));
- } catch (FileNotFoundException ex) {
- }
-
- //TODO remove: print cacheable methods to csv file
- try (PrintWriter pw = new PrintWriter(new File("cacheablemethods.csv"))) {
- pw.write("isStaticData,changeMoreThanUsed,usedByManyRequests,isUserSpecific,isCacheSizeLarge,isDataSizeLarge,isExpensive,signature,numberOfSameOccurrences,numberOfDifferentReturnOccurrences,totalOccurrences,sameOccurrencesAverageExecutionTime,sameOccurrencesTotalExecutionTime,hitRatio,missRatio\n");
- cacheableMethods.stream().forEach(ma -> pw.write(CacheabilityMetrics.allMetricsToString(ma.getMethodInfo(), ma.getMethodStats(), this, getMethodsInfoMap().size()) + "," + ma.getMethodInfo().getSignature() + "," + ma.getMethodStats().toCSV() + '\n'));
- } catch (FileNotFoundException ex) {
- }
- return cacheableMethods;
- }
-
- public HashMap<MethodInfo, MethodStats> countOccurrences(List<LogTrace> logs) {
- logger.info("Counting {0} occurrences", logs.size());
- sumExecutionTime = 0;
- sumHitRatio = 0;
- sumMissRatio = 0;
- sumShareability = 0;
- sumFrequency = 0;
-
- HashMap<MethodInfo, MethodStats> methodInfoMap = new HashMap<>();
-
- for (int i = 0; i < logs.size(); i++) {
- LogTrace logTrace = logs.get(i);
- System.out.print(".");
- System.out.flush();
- if (i != 0 && i % 100 == 0) {
- System.out.println();
- }
- if (methodInfoMap.containsKey(logTrace.getMethodInfo())) {
- continue;
- }
-
- MethodStats methodStats = new MethodStats(logTrace);
-
- for (int j = 0; j < logs.size(); j++) {
- LogTrace traceCompare = logs.get(j);
-
- if (i == j) {
- continue;
- }
-
- //if similar methods: same signature and params, different return
- if (traceCompare.getMethodInfo().equalsWithoutReturnedValue(logTrace.getMethodInfo())) {
- //if identical methods
- if (EqualsBuilder.reflectionEquals(traceCompare.getMethodInfo().getReturnedValue(), logTrace.getMethodInfo().getReturnedValue())) {
- methodStats.addSameOccurrence(traceCompare);
- } else {
- methodStats.addDifferentReturnOccurrence();
- }
- }
- }
-
- methodInfoMap.put(logTrace.getMethodInfo(), methodStats);
-
- sumExecutionTime += methodStats.getSameOccurrencesTotalExecutionTime();
- executionTimes.add(methodStats.getSameOccurrencesTotalExecutionTime());
-
- sumHitRatio += methodStats.hitRatio();
- hitRatios.add(methodStats.hitRatio());
-
- sumMissRatio += methodStats.missRatio();
- missRatios.add(methodStats.missRatio());
-
- sumShareability += methodStats.shareability();
- shareabilities.add(methodStats.shareability());
-
- sumFrequency += methodStats.getNumberOfSameOccurrences();
- frequencies.add(methodStats.getNumberOfSameOccurrences());
- }
-
- return methodInfoMap;
- }
-
- /**
- * General mean hit ratio of all calls
- *
- * @return
- */
- public double getAverageHitRatio() {
- if (population == 0) {
- return 0;
- }
- return new BigDecimal(sumHitRatio).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
- }
-
- public double getAverageMissRatio() {
- if (population == 0) {
- return 0;
- }
- return new BigDecimal(sumMissRatio).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
- }
-
- public double getAverageExecutionTime() {
- if (population == 0) {
- return 0;
- }
- return new BigDecimal(sumExecutionTime).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
- }
-
- public double getAverageShareability() {
- if (population == 0) {
- return 0;
- }
- return new BigDecimal(sumShareability).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
- }
-
- private Double StdDevHitRatio;
-
- public double getStdDevHitRatio() {
- if (population == 0) {
- return 0;
- }
- if (StdDevHitRatio != null) {
- return StdDevHitRatio;
- }
+import java.util.logging.Logger;
- double mean = getAverageHitRatio();
- double temp = 0;
- for (double a : hitRatios) {
- temp += (a - mean) * (a - mean);
- }
- StdDevHitRatio = Math.sqrt(temp / population);
- return StdDevHitRatio;
- }
+public final class FlowchartWorkFlow {
- private Double StdDevMissRatio;
+ private static final Logger logger = Logger.getLogger(FlowchartWorkFlow.class.getName());
- public double getStdDevMissRatio() {
- if (population == 0) {
- return 0;
- }
- if (StdDevMissRatio != null) {
- return StdDevMissRatio;
- }
+ private Collection<Method> methods;
- double mean = getAverageMissRatio();
- double temp = 0;
- for (double a : missRatios) {
- temp += (a - mean) * (a - mean);
- }
- StdDevMissRatio = Math.sqrt(temp / population);
- return StdDevMissRatio;
+ public FlowchartWorkFlow setMethods(Collection<Method> methods) {
+ this.methods = methods;
+ return this;
}
- private Double StdDevExecutionTimeRatio;
-
- public double getStdDevExecutionTimeRatio() {
- if (population == 0) {
- return 0;
- }
- if (StdDevExecutionTimeRatio != null) {
- return StdDevExecutionTimeRatio;
- }
-
- double mean = getAverageExecutionTime();
- double temp = executionTimes.stream()
- .map(executionTime -> (executionTime - mean) * (executionTime - mean))
- .reduce(Double::sum).get();
- StdDevExecutionTimeRatio = Math.sqrt(temp / population);
- return StdDevExecutionTimeRatio;
+ private void countStats() {
+ logger.log(Level.INFO, "Counting stats of {0} methods", this.methods.size());
+ this.methods.stream().parallel().forEach(Method::countStats);
}
- private Double StdDevFrequency;
-
- public double getStdDevFrequency() {
- if (population == 0) {
- return 0;
- }
- if (StdDevFrequency != null) {
- return StdDevFrequency;
- }
-
- double mean = getAverageFrequency();
- double temp = frequencies.stream()
- .map(frequency -> (frequency - mean) * (frequency - mean))
- .reduce(Double::sum).get();
- StdDevFrequency = Math.sqrt(temp / population);
- return StdDevFrequency;
- }
+ private void calculateThresholds() {
+ logger.log(Level.INFO, "Calculating thresholds");
+ Thresholds.reset();
+ Thresholds.population = getPopulation();
+ this.methods.stream().forEach(Method::calculateThresholds);
- private Double StdDevShareability;
+ logger.log(Level.INFO, "Average ExecutionTime: {0}", Thresholds.getAverageExecutionTime());
+ logger.log(Level.INFO, "Average HitRatio: {0}", Thresholds.getAverageHitRatio());
+ logger.log(Level.INFO, "Average MissRatio: {0}", Thresholds.getAverageMissRatio());
+ logger.log(Level.INFO, "Average shareability: {0}", Thresholds.getAverageShareability());
+ logger.log(Level.INFO, "StdDv ExecutionTime: {0}", Thresholds.getStdDevExecutionTimeRatio());
+ logger.log(Level.INFO, "StdDv HitRatio: {0}", Thresholds.getStdDevHitRatio());
+ logger.log(Level.INFO, "StdDv MissRatio: {0}", Thresholds.getStdDevMissRatio());
+ logger.log(Level.INFO, "StdDv shareability: {0}", Thresholds.getStdDevShareability());
+ logger.log(Level.INFO, "StdDv frequency: {0}", Thresholds.getStdDevFrequency());
- public double getStdDevShareability() {
- if (population == 0) {
- return 0;
- }
- if (StdDevShareability != null) {
- return StdDevShareability;
- }
-
- double mean = getAverageShareability();
- double temp = shareabilities.stream()
- .map((shareability) -> (shareability - mean) * (shareability - mean))
- .reduce(Double::sum).get();
- StdDevShareability = Math.sqrt(temp / population);
- return StdDevShareability;
- }
-
- public HashMap<MethodInfo, MethodStats> getMethodsInfoMap() {
- return methodsInfoMap;
- }
-
- //getting X% with most hits
- public double hitThreshold(int kStdDev) {
- return getAverageHitRatio() + (kStdDev * getStdDevHitRatio());
- }
-
- //getting X% with most misses
- public double missThreshold(int kStdDev) {
- return getAverageMissRatio() + (kStdDev * getStdDevMissRatio());
- }
-
- //getting X% most expensive methods
- public double expensivenessThreshold(int kStdDev) {
- return getAverageExecutionTime() + (kStdDev * getStdDevExecutionTimeRatio());
- }
-
- public double shareabilityThreshold(int kStdDev) {
- return getAverageShareability() + (kStdDev * getStdDevShareability());
- }
-
- //getting X% most frenquent
- public double frequencyThreshold(int kStdDev) {
- return getAverageFrequency() + (kStdDev * getStdDevFrequency());
- }
-
- /**
- * General miss ratio from a signature
- *
- * @param signature
- * @return
- */
- public double getMissRatio(String signature) {
- long occurrences = 0;
- long methods = 0;
- for (MethodInfo mi : methodsInfoMap.keySet()) {
- if (mi.getSignature().equals(signature)) {
- occurrences += methodsInfoMap.get(mi).getNumberOfSameOccurrences();
- methods++;
+ int k = 0;
+ logger.log(Level.INFO, "Using {0} stdDev to calculate thresholds...", k);
+ logger.log(Level.INFO, "Threshold ExecutionTime: {0}", Thresholds.expensivenessThreshold(k));
+ logger.log(Level.INFO, "Threshold HitRatio: {0}", Thresholds.hitThreshold(k));
+ logger.log(Level.INFO, "Threshold MissRatio: {0}", Thresholds.missThreshold(k));
+ logger.log(Level.INFO, "Threshold Shareability: {0}", Thresholds.shareabilityThreshold(k));
+ logger.log(Level.INFO, "Threshold frequency: {0}", Thresholds.frequencyThreshold(k));
+ }
+
+ public void filterCacheableInputs() {
+ countStats();
+ calculateThresholds();
+
+ logger.log(Level.INFO, "Deciding if methods are cacheable...");
+
+ Iterator<Method> iterator = this.methods.iterator();
+ while (iterator.hasNext()) {
+ Method method = iterator.next();
+ method.filterCacheableInputs();
+ if (method.getGroupsOfOccurrences().isEmpty()) {
+ iterator.remove();
}
}
- return occurrences / methods;
- }
- /**
- * General hit ratio from a signature
- *
- * @param signature
- * @return
- */
- public double getHitRatio(String signature) {
- long occurrences = 0;
- long methods = 0;
- for (MethodInfo mi : methodsInfoMap.keySet()) {
- if (mi.getSignature().equals(signature)) {
- occurrences += methodsInfoMap.get(mi).getNumberOfSameOccurrences();
- methods++;
- }
- }
- return occurrences / methods;
+ logger.log(Level.INFO, "{0} cacheable methods detected", this.methods.size());
}
- private Double AverageFrequency;
-
- public double getAverageFrequency() {
- if (frequencies.isEmpty()) {
- return 0;
- }
- if (AverageFrequency != null) {
- return AverageFrequency;
- }
-
- AverageFrequency = new BigDecimal(sumFrequency).divide(new BigDecimal(frequencies.size()), 5, RoundingMode.HALF_UP).doubleValue();
- return AverageFrequency;
+ private long getPopulation() {
+ return this.methods.stream().parallel()
+ .map(Method::getOccurrencesSize)
+ .reduce(Integer::sum)
+ .get();
}
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/CacheabilityMetrics.java b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/CacheabilityMetrics.java
index c90f88b..47822bf 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/CacheabilityMetrics.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/CacheabilityMetrics.java
@@ -1,124 +1,57 @@
package br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.stats;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.FlowchartWorkFlow;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.model.MethodStats;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.MethodInfo;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.GroupOfOccurrences;
import java.util.Optional;
public class CacheabilityMetrics {
- //total da população
- public static long sampleSize(long N, double Z, double e) {
- //Nível de confiança 90% -> Z=1.645
- //Nível de confiança 95% -> Z=1.96
- //Nível de confiança 99% -> Z=2.575
- //Qual o nível de certeza que precisa ter de que a amostra retrata com precisão a sua população?
- //double Z = 2.575;
-
- //e = É a margem de erro máximo que eu quero admitir (p.e. 5%)
- //Qual o nível de certeza que precisa ter de que os traces refletem as execuções da sua aplicação?
- //double e = 0.03;
- //p = É a proporção que esperamos encontrar. Este parâmetro tende confundir bastante à primeira vista:
- double p = 0.5;
-
- long n = (long) ((N * Math.pow(Z, 2) * p * (1 - p))
- / ((N - 1) * Math.pow(e, 2) + Math.pow(Z, 2) * p * (1 - p)));
-
- //simplified without the population
- //int nn = (int) ((Math.pow(Z,2) * p * (1-p)) / Math.pow(e,2));
- return n;
- }
-
- public static Optional<Boolean> isStaticData(MethodStats methodStats, FlowchartWorkFlow workflow, int population) {
-
- //executions of a method should represent a good portion of total logs in order to avoid 1 occur == 100% hit
-// if (!(methodStats.getNumberOfSameOccurrences() >= sampleSize(methodStats.getNumberOfOccurrences(), 1.645, 0.05)
-// && methodStats.getNumberOfOccurrences() >= sampleSize(population, 1.645, 0.05))) {
-// return Optional.empty();
-// }
- if (methodStats.getNumberOfSameOccurrences() < workflow.frequencyThreshold(0)) {
+ public static Optional<Boolean> isStaticData(GroupOfOccurrences groupOfOccurrences) {
+ if (groupOfOccurrences.getStats().getNumberOfSameOccurrences() < Thresholds.frequencyThreshold(0)) {
return Optional.empty();
}
- if (methodStats.hitRatio() == 100.0) {
+ if (groupOfOccurrences.getStats().getHitRatio() == 100.0) {
return Optional.of(true);
} else {
return Optional.of(false);
}
}
- public static Optional<Boolean> changeMoreThanUsed(MethodStats methodStats, FlowchartWorkFlow workflow) {
+ public static Optional<Boolean> changeMoreThanUsed(GroupOfOccurrences groupOfOccurrences) {
//+/- k sds
- if (methodStats.missRatio() > workflow.missThreshold(0)) {
+ if (groupOfOccurrences.getStats().getMissRatio() > Thresholds.missThreshold(0)) {
return Optional.of(true);
} else {
return Optional.of(false);
}
}
- public static Optional<Boolean> usedByManyRequests(MethodStats methodStats, FlowchartWorkFlow workflow, int population) {
-
- //same executions of a method should represent a good portion of total execution of such method
- if (methodStats.getNumberOfSameOccurrences() >= workflow.frequencyThreshold(0)) {
-// if (methodStats.getNumberOfOccurrences() >= sampleSize(population, 1.645, 0.05)) {
+ public static Optional<Boolean> usedByManyRequests(GroupOfOccurrences groupOfOccurrences) {
+ if (groupOfOccurrences.getStats().getNumberOfSameOccurrences() >= Thresholds.frequencyThreshold(0)) {
return Optional.of(true);
} else {
return Optional.of(false);
}
}
- public static Optional<Boolean> isUserSpecific(MethodStats methodStats, FlowchartWorkFlow workflow) {
-
- if (methodStats.getAmountOfIdentifiedSameOccurences() == 0) {
+ public static Optional<Boolean> isUserSpecific(GroupOfOccurrences groupOfOccurrences) {
+ if (groupOfOccurrences.getStats().getAmountOfIdentifiedSameOccurences() == 0) {
return Optional.empty();
}
//the less shareable, the more user specific
- if (methodStats.shareability() < workflow.shareabilityThreshold(0)) {
+ if (groupOfOccurrences.getStats().getShareability() < Thresholds.shareabilityThreshold(0)) {
return Optional.of(true);
} else {
return Optional.of(false);
}
}
- public static Optional<Boolean> isDataSizeLarge(MethodInfo methodInfo) {
-
- //TODO concept considered while caching
- if (true) {
- return Optional.of(false);
- }
-
- long shallowSize = methodInfo.getSizeOfReturnedValue(); // modified to interface
-
- BigDecimal bd = new BigDecimal(shallowSize)
- .multiply(new BigDecimal(100))
- .divide(new BigDecimal(Long.MAX_VALUE), 5, RoundingMode.HALF_UP); //cache free space replaced to infinity
- double dataSizePercent = bd.doubleValue();
-
- if (dataSizePercent <= 2.0) {
- return Optional.of(false);
- } else {
- return Optional.of(true);
- }
- }
-
- public static Optional<Boolean> isExpensive(MethodStats methodStats, FlowchartWorkFlow workflow) {
- if (methodStats.getSameOccurrencesAverageExecutionTime() >= workflow.expensivenessThreshold(0)) {
+ public static Optional<Boolean> isExpensive(GroupOfOccurrences groupOfOccurrences) {
+ if (groupOfOccurrences.getStats().getSameOccurrencesAverageExecutionTime() >= Thresholds.expensivenessThreshold(0)) {
return Optional.of(true);
} else {
return Optional.of(false);
}
}
- public static String allMetricsToString(MethodInfo methodInfo, MethodStats methodStats, FlowchartWorkFlow workflow, int population) {
- //isStaticData,changeMoreThanUsed,usedByManyRequests,isUserSpecific,isCacheSizeLarge,isDataSizeLarge,isExpensive
- return isStaticData(methodStats, workflow, population)
- + "," + changeMoreThanUsed(methodStats, workflow)
- + "," + usedByManyRequests(methodStats, workflow, population)
- + "," + isUserSpecific(methodStats, workflow)
- + "," + isDataSizeLarge(methodInfo)
- + "," + isExpensive(methodStats, workflow);
- }
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/CacheabilityPatternDecider.java b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/CacheabilityPatternDecider.java
index ff9644f..5d5c2a5 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/CacheabilityPatternDecider.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/CacheabilityPatternDecider.java
@@ -1,93 +1,38 @@
package br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.stats;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.CacheDecider;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.FlowchartWorkFlow;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.model.MethodStats;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.MethodInfo;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.GroupOfOccurrences;
import java.util.Optional;
-/**
- * TODO flowchart paper link
- *
- * @see
- */
-public class CacheabilityPatternDecider implements CacheDecider {
-
- private final int population;
- Logger logger = LoggerFactory.getLogger(CacheabilityPatternDecider.class);
-
- FlowchartWorkFlow workflow;
-
- public CacheabilityPatternDecider(int size, FlowchartWorkFlow workflow) {
- this.workflow = workflow;
- this.population = size;
- }
+public class CacheabilityPatternDecider {
/**
* Flowchart definition
*
- * @param methodStats
+ * @param groupOfOccurrences
* @return
*/
- @Override
- public boolean isCacheable(MethodInfo methodInfo, MethodStats methodStats) {
-
- //used more than once, in many parts of the reasoning
- Optional<Boolean> isCacheSizeLarge = Optional.of(true); // the cache is always large enough
-
+ public static boolean isCacheable(GroupOfOccurrences groupOfOccurrences) {
//Is the data completely static?
- Optional<Boolean> isStaticData = CacheabilityMetrics.isStaticData(methodStats, workflow, population);
+ Optional<Boolean> isStaticData = CacheabilityMetrics.isStaticData(groupOfOccurrences);
if (isStaticData.isPresent() && isStaticData.get()) { // staticity yes
-
- Optional<Boolean> isDataSizeLarge = CacheabilityMetrics.isDataSizeLarge(methodInfo);
- if (isDataSizeLarge.isPresent() && !isDataSizeLarge.get()) {
- return true;
- } else {
- if (isCacheSizeLarge.isPresent() && isCacheSizeLarge.get()) {
- return true;
- } else {
- return false;
- }
- }
- } else { // staticity no/not sure
-
- Optional<Boolean> changeMoreThanUsed = CacheabilityMetrics.changeMoreThanUsed(methodStats, workflow);
- if (changeMoreThanUsed.isPresent() && changeMoreThanUsed.get()) { //changeMoreThanUsed true
- return false;
- } else { //changeMoreThanUsed not/not sure
- Optional<Boolean> usedByManyRequests = CacheabilityMetrics.usedByManyRequests(methodStats, workflow, population);
- if (usedByManyRequests.isPresent() && !usedByManyRequests.get()) { //useByManyRequests no
- return false;
- } else {
- Optional<Boolean> isUserSpecific = CacheabilityMetrics.isUserSpecific(methodStats, workflow);
- if (isUserSpecific.isPresent() && isUserSpecific.get()) {
- if (isCacheSizeLarge.isPresent() && isCacheSizeLarge.get()) {
- return true;
- } else {
- return false;
- }
- } else {
- Optional<Boolean> isExpensive = CacheabilityMetrics.isExpensive(methodStats, workflow);
- if (!isExpensive.isPresent()) {
-
- if (isCacheSizeLarge.isPresent() && isCacheSizeLarge.get()) {
- return true;
- } else {
- return false;
- }
- } else {
- if (isExpensive.get()) {
- return true;
- } else {
- return false;
- }
- }
- }
- }
- }
+ return true;
+ }
+ // staticity no/not sure
+ Optional<Boolean> changeMoreThanUsed = CacheabilityMetrics.changeMoreThanUsed(groupOfOccurrences);
+ if (changeMoreThanUsed.isPresent() && changeMoreThanUsed.get()) { //changeMoreThanUsed true
+ return false;
+ }
+ //changeMoreThanUsed not/not sure
+ Optional<Boolean> usedByManyRequests = CacheabilityMetrics.usedByManyRequests(groupOfOccurrences);
+ if (usedByManyRequests.isPresent() && !usedByManyRequests.get()) { //useByManyRequests no
+ return false;
+ }
+ Optional<Boolean> isUserSpecific = CacheabilityMetrics.isUserSpecific(groupOfOccurrences);
+ if (isUserSpecific.isPresent() && isUserSpecific.get()) {
+ return true;
}
+ Optional<Boolean> isExpensive = CacheabilityMetrics.isExpensive(groupOfOccurrences);
+ return isExpensive.isPresent() ? isExpensive.get() : true;
}
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/Thresholds.java b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/Thresholds.java
new file mode 100644
index 0000000..d53bfe4
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/analysis/decision/flowchart/stats/Thresholds.java
@@ -0,0 +1,217 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.stats;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author romulo
+ */
+public class Thresholds {
+
+ public static double sumMissRatio;
+ public static double sumHitRatio;
+ public static double sumExecutionTime;
+ public static double sumShareability;
+ public static double sumFrequency;
+
+ public static Double averageFrequency;
+
+ public static Double stdDevHitRatio;
+ public static Double stdDevMissRatio;
+ public static Double stdDevExecutionTimeRatio;
+ public static Double stdDevFrequency;
+ public static Double stdDevShareability;
+
+ public static long population;
+
+ public static final List<Double> hitRatios = new ArrayList<>();
+ public static final List<Double> missRatios = new ArrayList<>();
+ public static final List<Long> executionTimes = new ArrayList<>();
+ public static final List<Double> shareabilities = new ArrayList<>();
+ public static final List<Long> frequencies = new ArrayList<>();
+
+ public static void reset() {
+ Thresholds.sumMissRatio = 0;
+ Thresholds.sumHitRatio = 0;
+ Thresholds.sumExecutionTime = 0;
+ Thresholds.sumShareability = 0;
+ Thresholds.sumFrequency = 0;
+
+ Thresholds.averageFrequency = 0D;
+
+ Thresholds.stdDevHitRatio = 0D;
+ Thresholds.stdDevMissRatio = 0D;
+ Thresholds.stdDevExecutionTimeRatio = 0D;
+ Thresholds.stdDevFrequency = 0D;
+ Thresholds.stdDevShareability = 0D;
+
+ Thresholds.population = 0;
+
+ Thresholds.hitRatios.clear();
+ Thresholds.missRatios.clear();
+ Thresholds.executionTimes.clear();
+ Thresholds.shareabilities.clear();
+ Thresholds.frequencies.clear();
+ }
+
+ /**
+ * General mean hit ratio of all calls
+ *
+ * @return
+ */
+ public static double getAverageHitRatio() {
+ if (population == 0) {
+ return 0;
+ }
+ return new BigDecimal(sumHitRatio).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
+ }
+
+ public static double getAverageMissRatio() {
+ if (population == 0) {
+ return 0;
+ }
+ return new BigDecimal(sumMissRatio).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
+ }
+
+ public static double getAverageExecutionTime() {
+ if (population == 0) {
+ return 0;
+ }
+ return new BigDecimal(sumExecutionTime).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
+ }
+
+ public static double getAverageShareability() {
+ if (population == 0) {
+ return 0;
+ }
+ return new BigDecimal(sumShareability).divide(new BigDecimal(population), 5, RoundingMode.HALF_UP).doubleValue();
+ }
+
+ public static double getStdDevHitRatio() {
+ if (population == 0) {
+ return 0;
+ }
+ if (stdDevHitRatio != null) {
+ return stdDevHitRatio;
+ }
+
+ double mean = getAverageHitRatio();
+ double temp = hitRatios.stream().parallel()
+ .map(hitRate -> (hitRate - mean) * (hitRate - mean))
+ .reduce(Double::sum)
+ .get();
+ stdDevHitRatio = Math.sqrt(temp / population);
+ return stdDevHitRatio;
+ }
+
+ public static double getStdDevMissRatio() {
+ if (population == 0) {
+ return 0;
+ }
+ if (stdDevMissRatio != null) {
+ return stdDevMissRatio;
+ }
+
+ double mean = getAverageMissRatio();
+ double temp = 0;
+ for (double a : missRatios) {
+ temp += (a - mean) * (a - mean);
+ }
+ stdDevMissRatio = Math.sqrt(temp / population);
+ return stdDevMissRatio;
+ }
+
+ public static double getStdDevExecutionTimeRatio() {
+ if (population == 0) {
+ return 0;
+ }
+ if (stdDevExecutionTimeRatio != null) {
+ return stdDevExecutionTimeRatio;
+ }
+
+ double mean = getAverageExecutionTime();
+ double temp = executionTimes.stream()
+ .map(executionTime -> (executionTime - mean) * (executionTime - mean))
+ .reduce(Double::sum).get();
+ stdDevExecutionTimeRatio = Math.sqrt(temp / population);
+ return stdDevExecutionTimeRatio;
+ }
+
+ public static double getStdDevFrequency() {
+ if (population == 0) {
+ return 0;
+ }
+ if (stdDevFrequency != null) {
+ return stdDevFrequency;
+ }
+
+ double mean = getAverageFrequency();
+ double temp = frequencies.stream()
+ .map(frequency -> (frequency - mean) * (frequency - mean))
+ .reduce(Double::sum).get();
+ stdDevFrequency = Math.sqrt(temp / population);
+ return stdDevFrequency;
+ }
+
+ public static double getStdDevShareability() {
+ if (population == 0) {
+ return 0;
+ }
+ if (stdDevShareability != null) {
+ return stdDevShareability;
+ }
+
+ double mean = getAverageShareability();
+ double temp = shareabilities.stream()
+ .map(shareability -> (shareability - mean) * (shareability - mean))
+ .reduce(Double::sum)
+ .get();
+ stdDevShareability = Math.sqrt(temp / population);
+ return stdDevShareability;
+ }
+
+ public static double getAverageFrequency() {
+ if (frequencies.isEmpty()) {
+ return 0;
+ }
+ if (averageFrequency != null) {
+ return averageFrequency;
+ }
+
+ averageFrequency = new BigDecimal(sumFrequency).divide(new BigDecimal(frequencies.size()), 5, RoundingMode.HALF_UP).doubleValue();
+ return averageFrequency;
+ }
+
+//getting X% with most hits
+ public static double hitThreshold(int kStdDev) {
+ return getAverageHitRatio() + (kStdDev * getStdDevHitRatio());
+ }
+
+//getting X% with most misses
+ public static double missThreshold(int kStdDev) {
+ return getAverageMissRatio() + (kStdDev * getStdDevMissRatio());
+ }
+
+//getting X% most expensive methods
+ public static double expensivenessThreshold(int kStdDev) {
+ return getAverageExecutionTime() + (kStdDev * getStdDevExecutionTimeRatio());
+ }
+
+ public static double shareabilityThreshold(int kStdDev) {
+ return getAverageShareability() + (kStdDev * getStdDevShareability());
+ }
+
+//getting X% most frenquent
+ public static double frequencyThreshold(int kStdDev) {
+ return getAverageFrequency() + (kStdDev * getStdDevFrequency());
+ }
+
+}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/GroupOfOccurrences.java b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/GroupOfOccurrences.java
new file mode 100644
index 0000000..8682038
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/GroupOfOccurrences.java
@@ -0,0 +1,73 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata;
+
+import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.stats.Stats;
+import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.stats.Thresholds;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+
+/**
+ *
+ * @author romulo
+ */
+public class GroupOfOccurrences {
+
+ private final Stats stats;
+ private final List<Occurrence> occurrences;
+
+ public GroupOfOccurrences() {
+ this.stats = new Stats();
+ this.occurrences = new ArrayList<>();
+ }
+
+ public Stats getStats() {
+ return stats;
+ }
+
+ public void addOccurrence(Occurrence occurrence) {
+ this.occurrences.add(occurrence);
+ }
+
+ protected void countStats() {
+ if (this.occurrences.size() == 1) {
+ this.stats.addSameOccurrence(this.occurrences.get(0));
+ return;
+ }
+ for (int i = 0; i < this.occurrences.size(); i++) {
+ Occurrence occurrence = this.occurrences.get(i);
+// load concrete
+ for (int j = i + 1; j < this.occurrences.size(); j++) {
+ Occurrence other = this.occurrences.get(j);
+ if (EqualsBuilder.reflectionEquals(occurrence.getReturnValue(), other.getReturnValue())) {
+ this.stats.addSameOccurrence(occurrence);
+ continue;
+ }
+ this.stats.addDifferentReturnOccurrence();
+ }
+// remove
+ }
+ }
+
+ protected void calculateThresholds() {
+ Thresholds.sumExecutionTime += this.stats.getSameOccurrencesTotalExecutionTime();
+ Thresholds.executionTimes.add(this.stats.getSameOccurrencesTotalExecutionTime());
+
+ Thresholds.sumHitRatio += this.stats.getHitRatio();
+ Thresholds.hitRatios.add(this.stats.getHitRatio());
+
+ Thresholds.sumMissRatio += this.stats.getMissRatio();
+ Thresholds.missRatios.add(this.stats.getMissRatio());
+
+ Thresholds.sumShareability += this.stats.getShareability();
+ Thresholds.shareabilities.add(this.stats.getShareability());
+
+ Thresholds.sumFrequency += this.stats.getNumberOfSameOccurrences();
+ Thresholds.frequencies.add(this.stats.getNumberOfSameOccurrences());
+ }
+
+}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/Method.java b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/Method.java
new file mode 100644
index 0000000..e6fe5cb
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/Method.java
@@ -0,0 +1,103 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata;
+
+import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.stats.CacheabilityPatternDecider;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author romulo
+ */
+public class Method {
+
+ private static final Logger logger = Logger.getLogger(Method.class.getName());
+
+ private final String name;
+ private final List<Occurrence> occurrences;
+ private Collection<GroupOfOccurrences> groupsOfOccurrences;
+
+ public Method(String name) {
+ this.name = name;
+ this.occurrences = new ArrayList<>();
+ }
+
+ public Method addOccurrence(Occurrence occurrence) {
+ this.occurrences.add(occurrence);
+ return this;
+ }
+
+ public Method clearTraces() {
+ this.occurrences.clear();
+ return this;
+ }
+
+ public int getOccurrencesSize() {
+ return this.occurrences.size();
+ }
+
+ public Collection<GroupOfOccurrences> getGroupsOfOccurrences() {
+ return groupsOfOccurrences;
+ }
+
+ public void groupByParameter() {
+ logger.log(Level.INFO, "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>() {
+ int i = 0;
+
+ @Override
+ public void accept(Occurrence occurrence) {
+ System.out.print(".");
+ System.out.flush();
+ if (++i % 100 == 0) {
+ System.out.println();
+ }
+ String parameters = Arrays.toString(occurrence.getParameters());
+ synchronized (groupByParameter) {
+ try {
+ groupByParameter.get(parameters).addOccurrence(occurrence);
+ } catch (Exception e) {
+ GroupOfOccurrences groupOfOccurrences = new GroupOfOccurrences();
+ groupOfOccurrences.addOccurrence(occurrence);
+ groupByParameter.put(parameters, groupOfOccurrences);
+ }
+ }
+ }
+ });
+ this.groupsOfOccurrences = groupByParameter.values();
+ groupByParameter.clear();
+ this.occurrences.clear();
+ }
+
+ public void countStats() {
+ groupByParameter();
+ this.groupsOfOccurrences.stream().parallel().forEach(GroupOfOccurrences::countStats);
+ }
+
+ public void calculateThresholds() {
+ this.groupsOfOccurrences.stream().forEach(GroupOfOccurrences::calculateThresholds);
+ }
+
+ public void filterCacheableInputs() {
+ Iterator<GroupOfOccurrences> iterator = this.groupsOfOccurrences.iterator();
+ while (iterator.hasNext()) {
+ GroupOfOccurrences groupOfOccurrences = iterator.next();
+ if (!CacheabilityPatternDecider.isCacheable(groupOfOccurrences)) {
+ iterator.remove();
+ }
+ }
+ }
+}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/OccurrenceConcrete.java b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/OccurrenceConcrete.java
new file mode 100644
index 0000000..086d319
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/adaptivecaching/monitoring/application/metadata/OccurrenceConcrete.java
@@ -0,0 +1,32 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata;
+
+/**
+ *
+ * @author romulo
+ */
+public class OccurrenceConcrete extends Occurrence {
+
+ private final Object[] parameters;
+ private final Object returnValue;
+
+ public OccurrenceConcrete(Object[] arguments, Object returnedValue, long startTime, long endTime, String userId) {
+ super(startTime, endTime, userId);
+ this.parameters = arguments;
+ this.returnValue = returnedValue;
+ }
+
+ @Override
+ public Object[] getParameters() {
+ return this.parameters;
+ }
+
+ @Override
+ public Object getReturnValue() {
+ return this.returnValue;
+ }
+}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/Main.java b/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/Main.java
index fff69c4..8d9e7d9 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/Main.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/Main.java
@@ -6,11 +6,10 @@
package br.ufrgs.inf.prosoft.approachescomparison.adapter;
import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.FlowchartWorkFlow;
-import br.ufrgs.inf.prosoft.adaptivecaching.analysis.decision.flowchart.model.MethodEntry;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.LogTrace;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.Method;
import br.ufrgs.inf.prosoft.trace.Trace;
+import java.util.Collection;
import java.util.List;
-import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -34,9 +33,11 @@ public class Main {
}
logger.log(Level.INFO, "Reading traces");
List<Trace> traces = TraceReader.partiallyParseFile(path);
- List<LogTrace> logList = TraceReader.getLogTraces(traces);
- FlowchartWorkFlow flowchartWorkFlow = new FlowchartWorkFlow(logList);
- Set<MethodEntry> process = flowchartWorkFlow.filterCacheableMethods(300000); // default value provided by the framework
- logger.log(Level.INFO, "{0} cacheable methods identified", process.size());
+ logger.log(Level.INFO, "Grouping by methods");
+ Collection<Method> methods = TraceReader.groupByMethods(traces);
+ FlowchartWorkFlow flowchartWorkFlow = new FlowchartWorkFlow();
+ flowchartWorkFlow.setMethods(methods);
+ logger.log(Level.INFO, "Filtering cacheable methods");
+ flowchartWorkFlow.filterCacheableInputs();
}
}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/TraceReader.java b/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/TraceReader.java
index 6ad3e04..4a018cd 100644
--- a/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/TraceReader.java
+++ b/src/main/java/br/ufrgs/inf/prosoft/approachescomparison/adapter/TraceReader.java
@@ -5,14 +5,17 @@
*/
package br.ufrgs.inf.prosoft.approachescomparison.adapter;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.LogTrace;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.MethodInfoConcrete;
-import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.MethodInfoReference;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.Occurrence;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.OccurrenceConcrete;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.OccurrenceReference;
+import br.ufrgs.inf.prosoft.adaptivecaching.monitoring.application.metadata.Method;
import br.ufrgs.inf.prosoft.trace.Parameter;
import br.ufrgs.inf.prosoft.trace.Trace;
import br.ufrgs.inf.prosoft.trace.TraceReference;
-import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -21,39 +24,42 @@ import java.util.stream.Collectors;
*
* @author romulo
*/
-public class TraceReader extends br.ufrgs.inf.prosoft.trace.TraceReader {
+public class TraceReader extends br.ufrgs.inf.prosoft.trace.reader.TraceReader {
private static final Logger logger = Logger.getLogger(TraceReader.class.getName());
- public static List<LogTrace> getLogTraces(List<Trace> traces) {
- logger.log(Level.INFO, "Converting {0} traces", traces.size());
- List<LogTrace> logTraces = new ArrayList<>();
- int index = 1;
+ public static Collection<Method> groupByMethods(List<Trace> traces) {
+ Map<String, Method> methodNameHasOccurrences = new HashMap<>();
while (!traces.isEmpty()) {
Trace trace = traces.remove(0);
try {
- System.out.print(".");
- System.out.flush();
- if (index++ % 100 == 0) {
- System.out.println();
- }
- LogTrace logTrace = new LogTrace().setStartTime(trace.getStartTime())
- .setEndTime(trace.getEndTime())
- .setUserId(trace.getUserSession());
+ Occurrence occurrence;
if (trace instanceof TraceReference) {
TraceReference traceReference = (TraceReference) trace;
- logTrace.setMethodInfo(new MethodInfoReference(traceReference.getName(), traceReference.getIndex()));
+ occurrence = new OccurrenceReference(traceReference.getIndex(),
+ trace.getStartTime(), trace.getEndTime(), trace.getUserSession());
} else {
- logTrace.setMethodInfo(new MethodInfoConcrete(trace.getName(),
- trace.getParameters().stream().map(Parameter::getData)
+ occurrence = new OccurrenceConcrete(
+ trace.getParameters().stream()
+ .map(Parameter::getData)
.collect(Collectors.toList()).toArray(),
- trace.getReturn().getData()));
+ trace.getReturn().getData(),
+ trace.getStartTime(),
+ trace.getEndTime(),
+ trace.getUserSession()
+ );
+ }
+ try {
+ methodNameHasOccurrences.get(trace.getName()).addOccurrence(occurrence);
+ } catch (Exception ex) {
+ Method method = new Method(trace.getName());
+ method.addOccurrence(occurrence);
+ methodNameHasOccurrences.put(trace.getName(), method);
}
- logTraces.add(logTrace);
} catch (Exception e) {
logger.log(Level.INFO, "Trace discarted: {0}", trace);
}
}
- return logTraces;
+ return methodNameHasOccurrences.values();
}
}