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