summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorRyan Campbell <ryanjcampbell@google.com>2017-10-05 09:12:38 -0700
committerRyan Campbell <ryanjcampbell@google.com>2017-10-05 09:23:14 -0700
commitcd4a171020fa1aec39528cb76b1c065c135d7819 (patch)
tree28b4db19e7fb1abe395b0a83ce836676a9255f61 /src/main
parentaec86eb7e80a44e6d6dad56d082aa581feb385e8 (diff)
downloaddashboard-cd4a171020fa1aec39528cb76b1c065c135d7819.tar.gz
Migrate tabular perf summaries to stat entities.
Move the tabular performance summaries (digest emails and the performance digest dashboard UI) to the stat summary entities instead of querying the data live. Test: staging Bug: 67413850 Change-Id: I7703a1e40918e5dfa5524309fd20416a462b9f05
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/android/vts/job/VtsPerformanceJobServlet.java50
-rw-r--r--src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java96
-rw-r--r--src/main/java/com/android/vts/util/PerformanceSummary.java86
-rw-r--r--src/main/java/com/android/vts/util/PerformanceUtil.java223
-rw-r--r--src/main/java/com/android/vts/util/ProfilingPointSummary.java95
-rw-r--r--src/main/java/com/android/vts/util/StatSummary.java14
6 files changed, 274 insertions, 290 deletions
diff --git a/src/main/java/com/android/vts/job/VtsPerformanceJobServlet.java b/src/main/java/com/android/vts/job/VtsPerformanceJobServlet.java
index 79a6aad..964c688 100644
--- a/src/main/java/com/android/vts/job/VtsPerformanceJobServlet.java
+++ b/src/main/java/com/android/vts/job/VtsPerformanceJobServlet.java
@@ -20,11 +20,9 @@ import com.android.vts.entity.TestEntity;
import com.android.vts.util.EmailHelper;
import com.android.vts.util.PerformanceSummary;
import com.android.vts.util.PerformanceUtil;
-import com.android.vts.util.PerformanceUtil.TimeInterval;
import com.android.vts.util.ProfilingPointSummary;
import com.android.vts.util.StatSummary;
import com.android.vts.util.TaskQueueHelper;
-import com.android.vts.util.TimeUtil;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
@@ -233,41 +231,43 @@ public class VtsPerformanceJobServlet extends HttpServlet {
return;
}
- List<TimeInterval> timeIntervals = new ArrayList<>();
long nowMicro = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
- String dateString = TimeUtil.getDateString(nowMicro);
- TimeInterval today =
- new TimeInterval(nowMicro - TimeUnit.DAYS.toMicros(1), nowMicro, dateString);
- timeIntervals.add(today);
+
+ // Add today to the list of time intervals to analyze
+ List<PerformanceSummary> summaries = new ArrayList<>();
+ PerformanceSummary today =
+ new PerformanceSummary(nowMicro - TimeUnit.DAYS.toMicros(1), nowMicro);
+ summaries.add(today);
// Add yesterday as a baseline time interval for analysis
long oneDayAgo = nowMicro - TimeUnit.DAYS.toMicros(1);
- String dateStringYesterday = TimeUtil.getDateString(oneDayAgo);
- TimeInterval yesterday =
- new TimeInterval(
- oneDayAgo - TimeUnit.DAYS.toMicros(1), oneDayAgo, dateStringYesterday);
- timeIntervals.add(yesterday);
+ PerformanceSummary yesterday =
+ new PerformanceSummary(oneDayAgo - TimeUnit.DAYS.toMicros(1), oneDayAgo);
+ summaries.add(yesterday);
// Add last week as a baseline time interval for analysis
long oneWeek = TimeUnit.DAYS.toMicros(7);
long oneWeekAgo = nowMicro - oneWeek;
- TimeInterval lastWeek = new TimeInterval(oneWeekAgo - oneWeek, oneWeekAgo, LAST_WEEK);
- timeIntervals.add(lastWeek);
- List<PerformanceSummary> perfSummaries = new ArrayList<>();
+ String spanString = "<span class='date-label'>";
+ String label =
+ spanString + TimeUnit.MICROSECONDS.toMillis(oneWeekAgo - oneWeek) + "</span>";
+ label += " - " + spanString + TimeUnit.MICROSECONDS.toMillis(oneWeekAgo) + "</span>";
+ PerformanceSummary lastWeek =
+ new PerformanceSummary(oneWeekAgo - oneWeek, oneWeekAgo, label);
+ summaries.add(lastWeek);
+ PerformanceUtil.updatePerformanceSummary(
+ testKey.getName(), oneWeekAgo - oneWeek, nowMicro, null, summaries);
+
+ List<PerformanceSummary> nonEmptySummaries = new ArrayList<>();
List<String> labels = new ArrayList<>();
labels.add("");
- for (TimeInterval interval : timeIntervals) {
- PerformanceSummary perfSummary = new PerformanceSummary();
- PerformanceUtil.updatePerformanceSummary(
- testKey.getName(), interval.start, interval.end, null, perfSummary);
- if (perfSummary.size() == 0) {
- continue;
- }
- perfSummaries.add(perfSummary);
- labels.add(interval.label);
+ for (PerformanceSummary perfSummary : summaries) {
+ if (perfSummary.size() == 0) continue;
+ nonEmptySummaries.add(perfSummary);
+ labels.add(perfSummary.label);
}
- String body = getPerformanceSummary(testKey.getName(), perfSummaries, labels);
+ String body = getPerformanceSummary(testKey.getName(), nonEmptySummaries, labels);
if (body == null || body.equals("")) {
return;
}
diff --git a/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java b/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java
index 44afbfa..856a28c 100644
--- a/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java
+++ b/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java
@@ -19,17 +19,13 @@ package com.android.vts.servlet;
import com.android.vts.util.DatastoreHelper;
import com.android.vts.util.PerformanceSummary;
import com.android.vts.util.PerformanceUtil;
-import com.android.vts.util.PerformanceUtil.TimeInterval;
import com.android.vts.util.ProfilingPointSummary;
import com.android.vts.util.StatSummary;
import java.io.IOException;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import javax.servlet.RequestDispatcher;
@@ -40,10 +36,6 @@ import javax.servlet.http.HttpServletResponse;
/** Servlet for producing tabular performance summaries. */
public class ShowPerformanceDigestServlet extends BaseServlet {
private static final String PERF_DIGEST_JSP = "WEB-INF/jsp/show_performance_digest.jsp";
- private static final String HIDL_HAL_OPTION = "hidl_hal_mode";
- private static final String[] splitKeysArray = new String[] {HIDL_HAL_OPTION};
- private static final Set<String> splitKeySet =
- new HashSet<String>(Arrays.asList(splitKeysArray));
private static final String MEAN = "Mean";
private static final String MIN = "Min";
@@ -57,9 +49,7 @@ public class ShowPerformanceDigestServlet extends BaseServlet {
private static final DecimalFormat FORMATTER;
- /**
- * Initialize the decimal formatter.
- */
+ /** Initialize the decimal formatter. */
static {
FORMATTER = new DecimalFormat("#.##");
FORMATTER.setRoundingMode(RoundingMode.HALF_UP);
@@ -81,14 +71,11 @@ public class ShowPerformanceDigestServlet extends BaseServlet {
/**
* Generates an HTML summary of the performance changes for the profiling results in the
- * specified
- * table.
+ * specified table.
*
* <p>Retrieves the past 24 hours of profiling data and compares it to the 24 hours that
- * preceded
- * it. Creates a table representation of the mean and standard deviation for each profiling
- * point.
- * When performance degrades, the cell is shaded red.
+ * preceded it. Creates a table representation of the mean and standard deviation for each
+ * profiling point. When performance degrades, the cell is shaded red.
*
* @param profilingPoint The name of the profiling point to summarize.
* @param testSummary The ProfilingPointSummary object to compare against.
@@ -98,8 +85,10 @@ public class ShowPerformanceDigestServlet extends BaseServlet {
* @returns An HTML string for a table comparing the profiling point results across time
* intervals.
*/
- public static String getPeformanceSummary(String profilingPoint,
- ProfilingPointSummary testSummary, List<PerformanceSummary> perfSummaries,
+ public static String getPerformanceSummary(
+ String profilingPoint,
+ ProfilingPointSummary testSummary,
+ List<PerformanceSummary> perfSummaries,
String sectionLabels) {
String tableHTML = "<table>";
@@ -149,10 +138,13 @@ public class ShowPerformanceDigestServlet extends BaseServlet {
tableHTML += FORMATTER.format(stats.getStd()) + "</td>";
for (PerformanceSummary prevPerformance : perfSummaries) {
if (prevPerformance.hasProfilingPoint(profilingPoint)) {
- StatSummary baseline = prevPerformance.getProfilingPointSummary(profilingPoint)
- .getStatSummary(label);
- tableHTML += PerformanceUtil.getAvgCasePerformanceComparisonHTML(
- baseline, stats, "cell inner-cell", "cell outer-cell", "", "");
+ StatSummary baseline =
+ prevPerformance
+ .getProfilingPointSummary(profilingPoint)
+ .getStatSummary(label);
+ tableHTML +=
+ PerformanceUtil.getAvgCasePerformanceComparisonHTML(
+ baseline, stats, "cell inner-cell", "cell outer-cell", "", "");
} else {
tableHTML += "<td></td><td></td><td></td><td></td>";
}
@@ -183,14 +175,16 @@ public class ShowPerformanceDigestServlet extends BaseServlet {
}
// Add today to the list of time intervals to analyze
- List<TimeInterval> timeIntervals = new ArrayList<>();
- TimeInterval today = new TimeInterval(startTime - TimeUnit.DAYS.toMicros(1), startTime);
- timeIntervals.add(today);
+ List<PerformanceSummary> summaries = new ArrayList<>();
+ PerformanceSummary today =
+ new PerformanceSummary(startTime - TimeUnit.DAYS.toMicros(1), startTime);
+ summaries.add(today);
// Add yesterday as a baseline time interval for analysis
long oneDayAgo = startTime - TimeUnit.DAYS.toMicros(1);
- TimeInterval yesterday = new TimeInterval(oneDayAgo - TimeUnit.DAYS.toMicros(1), oneDayAgo);
- timeIntervals.add(yesterday);
+ PerformanceSummary yesterday =
+ new PerformanceSummary(oneDayAgo - TimeUnit.DAYS.toMicros(1), oneDayAgo);
+ summaries.add(yesterday);
// Add last week as a baseline time interval for analysis
long oneWeek = TimeUnit.DAYS.toMicros(7);
@@ -199,42 +193,42 @@ public class ShowPerformanceDigestServlet extends BaseServlet {
String label =
spanString + TimeUnit.MICROSECONDS.toMillis(oneWeekAgo - oneWeek) + "</span>";
label += " - " + spanString + TimeUnit.MICROSECONDS.toMillis(oneWeekAgo) + "</span>";
- TimeInterval lastWeek = new TimeInterval(oneWeekAgo - oneWeek, oneWeekAgo, label);
- timeIntervals.add(lastWeek);
-
- List<PerformanceSummary> perfSummaries = new ArrayList<>();
+ PerformanceSummary lastWeek =
+ new PerformanceSummary(oneWeekAgo - oneWeek, oneWeekAgo, label);
+ summaries.add(lastWeek);
+ PerformanceUtil.updatePerformanceSummary(
+ testName, oneWeekAgo - oneWeek, startTime, selectedDevice, summaries);
+ int colCount = 0;
String sectionLabels = "";
- int i = 0;
- for (TimeInterval interval : timeIntervals) {
- PerformanceSummary perfSummary = new PerformanceSummary(splitKeySet);
- PerformanceUtil.updatePerformanceSummary(
- testName, interval.start, interval.end, selectedDevice, perfSummary);
- if (perfSummary.size() == 0) {
- continue;
- }
- perfSummaries.add(perfSummary);
- String content = interval.label;
+ List<PerformanceSummary> nonEmptySummaries = new ArrayList<>();
+ for (PerformanceSummary perfSummary : summaries) {
+ if (perfSummary.size() == 0) continue;
+
+ nonEmptySummaries.add(perfSummary);
+ String content = perfSummary.label;
sectionLabels += "<th class='section-label grey lighten-2 center' ";
- if (i++ == 0)
- sectionLabels += "colspan='3'";
- else
- sectionLabels += "colspan='4'";
+ if (colCount++ == 0) sectionLabels += "colspan='3'";
+ else sectionLabels += "colspan='4'";
sectionLabels += ">" + content + "</th>";
}
List<String> tables = new ArrayList<>();
List<String> tableTitles = new ArrayList<>();
List<String> tableSubtitles = new ArrayList<>();
- if (perfSummaries.size() != 0) {
- PerformanceSummary todayPerformance = perfSummaries.remove(0);
+ if (nonEmptySummaries.size() != 0) {
+ PerformanceSummary todayPerformance = nonEmptySummaries.remove(0);
String[] profilingNames = todayPerformance.getProfilingPointNames();
for (String profilingPointName : profilingNames) {
ProfilingPointSummary baselinePerformance =
todayPerformance.getProfilingPointSummary(profilingPointName);
- String table = getPeformanceSummary(
- profilingPointName, baselinePerformance, perfSummaries, sectionLabels);
+ String table =
+ getPerformanceSummary(
+ profilingPointName,
+ baselinePerformance,
+ nonEmptySummaries,
+ sectionLabels);
if (table != null) {
tables.add(table);
tableTitles.add(profilingPointName);
@@ -256,7 +250,7 @@ public class ShowPerformanceDigestServlet extends BaseServlet {
request.setAttribute("tableSubtitles", tableSubtitles);
request.setAttribute("startTime", Long.toString(startTime));
request.setAttribute("selectedDevice", selectedDevice);
- request.setAttribute("devices", DatastoreHelper.getAllProducts());
+ request.setAttribute("devices", DatastoreHelper.getAllBuildFlavors());
dispatcher = request.getRequestDispatcher(PERF_DIGEST_JSP);
try {
diff --git a/src/main/java/com/android/vts/util/PerformanceSummary.java b/src/main/java/com/android/vts/util/PerformanceSummary.java
index 05ed0b7..28e6975 100644
--- a/src/main/java/com/android/vts/util/PerformanceSummary.java
+++ b/src/main/java/com/android/vts/util/PerformanceSummary.java
@@ -13,39 +13,50 @@
*/
package com.android.vts.util;
-import com.android.vts.entity.ProfilingPointRunEntity;
-import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
+import com.android.vts.entity.ProfilingPointEntity;
+import com.android.vts.entity.ProfilingPointSummaryEntity;
import com.google.appengine.api.datastore.Entity;
import java.util.Arrays;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
+import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
/** PerformanceSummary, an object summarizing performance across profiling points for a test run. */
public class PerformanceSummary {
protected static Logger logger = Logger.getLogger(PerformanceSummary.class.getName());
private Map<String, ProfilingPointSummary> summaryMap;
- private Set<String> optionSplitKeys;
+
+ public final long startTime;
+ public final long endTime;
+ public final String label;
/** Creates a performance summary object. */
- public PerformanceSummary() {
+ public PerformanceSummary(long startTime, long endTime, String label) {
this.summaryMap = new HashMap<>();
- this.optionSplitKeys = new HashSet<>();
+ this.startTime = startTime;
+ this.endTime = endTime;
+ this.label = label;
+ }
+
+ /** Creates a performance summary object. */
+ public PerformanceSummary(long startTime, long endTime) {
+ this(
+ startTime,
+ endTime,
+ "<span class='date-label'>"
+ + Long.toString(TimeUnit.MICROSECONDS.toMillis(endTime))
+ + "</span>");
}
/**
- * Creates a performance summary object with the specified device name filter. If the specified
- * name is null, then use no filter.
+ * Determine if the performance summary contains the provided time.
*
- * @param optionSplitKeys A set of option keys to split on (i.e. profiling data with different
- * values corresponding to the option key will be analyzed as different profiling points).
+ * @param time The time (unix timestamp, microseconds) to check.
+ * @return True if the time is within the performance summary window, false otherwise.
*/
- public PerformanceSummary(Set<String> optionSplitKeys) {
- this();
- this.optionSplitKeys = optionSplitKeys;
+ public boolean contains(long time) {
+ return time >= startTime && time <= endTime;
}
/**
@@ -53,36 +64,37 @@ public class PerformanceSummary {
*
* @param profilingRun The Entity object whose data to add.
*/
- public void addData(Entity profilingRun) {
- ProfilingPointRunEntity pt = ProfilingPointRunEntity.fromEntity(profilingRun);
- if (pt == null)
- return;
- if (pt.regressionMode == VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DISABLED) {
- return;
- }
-
- String name = pt.name;
- String optionSuffix = PerformanceUtil.getOptionAlias(pt, optionSplitKeys);
+ public void addData(ProfilingPointEntity profilingPoint, Entity profilingRun) {
+ ProfilingPointSummaryEntity ppSummary =
+ ProfilingPointSummaryEntity.fromEntity(profilingRun);
+ if (ppSummary == null) return;
- if (pt.labels != null) {
- if (pt.labels.size() != pt.values.size()) {
- logger.log(Level.WARNING, "Labels and values are different sizes.");
- return;
- }
- if (!optionSuffix.equals("")) {
- name += " (" + optionSuffix + ")";
+ String name = profilingPoint.profilingPointName;
+ if (ppSummary.labels != null && ppSummary.labels.size() > 0) {
+ if (!ppSummary.series.equals("")) {
+ name += " (" + ppSummary.series + ")";
}
if (!summaryMap.containsKey(name)) {
- summaryMap.put(name, new ProfilingPointSummary());
+ summaryMap.put(
+ name,
+ new ProfilingPointSummary(
+ profilingPoint.xLabel,
+ profilingPoint.yLabel,
+ profilingPoint.regressionMode));
}
- summaryMap.get(name).update(pt);
+ summaryMap.get(name).update(ppSummary);
} else {
// Use the option suffix as the table name.
// Group all profiling points together into one table
- if (!summaryMap.containsKey(optionSuffix)) {
- summaryMap.put(optionSuffix, new ProfilingPointSummary());
+ if (!summaryMap.containsKey(ppSummary.series)) {
+ summaryMap.put(
+ ppSummary.series,
+ new ProfilingPointSummary(
+ profilingPoint.xLabel,
+ profilingPoint.yLabel,
+ profilingPoint.regressionMode));
}
- summaryMap.get(optionSuffix).updateLabel(pt, pt.name);
+ summaryMap.get(ppSummary.series).updateLabel(ppSummary, name);
}
}
diff --git a/src/main/java/com/android/vts/util/PerformanceUtil.java b/src/main/java/com/android/vts/util/PerformanceUtil.java
index f32f2ac..36acee7 100644
--- a/src/main/java/com/android/vts/util/PerformanceUtil.java
+++ b/src/main/java/com/android/vts/util/PerformanceUtil.java
@@ -13,25 +13,19 @@
*/
package com.android.vts.util;
-import com.android.vts.entity.DeviceInfoEntity;
+import com.android.vts.entity.ProfilingPointEntity;
import com.android.vts.entity.ProfilingPointRunEntity;
-import com.android.vts.entity.TestEntity;
-import com.android.vts.entity.TestRunEntity;
+import com.android.vts.entity.ProfilingPointSummaryEntity;
import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
-import com.google.appengine.api.datastore.Key;
-import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
-import com.google.appengine.api.datastore.Query.Filter;
-import com.google.appengine.api.datastore.Query.FilterOperator;
-import com.google.appengine.api.datastore.Query.FilterPredicate;
import java.io.IOException;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -54,27 +48,6 @@ public class PerformanceUtil {
FORMATTER.setRoundingMode(RoundingMode.HALF_UP);
}
- public static class TimeInterval {
- public final long start;
- public final long end;
- public final String label;
-
- public TimeInterval(long start, long end, String label) {
- this.start = start;
- this.end = end;
- this.label = label;
- }
-
- public TimeInterval(long start, long end) {
- this(
- start,
- end,
- "<span class='date-label'>"
- + Long.toString(TimeUnit.MICROSECONDS.toMillis(end))
- + "</span>");
- }
- }
-
/**
* Creates the HTML for a table cell representing the percent change between two numbers.
*
@@ -159,6 +132,94 @@ public class PerformanceUtil {
}
/**
+ * Updates a PerformanceSummary object with data in the specified window.
+ *
+ * @param testName The name of the table whose profiling vectors to retrieve.
+ * @param startTime The (inclusive) start time in microseconds to scan from.
+ * @param endTime The (inclusive) end time in microseconds at which to stop scanning.
+ * @param selectedDevice The name of the device whose data to query for, or null for unfiltered.
+ * @param summaries The list of PerformanceSummary objects to populate with data.
+ * @throws IOException
+ */
+ public static void updatePerformanceSummary(
+ String testName,
+ long startTime,
+ long endTime,
+ String selectedDevice,
+ List<PerformanceSummary> summaries) {
+ DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
+ Query profilingPointQuery =
+ new Query(ProfilingPointEntity.KIND)
+ .setFilter(
+ new Query.FilterPredicate(
+ ProfilingPointEntity.TEST_NAME,
+ Query.FilterOperator.EQUAL,
+ testName));
+
+ List<ProfilingPointEntity> profilingPoints = new ArrayList<>();
+ for (Entity e :
+ datastore
+ .prepare(profilingPointQuery)
+ .asIterable(DatastoreHelper.getLargeBatchOptions())) {
+ ProfilingPointEntity pp = ProfilingPointEntity.fromEntity(e);
+ if (pp == null) continue;
+ profilingPoints.add(pp);
+ }
+
+ Query.Filter startFilter =
+ new Query.FilterPredicate(
+ ProfilingPointSummaryEntity.START_TIME,
+ Query.FilterOperator.GREATER_THAN_OR_EQUAL,
+ startTime);
+ Query.Filter endFilter =
+ new Query.FilterPredicate(
+ ProfilingPointSummaryEntity.START_TIME,
+ Query.FilterOperator.LESS_THAN_OR_EQUAL,
+ endTime);
+ Query.Filter timeFilter = Query.CompositeFilterOperator.and(startFilter, endFilter);
+
+ Query.Filter deviceFilter;
+ if (selectedDevice != null) {
+ deviceFilter = FilterUtil.FilterKey.TARGET.getFilterForString(selectedDevice);
+ } else {
+ deviceFilter =
+ FilterUtil.FilterKey.TARGET.getFilterForString(ProfilingPointSummaryEntity.ALL);
+ }
+ deviceFilter =
+ Query.CompositeFilterOperator.and(
+ deviceFilter,
+ FilterUtil.FilterKey.BRANCH.getFilterForString(
+ ProfilingPointSummaryEntity.ALL));
+ Query.Filter filter = Query.CompositeFilterOperator.and(timeFilter, deviceFilter);
+
+ Map<ProfilingPointEntity, Iterable<Entity>> asyncEntities = new HashMap<>();
+ for (ProfilingPointEntity pp : profilingPoints) {
+ Query profilingQuery =
+ new Query(ProfilingPointSummaryEntity.KIND)
+ .setAncestor(pp.key)
+ .setFilter(filter);
+ asyncEntities.put(
+ pp,
+ datastore
+ .prepare(profilingQuery)
+ .asIterable(DatastoreHelper.getLargeBatchOptions()));
+ }
+
+ for (ProfilingPointEntity pp : asyncEntities.keySet()) {
+ for (Entity ppSummaryEntity : asyncEntities.get(pp)) {
+ ProfilingPointSummaryEntity ppSummary =
+ ProfilingPointSummaryEntity.fromEntity(ppSummaryEntity);
+ if (ppSummary == null) continue;
+ for (PerformanceSummary perfSummary : summaries) {
+ if (perfSummary.contains(ppSummary.startTime)) {
+ perfSummary.addData(pp, ppSummaryEntity);
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Compares a test StatSummary to a baseline StatSummary using average-case performance.
*
* @param baseline The StatSummary object containing initial values to compare against
@@ -200,108 +261,6 @@ public class PerformanceUtil {
}
/**
- * Updates a PerformanceSummary object with data in the specified window.
- *
- * @param testName The name of the table whose profiling vectors to retrieve.
- * @param startTime The (inclusive) start time in microseconds to scan from.
- * @param endTime The (inclusive) end time in microseconds at which to stop scanning.
- * @param selectedDevice The name of the device whose data to query for, or null for unfiltered.
- * @param perfSummary The PerformanceSummary object to update with data.
- * @throws IOException
- */
- public static void updatePerformanceSummary(
- String testName,
- long startTime,
- long endTime,
- String selectedDevice,
- PerformanceSummary perfSummary)
- throws IOException {
- DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
- Key testKey = KeyFactory.createKey(TestEntity.KIND, testName);
- Filter testTypeFilter = FilterUtil.getTestTypeFilter(false, true, false);
- Filter runFilter =
- FilterUtil.getTimeFilter(
- testKey, TestRunEntity.KIND, startTime, endTime, testTypeFilter);
-
- Query testRunQuery =
- new Query(TestRunEntity.KIND)
- .setAncestor(testKey)
- .setFilter(runFilter)
- .setKeysOnly();
-
- Set<Key> testRunKeys = new HashSet<>();
- for (Entity e :
- datastore
- .prepare(testRunQuery)
- .asIterable(DatastoreHelper.getLargeBatchOptions())) {
- testRunKeys.add(e.getKey());
- }
-
- if (selectedDevice != null) {
- Filter deviceFilter =
- FilterUtil.getDeviceTimeFilter(testKey, TestRunEntity.KIND, startTime, endTime);
- deviceFilter =
- Query.CompositeFilterOperator.and(
- deviceFilter,
- new FilterPredicate(
- DeviceInfoEntity.PRODUCT,
- FilterOperator.EQUAL,
- selectedDevice));
- Query deviceQuery =
- new Query(DeviceInfoEntity.KIND)
- .setAncestor(testKey)
- .setFilter(deviceFilter)
- .setKeysOnly();
- Set<Key> matchingTestRunKeys = new HashSet<>();
- for (Entity e :
- datastore
- .prepare(deviceQuery)
- .asIterable(DatastoreHelper.getLargeBatchOptions())) {
- if (testRunKeys.contains(e.getKey().getParent())) {
- matchingTestRunKeys.add(e.getKey().getParent());
- }
- }
- testRunKeys = matchingTestRunKeys;
- }
-
- Filter profilingFilter =
- FilterUtil.getProfilingTimeFilter(testKey, TestRunEntity.KIND, startTime, endTime);
- Query profilingQuery =
- new Query(ProfilingPointRunEntity.KIND)
- .setAncestor(testKey)
- .setFilter(profilingFilter)
- .setKeysOnly();
-
- List<Key> profilingKeys = new ArrayList<>();
- for (Entity e :
- datastore
- .prepare(profilingQuery)
- .asIterable(DatastoreHelper.getLargeBatchOptions())) {
- if (testRunKeys.contains(e.getKey().getParent())) {
- profilingKeys.add(e.getKey());
- }
- }
-
- List<Key> gets = new ArrayList<>();
- for (Key key : profilingKeys) {
- gets.add(key);
- if (gets.size() == MAX_BATCH_SIZE) {
- Map<Key, Entity> profilingPoints = datastore.get(gets);
- for (Key key2 : profilingPoints.keySet()) {
- perfSummary.addData(profilingPoints.get(key2));
- }
- gets = new ArrayList<>();
- }
- }
- if (gets.size() > 0) {
- Map<Key, Entity> profilingPoints = datastore.get(gets);
- for (Key key2 : profilingPoints.keySet()) {
- perfSummary.addData(profilingPoints.get(key2));
- }
- }
- }
-
- /**
* Generates a string of the values in optionsList which have matches in the profiling entity.
*
* @param profilingRun The entity for a profiling point run.
diff --git a/src/main/java/com/android/vts/util/ProfilingPointSummary.java b/src/main/java/com/android/vts/util/ProfilingPointSummary.java
index 8e0e24a..e842b4a 100644
--- a/src/main/java/com/android/vts/util/ProfilingPointSummary.java
+++ b/src/main/java/com/android/vts/util/ProfilingPointSummary.java
@@ -16,7 +16,7 @@
package com.android.vts.util;
-import com.android.vts.entity.ProfilingPointRunEntity;
+import com.android.vts.entity.ProfilingPointSummaryEntity;
import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
import java.util.ArrayList;
import java.util.HashMap;
@@ -34,10 +34,14 @@ public class ProfilingPointSummary implements Iterable<StatSummary> {
public String yLabel;
/** Initializes the summary with empty arrays. */
- public ProfilingPointSummary() {
+ public ProfilingPointSummary(
+ String xLabel, String yLabel, VtsProfilingRegressionMode regressionMode) {
statSummaries = new ArrayList<>();
labelIndices = new HashMap<>();
labels = new ArrayList<>();
+ this.regressionMode = regressionMode;
+ this.xLabel = xLabel;
+ this.yLabel = yLabel;
}
/**
@@ -57,8 +61,7 @@ public class ProfilingPointSummary implements Iterable<StatSummary> {
* @return The StatSummary object if it exists, or null otherwise.
*/
public StatSummary getStatSummary(String label) {
- if (!hasLabel(label))
- return null;
+ if (!hasLabel(label)) return null;
return statSummaries.get(labelIndices.get(label));
}
@@ -74,49 +77,50 @@ public class ProfilingPointSummary implements Iterable<StatSummary> {
/**
* Updates the profiling summary with the data from a new profiling report.
*
- * @param profilingRun The profiling point run entity object containing profiling data.
+ * @param ppSummary The profiling point run entity object containing profiling data.
*/
- public void update(ProfilingPointRunEntity profilingRun) {
- for (int i = 0; i < profilingRun.labels.size(); i++) {
- String label = profilingRun.labels.get(i);
+ public void update(ProfilingPointSummaryEntity ppSummary) {
+ for (String label : ppSummary.labels) {
+ if (!ppSummary.labelStats.containsKey(label)) continue;
if (!labelIndices.containsKey(label)) {
- StatSummary summary = new StatSummary(label, profilingRun.regressionMode);
labelIndices.put(label, statSummaries.size());
- statSummaries.add(summary);
+ labels.add(label);
+ statSummaries.add(ppSummary.labelStats.get(label));
+ } else {
+ StatSummary summary = getStatSummary(label);
+ summary.merge(ppSummary.labelStats.get(label));
}
- StatSummary summary = getStatSummary(label);
- summary.updateStats(profilingRun.values.get(i));
}
- this.regressionMode = profilingRun.regressionMode;
- this.labels = profilingRun.labels;
- this.xLabel = profilingRun.xLabel;
- this.yLabel = profilingRun.yLabel;
}
/**
* Updates the profiling summary at a label with the data from a new profiling report.
*
- * Updates the summary specified by the label with all values provided in the report. If
+ * <p>Updates the summary specified by the label with all values provided in the report. If
* labels are provided in the report, they will be ignored -- all values are updated only to the
* provided label.
*
- * @param profilingEntity The ProfilingPointRunEntity object containing profiling data.
+ * @param ppSummary The ProfilingPointSummaryEntity object containing profiling data.
* @param label The String label for which all values in the report will be updated.
*/
- public void updateLabel(ProfilingPointRunEntity profilingEntity, String label) {
+ public void updateLabel(ProfilingPointSummaryEntity ppSummary, String label) {
if (!labelIndices.containsKey(label)) {
- StatSummary summary = new StatSummary(label, profilingEntity.regressionMode);
labelIndices.put(label, labels.size());
labels.add(label);
- statSummaries.add(summary);
- }
- StatSummary summary = getStatSummary(label);
- for (long value : profilingEntity.values) {
- summary.updateStats(value);
+ StatSummary stat =
+ new StatSummary(
+ label,
+ ppSummary.globalStats.getMin(),
+ ppSummary.globalStats.getMax(),
+ ppSummary.globalStats.getMean(),
+ ppSummary.globalStats.getSumSq(),
+ ppSummary.globalStats.getCount(),
+ ppSummary.globalStats.getRegressionMode());
+ statSummaries.add(stat);
+ } else {
+ StatSummary summary = getStatSummary(label);
+ summary.merge(ppSummary.globalStats);
}
- this.regressionMode = profilingEntity.regressionMode;
- this.xLabel = profilingEntity.xLabel;
- this.yLabel = profilingEntity.yLabel;
}
/**
@@ -125,26 +129,27 @@ public class ProfilingPointSummary implements Iterable<StatSummary> {
*/
@Override
public Iterator<StatSummary> iterator() {
- Iterator<StatSummary> it = new Iterator<StatSummary>() {
- private int currentIndex = 0;
+ Iterator<StatSummary> it =
+ new Iterator<StatSummary>() {
+ private int currentIndex = 0;
- @Override
- public boolean hasNext() {
- return labels != null && currentIndex < labels.size();
- }
+ @Override
+ public boolean hasNext() {
+ return labels != null && currentIndex < labels.size();
+ }
- @Override
- public StatSummary next() {
- String label = labels.get(currentIndex++);
- return statSummaries.get(labelIndices.get(label));
- }
+ @Override
+ public StatSummary next() {
+ String label = labels.get(currentIndex++);
+ return statSummaries.get(labelIndices.get(label));
+ }
- @Override
- public void remove() {
- // Not supported
- throw new UnsupportedOperationException();
- }
- };
+ @Override
+ public void remove() {
+ // Not supported
+ throw new UnsupportedOperationException();
+ }
+ };
return it;
}
}
diff --git a/src/main/java/com/android/vts/util/StatSummary.java b/src/main/java/com/android/vts/util/StatSummary.java
index d3afe31..3b4713c 100644
--- a/src/main/java/com/android/vts/util/StatSummary.java
+++ b/src/main/java/com/android/vts/util/StatSummary.java
@@ -86,6 +86,20 @@ public class StatSummary {
}
/**
+ * Combine the mean and variance with another StatSummary.
+ *
+ * @param stat The StatSummary to combine with.
+ */
+ public void merge(StatSummary stat) {
+ double delta = stat.getMean() - mean;
+ int newN = n + stat.getCount();
+ sumSq = sumSq + stat.getSumSq() + delta / newN * delta * n * stat.getCount();
+ double recipN = 1.0 / newN;
+ mean = n * recipN * mean + stat.getCount() * recipN * stat.getMean();
+ n = newN;
+ }
+
+ /**
* Gets the best case of the stream.
*
* @return The min or max.