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