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