2010-07-30 Francois Chouinard <fchouinard@gmail.com> Fix for Bug311930 and Bug32168
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.ui / src / org / eclipse / linuxtools / lttng / ui / views / histogram / HistogramRequest.java
1 /*******************************************************************************
2 * Copyright (c) 2009 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 * William Bourque - Initial API and implementation
11 *
12 * Modifications:
13 * 2010-07-16 Yuriy Vashchuk - Heritage correction.
14 *******************************************************************************/
15 package org.eclipse.linuxtools.lttng.ui.views.histogram;
16
17 import org.eclipse.linuxtools.lttng.event.LttngEvent;
18 import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
19 import org.eclipse.linuxtools.tmf.request.ITmfDataRequest;
20 import org.eclipse.linuxtools.tmf.request.TmfEventRequest;
21
22 /**
23 * <b><u>HistogramRequest</u></b>
24 * <p>
25 * Request class, to perform a request to TMF for the histograms.
26 * <p>
27 */
28 public class HistogramRequest extends TmfEventRequest<LttngEvent> {
29 /*
30 private HistogramContent histogramContent = null;
31 */
32
33 private int lastInterval = 0;
34 private long lastRangeTime = 0L;
35 private long nbEventsInInterval = 0L;
36
37 private int nbIntervalNotEmpty = 1;
38 private int nbEventRead = 0;
39
40 private int lastDrawPosition = 0;
41
42 private HistogramCanvas parentCanvas = null;
43
44 private boolean isCompleted = false;
45
46 /**
47 * Constructor for HistogramRequest.<p>
48 * Prepare the request in TMF and reset the histogram content.
49 *
50 * @param range Range of the request.
51 * @param nbRequested Nb events requested. Can be "Infinity" for all.
52 * @param newParentCanvas HistogramCanvas related to the request.
53 * @param timeInterval Time interval to consider (i.e. : 1 interval is 1 bar in the histogram)
54 *
55 * @see org.eclipse.linuxtools.tmf.request.TmfEventRequest
56 */
57 public HistogramRequest(TmfTimeRange range, int nbRequested, HistogramCanvas newParentCanvas, long timeInterval, ITmfDataRequest.ExecutionType execType) {
58 super((Class<LttngEvent>)LttngEvent.class, range, nbRequested, HistogramConstant.MAX_EVENTS_PER_READ, execType);
59
60 setIsCompleted(false);
61
62 // *** FIXME ***
63 // This does not work! The request won't be processed or the number of events returned is wrong!
64 // We cannot use this !
65 //super((Class<LttngEvent>)dataType, range);
66
67 parentCanvas = newParentCanvas;
68
69 // Reset the content of the HistogramContent... the given data better be valid or this will fail.
70 parentCanvas.getHistogramContent().clearContentData();
71 parentCanvas.getHistogramContent().resetTable(range.getStartTime().getValue(), range.getEndTime().getValue(), timeInterval);
72
73 lastRangeTime = range.getStartTime().getValue();
74
75 // Notify the UI even before the request started, so we set the timestamp already.
76 parentCanvas.notifyParentUpdatedInformationAsynchronously();
77 }
78
79 /**
80 * HandleData function : will be called by TMF each time a new event is receive for the request.<p>
81 * Calculation for the content is done here.
82 */
83 @Override
84 public void handleData() {
85 LttngEvent[] result = getData();
86 LttngEvent event = (result.length > 0) ? result[0] : null;
87
88 // *** FIXME ***
89 // *** EVIL BUG ***
90 // The request by timerange only does not work! (see constructor above)
91 // However, the request with number of events will loop until it reach its number or EOF
92 // We have to filter out ourself the extra useless events!
93 //
94 if (event != null) {
95
96 LttngEvent tmpEvent = (LttngEvent) event;
97
98 // Tracer.trace("Hst: " + event.getTimestamp());
99
100 // This check is linked to the evil fix mentionned above
101 if ( ( tmpEvent.getTimestamp().getValue() >= parentCanvas.getHistogramContent().getStartTime() ) &&
102 ( tmpEvent.getTimestamp().getValue() <= parentCanvas.getHistogramContent().getEndTime() ) )
103 {
104
105 // Distance (in time) between this event and the last one we read
106 long distance = ( tmpEvent.getTimestamp().getValue() - lastRangeTime );
107
108 // Check if we changed of interval (the distance is higher than the interval time)
109 if ( distance > parentCanvas.getHistogramContent().getElementsTimeInterval() ) {
110
111 parentCanvas.getHistogramContent().getElementByIndex(lastInterval).intervalNbEvents = nbEventsInInterval;
112 lastRangeTime = tmpEvent.getTimestamp().getValue();
113
114 // * NOTE *
115 // We can skip several interval at once, so we need to find what was our interval now
116 lastInterval = (int)((lastRangeTime - parentCanvas.getHistogramContent().getStartTime()) / parentCanvas.getHistogramContent().getElementsTimeInterval() );
117
118 // *** HACK ***
119 // Because of the threads, weird phenomenons seem to happen here, like a position after the
120 // element range because another request was issued.
121 // This enforce the position but may result in slightly inconsistent result (i.e. a weird misplaced bar sometime).
122 if ( lastInterval < 0 ) {
123 lastInterval = 0;
124 }
125 else if ( lastInterval >= parentCanvas.getHistogramContent().getNbElement() ) {
126 lastInterval = (parentCanvas.getHistogramContent().getNbElement()-1);
127 }
128
129 // * NOTE *
130 // We save the time we have here. This mean only the FIRST time read in an interval will be saved.
131 parentCanvas.getHistogramContent().getElementByIndex(lastInterval).firstIntervalTimestamp = lastRangeTime;
132 parentCanvas.getHistogramContent().setReadyUpToPosition(lastInterval);
133
134 nbIntervalNotEmpty++;
135 nbEventsInInterval = 1L;
136 }
137 // We are still in the same interval, just keep counting
138 else {
139 nbEventsInInterval++;
140 }
141
142 if ( nbEventsInInterval > parentCanvas.getHistogramContent().getHeighestEventCount() ) {
143 parentCanvas.getHistogramContent().setHeighestEventCount(nbEventsInInterval);
144 }
145 nbEventRead++;
146
147 // Call an asynchronous redraw every REDRAW_EVERY_NB_EVENTS events
148 // That way we don't need to wait until to end to have something on the screen
149 if ( nbEventRead % HistogramConstant.REDRAW_EVERY_NB_EVENTS == 0 ) {
150 redrawAsyncronously();
151 }
152 }
153 }
154 // We got a null event! This mean we reach the end of the request.
155 // Save the last interval we had, so we won't miss the very last events at the end.
156 else {
157 // Save the last events
158 parentCanvas.getHistogramContent().getElementByIndex(lastInterval).intervalNbEvents = nbEventsInInterval;
159 // We reached the end of the request, so assume we fill up the content as well
160 parentCanvas.getHistogramContent().setReadyUpToPosition(parentCanvas.getHistogramContent().getNbElement());
161
162 // If the interval wasn't null, count this as a "non empty" interval
163 if (nbEventsInInterval > 0) {
164 nbIntervalNotEmpty++;
165 }
166 }
167 }
168
169 /**
170 * Function that is called when the request completed (successful or not).<p>
171 * Update information and redraw the screen.
172 */
173 @Override
174 public void handleCompleted() {
175 setIsCompleted(true);
176 parentCanvas.notifyParentUpdatedInformationAsynchronously();
177 redrawAsyncronously();
178 super.handleCompleted();
179 // System.out.println(System.currentTimeMillis() + ": HistogramView (" + ((getExecType() == ExecutionType.LONG) ? "long" : "short") + ") completed");
180 }
181
182 // /**
183 // * Function that is called when the request completed successfully.<p>
184 // */
185 // @Override
186 // public void handleSuccess() {
187 // // Nothing different from completed.
188 // }
189
190 // /**
191 // * Function that is called when the request completed in failure.<p>
192 // */
193 // @Override
194 // public void handleFailure() {
195 // // Nothing different from cancel.
196 // }
197
198 /**
199 * Function that is called when the request was cancelled.<p>
200 * Redraw and set the requestCompleted flag to true;
201 */
202 @Override
203 public void handleCancel() {
204 redrawAsyncronously();
205 }
206
207 /**
208 * Update the HistogramContent with the latest information.<p>
209 * This will perform some calculation that might be a bit harsh so it should'nt be called too often.
210 */
211 public void updateEventsInfo() {
212 // *** Note ***
213 // The average number of event is calculated while skipping empty interval if asked
214 int averageNumberOfEvents = 0;
215 if ( HistogramConstant.SKIP_EMPTY_INTERVALS_WHEN_CALCULATING_AVERAGE ) {
216 averageNumberOfEvents = (int)Math.ceil((double)nbEventRead / (double)nbIntervalNotEmpty);
217 }
218 else {
219 averageNumberOfEvents = (int)Math.ceil((double)nbEventRead / (double)parentCanvas.getHistogramContent().getNbElement());
220 }
221
222 parentCanvas.getHistogramContent().setAverageNumberOfEvents(averageNumberOfEvents);
223
224 // It is possible that the height factor didn't change;
225 // If not, we only need to redraw the updated section, no the whole content
226 // Save the actual height, recalculate the height and check if there was any changes
227 double previousHeightFactor = parentCanvas.getHistogramContent().getHeightFactor();
228 parentCanvas.getHistogramContent().recalculateHeightFactor();
229 if ( parentCanvas.getHistogramContent().getHeightFactor() != previousHeightFactor ) {
230 parentCanvas.getHistogramContent().recalculateEventHeight();
231 }
232 else {
233 parentCanvas.getHistogramContent().recalculateEventHeightInInterval(lastDrawPosition, parentCanvas.getHistogramContent().getReadyUpToPosition());
234 }
235
236 lastDrawPosition = parentCanvas.getHistogramContent().getReadyUpToPosition();
237 }
238
239 /**
240 * Perform an asynchonous redraw of the screen.
241 */
242 public void redrawAsyncronously() {
243 updateEventsInfo();
244 // Canvas redraw is already asynchronous
245 parentCanvas.redrawAsynchronously();
246 }
247
248 /**
249 * Getter for isCompleted variable
250 * @return true if the request is completed
251 */
252 public boolean getIsCompleted() {
253 return isCompleted;
254 }
255
256 /**
257 * Setter for isCompleted variable
258 * @param isCompleted value to set the completed flag
259 */
260 public void setIsCompleted(boolean isCompleted) {
261 this.isCompleted = isCompleted;
262 }
263
264 }
This page took 0.039347 seconds and 5 git commands to generate.