1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you
5  * may not use this file except in compliance with the License. You may
6  * obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13  * implied. See the License for the specific language governing
14  * permissions and limitations under the License.
15  */
16 
17 package com.android.vts.util;
18 
19 import com.android.vts.entity.ProfilingPointSummaryEntity;
20 import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26 
27 /** Represents statistical summaries of each profiling point. */
28 public class ProfilingPointSummary implements Iterable<StatSummary> {
29     private List<StatSummary> statSummaries;
30     private Map<String, Integer> labelIndices;
31     private List<String> labels;
32     private VtsProfilingRegressionMode regressionMode;
33     public String xLabel;
34     public String yLabel;
35 
36     /** Initializes the summary with empty arrays. */
ProfilingPointSummary( String xLabel, String yLabel, VtsProfilingRegressionMode regressionMode)37     public ProfilingPointSummary(
38             String xLabel, String yLabel, VtsProfilingRegressionMode regressionMode) {
39         statSummaries = new ArrayList<>();
40         labelIndices = new HashMap<>();
41         labels = new ArrayList<>();
42         this.regressionMode = regressionMode;
43         this.xLabel = xLabel;
44         this.yLabel = yLabel;
45     }
46 
47     /**
48      * Determines if a data label is present in the profiling point.
49      *
50      * @param label The name of the label.
51      * @return true if the label is present, false otherwise.
52      */
hasLabel(String label)53     public boolean hasLabel(String label) {
54         return labelIndices.containsKey(label);
55     }
56 
57     /**
58      * Gets the statistical summary for a specified data label.
59      *
60      * @param label The name of the label.
61      * @return The StatSummary object if it exists, or null otherwise.
62      */
getStatSummary(String label)63     public StatSummary getStatSummary(String label) {
64         if (!hasLabel(label)) return null;
65         return statSummaries.get(labelIndices.get(label));
66     }
67 
68     /**
69      * Gets the last-seen regression mode.
70      *
71      * @return The VtsProfilingRegressionMode value.
72      */
getRegressionMode()73     public VtsProfilingRegressionMode getRegressionMode() {
74         return regressionMode;
75     }
76 
77     /**
78      * Updates the profiling summary with the data from a new profiling report.
79      *
80      * @param ppSummary The profiling point run entity object containing profiling data.
81      */
update(ProfilingPointSummaryEntity ppSummary)82     public void update(ProfilingPointSummaryEntity ppSummary) {
83         for (String label : ppSummary.getLabels()) {
84             if (!ppSummary.getLabelStats().containsKey(label)) continue;
85             if (!labelIndices.containsKey(label)) {
86                 labelIndices.put(label, statSummaries.size());
87                 labels.add(label);
88                 statSummaries.add(ppSummary.getLabelStats().get(label));
89             } else {
90                 StatSummary summary = getStatSummary(label);
91                 summary.merge(ppSummary.getLabelStats().get(label));
92             }
93         }
94     }
95 
96     /**
97      * Updates the profiling summary at a label with the data from a new profiling report.
98      *
99      * <p>Updates the summary specified by the label with all values provided in the report. If
100      * labels are provided in the report, they will be ignored -- all values are updated only to the
101      * provided label.
102      *
103      * @param ppSummary The ProfilingPointSummaryEntity object containing profiling data.
104      * @param label The String label for which all values in the report will be updated.
105      */
updateLabel(ProfilingPointSummaryEntity ppSummary, String label)106     public void updateLabel(ProfilingPointSummaryEntity ppSummary, String label) {
107         if (!labelIndices.containsKey(label)) {
108             labelIndices.put(label, labels.size());
109             labels.add(label);
110             StatSummary stat =
111                     new StatSummary(
112                             label,
113                             ppSummary.getGlobalStats().getMin(),
114                             ppSummary.getGlobalStats().getMax(),
115                             ppSummary.getGlobalStats().getMean(),
116                             ppSummary.getGlobalStats().getSumSq(),
117                             ppSummary.getGlobalStats().getCount(),
118                             ppSummary.getGlobalStats().getRegressionMode());
119             statSummaries.add(stat);
120         } else {
121             StatSummary summary = getStatSummary(label);
122             summary.merge(ppSummary.getGlobalStats());
123         }
124     }
125 
126     /**
127      * Gets an iterator that returns stat summaries in the ordered the labels were specified in the
128      * ProfilingReportMessage objects.
129      */
130     @Override
iterator()131     public Iterator<StatSummary> iterator() {
132         Iterator<StatSummary> it =
133                 new Iterator<StatSummary>() {
134                     private int currentIndex = 0;
135 
136                     @Override
137                     public boolean hasNext() {
138                         return labels != null && currentIndex < labels.size();
139                     }
140 
141                     @Override
142                     public StatSummary next() {
143                         String label = labels.get(currentIndex++);
144                         return statSummaries.get(labelIndices.get(label));
145                     }
146 
147                     @Override
148                     public void remove() {
149                         // Not supported
150                         throw new UnsupportedOperationException();
151                     }
152                 };
153         return it;
154     }
155 }
156