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