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