Fix some null warnings
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / statistics / TmfEventsStatistics.java
CommitLineData
1c0de632 1/*******************************************************************************
60ae41e1 2 * Copyright (c) 2012, 2014 Ericsson
1c0de632
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
2bdf0193 13package org.eclipse.tracecompass.tmf.core.statistics;
1c0de632 14
202956f1
AM
15import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
16
f3f93fa6 17import java.util.Collection;
1c0de632 18import java.util.HashMap;
f3f93fa6
AM
19import java.util.LinkedList;
20import java.util.List;
1c0de632 21import java.util.Map;
f3f93fa6 22import java.util.TreeMap;
1c0de632 23
aa353506 24import org.eclipse.jdt.annotation.NonNull;
2bdf0193
AM
25import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
26import org.eclipse.tracecompass.tmf.core.event.ITmfLostEvent;
27import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
28import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
29import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
30import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
31import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
32import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
1c0de632
AM
33
34/**
35 * Implementation of ITmfStatistics which uses event requests to the trace to
36 * retrieve its information.
37 *
38 * There is almost no setup time, but queries themselves are longer than with a
39 * TmfStateStatistics. Queries are O(n * m), where n is the size of the trace,
40 * and m is the portion of the trace covered by the selected interval.
41 *
42 * @author Alexandre Montplaisir
1c0de632
AM
43 */
44public class TmfEventsStatistics implements ITmfStatistics {
45
8b260d9f
AM
46 /* All timestamps should be stored in nanoseconds in the statistics backend */
47 private static final int SCALE = ITmfTimestamp.NANOSECOND_SCALE;
48
1c0de632
AM
49 private final ITmfTrace trace;
50
51 /* Event request objects for the time-range request. */
52 private StatsTotalRequest totalRequest = null;
53 private StatsPerTypeRequest perTypeRequest = null;
54
55 /**
56 * Constructor
57 *
58 * @param trace
59 * The trace for which we are building the statistics
60 */
61 public TmfEventsStatistics(ITmfTrace trace) {
62 this.trace = trace;
63 }
64
1a4205d9
AM
65 @Override
66 public void dispose() {
67 cancelOngoingRequests();
68 }
69
f3f93fa6
AM
70 @Override
71 public List<Long> histogramQuery(long start, long end, int nb) {
72 final long[] borders = new long[nb];
73 final long increment = (end - start) / nb;
74
75 long curTime = start;
76 for (int i = 0; i < nb; i++) {
77 borders[i] = curTime;
78 curTime += increment;
79 }
80
81 HistogramQueryRequest req = new HistogramQueryRequest(borders, end);
82 sendAndWait(req);
83
a4524c1b 84 List<Long> results = new LinkedList<>(req.getResults());
f3f93fa6
AM
85 return results;
86
87 }
88
1c0de632
AM
89 private synchronized void cancelOngoingRequests() {
90 if (totalRequest != null && totalRequest.isRunning()) {
91 totalRequest.cancel();
92 }
93 if (perTypeRequest != null && perTypeRequest.isRunning()) {
94 perTypeRequest.cancel();
95 }
96 }
97
98 @Override
99 public long getEventsTotal() {
100 StatsTotalRequest request = new StatsTotalRequest(trace, TmfTimeRange.ETERNITY);
101 sendAndWait(request);
102
103 long total = request.getResult();
104 return total;
105 }
106
107 @Override
aa353506 108 public Map<@NonNull String, @NonNull Long> getEventTypesTotal() {
1c0de632
AM
109 StatsPerTypeRequest request = new StatsPerTypeRequest(trace, TmfTimeRange.ETERNITY);
110 sendAndWait(request);
111
aa353506 112 return request.getResults();
1c0de632
AM
113 }
114
115 @Override
8b260d9f
AM
116 public long getEventsInRange(long start, long end) {
117 ITmfTimestamp startTS = new TmfTimestamp(start, SCALE);
118 ITmfTimestamp endTS = new TmfTimestamp(end, SCALE);
119 TmfTimeRange range = new TmfTimeRange(startTS, endTS);
120
1c0de632
AM
121 StatsTotalRequest request = new StatsTotalRequest(trace, range);
122 sendAndWait(request);
123
124 long total = request.getResult();
125 return total;
126 }
127
128 @Override
8b260d9f
AM
129 public Map<String, Long> getEventTypesInRange(long start, long end) {
130 ITmfTimestamp startTS = new TmfTimestamp(start, SCALE);
131 ITmfTimestamp endTS = new TmfTimestamp(end, SCALE);
132 TmfTimeRange range = new TmfTimeRange(startTS, endTS);
133
1c0de632
AM
134 StatsPerTypeRequest request = new StatsPerTypeRequest(trace, range);
135 sendAndWait(request);
136
137 Map<String, Long> stats = request.getResults();
138 return stats;
139 }
140
141 private void sendAndWait(TmfEventRequest request) {
142 trace.sendRequest(request);
143 try {
144 request.waitForCompletion();
145 } catch (InterruptedException e) {
146 e.printStackTrace();
147 }
148 }
149
150
151 /**
152 * Event request to get the total number of events
153 */
154 private class StatsTotalRequest extends TmfEventRequest {
155
156 /* Total number of events the request has found */
157 private long total;
158
159 public StatsTotalRequest(ITmfTrace trace, TmfTimeRange range) {
2740e05c 160 super(trace.getEventType(), range, 0, ITmfEventRequest.ALL_DATA,
fd3f1eff 161 ITmfEventRequest.ExecutionType.BACKGROUND);
1c0de632
AM
162 total = 0;
163 }
164
165 public long getResult() {
166 return total;
167 }
168
169 @Override
170 public void handleData(final ITmfEvent event) {
171 super.handleData(event);
6debe8aa
AM
172 if (!(event instanceof ITmfLostEvent) && event.getTrace() == trace) {
173 total += 1;
1c0de632
AM
174 }
175 }
176 }
177
178
179 /**
180 * Event request to get the counts per event type
181 */
182 private class StatsPerTypeRequest extends TmfEventRequest {
183
184 /* Map in which the results are saved */
aa353506 185 private final Map<@NonNull String, @NonNull Long> stats;
1c0de632
AM
186
187 public StatsPerTypeRequest(ITmfTrace trace, TmfTimeRange range) {
2740e05c 188 super(trace.getEventType(), range, 0, ITmfEventRequest.ALL_DATA,
fd3f1eff 189 ITmfEventRequest.ExecutionType.BACKGROUND);
a4524c1b 190 this.stats = new HashMap<>();
1c0de632
AM
191 }
192
aa353506 193 public Map<@NonNull String, @NonNull Long> getResults() {
1c0de632
AM
194 return stats;
195 }
196
197 @Override
5419a136
AM
198 public void handleData(final ITmfEvent event) {
199 super.handleData(event);
41f3b36b 200 if (event.getTrace() == trace) {
578716e6 201 String eventType = event.getName();
6debe8aa
AM
202 /*
203 * Special handling for lost events: instead of counting just
204 * one, we will count how many actual events it represents.
205 */
206 if (event instanceof ITmfLostEvent) {
207 ITmfLostEvent le = (ITmfLostEvent) event;
e8f9ac01 208 incrementStats(eventType, le.getNbLostEvents());
6debe8aa 209 return;
1c0de632 210 }
6debe8aa
AM
211
212 /* For standard event types, just increment by one */
6debe8aa 213 incrementStats(eventType, 1L);
1c0de632
AM
214 }
215 }
216
aa353506 217 private void incrementStats(@NonNull String key, long count) {
6debe8aa 218 if (stats.containsKey(key)) {
202956f1 219 long curValue = checkNotNull(stats.get(key));
6debe8aa 220 stats.put(key, curValue + count);
1c0de632 221 } else {
6debe8aa 222 stats.put(key, count);
1c0de632
AM
223 }
224 }
225 }
226
f3f93fa6
AM
227 /**
228 * Event request for histogram queries. It is much faster to do one event
229 * request then set the results accordingly than doing thousands of them one
230 * by one.
231 */
232 private class HistogramQueryRequest extends TmfEventRequest {
233
234 /** Map of <borders, number of events> */
235 private final TreeMap<Long, Long> results;
236
237 /**
238 * New histogram request
239 *
240 * @param borders
241 * The array of borders (not including the end time). The
242 * first element should be the start time of the queries.
243 * @param endTime
244 * The end time of the query. Not used in the results map,
245 * but we need to know when to stop the event request.
246 */
247 public HistogramQueryRequest(long[] borders, long endTime) {
248 super(trace.getEventType(),
249 new TmfTimeRange(
250 new TmfTimestamp(borders[0], SCALE),
251 new TmfTimestamp(endTime, SCALE)),
7184fc40 252 0,
2740e05c 253 ITmfEventRequest.ALL_DATA,
fd3f1eff 254 ITmfEventRequest.ExecutionType.BACKGROUND);
f3f93fa6
AM
255
256 /* Prepare the results map, with all counts at 0 */
a4524c1b 257 results = new TreeMap<>();
f3f93fa6
AM
258 for (long border : borders) {
259 results.put(border, 0L);
260 }
261 }
262
263 public Collection<Long> getResults() {
264 return results.values();
265 }
266
267 @Override
5419a136
AM
268 public void handleData(ITmfEvent event) {
269 super.handleData(event);
41f3b36b 270 if (event.getTrace() == trace) {
f3f93fa6
AM
271 long ts = event.getTimestamp().normalize(0, SCALE).getValue();
272 Long key = results.floorKey(ts);
273 if (key != null) {
274 incrementValue(key);
275 }
276 }
277 }
278
279 private void incrementValue(Long key) {
202956f1 280 long value = checkNotNull(results.get(key));
f3f93fa6
AM
281 value++;
282 results.put(key, value);
283 }
284 }
285
1c0de632 286}
This page took 0.102216 seconds and 5 git commands to generate.