Commit | Line | Data |
---|---|---|
8c8bf09f ASL |
1 | /******************************************************************************* |
2 | * Copyright (c) 2009, 2010 Ericsson | |
9b749023 | 3 | * |
8c8bf09f ASL |
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 | |
9b749023 | 8 | * |
8c8bf09f ASL |
9 | * Contributors: |
10 | * Francois Chouinard - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
8fd82db5 | 13 | package org.eclipse.linuxtools.internal.tmf.core.request; |
8c8bf09f ASL |
14 | |
15 | import java.util.Vector; | |
16 | ||
72f1e62a | 17 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; |
8fd82db5 FC |
18 | import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest; |
19 | import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest; | |
8c8bf09f ASL |
20 | |
21 | /** | |
8fd82db5 | 22 | * The TMF coalesced data request |
9b749023 | 23 | * |
8fd82db5 FC |
24 | * @version 1.0 |
25 | * @author Francois Chouinard | |
8c8bf09f | 26 | */ |
72f1e62a | 27 | public class TmfCoalescedDataRequest<T extends ITmfEvent> extends TmfDataRequest<T> { |
8c8bf09f ASL |
28 | |
29 | // ------------------------------------------------------------------------ | |
30 | // Attributes | |
31 | // ------------------------------------------------------------------------ | |
32 | ||
0d9a6d76 FC |
33 | /** |
34 | * The list of coalesced requests | |
35 | */ | |
2fb2eb37 | 36 | protected Vector<ITmfDataRequest<T>> fRequests = new Vector<ITmfDataRequest<T>>(); |
8c8bf09f ASL |
37 | |
38 | // ------------------------------------------------------------------------ | |
39 | // Constructor | |
40 | // ------------------------------------------------------------------------ | |
41 | ||
42 | /** | |
0d9a6d76 FC |
43 | * Request all the events of a given type (high priority) |
44 | * Events are returned in blocks of the default size (DEFAULT_BLOCK_SIZE). | |
9b749023 | 45 | * |
0d9a6d76 | 46 | * @param dataType the requested data type |
8c8bf09f ASL |
47 | */ |
48 | public TmfCoalescedDataRequest(Class<T> dataType) { | |
f6b14ce2 | 49 | this(dataType, 0, ALL_DATA, DEFAULT_BLOCK_SIZE, ExecutionType.FOREGROUND); |
cb866e08 FC |
50 | } |
51 | ||
0d9a6d76 FC |
52 | /** |
53 | * Request all the events of a given type (given priority) | |
54 | * Events are returned in blocks of the default size (DEFAULT_BLOCK_SIZE). | |
9b749023 | 55 | * |
0d9a6d76 FC |
56 | * @param dataType the requested data type |
57 | * @param priority the requested execution priority | |
58 | */ | |
59 | public TmfCoalescedDataRequest(Class<T> dataType, ExecutionType priority) { | |
60 | this(dataType, 0, ALL_DATA, DEFAULT_BLOCK_SIZE, priority); | |
8c8bf09f ASL |
61 | } |
62 | ||
63 | /** | |
0d9a6d76 FC |
64 | * Request all the events of a given type from the given index (high priority) |
65 | * Events are returned in blocks of the default size (DEFAULT_BLOCK_SIZE). | |
9b749023 | 66 | * |
0d9a6d76 FC |
67 | * @param dataType the requested data type |
68 | * @param index the index of the first event to retrieve | |
8c8bf09f | 69 | */ |
9e0640dc | 70 | public TmfCoalescedDataRequest(Class<T> dataType, long index) { |
f6b14ce2 | 71 | this(dataType, index, ALL_DATA, DEFAULT_BLOCK_SIZE, ExecutionType.FOREGROUND); |
cb866e08 FC |
72 | } |
73 | ||
0d9a6d76 FC |
74 | /** |
75 | * Request all the events of a given type from the given index (given priority) | |
76 | * Events are returned in blocks of the default size (DEFAULT_BLOCK_SIZE). | |
9b749023 | 77 | * |
0d9a6d76 FC |
78 | * @param dataType the requested data type |
79 | * @param index the index of the first event to retrieve | |
80 | * @param priority the requested execution priority | |
81 | */ | |
9e0640dc | 82 | public TmfCoalescedDataRequest(Class<T> dataType, long index, ExecutionType priority) { |
0d9a6d76 | 83 | this(dataType, index, ALL_DATA, DEFAULT_BLOCK_SIZE, priority); |
8c8bf09f ASL |
84 | } |
85 | ||
86 | /** | |
0d9a6d76 FC |
87 | * Request 'n' events of a given type from the given index (high priority) |
88 | * Events are returned in blocks of the default size (DEFAULT_BLOCK_SIZE). | |
9b749023 | 89 | * |
0d9a6d76 FC |
90 | * @param dataType the requested data type |
91 | * @param index the index of the first event to retrieve | |
92 | * @param nbRequested the number of events requested | |
8c8bf09f | 93 | */ |
9e0640dc | 94 | public TmfCoalescedDataRequest(Class<T> dataType, long index, int nbRequested) { |
f6b14ce2 | 95 | this(dataType, index, nbRequested, DEFAULT_BLOCK_SIZE, ExecutionType.FOREGROUND); |
cb866e08 FC |
96 | } |
97 | ||
0d9a6d76 FC |
98 | /** |
99 | * Request 'n' events of a given type from the given index (given priority) | |
100 | * Events are returned in blocks of the default size (DEFAULT_BLOCK_SIZE). | |
9b749023 | 101 | * |
0d9a6d76 FC |
102 | * @param dataType the requested data type |
103 | * @param index the index of the first event to retrieve | |
104 | * @param nbRequested the number of events requested | |
105 | * @param priority the requested execution priority | |
106 | */ | |
9e0640dc | 107 | public TmfCoalescedDataRequest(Class<T> dataType, long index, int nbRequested, ExecutionType priority) { |
0d9a6d76 | 108 | this(dataType, index, nbRequested, DEFAULT_BLOCK_SIZE, priority); |
8c8bf09f ASL |
109 | } |
110 | ||
111 | /** | |
0d9a6d76 FC |
112 | * Request 'n' events of a given type from the given index (high priority). |
113 | * Events are returned in blocks of the given size. | |
9b749023 | 114 | * |
0d9a6d76 FC |
115 | * @param dataType the requested data type |
116 | * @param index the index of the first event to retrieve | |
117 | * @param nbRequested the number of events requested | |
118 | * @param blockSize the number of events per block | |
8c8bf09f | 119 | */ |
9e0640dc | 120 | public TmfCoalescedDataRequest(Class<T> dataType, long index, int nbRequested, int blockSize) { |
f6b14ce2 | 121 | super(dataType, index, nbRequested, blockSize, ExecutionType.FOREGROUND); |
cb866e08 FC |
122 | } |
123 | ||
0d9a6d76 FC |
124 | /** |
125 | * Request 'n' events of a given type from the given index (given priority). | |
126 | * Events are returned in blocks of the given size. | |
9b749023 | 127 | * |
0d9a6d76 FC |
128 | * @param dataType the requested data type |
129 | * @param index the index of the first event to retrieve | |
130 | * @param nbRequested the number of events requested | |
131 | * @param blockSize the number of events per block | |
132 | * @param priority the requested execution priority | |
133 | */ | |
9e0640dc | 134 | public TmfCoalescedDataRequest(Class<T> dataType, long index, int nbRequested, int blockSize, ExecutionType priority) { |
0d9a6d76 | 135 | super(dataType, index, nbRequested, blockSize, priority); |
8c8bf09f ASL |
136 | } |
137 | ||
138 | // ------------------------------------------------------------------------ | |
139 | // Management | |
140 | // ------------------------------------------------------------------------ | |
141 | ||
9b749023 AM |
142 | /** |
143 | * Add a request to this one. | |
144 | * | |
145 | * @param request The request to add | |
146 | */ | |
147 | public void addRequest(ITmfDataRequest<T> request) { | |
148 | fRequests.add(request); | |
923b8517 | 149 | merge(request); |
9b749023 | 150 | } |
8c8bf09f | 151 | |
9b749023 AM |
152 | /** |
153 | * Check if a request is compatible with the current coalesced one | |
154 | * | |
155 | * @param request | |
156 | * The request to verify | |
157 | * @return If the request is compatible, true or false | |
158 | */ | |
159 | public boolean isCompatible(ITmfDataRequest<T> request) { | |
160 | if (request.getExecType() == getExecType()) { | |
161 | return overlaps(request); | |
162 | } | |
163 | return false; | |
164 | } | |
8c8bf09f | 165 | |
923b8517 FC |
166 | private boolean overlaps(ITmfDataRequest<T> request) { |
167 | long start = request.getIndex(); | |
168 | long end = start + request.getNbRequested(); | |
169 | ||
170 | // Return true if either the start or end index falls within | |
171 | // the coalesced request boundaries | |
172 | return (start <= (fIndex + fNbRequested + 1) && (end >= fIndex - 1)); | |
173 | } | |
174 | ||
175 | private void merge(ITmfDataRequest<T> request) { | |
176 | long start = request.getIndex(); | |
177 | long end = Math.min(start + request.getNbRequested(), TmfDataRequest.ALL_DATA); | |
9b749023 | 178 | |
923b8517 FC |
179 | if (start < fIndex) { |
180 | if (fNbRequested != TmfDataRequest.ALL_DATA) { | |
181 | fNbRequested += (fIndex - start); | |
182 | } | |
183 | fIndex = start; | |
184 | } | |
185 | if ((request.getNbRequested() == TmfDataRequest.ALL_DATA) || | |
186 | (fNbRequested == TmfDataRequest.ALL_DATA)) | |
187 | { | |
188 | fNbRequested = TmfDataRequest.ALL_DATA; | |
189 | } else { | |
190 | fNbRequested = (int) Math.max(end - fIndex, fNbRequested); | |
191 | } | |
192 | } | |
193 | ||
9b749023 AM |
194 | /** |
195 | * @return The list of IDs of the sub-requests | |
196 | */ | |
90891c08 FC |
197 | @SuppressWarnings("nls") |
198 | public String getSubRequestIds() { | |
199 | StringBuffer result = new StringBuffer("["); | |
200 | for (int i = 0; i < fRequests.size(); i++) { | |
9b749023 AM |
201 | if (i != 0) { |
202 | result.append(", "); | |
203 | } | |
90891c08 FC |
204 | result.append(fRequests.get(i).getRequestId()); |
205 | } | |
206 | result.append("]"); | |
207 | return result.toString(); | |
208 | } | |
209 | ||
8c8bf09f ASL |
210 | // ------------------------------------------------------------------------ |
211 | // ITmfDataRequest | |
212 | // ------------------------------------------------------------------------ | |
213 | ||
214 | @Override | |
f9673903 FC |
215 | public void handleData(T data) { |
216 | super.handleData(data); | |
217 | // Don't call sub-requests handleData() unless this is a | |
218 | // TmfCoalescedDataRequest; extended classes should call | |
219 | // the sub-requests handleData(). | |
220 | if (getClass() == TmfCoalescedDataRequest.class) { | |
ad4f74f5 | 221 | long index = getIndex() + getNbRead(); |
f9673903 | 222 | for (ITmfDataRequest<T> request : fRequests) { |
c1c69938 | 223 | if (!request.isCompleted()) { |
1b70b6dc | 224 | if (request.getDataType().isInstance(data)) { |
923b8517 FC |
225 | long start = request.getIndex(); |
226 | long end = start + request.getNbRequested() - 1; | |
227 | if (index >= start && index < end) { | |
228 | request.handleData(data); | |
229 | } | |
1b70b6dc | 230 | } |
c1c69938 | 231 | } |
f9673903 FC |
232 | } |
233 | } | |
8c8bf09f ASL |
234 | } |
235 | ||
c1c69938 FC |
236 | @Override |
237 | public void start() { | |
238 | for (ITmfDataRequest<T> request : fRequests) { | |
239 | if (!request.isCompleted()) { | |
240 | request.start(); | |
241 | } | |
242 | } | |
243 | super.start(); | |
244 | } | |
9b749023 | 245 | |
f9673903 FC |
246 | @Override |
247 | public void done() { | |
2fb2eb37 | 248 | for (ITmfDataRequest<T> request : fRequests) { |
c1c69938 FC |
249 | if (!request.isCompleted()) { |
250 | request.done(); | |
251 | } | |
8c8bf09f | 252 | } |
2fb2eb37 | 253 | super.done(); |
8c8bf09f ASL |
254 | } |
255 | ||
256 | @Override | |
f9673903 | 257 | public void fail() { |
2fb2eb37 FC |
258 | for (ITmfDataRequest<T> request : fRequests) { |
259 | request.fail(); | |
8c8bf09f | 260 | } |
2fb2eb37 | 261 | super.fail(); |
8c8bf09f ASL |
262 | } |
263 | ||
264 | @Override | |
f9673903 | 265 | public void cancel() { |
2fb2eb37 | 266 | for (ITmfDataRequest<T> request : fRequests) { |
c1c69938 FC |
267 | if (!request.isCompleted()) { |
268 | request.cancel(); | |
269 | } | |
8c8bf09f | 270 | } |
2fb2eb37 | 271 | super.cancel(); |
8c8bf09f | 272 | } |
9b749023 | 273 | |
c1c69938 | 274 | @Override |
9b749023 | 275 | public synchronized boolean isCompleted() { |
c1c69938 FC |
276 | // Firstly, check if coalescing request is completed |
277 | if (super.isCompleted()) { | |
278 | return true; | |
279 | } | |
280 | ||
281 | // Secondly, check if all sub-requests are finished | |
282 | if (fRequests.size() > 0) { | |
9b749023 | 283 | // If all sub requests are completed the coalesced request is |
c1c69938 FC |
284 | // treated as completed, too. |
285 | for (ITmfDataRequest<T> request : fRequests) { | |
286 | if (!request.isCompleted()) { | |
287 | return false; | |
288 | } | |
289 | } | |
290 | return true; | |
291 | } | |
292 | ||
293 | // Coalescing request is not finished if there are no sub-requests | |
294 | return false; | |
295 | } | |
8c8bf09f | 296 | |
c1c69938 | 297 | @Override |
9b749023 | 298 | public synchronized boolean isCancelled() { |
c1c69938 FC |
299 | // Firstly, check if coalescing request is canceled |
300 | if (super.isCancelled()) { | |
301 | return true; | |
302 | } | |
303 | ||
304 | // Secondly, check if all sub-requests are canceled | |
305 | if (fRequests.size() > 0) { | |
9b749023 | 306 | // If all sub requests are canceled the coalesced request is |
c1c69938 FC |
307 | // treated as completed, too. |
308 | for (ITmfDataRequest<T> request : fRequests) { | |
309 | if (!request.isCancelled()) { | |
310 | return false; | |
311 | } | |
312 | } | |
313 | return true; | |
314 | } | |
315 | ||
316 | // Coalescing request is not canceled if there are no sub-requests | |
317 | return false; | |
318 | ||
319 | } | |
320 | ||
9b749023 | 321 | |
2fb2eb37 FC |
322 | // ------------------------------------------------------------------------ |
323 | // Object | |
324 | // ------------------------------------------------------------------------ | |
8c8bf09f ASL |
325 | |
326 | @Override | |
2fb2eb37 FC |
327 | // All requests have a unique id |
328 | public int hashCode() { | |
329 | return super.hashCode(); | |
8c8bf09f ASL |
330 | } |
331 | ||
332 | @Override | |
2fb2eb37 FC |
333 | public boolean equals(Object other) { |
334 | if (other instanceof TmfCoalescedDataRequest<?>) { | |
335 | TmfCoalescedDataRequest<?> request = (TmfCoalescedDataRequest<?>) other; | |
cb866e08 FC |
336 | return (request.getDataType() == getDataType()) && |
337 | (request.getIndex() == getIndex()) && | |
338 | (request.getNbRequested() == getNbRequested() && | |
339 | (request.getExecType() == getExecType())); | |
2fb2eb37 FC |
340 | } |
341 | return false; | |
8c8bf09f ASL |
342 | } |
343 | ||
344 | @Override | |
3b38ea61 | 345 | @SuppressWarnings("nls") |
2fb2eb37 | 346 | public String toString() { |
9b749023 | 347 | return "[TmfCoalescedDataRequest(" + getRequestId() + "," + getDataType().getSimpleName() |
8016d660 | 348 | + "," + getIndex() + "," + getNbRequested() + "," + getBlockSize() + ")]"; |
8c8bf09f | 349 | } |
8c8bf09f | 350 | } |