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
13 * 2010-07-16 Yuriy Vashchuk - Heritage correction.
14 *******************************************************************************/
15 package org
.eclipse
.linuxtools
.lttng
.ui
.views
.histogram
;
17 import org
.eclipse
.linuxtools
.lttng
.LttngConstants
;
18 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEvent
;
19 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
20 import org
.eclipse
.linuxtools
.tmf
.request
.ITmfDataRequest
;
21 import org
.eclipse
.linuxtools
.tmf
.request
.TmfEventRequest
;
24 * <b><u>HistogramRequest</u></b>
26 * Request class, to perform a request to TMF for the histograms.
29 public class HistogramRequest
extends TmfEventRequest
<LttngEvent
> {
31 private HistogramContent histogramContent = null;
34 private int lastInterval
= 0;
35 private long lastRangeTime
= 0L;
36 private long nbEventsInInterval
= 0L;
38 private int nbIntervalNotEmpty
= 1;
39 private int nbEventRead
= 0;
41 private int lastDrawPosition
= 0;
43 private HistogramCanvas parentCanvas
= null;
45 private boolean isCompleted
= false;
48 * Constructor for HistogramRequest.<p>
49 * Prepare the request in TMF and reset the histogram content.
51 * @param range Range of the request.
52 * @param nbRequested Nb events requested. Can be "Infinity" for all.
53 * @param newParentCanvas HistogramCanvas related to the request.
54 * @param timeInterval Time interval to consider (i.e. : 1 interval is 1 bar in the histogram)
56 * @see org.eclipse.linuxtools.tmf.request.TmfEventRequest
58 public HistogramRequest(TmfTimeRange range
, int nbRequested
, HistogramCanvas newParentCanvas
, long timeInterval
, ITmfDataRequest
.ExecutionType execType
) {
59 super((Class
<LttngEvent
>)LttngEvent
.class, range
, nbRequested
, LttngConstants
.DEFAULT_BLOCK_SIZE
, execType
);
61 setIsCompleted(false);
64 // This does not work! The request won't be processed or the number of events returned is wrong!
65 // We cannot use this !
66 //super((Class<LttngEvent>)dataType, range);
68 parentCanvas
= newParentCanvas
;
70 // Reset the content of the HistogramContent... the given data better be valid or this will fail.
71 parentCanvas
.getHistogramContent().clearContentData();
72 parentCanvas
.getHistogramContent().resetTable(range
.getStartTime().getValue(), range
.getEndTime().getValue(), timeInterval
);
74 lastRangeTime
= range
.getStartTime().getValue();
76 // Notify the UI even before the request started, so we set the timestamp already.
77 parentCanvas
.notifyParentUpdatedInformationAsynchronously();
81 * HandleData function : will be called by TMF each time a new event is receive for the request.<p>
82 * Calculation for the content is done here.
85 // public void handleData() {
86 // LttngEvent[] result = getData();
87 // LttngEvent event = (result.length > 0) ? result[0] : null;
90 public void handleData(LttngEvent event
) {
91 super.handleData(event
);
95 // The request by timerange only does not work! (see constructor above)
96 // However, the request with number of events will loop until it reach its number or EOF
97 // We have to filter out ourself the extra useless events!
101 // Tracer.trace("Hst: " + event.getTimestamp());
103 // This check is linked to the evil fix mentionned above
104 if ( ( event
.getTimestamp().getValue() >= parentCanvas
.getHistogramContent().getStartTime() ) &&
105 ( event
.getTimestamp().getValue() <= parentCanvas
.getHistogramContent().getEndTime() ) )
108 // Distance (in time) between this event and the last one we read
109 long distance
= ( event
.getTimestamp().getValue() - lastRangeTime
);
111 // Check if we changed of interval (the distance is higher than the interval time)
112 if ( distance
> parentCanvas
.getHistogramContent().getElementsTimeInterval() ) {
114 parentCanvas
.getHistogramContent().getElementByIndex(lastInterval
).intervalNbEvents
= nbEventsInInterval
;
115 lastRangeTime
= event
.getTimestamp().getValue();
118 // We can skip several interval at once, so we need to find what was our interval now
119 lastInterval
= (int)((lastRangeTime
- parentCanvas
.getHistogramContent().getStartTime()) / parentCanvas
.getHistogramContent().getElementsTimeInterval() );
122 // Because of the threads, weird phenomenons seem to happen here, like a position after the
123 // element range because another request was issued.
124 // This enforce the position but may result in slightly inconsistent result (i.e. a weird misplaced bar sometime).
125 if ( lastInterval
< 0 ) {
128 else if ( lastInterval
>= parentCanvas
.getHistogramContent().getNbElement() ) {
129 lastInterval
= (parentCanvas
.getHistogramContent().getNbElement()-1);
133 // We save the time we have here. This mean only the FIRST time read in an interval will be saved.
134 parentCanvas
.getHistogramContent().getElementByIndex(lastInterval
).firstIntervalTimestamp
= lastRangeTime
;
135 parentCanvas
.getHistogramContent().setReadyUpToPosition(lastInterval
);
137 nbIntervalNotEmpty
++;
138 nbEventsInInterval
= 1L;
140 // We are still in the same interval, just keep counting
142 nbEventsInInterval
++;
145 if ( nbEventsInInterval
> parentCanvas
.getHistogramContent().getHeighestEventCount() ) {
146 parentCanvas
.getHistogramContent().setHeighestEventCount(nbEventsInInterval
);
150 // Call an asynchronous redraw every REDRAW_EVERY_NB_EVENTS events
151 // That way we don't need to wait until to end to have something on the screen
152 if ( nbEventRead
% HistogramConstant
.REDRAW_EVERY_NB_EVENTS
== 0 ) {
153 redrawAsyncronously();
157 // We got a null event! This mean we reach the end of the request.
158 // Save the last interval we had, so we won't miss the very last events at the end.
160 // Save the last events
161 parentCanvas
.getHistogramContent().getElementByIndex(lastInterval
).intervalNbEvents
= nbEventsInInterval
;
162 // We reached the end of the request, so assume we fill up the content as well
163 parentCanvas
.getHistogramContent().setReadyUpToPosition(parentCanvas
.getHistogramContent().getNbElement());
165 // If the interval wasn't null, count this as a "non empty" interval
166 if (nbEventsInInterval
> 0) {
167 nbIntervalNotEmpty
++;
173 * Function that is called when the request completed (successful or not).<p>
174 * Update information and redraw the screen.
177 public void handleCompleted() {
178 setIsCompleted(true);
179 parentCanvas
.notifyParentUpdatedInformationAsynchronously();
180 redrawAsyncronously();
181 super.handleCompleted();
182 // System.out.println(System.currentTimeMillis() + ": HistogramView (" + ((getExecType() == ExecutionType.LONG) ? "long" : "short") + ") completed");
186 // * Function that is called when the request completed successfully.<p>
189 // public void handleSuccess() {
190 // // Nothing different from completed.
194 // * Function that is called when the request completed in failure.<p>
197 // public void handleFailure() {
198 // // Nothing different from cancel.
202 * Function that is called when the request was cancelled.<p>
203 * Redraw and set the requestCompleted flag to true;
206 public void handleCancel() {
207 redrawAsyncronously();
208 super.handleCancel();
212 * Update the HistogramContent with the latest information.<p>
213 * This will perform some calculation that might be a bit harsh so it should'nt be called too often.
215 public void updateEventsInfo() {
217 // The average number of event is calculated while skipping empty interval if asked
218 int averageNumberOfEvents
= 0;
219 if ( HistogramConstant
.SKIP_EMPTY_INTERVALS_WHEN_CALCULATING_AVERAGE
) {
220 averageNumberOfEvents
= (int)Math
.ceil((double)nbEventRead
/ (double)nbIntervalNotEmpty
);
223 averageNumberOfEvents
= (int)Math
.ceil((double)nbEventRead
/ (double)parentCanvas
.getHistogramContent().getNbElement());
226 parentCanvas
.getHistogramContent().setAverageNumberOfEvents(averageNumberOfEvents
);
228 // It is possible that the height factor didn't change;
229 // If not, we only need to redraw the updated section, no the whole content
230 // Save the actual height, recalculate the height and check if there was any changes
231 double previousHeightFactor
= parentCanvas
.getHistogramContent().getHeightFactor();
232 parentCanvas
.getHistogramContent().recalculateHeightFactor();
233 if ( parentCanvas
.getHistogramContent().getHeightFactor() != previousHeightFactor
) {
234 parentCanvas
.getHistogramContent().recalculateEventHeight();
237 parentCanvas
.getHistogramContent().recalculateEventHeightInInterval(lastDrawPosition
, parentCanvas
.getHistogramContent().getReadyUpToPosition());
240 lastDrawPosition
= parentCanvas
.getHistogramContent().getReadyUpToPosition();
244 * Perform an asynchonous redraw of the screen.
246 public void redrawAsyncronously() {
248 // Canvas redraw is already asynchronous
249 parentCanvas
.redrawAsynchronously();
253 * Getter for isCompleted variable
254 * @return true if the request is completed
256 public boolean getIsCompleted() {
261 * Setter for isCompleted variable
262 * @param isCompleted value to set the completed flag
264 public void setIsCompleted(boolean isCompleted
) {
265 this.isCompleted
= isCompleted
;