1 /*******************************************************************************
2 * Copyright (c) 2009 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 * William Bourque - Initial API and implementation
11 *******************************************************************************/
12 package org
.eclipse
.linuxtools
.lttng
.ui
.views
.histogram
;
14 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEvent
;
15 import org
.eclipse
.linuxtools
.tmf
.event
.TmfEvent
;
16 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
17 import org
.eclipse
.linuxtools
.tmf
.request
.ITmfDataRequest
;
18 import org
.eclipse
.linuxtools
.tmf
.request
.TmfEventRequest
;
21 * <b><u>HistogramRequest</u></b>
23 * Request class, to perform a request to TMF for the histograms.
26 public class HistogramRequest
extends TmfEventRequest
<LttngEvent
> {
27 protected HistogramContent histogramContent
= null;
29 protected int lastInterval
= 0;
30 protected long lastRangeTime
= 0L;
31 protected long nbEventsInInterval
= 0L;
33 protected int nbIntervalNotEmpty
= 1;
34 protected int nbEventRead
= 0;
36 protected int lastDrawPosition
= 0;
38 protected HistogramCanvas parentCanvas
= null;
41 * Constructor for HistogramRequest.<p>
42 * Prepare the request in TMF and reset the histogram content.
44 * @param range Range of the request.
45 * @param nbRequested Nb events requested. Can be "Infinity" for all.
46 * @param newParentCanvas HistogramCanvas related to the request.
47 * @param timeInterval Time interval to consider (i.e. : 1 interval is 1 bar in the histogram)
49 * @see org.eclipse.linuxtools.tmf.request.TmfEventRequest
51 public HistogramRequest(TmfTimeRange range
, int nbRequested
, HistogramCanvas newParentCanvas
, long timeInterval
, ITmfDataRequest
.ExecutionType execType
) {
52 super((Class
<LttngEvent
>)LttngEvent
.class, range
, nbRequested
, HistogramConstant
.MAX_EVENTS_PER_READ
, execType
);
55 // This does not work! The request won't be processed or the number of events returned is wrong!
56 // We cannot use this !
57 //super((Class<LttngEvent>)dataType, range);
59 parentCanvas
= newParentCanvas
;
60 histogramContent
= parentCanvas
.getHistogramContent();
62 // Reset the content of the HistogramContent... the given data better be valid or this will fail.
63 histogramContent
.clearContentData();
64 histogramContent
.resetTable(range
.getStartTime().getValue(), range
.getEndTime().getValue(), timeInterval
);
66 lastRangeTime
= range
.getStartTime().getValue();
68 // Notify the UI even before the request started, so we set the timestamp already.
69 parentCanvas
.notifyParentUpdatedInformationAsynchronously();
73 * HandleData function : will be called by TMF each time a new event is receive for the request.<p>
74 * Calculation for the content is done here.
77 public void handleData() {
78 TmfEvent
[] result
= getData();
79 TmfEvent
[] evt
= new TmfEvent
[1];
81 evt
[0] = (result
.length
> 0) ? result
[0] : null;
85 // The request by timerange only does not work! (see constructor above)
86 // However, the request with number of events will loop until it reach its number or EOF
87 // We have to filter out ourself the extra useless events!
91 LttngEvent tmpEvent
= (LttngEvent
)evt
[0];
93 // This check is linked to the evil fix mentionned above
94 if ( ( tmpEvent
.getTimestamp().getValue() >= histogramContent
.getStartTime() ) &&
95 ( tmpEvent
.getTimestamp().getValue() <= histogramContent
.getEndTime() ) )
98 // Distance (in time) between this event and the last one we read
99 long distance
= ( tmpEvent
.getTimestamp().getValue() - lastRangeTime
);
101 // Check if we changed of interval (the distance is higher than the interval time)
102 if ( distance
> histogramContent
.getElementsTimeInterval() ) {
104 histogramContent
.getElementByIndex(lastInterval
).intervalNbEvents
= nbEventsInInterval
;
105 lastRangeTime
= tmpEvent
.getTimestamp().getValue();
108 // We can skip several interval at once, so we need to find what was our interval now
109 lastInterval
= (int)((lastRangeTime
- histogramContent
.getStartTime()) / histogramContent
.getElementsTimeInterval() );
112 // Because of the threads, weird phenomenons seem to happen here, like a position after the
113 // element range because another request was issued.
114 // This enforce the position but may result in slightly inconsistent result (i.e. a weird misplaced bar sometime).
115 if ( lastInterval
< 0 ) {
118 else if ( lastInterval
>= histogramContent
.getNbElement() ) {
119 lastInterval
= (histogramContent
.getNbElement()-1);
123 // We save the time we have here. This mean only the FIRST time read in an interval will be saved.
124 histogramContent
.getElementByIndex(lastInterval
).firstIntervalTimestamp
= lastRangeTime
;
125 histogramContent
.setReadyUpToPosition(lastInterval
);
127 nbIntervalNotEmpty
++;
128 nbEventsInInterval
= 1L;
130 // We are still in the same interval, just keep counting
132 nbEventsInInterval
++;
135 if ( nbEventsInInterval
> histogramContent
.getHeighestEventCount() ) {
136 histogramContent
.setHeighestEventCount(nbEventsInInterval
);
140 // Call an asynchronous redraw every REDRAW_EVERY_NB_EVENTS events
141 // That way we don't need to wait until to end to have something on the screen
142 if ( nbEventRead
% HistogramConstant
.REDRAW_EVERY_NB_EVENTS
== 0 ) {
143 redrawAsyncronously();
147 // We got a null event! This mean we reach the end of the request.
148 // Save the last interval we had, so we won't miss the very last events at the end.
150 // Save the last events
151 histogramContent
.getElementByIndex(lastInterval
).intervalNbEvents
= nbEventsInInterval
;
152 // We reached the end of the request, so assume we fill up the content as well
153 histogramContent
.setReadyUpToPosition(histogramContent
.getNbElement());
155 // If the interval wasn't null, count this as a "non empty" interval
156 if (nbEventsInInterval
> 0) {
157 nbIntervalNotEmpty
++;
163 * Function that is called when the request completed (successful or not).<p>
164 * Update information and redraw the screen.
167 public void handleCompleted() {
168 parentCanvas
.notifyParentUpdatedInformationAsynchronously();
169 redrawAsyncronously();
173 * Function that is called when the request completed successfully.<p>
176 public void handleSuccess() {
177 // Nothing different from completed.
181 * Function that is called when the request completed in failure.<p>
184 public void handleFailure() {
185 // Nothing different from cancel.
189 * Function that is called when the request was cancelled.<p>
190 * Redraw and set the requestCompleted flag to true;
193 public void handleCancel() {
194 redrawAsyncronously();
198 * Update the HistogramContent with the latest information.<p>
199 * This will perform some calculation that might be a bit harsh so it should'nt be called too often.
201 public void updateEventsInfo() {
203 // The average number of event is calculated while skipping empty interval if asked
204 int averageNumberOfEvents
= 0;
205 if ( HistogramConstant
.SKIP_EMPTY_INTERVALS_WHEN_CALCULATING_AVERAGE
) {
206 averageNumberOfEvents
= (int)Math
.ceil((double)nbEventRead
/ (double)nbIntervalNotEmpty
);
209 averageNumberOfEvents
= (int)Math
.ceil((double)nbEventRead
/ (double)histogramContent
.getNbElement());
212 histogramContent
.setAverageNumberOfEvents(averageNumberOfEvents
);
214 // It is possible that the height factor didn't change;
215 // If not, we only need to redraw the updated section, no the whole content
216 // Save the actual height, recalculate the height and check if there was any changes
217 double previousHeightFactor
= histogramContent
.getHeightFactor();
218 histogramContent
.recalculateHeightFactor();
219 if ( histogramContent
.getHeightFactor() != previousHeightFactor
) {
220 histogramContent
.recalculateEventHeight();
223 histogramContent
.recalculateEventHeightInInterval(lastDrawPosition
, histogramContent
.getReadyUpToPosition());
226 lastDrawPosition
= histogramContent
.getReadyUpToPosition();
230 * Perform an asynchonous redraw of the screen.
232 public void redrawAsyncronously() {
234 // Canvas redraw is already asynchronous
235 parentCanvas
.redrawAsynchronously();