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