Merge branch 'FixJUnits'
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf / src / org / eclipse / linuxtools / tmf / request / TmfDataRequest.java
CommitLineData
8c8bf09f 1/*******************************************************************************
e31e01e8 2 * Copyright (c) 2009, 2010 Ericsson
8c8bf09f
ASL
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
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.tmf.request;
14
1a971e96
FC
15import java.util.concurrent.CountDownLatch;
16
ce785d7d 17import org.eclipse.linuxtools.tmf.Tracer;
e31e01e8 18import org.eclipse.linuxtools.tmf.event.TmfData;
8c8bf09f
ASL
19
20/**
21 * <b><u>TmfDataRequest</u></b>
22 * <p>
23 * TmfDataRequests are used to obtain blocks of contiguous data from a data
e31e01e8 24 * provider. Open ranges can be used, especially for continuous streaming.
8c8bf09f 25 * <p>
e31e01e8
FC
26 * The request is processed asynchronously by a TmfProvider and, as blocks
27 * of data become available, handleData() is invoked synchronously for each
28 * block. Upon return, the data instances go out of scope and become eligible
29 * for gc. It is is thus the responsibility of the requester to either clone
30 * or keep a reference to the data it wishes to track specifically.
8c8bf09f 31 * <p>
e31e01e8
FC
32 * This data block approach is used to avoid busting the heap for very
33 * large trace files. The block size is configurable.
8c8bf09f 34 * <p>
e31e01e8
FC
35 * The TmfProvider indicates that the request is completed by calling done().
36 * The request can be canceled at any time with cancel().
8c8bf09f
ASL
37 * <p>
38 * Typical usage:
39 *<pre><code><i>TmfTimeWindow range = new TmfTimewindow(...);
e31e01e8 40 *TmfDataRequest&lt;DataType[]&gt; request = new TmfDataRequest&lt;DataType[]&gt;(DataType.class, 0, NB_EVENTS, BLOCK_SIZE) {
0ab46cd3 41 * public void handleData() {
8c8bf09f
ASL
42 * DataType[] data = request.getData();
43 * for (DataType e : data) {
44 * // do something
45 * }
46 * }
0ab46cd3
FC
47 * public void handleSuccess() {
48 * // do something
49 * }
50 * }
51 * public void handleFailure() {
52 * // do something
53 * }
54 * }
55 * public void handleCancel() {
56 * // do something
57 * }
58 * }
8c8bf09f
ASL
59 *};
60 *fProcessor.process(request, true);
61 *</i></code></pre>
62 *
e31e01e8
FC
63 * TODO: Consider decoupling from "time range", "rank", etc and for the more
64 * generic notion of "criteria". This would allow to extend for "time range", etc
65 * instead of providing specialized constructors. This also means removing the
66 * criteria info from the data structure (with the possible exception of fNbRequested).
67 * The nice thing about it is that it would prepare us well for the coming generation
68 * of analysis tools.
0ab46cd3
FC
69 *
70 * TODO: Implement request failures (codes, etc...)
8c8bf09f 71 */
951d134a 72public abstract class TmfDataRequest<T extends TmfData> implements ITmfDataRequest<T> {
8c8bf09f 73
e31e01e8 74 // ------------------------------------------------------------------------
8c8bf09f 75 // Constants
e31e01e8 76 // ------------------------------------------------------------------------
8c8bf09f
ASL
77
78 // The default maximum number of events per chunk
79 public static final int DEFAULT_BLOCK_SIZE = 1000;
80
81 // The request count for all the events
e31e01e8 82 public static final int ALL_DATA = Integer.MAX_VALUE;
8c8bf09f 83
fc6ccf6f
FC
84 private static int fRequestNumber = 0;
85
e31e01e8 86 // ------------------------------------------------------------------------
8c8bf09f 87 // Attributes
e31e01e8 88 // ------------------------------------------------------------------------
8c8bf09f 89
550d787e
FC
90 private final Class<T> fDataType;
91 private final ExecutionType fExecType;
92 private final int fRequestId; // A unique request ID
93 private final int fIndex; // The index (rank) of the requested event
94 private final int fNbRequested; // The number of requested events (ALL_DATA for all)
8016d660 95 private final int fBlockSize; // The block size (for BG requests)
f9673903 96 private int fNbRead; // The number of reads so far
8c8bf09f 97
1a971e96
FC
98 private CountDownLatch startedLatch = new CountDownLatch(1);
99 private CountDownLatch completedLatch = new CountDownLatch(1);
550d787e
FC
100 private boolean fRequestRunning = false;
101 private boolean fRequestCompleted = false;
102 private boolean fRequestFailed = false;
103 private boolean fRequestCanceled = false;
8c8bf09f 104
e31e01e8 105 // ------------------------------------------------------------------------
8c8bf09f 106 // Constructors
e31e01e8 107 // ------------------------------------------------------------------------
8c8bf09f 108
2fb2eb37
FC
109 /**
110 * Resets the request counter (used for testing)
111 */
112 public static void reset() {
113 fRequestNumber = 0;
114 }
115
8c8bf09f 116 /**
e31e01e8 117 * Default constructor
2fb2eb37
FC
118 *
119 * @param dataType the requested data type
8c8bf09f 120 */
951d134a 121 public TmfDataRequest(Class<T> dataType) {
f6b14ce2 122 this(dataType, 0, ALL_DATA, DEFAULT_BLOCK_SIZE, ExecutionType.FOREGROUND);
550d787e
FC
123 }
124
125 public TmfDataRequest(Class<T> dataType, ExecutionType execType) {
126 this(dataType, 0, ALL_DATA, DEFAULT_BLOCK_SIZE, execType);
8c8bf09f
ASL
127 }
128
129 /**
2fb2eb37
FC
130 * @param dataType the requested data type
131 * @param nbRequested the number of data items requested
8c8bf09f 132 */
951d134a 133 public TmfDataRequest(Class<T> dataType, int index) {
f6b14ce2 134 this(dataType, index, ALL_DATA, DEFAULT_BLOCK_SIZE, ExecutionType.FOREGROUND);
550d787e
FC
135 }
136
137 public TmfDataRequest(Class<T> dataType, int index, ExecutionType execType) {
138 this(dataType, index, ALL_DATA, DEFAULT_BLOCK_SIZE, execType);
8c8bf09f
ASL
139 }
140
141 /**
2fb2eb37
FC
142 * @param dataType the requested data type
143 * @param index the index (rank) of the first event requested
144 * @param blockSize the number of data items per block
8c8bf09f 145 */
951d134a 146 public TmfDataRequest(Class<T> dataType, int index, int nbRequested) {
f6b14ce2 147 this(dataType, index, nbRequested, DEFAULT_BLOCK_SIZE, ExecutionType.FOREGROUND);
550d787e
FC
148 }
149
150 public TmfDataRequest(Class<T> dataType, int index, int nbRequested, ExecutionType execType) {
151 this(dataType, index, nbRequested, DEFAULT_BLOCK_SIZE, execType);
8c8bf09f
ASL
152 }
153
154 /**
2fb2eb37
FC
155 * @param dataType the requested data type
156 * @param index the index (rank) of the first event requested
157 * @param nbRequested the number of data items requested
158 * @param blockSize the number of data items per block
8c8bf09f 159 */
951d134a 160 public TmfDataRequest(Class<T> dataType, int index, int nbRequested, int blockSize) {
f6b14ce2 161 this(dataType, index, nbRequested, blockSize, ExecutionType.FOREGROUND);
550d787e
FC
162 }
163
164 public TmfDataRequest(Class<T> dataType, int index, int nbRequested, int blockSize, ExecutionType execType) {
fc6ccf6f 165 fRequestId = fRequestNumber++;
e31e01e8
FC
166 fDataType = dataType;
167 fIndex = index;
168 fNbRequested = nbRequested;
8016d660 169 fBlockSize = blockSize;
550d787e 170 fExecType = execType;
e31e01e8 171 fNbRead = 0;
3b38ea61 172 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "created"); //$NON-NLS-1$
2fb2eb37
FC
173 }
174
175 /**
176 * Copy constructor
177 */
178 @SuppressWarnings("unused")
179 private TmfDataRequest(TmfDataRequest<T> other) {
550d787e 180 this(null, 0, ALL_DATA, DEFAULT_BLOCK_SIZE);
8c8bf09f 181 }
951d134a 182
e31e01e8 183 // ------------------------------------------------------------------------
165c977c 184 // Accessors
e31e01e8 185 // ------------------------------------------------------------------------
8c8bf09f 186
fc6ccf6f
FC
187 /**
188 * @return the request ID
189 */
d4011df2 190 @Override
2fb2eb37 191 public int getRequestId() {
fc6ccf6f
FC
192 return fRequestId;
193 }
194
28b94d61 195 /**
951d134a 196 * @return the index of the first event requested
28b94d61 197 */
d4011df2 198 @Override
951d134a 199 public int getIndex() {
28b94d61
FC
200 return fIndex;
201 }
202
550d787e
FC
203 /**
204 * @return the index of the first event requested
205 */
d4011df2 206 @Override
550d787e
FC
207 public ExecutionType getExecType() {
208 return fExecType;
209 }
210
8c8bf09f 211 /**
e31e01e8 212 * @return the number of requested events (ALL_DATA = all)
8c8bf09f 213 */
d4011df2
FC
214 @Override
215 public int getNbRequested() {
e31e01e8 216 return fNbRequested;
8c8bf09f
ASL
217 }
218
8016d660
FC
219 /**
220 * @return the block size (for BG requests)
221 */
222 @Override
223 public int getBlockSize() {
224 return fBlockSize;
225 }
226
660c9e60
FC
227 /**
228 * @return the number of events read so far
229 */
d4011df2
FC
230 @Override
231 public synchronized int getNbRead() {
e31e01e8 232 return fNbRead;
660c9e60
FC
233 }
234
550d787e
FC
235 /**
236 * @return indicates if the request is completed
237 */
d4011df2 238 @Override
c1c69938 239 public synchronized boolean isRunning() {
550d787e
FC
240 return fRequestRunning;
241 }
242
8c8bf09f
ASL
243 /**
244 * @return indicates if the request is completed
245 */
d4011df2 246 @Override
c1c69938 247 public synchronized boolean isCompleted() {
8c8bf09f
ASL
248 return fRequestCompleted;
249 }
250
0ab46cd3
FC
251 /**
252 * @return indicates if the request is canceled
253 */
d4011df2 254 @Override
c1c69938 255 public synchronized boolean isFailed() {
0ab46cd3
FC
256 return fRequestFailed;
257 }
258
8c8bf09f
ASL
259 /**
260 * @return indicates if the request is canceled
261 */
d4011df2 262 @Override
c1c69938 263 public synchronized boolean isCancelled() {
8c8bf09f
ASL
264 return fRequestCanceled;
265 }
266
e31e01e8
FC
267 /**
268 * @return the requested data type
269 */
d4011df2
FC
270 @Override
271 public Class<T> getDataType() {
e31e01e8
FC
272 return fDataType;
273 }
274
275 // ------------------------------------------------------------------------
8c8bf09f 276 // Operators
e31e01e8 277 // ------------------------------------------------------------------------
8c8bf09f
ASL
278
279 /**
660c9e60 280 * Sets the data object to specified value. To be called by the
8c8bf09f 281 * asynchronous method implementor.
f9673903 282 *
8c8bf09f
ASL
283 * @param data Data value to set.
284 */
dc299841 285
8c8bf09f 286 /**
0ab46cd3
FC
287 * Handle a block of incoming data. This method is called every time
288 * a block of data becomes available.
8c8bf09f
ASL
289 *
290 * - Data items are received in the order they appear in the stream.
291 * - Called by the request processor, in its execution thread, every time a
292 * block of data becomes available.
293 * - Request processor performs a synchronous call to handlePartialResult()
294 * i.e. its execution threads holds until handlePartialData() returns.
295 * - Original data items are disposed of on return i.e. keep a reference
296 * (or a copy) if some persistence is needed between invocations.
297 * - When there is no more data, done() is called.
298 *
f9673903 299 * @param events - an events
8c8bf09f 300 */
d4011df2
FC
301 @Override
302 public void handleData(T data) {
f9673903
FC
303 if (data != null) {
304 fNbRead++;
305 }
306 }
9aae0442 307
d4011df2
FC
308 @Override
309 public void handleStarted() {
dc299841 310 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "started"); //$NON-NLS-1$
550d787e
FC
311 }
312
0ab46cd3
FC
313 /**
314 * Handle the completion of the request. It is called when there is no more
315 * data available either because:
316 * - the request completed normally
317 * - the request failed
318 * - the request was canceled
319 *
320 * As a convenience, handleXXXX methods are provided. They are meant to be
321 * overridden by the application if it needs to handle these conditions.
322 */
d4011df2
FC
323 @Override
324 public void handleCompleted() {
0ab46cd3
FC
325 if (fRequestFailed) {
326 handleFailure();
327 }
328 else if (fRequestCanceled) {
329 handleCancel();
330 }
37c8b509 331 else {
36548af3 332 handleSuccess();
37c8b509 333 }
dc299841 334 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "completed"); //$NON-NLS-1$
0ab46cd3
FC
335 }
336
d4011df2
FC
337 @Override
338 public void handleSuccess() {
dc299841 339 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "succeeded"); //$NON-NLS-1$
0ab46cd3
FC
340 }
341
d4011df2
FC
342 @Override
343 public void handleFailure() {
dc299841 344 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "failed"); //$NON-NLS-1$
0ab46cd3
FC
345 }
346
d4011df2
FC
347 @Override
348 public void handleCancel() {
dc299841 349 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "cancelled"); //$NON-NLS-1$
8c8bf09f
ASL
350 }
351
0c2a2e08
FC
352 /**
353 * To suspend the client thread until the request starts (or is
354 * canceled).
355 *
356 * @throws InterruptedException
357 */
358 public void waitForStart() throws InterruptedException {
1a971e96
FC
359 while (!fRequestRunning) {
360 startedLatch.await();
361 }
0c2a2e08
FC
362 }
363
8c8bf09f
ASL
364 /**
365 * To suspend the client thread until the request completes (or is
366 * canceled).
367 *
368 * @throws InterruptedException
369 */
d4011df2
FC
370 @Override
371 public void waitForCompletion() throws InterruptedException {
1a971e96
FC
372 while (!fRequestCompleted) {
373 completedLatch.await();
374 }
9aae0442
ASL
375 }
376
550d787e
FC
377 /**
378 * Called by the request processor upon starting to service the request.
379 */
d4011df2
FC
380 @Override
381 public void start() {
1a971e96 382 synchronized(this) {
550d787e 383 fRequestRunning = true;
550d787e
FC
384 }
385 handleStarted();
1a971e96 386 startedLatch.countDown();
550d787e
FC
387 }
388
8c8bf09f 389 /**
0ab46cd3 390 * Called by the request processor upon completion.
8c8bf09f 391 */
d4011df2
FC
392 @Override
393 public void done() {
1a971e96 394 synchronized(this) {
9b635e61
FC
395 if (!fRequestCompleted) {
396 fRequestRunning = false;
397 fRequestCompleted = true;
398 }
8c8bf09f 399 }
1a971e96
FC
400 handleCompleted();
401 completedLatch.countDown();
8c8bf09f
ASL
402 }
403
404 /**
0ab46cd3
FC
405 * Called by the request processor upon failure.
406 */
d4011df2 407 @Override
c1c69938
FC
408 public void fail() {
409 synchronized(this) {
410 fRequestFailed = true;
411 }
1a971e96 412 done();
0ab46cd3
FC
413 }
414
415 /**
416 * Called by the request processor upon cancellation.
8c8bf09f 417 */
d4011df2 418 @Override
c1c69938
FC
419 public void cancel() {
420 synchronized(this) {
421 fRequestCanceled = true;
422 }
1a971e96 423 done();
8c8bf09f
ASL
424 }
425
cbd4ad82
FC
426 // ------------------------------------------------------------------------
427 // Object
428 // ------------------------------------------------------------------------
429
430 @Override
2fb2eb37 431 // All requests have a unique id
cbd4ad82 432 public int hashCode() {
2fb2eb37 433 return getRequestId();
cbd4ad82
FC
434 }
435
436 @Override
437 public boolean equals(Object other) {
438 if (other instanceof TmfDataRequest<?>) {
439 TmfDataRequest<?> request = (TmfDataRequest<?>) other;
440 return (request.fDataType == fDataType) &&
441 (request.fIndex == fIndex) &&
442 (request.fNbRequested == fNbRequested);
443 }
444 return false;
445 }
446
2fb2eb37 447 @Override
3b38ea61 448 @SuppressWarnings("nls")
2fb2eb37 449 public String toString() {
1a971e96 450 return "[TmfDataRequest(" + fRequestId + "," + fDataType.getSimpleName() +
8016d660 451 "," + fIndex + "," + fNbRequested + "," + getBlockSize() + ")]";
2fb2eb37 452 }
8c8bf09f 453}
This page took 0.057426 seconds and 5 git commands to generate.