Commit | Line | Data |
---|---|---|
5419a136 | 1 | /******************************************************************************* |
61759503 | 2 | * Copyright (c) 2009, 2013 Ericsson |
5419a136 AM |
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 | * Francois Chouinard - Initial API and implementation | |
fd3f1eff | 11 | * Alexandre Montplaisir - Merge with TmfCoalescedDataRequest |
5419a136 AM |
12 | *******************************************************************************/ |
13 | ||
14 | package org.eclipse.linuxtools.internal.tmf.core.request; | |
15 | ||
fd3f1eff AM |
16 | import java.util.ArrayList; |
17 | import java.util.List; | |
18 | ||
5419a136 AM |
19 | import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer; |
20 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; | |
5419a136 | 21 | import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; |
fd3f1eff | 22 | import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; |
3bd46eef AM |
23 | import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; |
24 | import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; | |
5419a136 AM |
25 | |
26 | /** | |
27 | * The TMF coalesced event request | |
28 | * | |
5419a136 | 29 | * @author Francois Chouinard |
fd3f1eff | 30 | * @since 3.0 |
5419a136 | 31 | */ |
fd3f1eff | 32 | public class TmfCoalescedEventRequest extends TmfEventRequest { |
5419a136 AM |
33 | |
34 | // ------------------------------------------------------------------------ | |
35 | // Attributes | |
36 | // ------------------------------------------------------------------------ | |
37 | ||
fd3f1eff AM |
38 | /** The list of coalesced requests */ |
39 | private final List<ITmfEventRequest> fRequests = new ArrayList<ITmfEventRequest>(); | |
40 | ||
41 | /** | |
42 | * We do not use super.fRange, because in the case of coalesced requests, | |
43 | * the global range can be modified as sub-requets are added. | |
44 | */ | |
45 | private TmfTimeRange fRange; | |
5419a136 AM |
46 | |
47 | // ------------------------------------------------------------------------ | |
48 | // Constructor | |
49 | // ------------------------------------------------------------------------ | |
50 | ||
51 | /** | |
cf5bad96 AM |
52 | * Request 'n' events of a given type for the given time range (given |
53 | * priority). Events are returned in blocks of the given size. | |
5419a136 | 54 | * |
cf5bad96 AM |
55 | * @param dataType |
56 | * The requested data type | |
57 | * @param range | |
58 | * The range of the request. You can use | |
59 | * {@link TmfTimeRange#ETERNITY} to request all events. | |
60 | * @param index | |
61 | * The index of the first event to retrieve. Use '0' to start at | |
62 | * the beginning. | |
63 | * @param nbRequested | |
64 | * The number of events requested. You can use | |
fd3f1eff | 65 | * {@link TmfEventRequest#ALL_DATA} to request all events. |
cf5bad96 AM |
66 | * @param priority |
67 | * The requested execution priority | |
5419a136 | 68 | */ |
cf5bad96 AM |
69 | public TmfCoalescedEventRequest(Class<? extends ITmfEvent> dataType, |
70 | TmfTimeRange range, | |
71 | long index, | |
72 | int nbRequested, | |
cf5bad96 | 73 | ExecutionType priority) { |
fd3f1eff | 74 | super(ITmfEvent.class, null, index, nbRequested, priority); |
5419a136 AM |
75 | fRange = range; |
76 | ||
77 | if (TmfCoreTracer.isRequestTraced()) { | |
78 | String type = getClass().getName(); | |
79 | type = type.substring(type.lastIndexOf('.') + 1); | |
80 | @SuppressWarnings("nls") | |
81 | String message = "CREATED " | |
fd3f1eff | 82 | + (getExecType() == ITmfEventRequest.ExecutionType.BACKGROUND ? "(BG)" : "(FG)") |
5419a136 AM |
83 | + " Type=" + type + " Index=" + getIndex() + " NbReq=" + getNbRequested() |
84 | + " Range=" + getRange() | |
85 | + " DataType=" + getDataType().getSimpleName(); | |
86 | TmfCoreTracer.traceRequest(this, message); | |
87 | } | |
88 | } | |
89 | ||
fd3f1eff AM |
90 | @Override |
91 | public TmfTimeRange getRange() { | |
92 | return fRange; | |
93 | } | |
94 | ||
5419a136 AM |
95 | // ------------------------------------------------------------------------ |
96 | // Management | |
97 | // ------------------------------------------------------------------------ | |
98 | ||
fd3f1eff AM |
99 | /** |
100 | * Add a request to this one. | |
101 | * | |
102 | * @param request | |
103 | * The request to add | |
104 | */ | |
105 | public void addRequest(ITmfEventRequest request) { | |
106 | fRequests.add(request); | |
107 | merge(request); | |
5419a136 AM |
108 | } |
109 | ||
fd3f1eff AM |
110 | /** |
111 | * Check if a request is compatible with the current coalesced one | |
112 | * | |
113 | * @param request | |
114 | * The request to verify | |
115 | * @return If the request is compatible, true or false | |
116 | */ | |
117 | public boolean isCompatible(ITmfEventRequest request) { | |
118 | if (request.getExecType() == getExecType() && | |
119 | ranksOverlap(request) && | |
120 | timeRangesOverlap(request)) { | |
121 | return true; | |
cf5bad96 AM |
122 | } |
123 | return false; | |
124 | } | |
5419a136 | 125 | |
fd3f1eff AM |
126 | private boolean ranksOverlap(ITmfEventRequest request) { |
127 | long start = request.getIndex(); | |
128 | long end = start + request.getNbRequested(); | |
129 | ||
130 | // Return true if either the start or end index falls within | |
131 | // the coalesced request boundaries | |
132 | return (start <= (fIndex + fNbRequested + 1) && (end >= fIndex - 1)); | |
133 | } | |
134 | ||
135 | private boolean timeRangesOverlap(ITmfEventRequest request) { | |
5419a136 | 136 | ITmfTimestamp startTime = request.getRange().getStartTime(); |
cf5bad96 | 137 | ITmfTimestamp endTime = request.getRange().getEndTime(); |
fd3f1eff AM |
138 | return (startTime.compareTo(endTime) <= 0) && |
139 | (fRange.getStartTime().compareTo(fRange.getEndTime()) <= 0); | |
5419a136 AM |
140 | } |
141 | ||
142 | private void merge(ITmfEventRequest request) { | |
fd3f1eff AM |
143 | long start = request.getIndex(); |
144 | long end = Math.min(start + request.getNbRequested(), TmfEventRequest.ALL_DATA); | |
145 | ||
146 | if (start < fIndex) { | |
147 | if (fNbRequested != TmfEventRequest.ALL_DATA) { | |
148 | fNbRequested += (fIndex - start); | |
149 | } | |
150 | fIndex = start; | |
151 | } | |
152 | if ((request.getNbRequested() == TmfEventRequest.ALL_DATA) || | |
153 | (fNbRequested == TmfEventRequest.ALL_DATA)) { | |
154 | fNbRequested = TmfEventRequest.ALL_DATA; | |
155 | } else { | |
156 | fNbRequested = (int) Math.max(end - fIndex, fNbRequested); | |
157 | } | |
158 | ||
5419a136 | 159 | ITmfTimestamp startTime = request.getRange().getStartTime(); |
cf5bad96 | 160 | ITmfTimestamp endTime = request.getRange().getEndTime(); |
5419a136 AM |
161 | if (!fRange.contains(startTime) && fRange.getStartTime().compareTo(startTime) > 0) { |
162 | fRange = new TmfTimeRange(startTime, fRange.getEndTime()); | |
163 | } | |
164 | if (!fRange.contains(endTime) && fRange.getEndTime().compareTo(endTime) < 0) { | |
165 | fRange = new TmfTimeRange(fRange.getStartTime(), endTime); | |
166 | } | |
167 | } | |
168 | ||
fd3f1eff AM |
169 | /** |
170 | * @return The list of IDs of the sub-requests | |
171 | */ | |
172 | @SuppressWarnings("nls") | |
173 | public String getSubRequestIds() { | |
174 | StringBuffer result = new StringBuffer("["); | |
175 | for (int i = 0; i < fRequests.size(); i++) { | |
176 | if (i != 0) { | |
177 | result.append(", "); | |
178 | } | |
179 | result.append(fRequests.get(i).getRequestId()); | |
180 | } | |
181 | result.append("]"); | |
182 | return result.toString(); | |
183 | } | |
184 | ||
5419a136 | 185 | // ------------------------------------------------------------------------ |
fd3f1eff | 186 | // ITmfEventRequest |
5419a136 AM |
187 | // ------------------------------------------------------------------------ |
188 | ||
189 | @Override | |
190 | public void handleData(ITmfEvent data) { | |
191 | super.handleData(data); | |
192 | long index = getIndex() + getNbRead() - 1; | |
fd3f1eff | 193 | for (ITmfEventRequest request : fRequests) { |
5419a136 AM |
194 | if (data == null) { |
195 | request.handleData(null); | |
196 | } else { | |
197 | long start = request.getIndex(); | |
198 | long end = start + request.getNbRequested(); | |
fd3f1eff AM |
199 | if (!request.isCompleted() && index >= start && index < end) { |
200 | ITmfTimestamp ts = data.getTimestamp(); | |
201 | if (request.getRange().contains(ts)) { | |
202 | if (request.getDataType().isInstance(data)) { | |
203 | request.handleData(data); | |
5419a136 AM |
204 | } |
205 | } | |
206 | } | |
207 | } | |
208 | } | |
209 | } | |
210 | ||
fd3f1eff AM |
211 | @Override |
212 | public void start() { | |
213 | for (ITmfEventRequest request : fRequests) { | |
214 | if (!request.isCompleted()) { | |
215 | request.start(); | |
216 | } | |
217 | } | |
218 | super.start(); | |
219 | } | |
5419a136 | 220 | |
cf5bad96 | 221 | @Override |
fd3f1eff AM |
222 | public void done() { |
223 | for (ITmfEventRequest request : fRequests) { | |
224 | if (!request.isCompleted()) { | |
225 | request.done(); | |
226 | } | |
227 | } | |
228 | super.done(); | |
229 | } | |
230 | ||
231 | @Override | |
232 | public void fail() { | |
233 | for (ITmfEventRequest request : fRequests) { | |
234 | request.fail(); | |
235 | } | |
236 | super.fail(); | |
237 | } | |
238 | ||
239 | @Override | |
240 | public void cancel() { | |
241 | for (ITmfEventRequest request : fRequests) { | |
242 | if (!request.isCompleted()) { | |
243 | request.cancel(); | |
244 | } | |
245 | } | |
246 | super.cancel(); | |
cf5bad96 | 247 | } |
5419a136 | 248 | |
cf5bad96 | 249 | @Override |
fd3f1eff AM |
250 | public synchronized boolean isCompleted() { |
251 | // Firstly, check if coalescing request is completed | |
252 | if (super.isCompleted()) { | |
253 | return true; | |
254 | } | |
255 | ||
256 | // Secondly, check if all sub-requests are finished | |
257 | if (fRequests.size() > 0) { | |
258 | // If all sub requests are completed the coalesced request is | |
259 | // treated as completed, too. | |
260 | for (ITmfEventRequest request : fRequests) { | |
261 | if (!request.isCompleted()) { | |
262 | return false; | |
263 | } | |
264 | } | |
265 | return true; | |
266 | } | |
267 | ||
268 | // Coalescing request is not finished if there are no sub-requests | |
269 | return false; | |
270 | } | |
271 | ||
272 | @Override | |
273 | public synchronized boolean isCancelled() { | |
274 | // Firstly, check if coalescing request is canceled | |
275 | if (super.isCancelled()) { | |
276 | return true; | |
277 | } | |
278 | ||
279 | // Secondly, check if all sub-requests are canceled | |
280 | if (fRequests.size() > 0) { | |
281 | // If all sub requests are canceled the coalesced request is | |
282 | // treated as completed, too. | |
283 | for (ITmfEventRequest request : fRequests) { | |
284 | if (!request.isCancelled()) { | |
285 | return false; | |
286 | } | |
287 | } | |
288 | return true; | |
289 | } | |
290 | ||
291 | // Coalescing request is not canceled if there are no sub-requests | |
292 | return false; | |
293 | ||
cf5bad96 | 294 | } |
5419a136 AM |
295 | |
296 | // ------------------------------------------------------------------------ | |
297 | // Object | |
298 | // ------------------------------------------------------------------------ | |
299 | ||
300 | @Override | |
301 | // All requests have a unique id | |
302 | public int hashCode() { | |
cf5bad96 | 303 | return super.hashCode(); |
5419a136 AM |
304 | } |
305 | ||
306 | @Override | |
307 | public boolean equals(Object other) { | |
cf5bad96 AM |
308 | if (other instanceof TmfCoalescedEventRequest) { |
309 | TmfCoalescedEventRequest request = (TmfCoalescedEventRequest) other; | |
310 | return (request.getDataType() == getDataType()) && | |
311 | (request.getIndex() == getIndex()) && | |
312 | (request.getNbRequested() == getNbRequested()) && | |
fd3f1eff | 313 | (request.getRange().equals(fRange)); |
cf5bad96 AM |
314 | } |
315 | return false; | |
5419a136 AM |
316 | } |
317 | ||
318 | @Override | |
319 | @SuppressWarnings("nls") | |
320 | public String toString() { | |
cf5bad96 | 321 | return "[TmfCoalescedEventRequest(" + getRequestId() + "," + getDataType().getSimpleName() |
b1b156f3 | 322 | + "," + getExecType() + "," + getRange() + "," + getIndex() + "," + getNbRequested() |
f4d1e591 | 323 | + ", " + fRequests.toString() + ")]"; |
5419a136 AM |
324 | } |
325 | ||
326 | } |