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