Internalize some classes and fix a pile of warnings
[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
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
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:
12c155f5
FC
36 *
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>
62 *
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.
0ab46cd3
FC
67 *
68 * TODO: Implement request failures (codes, etc...)
8fd82db5
FC
69 *
70 * @version 1.0
71 * @author Francois Chouinard
8c8bf09f 72 */
72f1e62a 73public abstract class TmfDataRequest<T extends ITmfEvent> implements ITmfDataRequest<T> {
8c8bf09f 74
e31e01e8 75 // ------------------------------------------------------------------------
8c8bf09f 76 // Constants
e31e01e8 77 // ------------------------------------------------------------------------
8c8bf09f
ASL
78
79 // The default maximum number of events per chunk
80 public static final int DEFAULT_BLOCK_SIZE = 1000;
81
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
12c155f5 91 private final Class<T> 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
12c155f5 99 private CountDownLatch startedLatch = new CountDownLatch(1);
1a971e96 100 private 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).
12c155f5 120 *
0d9a6d76 121 * @param dataType the requested data type
8c8bf09f 122 */
951d134a 123 public TmfDataRequest(Class<T> 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).
130 *
131 * @param dataType the requested data type
132 * @param priority the requested execution priority
133 */
134 public TmfDataRequest(Class<T> dataType, ExecutionType priority) {
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).
141 *
142 * @param dataType the requested data type
143 * @param index the index of the first event to retrieve
8c8bf09f 144 */
9e0640dc 145 public TmfDataRequest(Class<T> 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).
152 *
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 */
9e0640dc 157 public TmfDataRequest(Class<T> 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).
164 *
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 */
9e0640dc 169 public TmfDataRequest(Class<T> 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).
176 *
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 */
9e0640dc 182 public TmfDataRequest(Class<T> 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.
189 *
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 */
9e0640dc 195 public TmfDataRequest(Class<T> 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.
202 *
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 */
9e0640dc 209 public TmfDataRequest(Class<T> 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")
227 String message = "CREATED "
228 + (getExecType() == ITmfDataRequest.ExecutionType.BACKGROUND ? "(BG)" : "(FG)")
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")
12c155f5
FC
239 private TmfDataRequest(TmfDataRequest<T> other) {
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
12c155f5 331 public Class<T> 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
12c155f5
FC
341 *
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.
12c155f5 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.
8c8bf09f 365 *
0d9a6d76 366 * @param data a piece of data
8c8bf09f 367 */
d4011df2 368 @Override
12c155f5 369 public void handleData(T data) {
f9673903 370 if (data != null) {
12c155f5 371 fNbRead++;
f9673903
FC
372 }
373 }
9aae0442 374
d4011df2 375 @Override
12c155f5
FC
376 public void handleStarted() {
377 if (Tracer.isRequestTraced())
90891c08 378 Tracer.traceRequest(this, "STARTED"); //$NON-NLS-1$
550d787e
FC
379 }
380
0ab46cd3 381 /**
0d9a6d76
FC
382 * Handle the completion of the request. It is called when there is no
383 * more data available either because:
384 * - the request completed normally
385 * - the request failed
386 * - the request was canceled
0ab46cd3 387 *
0d9a6d76
FC
388 * As a convenience, handleXXXX methods are provided. They are meant to be
389 * overridden by the application if it needs to handle these conditions.
0ab46cd3 390 */
d4011df2 391 @Override
6a1801b4
BH
392 public void handleCompleted() {
393 boolean requestFailed = false;
394 boolean requestCanceled = false;
395 synchronized (this) {
396 requestFailed = fRequestFailed;
397 requestCanceled = fRequestCanceled;
398 }
399
400 if (requestFailed) {
12c155f5 401 handleFailure();
6a1801b4 402 } else if (requestCanceled) {
12c155f5
FC
403 handleCancel();
404 } else {
405 handleSuccess();
406 }
407 if (Tracer.isRequestTraced())
90891c08 408 Tracer.traceRequest(this, "COMPLETED (" + fNbRead + " events read)"); //$NON-NLS-1$ //$NON-NLS-2$
0ab46cd3
FC
409 }
410
d4011df2 411 @Override
12c155f5
FC
412 public void handleSuccess() {
413 if (Tracer.isRequestTraced())
90891c08 414 Tracer.traceRequest(this, "SUCCEEDED"); //$NON-NLS-1$
0ab46cd3
FC
415 }
416
d4011df2 417 @Override
12c155f5
FC
418 public void handleFailure() {
419 if (Tracer.isRequestTraced())
90891c08 420 Tracer.traceRequest(this, "FAILED"); //$NON-NLS-1$
0ab46cd3
FC
421 }
422
d4011df2 423 @Override
12c155f5
FC
424 public void handleCancel() {
425 if (Tracer.isRequestTraced())
90891c08 426 Tracer.traceRequest(this, "CANCELLED"); //$NON-NLS-1$
8c8bf09f
ASL
427 }
428
0c2a2e08 429 /**
12c155f5 430 * To suspend the client thread until the request starts (or is canceled).
0c2a2e08 431 *
12c155f5 432 * @throws InterruptedException
0c2a2e08
FC
433 */
434 public void waitForStart() throws InterruptedException {
12c155f5
FC
435 while (!fRequestRunning) {
436 startedLatch.await();
437 }
0c2a2e08
FC
438 }
439
8c8bf09f 440 /**
12c155f5 441 * To suspend the client thread until the request completes (or is canceled).
8c8bf09f 442 *
12c155f5 443 * @throws InterruptedException
8c8bf09f 444 */
d4011df2 445 @Override
12c155f5
FC
446 public void waitForCompletion() throws InterruptedException {
447 while (!fRequestCompleted) {
448 completedLatch.await();
449 }
9aae0442
ASL
450 }
451
550d787e
FC
452 /**
453 * Called by the request processor upon starting to service the request.
454 */
d4011df2 455 @Override
12c155f5
FC
456 public void start() {
457 synchronized (this) {
550d787e 458 fRequestRunning = true;
550d787e
FC
459 }
460 handleStarted();
1a971e96 461 startedLatch.countDown();
550d787e
FC
462 }
463
8c8bf09f 464 /**
0ab46cd3 465 * Called by the request processor upon completion.
8c8bf09f 466 */
d4011df2 467 @Override
12c155f5
FC
468 public void done() {
469 synchronized (this) {
470 if (!fRequestCompleted) {
471 fRequestRunning = false;
9b635e61 472 fRequestCompleted = true;
a79913eb
FC
473 } else {
474 return;
9b635e61 475 }
8c8bf09f 476 }
475743b7
FC
477 try {
478 handleCompleted();
479 } finally {
480 completedLatch.countDown();
481 }
8c8bf09f
ASL
482 }
483
484 /**
0ab46cd3
FC
485 * Called by the request processor upon failure.
486 */
d4011df2 487 @Override
c1c69938 488 public void fail() {
12c155f5 489 synchronized (this) {
c1c69938
FC
490 fRequestFailed = true;
491 }
1a971e96 492 done();
0ab46cd3
FC
493 }
494
495 /**
496 * Called by the request processor upon cancellation.
8c8bf09f 497 */
d4011df2 498 @Override
c1c69938 499 public void cancel() {
12c155f5 500 synchronized (this) {
c1c69938
FC
501 fRequestCanceled = true;
502 }
12c155f5 503 done();
8c8bf09f
ASL
504 }
505
cbd4ad82
FC
506 // ------------------------------------------------------------------------
507 // Object
508 // ------------------------------------------------------------------------
509
510 @Override
2fb2eb37 511 // All requests have a unique id
cbd4ad82 512 public int hashCode() {
12c155f5 513 return getRequestId();
cbd4ad82
FC
514 }
515
516 @Override
517 public boolean equals(Object other) {
12c155f5
FC
518 if (other instanceof TmfDataRequest<?>) {
519 TmfDataRequest<?> request = (TmfDataRequest<?>) other;
520 return (request.fDataType == fDataType) && (request.fIndex == fIndex)
521 && (request.fNbRequested == fNbRequested);
522 }
523 return false;
cbd4ad82
FC
524 }
525
2fb2eb37 526 @Override
3b38ea61 527 @SuppressWarnings("nls")
2fb2eb37 528 public String toString() {
12c155f5
FC
529 return "[TmfDataRequest(" + fRequestId + "," + fDataType.getSimpleName() + "," + fIndex + "," + fNbRequested
530 + "," + getBlockSize() + ")]";
2fb2eb37 531 }
8c8bf09f 532}
This page took 0.065565 seconds and 5 git commands to generate.