1 /*******************************************************************************
2 * Copyright (c) 2012 Ericsson
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
10 * Alexandre Montplaisir - Initial API and implementation
11 ******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.core
.statistics
;
15 import java
.util
.HashMap
;
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
;
30 * Implementation of ITmfStatistics which uses event requests to the trace to
31 * retrieve its information.
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.
37 * @author Alexandre Montplaisir
40 public class TmfEventsStatistics
implements ITmfStatistics
{
42 private final ITmfTrace trace
;
44 /* Event request objects for the time-range request. */
45 private StatsTotalRequest totalRequest
= null;
46 private StatsPerTypeRequest perTypeRequest
= null;
52 * The trace for which we are building the statistics
54 public TmfEventsStatistics(ITmfTrace trace
) {
59 public void dispose() {
60 cancelOngoingRequests();
64 public void updateStats(final boolean isGlobal
, ITmfTimestamp start
,
66 cancelOngoingRequests();
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.
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
);
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).
82 this.totalRequest
= totalReq
;
83 this.perTypeRequest
= perTypeReq
;
86 trace
.sendRequest(totalReq
);
87 trace
.sendRequest(perTypeReq
);
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.
93 Thread statsThread
= new Thread("Statistics update") { //$NON-NLS-1$
96 /* Wait for both requests to complete */
98 totalReq
.waitForCompletion();
99 perTypeReq
.waitForCompletion();
100 } catch (InterruptedException e
) {
105 * If the request was cancelled, this means a newer one was
106 * sent, discard the current one and return without sending
109 if (totalReq
.isCancelled() || perTypeReq
.isCancelled()) {
113 /* If it completed successfully, retrieve the results. */
114 long total
= totalReq
.getResult();
115 Map
<String
, Long
> map
= perTypeReq
.getResults();
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
);
126 private synchronized void cancelOngoingRequests() {
127 if (totalRequest
!= null && totalRequest
.isRunning()) {
128 totalRequest
.cancel();
130 if (perTypeRequest
!= null && perTypeRequest
.isRunning()) {
131 perTypeRequest
.cancel();
136 public long getEventsTotal() {
137 StatsTotalRequest request
= new StatsTotalRequest(trace
, TmfTimeRange
.ETERNITY
);
138 sendAndWait(request
);
140 long total
= request
.getResult();
145 public Map
<String
, Long
> getEventTypesTotal() {
146 StatsPerTypeRequest request
= new StatsPerTypeRequest(trace
, TmfTimeRange
.ETERNITY
);
147 sendAndWait(request
);
149 Map
<String
, Long
> stats
= request
.getResults();
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
);
159 long total
= request
.getResult();
164 public Map
<String
, Long
> getEventTypesInRange(ITmfTimestamp start
,
166 TmfTimeRange range
= new TmfTimeRange(start
, end
);
167 StatsPerTypeRequest request
= new StatsPerTypeRequest(trace
, range
);
168 sendAndWait(request
);
170 Map
<String
, Long
> stats
= request
.getResults();
174 private void sendAndWait(TmfEventRequest request
) {
175 trace
.sendRequest(request
);
177 request
.waitForCompletion();
178 } catch (InterruptedException e
) {
185 * Event request to get the total number of events
187 private class StatsTotalRequest
extends TmfEventRequest
{
189 /* Total number of events the request has found */
192 public StatsTotalRequest(ITmfTrace trace
, TmfTimeRange range
) {
193 super(trace
.getEventType(), range
, TmfDataRequest
.ALL_DATA
,
194 trace
.getCacheSize(), ITmfDataRequest
.ExecutionType
.BACKGROUND
);
198 public long getResult() {
203 public void handleData(final ITmfEvent event
) {
204 super.handleData(event
);
206 if (event
.getTrace() == trace
) {
215 * Event request to get the counts per event type
217 private class StatsPerTypeRequest
extends TmfEventRequest
{
219 /* Map in which the results are saved */
220 private final Map
<String
, Long
> stats
;
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
>();
228 public Map
<String
, Long
> getResults() {
233 public void handleData(final ITmfEvent event
) {
234 super.handleData(event
);
236 if (event
.getTrace() == trace
) {
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);
248 stats
.put(eventType
, 1L);