analysis: Move plugins to their own sub-directory
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / statistics / TmfStateStatistics.java
CommitLineData
200789b3 1/*******************************************************************************
60ae41e1 2 * Copyright (c) 2012, 2014 Ericsson
200789b3
AM
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Alexandre Montplaisir - Initial API and implementation
63fe91fb 11 * Patrick Tasse - Fix TimeRangeException
200789b3
AM
12 ******************************************************************************/
13
2bdf0193 14package org.eclipse.tracecompass.tmf.core.statistics;
200789b3 15
200789b3 16import java.util.HashMap;
f3f93fa6 17import java.util.LinkedList;
200789b3
AM
18import java.util.List;
19import java.util.Map;
20
8192f2c6 21import org.eclipse.jdt.annotation.NonNull;
e894a508
AM
22import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
23import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
24import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
25import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
200789b3
AM
26
27/**
1c0de632 28 * Implementation of ITmfStatistics which uses a state history for storing its
802017fe
AM
29 * information. In reality, it uses two state histories, one for "event totals"
30 * information (which should ideally use a fast backend), and another one for
31 * the rest (per event type, per CPU, etc.).
1c0de632 32 *
802017fe
AM
33 * Compared to the event-request-based statistics calculations, it adds the
34 * building the history first, but gives much faster response times once built :
35 * Queries are O(log n) wrt the size of the trace, and O(1) wrt to the size of
36 * the time interval selected.
200789b3
AM
37 *
38 * @author Alexandre Montplaisir
200789b3 39 */
1c0de632 40public class TmfStateStatistics implements ITmfStatistics {
200789b3 41
802017fe
AM
42 // ------------------------------------------------------------------------
43 // Fields
44 // ------------------------------------------------------------------------
200789b3 45
802017fe
AM
46 /** The event totals state system */
47 private final ITmfStateSystem totalsStats;
48
49 /** The state system for event types */
50 private final ITmfStateSystem typesStats;
51
52 // ------------------------------------------------------------------------
53 // Constructors
54 // ------------------------------------------------------------------------
200789b3
AM
55
56 /**
57 * Constructor
58 *
8192f2c6
AM
59 * @param totals
60 * The state system containing the "totals" information
61 * @param eventTypes
62 * The state system containing the "event types" information
200789b3 63 */
d6b46913 64 public TmfStateStatistics(@NonNull ITmfStateSystem totals, @NonNull ITmfStateSystem eventTypes) {
8192f2c6
AM
65 this.totalsStats = totals;
66 this.typesStats = eventTypes;
802017fe
AM
67 }
68
6c5e0863 69 /**
8192f2c6
AM
70 * Return the state system containing the "totals" values
71 *
72 * @return The "totals" state system
8192f2c6
AM
73 */
74 public ITmfStateSystem getTotalsSS() {
75 return totalsStats;
76 }
77
78 /**
79 * Return the state system containing the "event types" values
80 *
81 * @return The "event types" state system
6c5e0863 82 */
8192f2c6
AM
83 public ITmfStateSystem getEventTypesSS() {
84 return typesStats;
e1c43333
AM
85 }
86
200789b3 87 // ------------------------------------------------------------------------
1c0de632 88 // ITmfStatistics
200789b3
AM
89 // ------------------------------------------------------------------------
90
1a4205d9
AM
91 @Override
92 public void dispose() {
802017fe
AM
93 totalsStats.dispose();
94 typesStats.dispose();
1a4205d9
AM
95 }
96
f3f93fa6
AM
97 @Override
98 public List<Long> histogramQuery(final long start, final long end, final int nb) {
a4524c1b 99 final List<Long> list = new LinkedList<>();
f3f93fa6
AM
100 final long increment = (end - start) / nb;
101
2002c638 102 if (totalsStats.isCancelled()) {
802017fe 103 return list;
f3f93fa6
AM
104 }
105
106 /*
107 * We will do one state system query per "border", and save the
108 * differences between each border.
109 */
802017fe 110 long prevTotal = (start == totalsStats.getStartTime()) ? 0 : getEventCountAt(start);
f3f93fa6
AM
111 long curTime = start + increment;
112
113 long curTotal, count;
114 for (int i = 0; i < nb - 1; i++) {
115 curTotal = getEventCountAt(curTime);
116 count = curTotal - prevTotal;
117 list.add(count);
118
119 curTime += increment;
120 prevTotal = curTotal;
121 }
122
123 /*
124 * For the last bucket, we'll stretch its end time to the end time of
125 * the requested range, in case it got truncated down.
126 */
127 curTotal = getEventCountAt(end);
128 count = curTotal - prevTotal;
129 list.add(count);
1c0de632 130
f3f93fa6 131 return list;
1c0de632
AM
132 }
133
200789b3
AM
134 @Override
135 public long getEventsTotal() {
802017fe 136 long endTime = totalsStats.getCurrentEndTime();
e1c43333 137 int count = 0;
df310609
AM
138
139 try {
802017fe
AM
140 final int quark = totalsStats.getQuarkAbsolute(Attributes.TOTAL);
141 count= totalsStats.querySingleState(endTime, quark).getStateValue().unboxInt();
1c0de632 142
f0c73a6f 143 } catch (StateSystemDisposedException e) {
1c0de632
AM
144 /* Assume there is no events for that range */
145 return 0;
f0c73a6f 146 } catch (AttributeNotFoundException e) {
96345c5a 147 e.printStackTrace();
200789b3 148 }
df310609 149
e1c43333 150 return count;
200789b3
AM
151 }
152
153 @Override
154 public Map<String, Long> getEventTypesTotal() {
55954069 155 final Map<String, Long> map = new HashMap<>();
802017fe 156 long endTime = typesStats.getCurrentEndTime();
200789b3
AM
157
158 try {
159 /* Get the list of quarks, one for each even type in the database */
802017fe
AM
160 int quark = typesStats.getQuarkAbsolute(Attributes.EVENT_TYPES);
161 List<Integer> quarks = typesStats.getSubAttributes(quark, false);
200789b3
AM
162
163 /* Since we want the total we can look only at the end */
802017fe 164 List<ITmfStateInterval> endState = typesStats.queryFullState(endTime);
200789b3
AM
165
166 String curEventName;
167 long eventCount;
168 for (int typeQuark : quarks) {
802017fe 169 curEventName = typesStats.getAttributeName(typeQuark);
200789b3
AM
170 eventCount = endState.get(typeQuark).getStateValue().unboxInt();
171 map.put(curEventName, eventCount);
172 }
173
f0c73a6f 174 } catch (StateSystemDisposedException e) {
1c0de632 175 /* Assume there is no events, nothing will be put in the map. */
f0c73a6f 176 } catch (AttributeNotFoundException e) {
96345c5a 177 e.printStackTrace();
200789b3
AM
178 }
179 return map;
180 }
181
182 @Override
8b260d9f 183 public long getEventsInRange(long start, long end) {
f3f93fa6 184 long startCount;
802017fe 185 if (start == totalsStats.getStartTime()) {
f3f93fa6
AM
186 startCount = 0;
187 } else {
188 /*
189 * We want the events happening at "start" to be included, so we'll
190 * need to query one unit before that point.
191 */
192 startCount = getEventCountAt(start - 1);
200789b3 193 }
f3f93fa6 194 long endCount = getEventCountAt(end);
df310609 195
f3f93fa6 196 return endCount - startCount;
200789b3
AM
197 }
198
199 @Override
8b260d9f 200 public Map<String, Long> getEventTypesInRange(long start, long end) {
55954069
AM
201 final Map<String, Long> map = new HashMap<>();
202 List<Integer> quarks;
200789b3
AM
203
204 /* Make sure the start/end times are within the state history, so we
205 * don't get TimeRange exceptions.
206 */
63fe91fb
PT
207 long startTime = checkStartTime(start, typesStats);
208 long endTime = checkEndTime(end, typesStats);
f0c73a6f
PT
209 if (endTime < startTime) {
210 /* The start/end times do not intersect this state system range.
211 * Return the empty map. */
212 return map;
213 }
200789b3
AM
214
215 try {
216 /* Get the list of quarks, one for each even type in the database */
802017fe 217 int quark = typesStats.getQuarkAbsolute(Attributes.EVENT_TYPES);
55954069
AM
218 quarks = typesStats.getSubAttributes(quark, false);
219 } catch (AttributeNotFoundException e) {
220 /*
221 * The state system does not (yet?) have the needed attributes, it
222 * probably means there are no events counted yet. Return the empty
223 * map.
224 */
225 return map;
226 }
200789b3 227
55954069 228 try {
802017fe 229 List<ITmfStateInterval> endState = typesStats.queryFullState(endTime);
200789b3 230
802017fe 231 if (startTime == typesStats.getStartTime()) {
e1c43333
AM
232 /* Only use the values picked up at the end time */
233 for (int typeQuark : quarks) {
55954069
AM
234 String curEventName = typesStats.getAttributeName(typeQuark);
235 long eventCount = endState.get(typeQuark).getStateValue().unboxInt();
e1c43333
AM
236 if (eventCount == -1) {
237 eventCount = 0;
238 }
239 map.put(curEventName, eventCount);
200789b3 240 }
e1c43333 241 } else {
200789b3 242 /*
e1c43333
AM
243 * Query the start time at -1, so the beginning of the interval
244 * is inclusive.
200789b3 245 */
802017fe 246 List<ITmfStateInterval> startState = typesStats.queryFullState(startTime - 1);
e1c43333 247 for (int typeQuark : quarks) {
55954069
AM
248 String curEventName = typesStats.getAttributeName(typeQuark);
249 long countAtStart = startState.get(typeQuark).getStateValue().unboxInt();
250 long countAtEnd = endState.get(typeQuark).getStateValue().unboxInt();
e1c43333
AM
251
252 if (countAtStart == -1) {
253 countAtStart = 0;
254 }
255 if (countAtEnd == -1) {
256 countAtEnd = 0;
257 }
55954069 258 long eventCount = countAtEnd - countAtStart;
e1c43333 259 map.put(curEventName, eventCount);
200789b3 260 }
200789b3 261 }
e1c43333 262
f0c73a6f 263 } catch (StateSystemDisposedException e) {
55954069 264 /* Assume there is no (more) events, nothing will be put in the map. */
200789b3
AM
265 }
266 return map;
267 }
268
802017fe
AM
269 // ------------------------------------------------------------------------
270 // Helper methods
271 // ------------------------------------------------------------------------
272
f3f93fa6
AM
273 private long getEventCountAt(long timestamp) {
274 /* Make sure the target time is within the range of the history */
63fe91fb
PT
275 long ts = checkStartTime(timestamp, totalsStats);
276 ts = checkEndTime(ts, totalsStats);
f3f93fa6
AM
277
278 try {
802017fe
AM
279 final int quark = totalsStats.getQuarkAbsolute(Attributes.TOTAL);
280 long count = totalsStats.querySingleState(ts, quark).getStateValue().unboxInt();
f3f93fa6
AM
281 return count;
282
f0c73a6f
PT
283 } catch (StateSystemDisposedException e) {
284 /* Assume there is no (more) events, nothing will be put in the map. */
285 } catch (AttributeNotFoundException e) {
f3f93fa6
AM
286 e.printStackTrace();
287 }
288
289 return 0;
290 }
291
63fe91fb 292 private static long checkStartTime(long initialStart, ITmfStateSystem ss) {
8b260d9f 293 long start = initialStart;
63fe91fb
PT
294 if (start < ss.getStartTime()) {
295 return ss.getStartTime();
200789b3
AM
296 }
297 return start;
298 }
299
63fe91fb 300 private static long checkEndTime(long initialEnd, ITmfStateSystem ss) {
8b260d9f 301 long end = initialEnd;
63fe91fb
PT
302 if (end > ss.getCurrentEndTime()) {
303 return ss.getCurrentEndTime();
200789b3
AM
304 }
305 return end;
306 }
307
200789b3
AM
308 /**
309 * The attribute names that are used in the state provider
310 */
311 public static class Attributes {
312
df310609
AM
313 /** Total nb of events */
314 public static final String TOTAL = "total"; //$NON-NLS-1$
315
200789b3
AM
316 /** event_types */
317 public static final String EVENT_TYPES = "event_types"; //$NON-NLS-1$<
318 }
319}
This page took 0.09082 seconds and 5 git commands to generate.