tmf/lttng: Update 2014 copyrights
[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
11 ******************************************************************************/
12
13package org.eclipse.linuxtools.tmf.core.statistics;
14
200789b3 15import java.util.HashMap;
f3f93fa6 16import java.util.LinkedList;
200789b3
AM
17import java.util.List;
18import java.util.Map;
19
8192f2c6 20import org.eclipse.jdt.annotation.NonNull;
200789b3 21import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
96345c5a 22import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
200789b3
AM
23import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
24import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
200789b3 25import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
200789b3 26import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
200789b3
AM
27
28/**
1c0de632 29 * Implementation of ITmfStatistics which uses a state history for storing its
802017fe
AM
30 * information. In reality, it uses two state histories, one for "event totals"
31 * information (which should ideally use a fast backend), and another one for
32 * the rest (per event type, per CPU, etc.).
1c0de632 33 *
802017fe
AM
34 * Compared to the event-request-based statistics calculations, it adds the
35 * building the history first, but gives much faster response times once built :
36 * Queries are O(log n) wrt the size of the trace, and O(1) wrt to the size of
37 * the time interval selected.
200789b3
AM
38 *
39 * @author Alexandre Montplaisir
40 * @since 2.0
41 */
1c0de632 42public class TmfStateStatistics implements ITmfStatistics {
200789b3 43
802017fe
AM
44 // ------------------------------------------------------------------------
45 // Fields
46 // ------------------------------------------------------------------------
200789b3 47
802017fe
AM
48 /** The event totals state system */
49 private final ITmfStateSystem totalsStats;
50
51 /** The state system for event types */
52 private final ITmfStateSystem typesStats;
53
54 // ------------------------------------------------------------------------
55 // Constructors
56 // ------------------------------------------------------------------------
200789b3
AM
57
58 /**
59 * Constructor
60 *
8192f2c6
AM
61 * @param totals
62 * The state system containing the "totals" information
63 * @param eventTypes
64 * The state system containing the "event types" information
65 * @since 3.0
200789b3 66 */
d6b46913 67 public TmfStateStatistics(@NonNull ITmfStateSystem totals, @NonNull ITmfStateSystem eventTypes) {
8192f2c6
AM
68 this.totalsStats = totals;
69 this.typesStats = eventTypes;
802017fe
AM
70 }
71
6c5e0863 72 /**
8192f2c6
AM
73 * Return the state system containing the "totals" values
74 *
75 * @return The "totals" state system
76 * @since 3.0
77 */
78 public ITmfStateSystem getTotalsSS() {
79 return totalsStats;
80 }
81
82 /**
83 * Return the state system containing the "event types" values
84 *
85 * @return The "event types" state system
86 * @since 3.0
6c5e0863 87 */
8192f2c6
AM
88 public ITmfStateSystem getEventTypesSS() {
89 return typesStats;
e1c43333
AM
90 }
91
200789b3 92 // ------------------------------------------------------------------------
1c0de632 93 // ITmfStatistics
200789b3
AM
94 // ------------------------------------------------------------------------
95
1a4205d9
AM
96 @Override
97 public void dispose() {
802017fe
AM
98 totalsStats.dispose();
99 typesStats.dispose();
1a4205d9
AM
100 }
101
f3f93fa6
AM
102 @Override
103 public List<Long> histogramQuery(final long start, final long end, final int nb) {
a4524c1b 104 final List<Long> list = new LinkedList<>();
f3f93fa6
AM
105 final long increment = (end - start) / nb;
106
2002c638 107 if (totalsStats.isCancelled()) {
802017fe 108 return list;
f3f93fa6
AM
109 }
110
111 /*
112 * We will do one state system query per "border", and save the
113 * differences between each border.
114 */
802017fe 115 long prevTotal = (start == totalsStats.getStartTime()) ? 0 : getEventCountAt(start);
f3f93fa6
AM
116 long curTime = start + increment;
117
118 long curTotal, count;
119 for (int i = 0; i < nb - 1; i++) {
120 curTotal = getEventCountAt(curTime);
121 count = curTotal - prevTotal;
122 list.add(count);
123
124 curTime += increment;
125 prevTotal = curTotal;
126 }
127
128 /*
129 * For the last bucket, we'll stretch its end time to the end time of
130 * the requested range, in case it got truncated down.
131 */
132 curTotal = getEventCountAt(end);
133 count = curTotal - prevTotal;
134 list.add(count);
1c0de632 135
f3f93fa6 136 return list;
1c0de632
AM
137 }
138
200789b3
AM
139 @Override
140 public long getEventsTotal() {
802017fe 141 long endTime = totalsStats.getCurrentEndTime();
e1c43333 142 int count = 0;
df310609
AM
143
144 try {
802017fe
AM
145 final int quark = totalsStats.getQuarkAbsolute(Attributes.TOTAL);
146 count= totalsStats.querySingleState(endTime, quark).getStateValue().unboxInt();
1c0de632
AM
147
148 } catch (TimeRangeException e) {
149 /* Assume there is no events for that range */
150 return 0;
55954069 151 } catch (AttributeNotFoundException | StateValueTypeException | StateSystemDisposedException e) {
96345c5a 152 e.printStackTrace();
200789b3 153 }
df310609 154
e1c43333 155 return count;
200789b3
AM
156 }
157
158 @Override
159 public Map<String, Long> getEventTypesTotal() {
55954069 160 final Map<String, Long> map = new HashMap<>();
802017fe 161 long endTime = typesStats.getCurrentEndTime();
200789b3
AM
162
163 try {
164 /* Get the list of quarks, one for each even type in the database */
802017fe
AM
165 int quark = typesStats.getQuarkAbsolute(Attributes.EVENT_TYPES);
166 List<Integer> quarks = typesStats.getSubAttributes(quark, false);
200789b3
AM
167
168 /* Since we want the total we can look only at the end */
802017fe 169 List<ITmfStateInterval> endState = typesStats.queryFullState(endTime);
200789b3
AM
170
171 String curEventName;
172 long eventCount;
173 for (int typeQuark : quarks) {
802017fe 174 curEventName = typesStats.getAttributeName(typeQuark);
200789b3
AM
175 eventCount = endState.get(typeQuark).getStateValue().unboxInt();
176 map.put(curEventName, eventCount);
177 }
178
179 } catch (TimeRangeException e) {
1c0de632 180 /* Assume there is no events, nothing will be put in the map. */
8192f2c6 181 } catch (AttributeNotFoundException | StateValueTypeException | StateSystemDisposedException e) {
96345c5a 182 e.printStackTrace();
200789b3
AM
183 }
184 return map;
185 }
186
187 @Override
8b260d9f 188 public long getEventsInRange(long start, long end) {
f3f93fa6 189 long startCount;
802017fe 190 if (start == totalsStats.getStartTime()) {
f3f93fa6
AM
191 startCount = 0;
192 } else {
193 /*
194 * We want the events happening at "start" to be included, so we'll
195 * need to query one unit before that point.
196 */
197 startCount = getEventCountAt(start - 1);
200789b3 198 }
f3f93fa6 199 long endCount = getEventCountAt(end);
df310609 200
f3f93fa6 201 return endCount - startCount;
200789b3
AM
202 }
203
204 @Override
8b260d9f 205 public Map<String, Long> getEventTypesInRange(long start, long end) {
55954069
AM
206 final Map<String, Long> map = new HashMap<>();
207 List<Integer> quarks;
200789b3
AM
208
209 /* Make sure the start/end times are within the state history, so we
210 * don't get TimeRange exceptions.
211 */
1c0de632
AM
212 long startTime = checkStartTime(start);
213 long endTime = checkEndTime(end);
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
55954069
AM
263 } catch (TimeRangeException | StateSystemDisposedException e) {
264 /* Assume there is no (more) events, nothing will be put in the map. */
265 } catch (StateValueTypeException e) {
200789b3 266 /*
55954069 267 * This exception type would show a logic problem however,
1c0de632 268 * so they should not happen.
200789b3 269 */
55954069 270 throw new IllegalStateException();
200789b3
AM
271 }
272 return map;
273 }
274
802017fe
AM
275 // ------------------------------------------------------------------------
276 // Helper methods
277 // ------------------------------------------------------------------------
278
f3f93fa6
AM
279 private long getEventCountAt(long timestamp) {
280 /* Make sure the target time is within the range of the history */
281 long ts = checkStartTime(timestamp);
282 ts = checkEndTime(ts);
283
284 try {
802017fe
AM
285 final int quark = totalsStats.getQuarkAbsolute(Attributes.TOTAL);
286 long count = totalsStats.querySingleState(ts, quark).getStateValue().unboxInt();
f3f93fa6
AM
287 return count;
288
289 } catch (TimeRangeException e) {
290 /* Assume there is no events for that range */
8192f2c6 291 } catch (AttributeNotFoundException | StateValueTypeException | StateSystemDisposedException e) {
f3f93fa6
AM
292 e.printStackTrace();
293 }
294
295 return 0;
296 }
297
8b260d9f
AM
298 private long checkStartTime(long initialStart) {
299 long start = initialStart;
802017fe
AM
300 if (start < totalsStats.getStartTime()) {
301 return totalsStats.getStartTime();
200789b3
AM
302 }
303 return start;
304 }
305
8b260d9f
AM
306 private long checkEndTime(long initialEnd) {
307 long end = initialEnd;
802017fe
AM
308 if (end > totalsStats.getCurrentEndTime()) {
309 return totalsStats.getCurrentEndTime();
200789b3
AM
310 }
311 return end;
312 }
313
200789b3
AM
314 /**
315 * The attribute names that are used in the state provider
316 */
317 public static class Attributes {
318
df310609
AM
319 /** Total nb of events */
320 public static final String TOTAL = "total"; //$NON-NLS-1$
321
200789b3
AM
322 /** event_types */
323 public static final String EVENT_TYPES = "event_types"; //$NON-NLS-1$<
324 }
325}
This page took 0.053053 seconds and 5 git commands to generate.