Commit | Line | Data |
---|---|---|
378e7718 WB |
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 | *******************************************************************************/ | |
6e512b93 ASL |
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.TmfEvent; | |
16 | import org.eclipse.linuxtools.tmf.event.TmfTimeRange; | |
550d787e | 17 | import org.eclipse.linuxtools.tmf.request.ITmfDataRequest; |
6e512b93 ASL |
18 | import org.eclipse.linuxtools.tmf.request.TmfEventRequest; |
19 | ||
378e7718 WB |
20 | /** |
21 | * <b><u>HistogramRequest</u></b> | |
22 | * <p> | |
23 | * Request class, to perform a request to TMF for the histograms. | |
24 | * <p> | |
25 | */ | |
6e512b93 | 26 | public class HistogramRequest extends TmfEventRequest<LttngEvent> { |
7c1540ab | 27 | protected HistogramContent histogramContent = null; |
6e512b93 | 28 | |
1406f802 WB |
29 | protected int lastInterval = 0; |
30 | protected long lastRangeTime = 0L; | |
1155ca9f | 31 | protected long nbEventsInInterval = 0L; |
6e512b93 | 32 | |
1406f802 WB |
33 | protected int nbIntervalNotEmpty = 1; |
34 | protected int nbEventRead = 0; | |
6e512b93 | 35 | |
1406f802 | 36 | protected int lastDrawPosition = 0; |
3fda53ab | 37 | |
7c1540ab | 38 | protected HistogramCanvas parentCanvas = null; |
ecfd1d41 | 39 | |
378e7718 WB |
40 | /** |
41 | * Constructor for HistogramRequest.<p> | |
42 | * Prepare the request in TMF and reset the histogram content. | |
43 | * | |
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) | |
48 | * | |
49 | * @see org.eclipse.linuxtools.tmf.request.TmfEventRequest | |
50 | */ | |
550d787e FC |
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); | |
6e512b93 | 53 | |
ecfd1d41 WB |
54 | // *** FIXME *** |
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); | |
833a21aa | 58 | |
6e512b93 | 59 | parentCanvas = newParentCanvas; |
378e7718 | 60 | histogramContent = parentCanvas.getHistogramContent(); |
6e512b93 | 61 | |
378e7718 | 62 | // Reset the content of the HistogramContent... the given data better be valid or this will fail. |
833a21aa WB |
63 | histogramContent.clearContentData(); |
64 | histogramContent.resetTable(range.getStartTime().getValue(), range.getEndTime().getValue(), timeInterval); | |
65 | ||
66 | lastRangeTime = range.getStartTime().getValue(); | |
ecfd1d41 | 67 | |
833a21aa WB |
68 | // Notify the UI even before the request started, so we set the timestamp already. |
69 | parentCanvas.notifyParentUpdatedInformationAsynchronously(); | |
6e512b93 | 70 | } |
378e7718 WB |
71 | |
72 | /** | |
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. | |
75 | */ | |
6e512b93 ASL |
76 | @Override |
77 | public void handleData() { | |
78 | TmfEvent[] result = getData(); | |
79 | TmfEvent[] evt = new TmfEvent[1]; | |
80 | ||
81 | evt[0] = (result.length > 0) ? result[0] : null; | |
82 | ||
ecfd1d41 WB |
83 | // *** FIXME *** |
84 | // *** EVIL BUG *** | |
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! | |
88 | // | |
7ef9ae3f WB |
89 | if (evt[0] != null) { |
90 | ||
6e512b93 ASL |
91 | LttngEvent tmpEvent = (LttngEvent)evt[0]; |
92 | ||
ecfd1d41 | 93 | // This check is linked to the evil fix mentionned above |
833a21aa WB |
94 | if ( ( tmpEvent.getTimestamp().getValue() >= histogramContent.getStartTime() ) && |
95 | ( tmpEvent.getTimestamp().getValue() <= histogramContent.getEndTime() ) ) | |
96 | { | |
378e7718 WB |
97 | |
98 | // Distance (in time) between this event and the last one we read | |
ecfd1d41 | 99 | long distance = ( tmpEvent.getTimestamp().getValue() - lastRangeTime ); |
6e512b93 | 100 | |
378e7718 | 101 | // Check if we changed of interval (the distance is higher than the interval time) |
3fda53ab | 102 | if ( distance > histogramContent.getElementsTimeInterval() ) { |
ecfd1d41 | 103 | |
378e7718 | 104 | histogramContent.getElementByIndex(lastInterval).intervalNbEvents = nbEventsInInterval; |
ecfd1d41 WB |
105 | lastRangeTime = tmpEvent.getTimestamp().getValue(); |
106 | ||
378e7718 WB |
107 | // * NOTE * |
108 | // We can skip several interval at once, so we need to find what was our interval now | |
3fda53ab | 109 | lastInterval = (int)((lastRangeTime - histogramContent.getStartTime()) / histogramContent.getElementsTimeInterval() ); |
ecfd1d41 WB |
110 | |
111 | // *** HACK *** | |
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). | |
378e7718 WB |
115 | if ( lastInterval < 0 ) { |
116 | lastInterval = 0; | |
ecfd1d41 | 117 | } |
378e7718 WB |
118 | else if ( lastInterval >= histogramContent.getNbElement() ) { |
119 | lastInterval = (histogramContent.getNbElement()-1); | |
ecfd1d41 WB |
120 | } |
121 | ||
378e7718 | 122 | // * NOTE * |
050df4a5 | 123 | // We save the time we have here. This mean only the FIRST time read in an interval will be saved. |
378e7718 WB |
124 | histogramContent.getElementByIndex(lastInterval).firstIntervalTimestamp = lastRangeTime; |
125 | histogramContent.setReadyUpToPosition(lastInterval); | |
ecfd1d41 | 126 | |
378e7718 | 127 | nbIntervalNotEmpty++; |
544fe9b7 | 128 | nbEventsInInterval = 1L; |
6e512b93 | 129 | } |
378e7718 | 130 | // We are still in the same interval, just keep counting |
ecfd1d41 | 131 | else { |
378e7718 | 132 | nbEventsInInterval++; |
ecfd1d41 WB |
133 | } |
134 | ||
1406f802 WB |
135 | if ( nbEventsInInterval > histogramContent.getHeighestEventCount() ) { |
136 | histogramContent.setHeighestEventCount(nbEventsInInterval); | |
137 | } | |
ecfd1d41 | 138 | nbEventRead++; |
6cf16d22 | 139 | |
378e7718 WB |
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 ) { | |
6cf16d22 WB |
143 | redrawAsyncronously(); |
144 | } | |
ecfd1d41 | 145 | } |
b59134e1 | 146 | } |
7ef9ae3f WB |
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. | |
149 | else { | |
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()); | |
154 | ||
155 | // If the interval wasn't null, count this as a "non empty" interval | |
156 | if (nbEventsInInterval > 0) { | |
157 | nbIntervalNotEmpty++; | |
158 | } | |
159 | } | |
6e512b93 ASL |
160 | } |
161 | ||
378e7718 WB |
162 | /** |
163 | * Function that is called when the request completed (successful or not).<p> | |
164 | * Update information and redraw the screen. | |
165 | */ | |
6e512b93 ASL |
166 | @Override |
167 | public void handleCompleted() { | |
833a21aa | 168 | parentCanvas.notifyParentUpdatedInformationAsynchronously(); |
6e512b93 ASL |
169 | redrawAsyncronously(); |
170 | } | |
171 | ||
378e7718 WB |
172 | /** |
173 | * Function that is called when the request completed successfully.<p> | |
174 | */ | |
6e512b93 ASL |
175 | @Override |
176 | public void handleSuccess() { | |
6cf16d22 | 177 | // Nothing different from completed. |
6e512b93 ASL |
178 | } |
179 | ||
378e7718 WB |
180 | /** |
181 | * Function that is called when the request completed in failure.<p> | |
182 | */ | |
6e512b93 ASL |
183 | @Override |
184 | public void handleFailure() { | |
6cf16d22 | 185 | // Nothing different from cancel. |
6e512b93 ASL |
186 | } |
187 | ||
378e7718 WB |
188 | /** |
189 | * Function that is called when the request was cancelled.<p> | |
190 | * Redraw and set the requestCompleted flag to true; | |
191 | */ | |
6e512b93 ASL |
192 | @Override |
193 | public void handleCancel() { | |
6cf16d22 | 194 | redrawAsyncronously(); |
6e512b93 ASL |
195 | } |
196 | ||
378e7718 WB |
197 | /** |
198 | * Update the HistogramContent with the latest information.<p> | |
050df4a5 | 199 | * This will perform some calculation that might be a bit harsh so it should'nt be called too often. |
378e7718 | 200 | */ |
6e512b93 | 201 | public void updateEventsInfo() { |
050df4a5 WB |
202 | // *** Note *** |
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 ) { | |
1406f802 | 206 | averageNumberOfEvents = (int)Math.ceil((double)nbEventRead / (double)nbIntervalNotEmpty); |
050df4a5 WB |
207 | } |
208 | else { | |
1406f802 | 209 | averageNumberOfEvents = (int)Math.ceil((double)nbEventRead / (double)histogramContent.getNbElement()); |
050df4a5 | 210 | } |
1406f802 | 211 | |
3fda53ab WB |
212 | histogramContent.setAverageNumberOfEvents(averageNumberOfEvents); |
213 | ||
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(); | |
221 | } | |
222 | else { | |
223 | histogramContent.recalculateEventHeightInInterval(lastDrawPosition, histogramContent.getReadyUpToPosition()); | |
224 | } | |
050df4a5 | 225 | |
3fda53ab | 226 | lastDrawPosition = histogramContent.getReadyUpToPosition(); |
6e512b93 ASL |
227 | } |
228 | ||
378e7718 WB |
229 | /** |
230 | * Perform an asynchonous redraw of the screen. | |
231 | */ | |
6e512b93 ASL |
232 | public void redrawAsyncronously() { |
233 | updateEventsInfo(); | |
378e7718 | 234 | // Canvas redraw is already asynchronous |
6cf16d22 | 235 | parentCanvas.redrawAsynchronously(); |
6e512b93 ASL |
236 | } |
237 | ||
238 | } |