tmf: Add dispose methods to the state and stats backends
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / statistics / TmfEventsStatistics.java
1 /*******************************************************************************
2 * Copyright (c) 2012 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.HashMap;
16 import java.util.Map;
17
18 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
19 import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
20 import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
21 import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
22 import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
23 import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
24 import org.eclipse.linuxtools.tmf.core.signal.TmfSignal;
25 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
26 import org.eclipse.linuxtools.tmf.core.signal.TmfStatsUpdatedSignal;
27 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
28
29 /**
30 * Implementation of ITmfStatistics which uses event requests to the trace to
31 * retrieve its information.
32 *
33 * There is almost no setup time, but queries themselves are longer than with a
34 * TmfStateStatistics. Queries are O(n * m), where n is the size of the trace,
35 * and m is the portion of the trace covered by the selected interval.
36 *
37 * @author Alexandre Montplaisir
38 * @since 2.0
39 */
40 public class TmfEventsStatistics implements ITmfStatistics {
41
42 private final ITmfTrace trace;
43
44 /* Event request objects for the time-range request. */
45 private StatsTotalRequest totalRequest = null;
46 private StatsPerTypeRequest perTypeRequest = null;
47
48 /**
49 * Constructor
50 *
51 * @param trace
52 * The trace for which we are building the statistics
53 */
54 public TmfEventsStatistics(ITmfTrace trace) {
55 this.trace = trace;
56 }
57
58 @Override
59 public void dispose() {
60 cancelOngoingRequests();
61 }
62
63 @Override
64 public void updateStats(final boolean isGlobal, ITmfTimestamp start,
65 ITmfTimestamp end) {
66 cancelOngoingRequests();
67
68 /*
69 * Prepare and send the event requests. This needs to be done in the
70 * same thread, since it will be run by TmfStatisticsViewer's signal
71 * handlers, to ensure they get correctly coalesced.
72 */
73 TmfTimeRange range = isGlobal ? TmfTimeRange.ETERNITY : new TmfTimeRange(start, end);
74 final StatsTotalRequest totalReq = new StatsTotalRequest(trace, range);
75 final StatsPerTypeRequest perTypeReq = new StatsPerTypeRequest(trace, range);
76
77 /*
78 * Only allow one time-range request at a time (there should be only one
79 * global request at the beginning anyway, no need to track those).
80 */
81 if (!isGlobal) {
82 this.totalRequest = totalReq;
83 this.perTypeRequest = perTypeReq;
84 }
85
86 trace.sendRequest(totalReq);
87 trace.sendRequest(perTypeReq);
88
89 /*
90 * This thread can now return. Start a new thread that will wait until
91 * the request are done and will then send the results.
92 */
93 Thread statsThread = new Thread("Statistics update") { //$NON-NLS-1$
94 @Override
95 public void run() {
96 /* Wait for both requests to complete */
97 try {
98 totalReq.waitForCompletion();
99 perTypeReq.waitForCompletion();
100 } catch (InterruptedException e) {
101 e.printStackTrace();
102 }
103
104 /*
105 * If the request was cancelled, this means a newer one was
106 * sent, discard the current one and return without sending
107 * the signal.
108 */
109 if (totalReq.isCancelled() || perTypeReq.isCancelled()) {
110 return;
111 }
112
113 /* If it completed successfully, retrieve the results. */
114 long total = totalReq.getResult();
115 Map<String, Long> map = perTypeReq.getResults();
116
117 /* Send the signal to notify the stats viewer to update its display. */
118 TmfSignal sig = new TmfStatsUpdatedSignal(this, trace, isGlobal, total, map);
119 TmfSignalManager.dispatchSignal(sig);
120 }
121 };
122 statsThread.start();
123 return;
124 }
125
126 private synchronized void cancelOngoingRequests() {
127 if (totalRequest != null && totalRequest.isRunning()) {
128 totalRequest.cancel();
129 }
130 if (perTypeRequest != null && perTypeRequest.isRunning()) {
131 perTypeRequest.cancel();
132 }
133 }
134
135 @Override
136 public long getEventsTotal() {
137 StatsTotalRequest request = new StatsTotalRequest(trace, TmfTimeRange.ETERNITY);
138 sendAndWait(request);
139
140 long total = request.getResult();
141 return total;
142 }
143
144 @Override
145 public Map<String, Long> getEventTypesTotal() {
146 StatsPerTypeRequest request = new StatsPerTypeRequest(trace, TmfTimeRange.ETERNITY);
147 sendAndWait(request);
148
149 Map<String, Long> stats = request.getResults();
150 return stats;
151 }
152
153 @Override
154 public long getEventsInRange(ITmfTimestamp start, ITmfTimestamp end) {
155 TmfTimeRange range = new TmfTimeRange(start, end);
156 StatsTotalRequest request = new StatsTotalRequest(trace, range);
157 sendAndWait(request);
158
159 long total = request.getResult();
160 return total;
161 }
162
163 @Override
164 public Map<String, Long> getEventTypesInRange(ITmfTimestamp start,
165 ITmfTimestamp end) {
166 TmfTimeRange range = new TmfTimeRange(start, end);
167 StatsPerTypeRequest request = new StatsPerTypeRequest(trace, range);
168 sendAndWait(request);
169
170 Map<String, Long> stats = request.getResults();
171 return stats;
172 }
173
174 private void sendAndWait(TmfEventRequest request) {
175 trace.sendRequest(request);
176 try {
177 request.waitForCompletion();
178 } catch (InterruptedException e) {
179 e.printStackTrace();
180 }
181 }
182
183
184 /**
185 * Event request to get the total number of events
186 */
187 private class StatsTotalRequest extends TmfEventRequest {
188
189 /* Total number of events the request has found */
190 private long total;
191
192 public StatsTotalRequest(ITmfTrace trace, TmfTimeRange range) {
193 super(trace.getEventType(), range, TmfDataRequest.ALL_DATA,
194 trace.getCacheSize(), ITmfDataRequest.ExecutionType.BACKGROUND);
195 total = 0;
196 }
197
198 public long getResult() {
199 return total;
200 }
201
202 @Override
203 public void handleData(final ITmfEvent event) {
204 super.handleData(event);
205 if (event != null) {
206 if (event.getTrace() == trace) {
207 total += 1;
208 }
209 }
210 }
211 }
212
213
214 /**
215 * Event request to get the counts per event type
216 */
217 private class StatsPerTypeRequest extends TmfEventRequest {
218
219 /* Map in which the results are saved */
220 private final Map<String, Long> stats;
221
222 public StatsPerTypeRequest(ITmfTrace trace, TmfTimeRange range) {
223 super(trace.getEventType(), range, TmfDataRequest.ALL_DATA,
224 trace.getCacheSize(), ITmfDataRequest.ExecutionType.BACKGROUND);
225 this.stats = new HashMap<String, Long>();
226 }
227
228 public Map<String, Long> getResults() {
229 return stats;
230 }
231
232 @Override
233 public void handleData(final ITmfEvent event) {
234 super.handleData(event);
235 if (event != null) {
236 if (event.getTrace() == trace) {
237 processEvent(event);
238 }
239 }
240 }
241
242 private void processEvent(ITmfEvent event) {
243 String eventType = event.getType().getName();
244 if (stats.containsKey(eventType)) {
245 long curValue = stats.get(eventType);
246 stats.put(eventType, curValue + 1L);
247 } else {
248 stats.put(eventType, 1L);
249 }
250 }
251 }
252
253 }
This page took 0.054574 seconds and 5 git commands to generate.