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