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