2010-06-21 fchouinard@gmail.com Fix for Bug316276
[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)
93 private final int fBlockSize; // The maximum number of events per chunk
cb866e08 94 protected int fNbRead; // The number of reads so far
8c8bf09f 95
9b635e61 96 private final Object lock;
550d787e
FC
97 private boolean fRequestRunning = false;
98 private boolean fRequestCompleted = false;
99 private boolean fRequestFailed = false;
100 private boolean fRequestCanceled = false;
8c8bf09f 101
e31e01e8 102 private T[] fData; // Data object
8c8bf09f 103
e31e01e8 104 // ------------------------------------------------------------------------
8c8bf09f 105 // Constructors
e31e01e8 106 // ------------------------------------------------------------------------
8c8bf09f 107
2fb2eb37
FC
108 /**
109 * Resets the request counter (used for testing)
110 */
111 public static void reset() {
112 fRequestNumber = 0;
113 }
114
8c8bf09f 115 /**
e31e01e8 116 * Default constructor
2fb2eb37
FC
117 *
118 * @param dataType the requested data type
8c8bf09f 119 */
951d134a 120 public TmfDataRequest(Class<T> dataType) {
550d787e
FC
121 this(dataType, 0, ALL_DATA, DEFAULT_BLOCK_SIZE, ExecutionType.SHORT);
122 }
123
124 public TmfDataRequest(Class<T> dataType, ExecutionType execType) {
125 this(dataType, 0, ALL_DATA, DEFAULT_BLOCK_SIZE, execType);
8c8bf09f
ASL
126 }
127
128 /**
2fb2eb37
FC
129 * @param dataType the requested data type
130 * @param nbRequested the number of data items requested
8c8bf09f 131 */
951d134a 132 public TmfDataRequest(Class<T> dataType, int index) {
550d787e
FC
133 this(dataType, index, ALL_DATA, DEFAULT_BLOCK_SIZE, ExecutionType.SHORT);
134 }
135
136 public TmfDataRequest(Class<T> dataType, int index, ExecutionType execType) {
137 this(dataType, index, ALL_DATA, DEFAULT_BLOCK_SIZE, execType);
8c8bf09f
ASL
138 }
139
140 /**
2fb2eb37
FC
141 * @param dataType the requested data type
142 * @param index the index (rank) of the first event requested
143 * @param blockSize the number of data items per block
8c8bf09f 144 */
951d134a 145 public TmfDataRequest(Class<T> dataType, int index, int nbRequested) {
550d787e
FC
146 this(dataType, index, nbRequested, DEFAULT_BLOCK_SIZE, ExecutionType.SHORT);
147 }
148
149 public TmfDataRequest(Class<T> dataType, int index, int nbRequested, ExecutionType execType) {
150 this(dataType, index, nbRequested, DEFAULT_BLOCK_SIZE, execType);
8c8bf09f
ASL
151 }
152
153 /**
2fb2eb37
FC
154 * @param dataType the requested data type
155 * @param index the index (rank) of the first event requested
156 * @param nbRequested the number of data items requested
157 * @param blockSize the number of data items per block
8c8bf09f 158 */
951d134a 159 public TmfDataRequest(Class<T> dataType, int index, int nbRequested, int blockSize) {
550d787e
FC
160 this(dataType, index, nbRequested, blockSize, ExecutionType.SHORT);
161 }
162
163 public TmfDataRequest(Class<T> dataType, int index, int nbRequested, int blockSize, ExecutionType execType) {
fc6ccf6f 164 fRequestId = fRequestNumber++;
e31e01e8
FC
165 fDataType = dataType;
166 fIndex = index;
167 fNbRequested = nbRequested;
168 fBlockSize = blockSize;
550d787e 169 fExecType = execType;
e31e01e8 170 fNbRead = 0;
2fb2eb37 171 lock = new Object();
550d787e 172 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "created");
2fb2eb37
FC
173 }
174
175 /**
176 * Copy constructor
177 */
178 @SuppressWarnings("unused")
179 private TmfDataRequest(TmfDataRequest<T> other) {
550d787e 180 this(null, 0, ALL_DATA, DEFAULT_BLOCK_SIZE);
8c8bf09f 181 }
951d134a 182
e31e01e8 183 // ------------------------------------------------------------------------
165c977c 184 // Accessors
e31e01e8 185 // ------------------------------------------------------------------------
8c8bf09f 186
fc6ccf6f
FC
187 /**
188 * @return the request ID
189 */
2fb2eb37 190 public int getRequestId() {
fc6ccf6f
FC
191 return fRequestId;
192 }
193
28b94d61 194 /**
951d134a 195 * @return the index of the first event requested
28b94d61 196 */
951d134a 197 public int getIndex() {
28b94d61
FC
198 return fIndex;
199 }
200
550d787e
FC
201 /**
202 * @return the index of the first event requested
203 */
204 public ExecutionType getExecType() {
205 return fExecType;
206 }
207
8c8bf09f 208 /**
e31e01e8 209 * @return the number of requested events (ALL_DATA = all)
8c8bf09f 210 */
e31e01e8
FC
211 public int getNbRequested() {
212 return fNbRequested;
8c8bf09f
ASL
213 }
214
9aae0442 215 /**
165c977c 216 * @return the block size
9aae0442 217 */
165c977c
FC
218 public int getBlockize() {
219 return fBlockSize;
9aae0442
ASL
220 }
221
660c9e60
FC
222 /**
223 * @return the number of events read so far
224 */
2fb2eb37 225 public synchronized int getNbRead() {
e31e01e8 226 return fNbRead;
660c9e60
FC
227 }
228
550d787e
FC
229 /**
230 * @return indicates if the request is completed
231 */
232 public boolean isRunning() {
233 return fRequestRunning;
234 }
235
8c8bf09f
ASL
236 /**
237 * @return indicates if the request is completed
238 */
239 public boolean isCompleted() {
240 return fRequestCompleted;
241 }
242
0ab46cd3
FC
243 /**
244 * @return indicates if the request is canceled
245 */
246 public boolean isFailed() {
247 return fRequestFailed;
248 }
249
8c8bf09f
ASL
250 /**
251 * @return indicates if the request is canceled
252 */
253 public boolean isCancelled() {
254 return fRequestCanceled;
255 }
256
e31e01e8
FC
257 /**
258 * @return the requested data type
259 */
951d134a 260 public Class<T> getDataType() {
e31e01e8
FC
261 return fDataType;
262 }
263
264 // ------------------------------------------------------------------------
8c8bf09f 265 // Operators
e31e01e8 266 // ------------------------------------------------------------------------
8c8bf09f
ASL
267
268 /**
660c9e60 269 * Sets the data object to specified value. To be called by the
8c8bf09f
ASL
270 * asynchronous method implementor.
271 * @param data Data value to set.
272 */
e31e01e8
FC
273 public synchronized void setData(T[] data) {
274 fNbRead += data.length;
8c8bf09f
ASL
275 fData = data;
276 }
277
278 /**
279 * Returns the data value, null if not set.
280 */
e31e01e8 281 public synchronized T[] getData() {
8c8bf09f
ASL
282 return fData;
283 }
284
285 /**
0ab46cd3
FC
286 * Handle a block of incoming data. This method is called every time
287 * a block of data becomes available.
8c8bf09f
ASL
288 *
289 * - Data items are received in the order they appear in the stream.
290 * - Called by the request processor, in its execution thread, every time a
291 * block of data becomes available.
292 * - Request processor performs a synchronous call to handlePartialResult()
293 * i.e. its execution threads holds until handlePartialData() returns.
294 * - Original data items are disposed of on return i.e. keep a reference
295 * (or a copy) if some persistence is needed between invocations.
296 * - When there is no more data, done() is called.
297 *
298 * @param events - an array of events
299 */
951d134a 300 public abstract void handleData();
9aae0442 301
550d787e
FC
302 public void handleStarted() {
303 }
304
0ab46cd3
FC
305 /**
306 * Handle the completion of the request. It is called when there is no more
307 * data available either because:
308 * - the request completed normally
309 * - the request failed
310 * - the request was canceled
311 *
312 * As a convenience, handleXXXX methods are provided. They are meant to be
313 * overridden by the application if it needs to handle these conditions.
314 */
8c8bf09f 315 public void handleCompleted() {
0ab46cd3 316 if (fRequestFailed) {
550d787e 317 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "failed");
0ab46cd3
FC
318 handleFailure();
319 }
320 else if (fRequestCanceled) {
550d787e 321 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "cancelled");
0ab46cd3
FC
322 handleCancel();
323 }
37c8b509 324 else {
550d787e 325 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "succeeded");
36548af3 326 handleSuccess();
37c8b509 327 }
0ab46cd3
FC
328 }
329
330 public void handleSuccess() {
331 }
332
333 public void handleFailure() {
334 }
335
336 public void handleCancel() {
8c8bf09f
ASL
337 }
338
339 /**
340 * To suspend the client thread until the request completes (or is
341 * canceled).
342 *
343 * @throws InterruptedException
344 */
2fb2eb37 345 public void waitForCompletion() throws InterruptedException {
8c8bf09f
ASL
346 synchronized (lock) {
347 while (!fRequestCompleted)
2fb2eb37 348 lock.wait();
9aae0442 349 }
9aae0442
ASL
350 }
351
550d787e
FC
352 /**
353 * Called by the request processor upon starting to service the request.
354 */
355 public void start() {
356 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "starting");
357 synchronized(lock) {
358 fRequestRunning = true;
359 lock.notify();
360 }
361 handleStarted();
9b635e61 362 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "started");
550d787e
FC
363 }
364
8c8bf09f 365 /**
0ab46cd3 366 * Called by the request processor upon completion.
8c8bf09f
ASL
367 */
368 public void done() {
550d787e 369 if (Tracer.isRequestTraced()) Tracer.traceRequest(this, "completing");
8c8bf09f 370 synchronized(lock) {
9b635e61
FC
371 if (!fRequestCompleted) {
372 fRequestRunning = false;
373 fRequestCompleted = true;
374 }
375 handleCompleted();
8c8bf09f
ASL
376 lock.notify();
377 }
8c8bf09f
ASL
378 }
379
380 /**
0ab46cd3
FC
381 * Called by the request processor upon failure.
382 */
383 public void fail() {
384 synchronized(lock) {
385 fRequestFailed = true;
386 done();
387 }
388 }
389
390 /**
391 * Called by the request processor upon cancellation.
8c8bf09f
ASL
392 */
393 public void cancel() {
394 synchronized(lock) {
395 fRequestCanceled = true;
0ab46cd3 396 done();
8c8bf09f
ASL
397 }
398 }
399
cbd4ad82
FC
400 // ------------------------------------------------------------------------
401 // Object
402 // ------------------------------------------------------------------------
403
404 @Override
2fb2eb37 405 // All requests have a unique id
cbd4ad82 406 public int hashCode() {
2fb2eb37 407 return getRequestId();
cbd4ad82
FC
408 }
409
410 @Override
411 public boolean equals(Object other) {
412 if (other instanceof TmfDataRequest<?>) {
413 TmfDataRequest<?> request = (TmfDataRequest<?>) other;
414 return (request.fDataType == fDataType) &&
415 (request.fIndex == fIndex) &&
416 (request.fNbRequested == fNbRequested);
417 }
418 return false;
419 }
420
2fb2eb37
FC
421 @Override
422 public String toString() {
423 return "[TmfDataRequest(" + fRequestId + "," + fDataType.getSimpleName()
424 + "," + fIndex + "," + fNbRequested + "," + fBlockSize + ")]";
425 }
426
8c8bf09f 427}
This page took 0.066973 seconds and 5 git commands to generate.