560c4431516b437880b82e7937b51b8333317407
1 /*******************************************************************************
2 * Copyright (c) 2009, 2010 Ericsson
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
10 * Francois Chouinard - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.request
;
15 import org
.eclipse
.linuxtools
.tmf
.Tracer
;
16 import org
.eclipse
.linuxtools
.tmf
.event
.TmfData
;
19 * <b><u>TmfDataRequest</u></b>
21 * TmfDataRequests are used to obtain blocks of contiguous data from a data
22 * provider. Open ranges can be used, especially for continuous streaming.
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.
30 * This data block approach is used to avoid busting the heap for very
31 * large trace files. The block size is configurable.
33 * The TmfProvider indicates that the request is completed by calling done().
34 * The request can be canceled at any time with cancel().
37 *<pre><code><i>TmfTimeWindow range = new TmfTimewindow(...);
38 *TmfDataRequest<DataType[]> request = new TmfDataRequest<DataType[]>(DataType.class, 0, NB_EVENTS, BLOCK_SIZE) {
39 * public void handleData() {
40 * DataType[] data = request.getData();
41 * for (DataType e : data) {
45 * public void handleSuccess() {
49 * public void handleFailure() {
53 * public void handleCancel() {
58 *fProcessor.process(request, true);
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
68 * TODO: Implement request failures (codes, etc...)
70 public abstract class TmfDataRequest
<T
extends TmfData
> implements ITmfDataRequest
<T
> {
72 // ------------------------------------------------------------------------
74 // ------------------------------------------------------------------------
76 // The default maximum number of events per chunk
77 public static final int DEFAULT_BLOCK_SIZE
= 1000;
79 // The request count for all the events
80 public static final int ALL_DATA
= Integer
.MAX_VALUE
;
82 private static int fRequestNumber
= 0;
84 // ------------------------------------------------------------------------
86 // ------------------------------------------------------------------------
88 private final Class
<T
> fDataType
;
89 private final int fRequestId
; // A unique request ID
90 private final int fIndex
; // The index (rank) of the requested event
91 private final int fNbRequested
; // The number of requested events (ALL_DATA for all)
92 private final int fBlockSize
; // The maximum number of events per chunk
93 private int fNbRead
; // The number of reads so far
95 private final Object lock
;
96 private boolean fRequestRunning
= false;
97 private boolean fRequestCompleted
= false;
98 private boolean fRequestFailed
= false;
99 private boolean fRequestCanceled
= false;
101 private T
[] fData
; // Data object
103 // ------------------------------------------------------------------------
105 // ------------------------------------------------------------------------
108 * Resets the request counter (used for testing)
110 public static void reset() {
115 * Default constructor
117 * @param dataType the requested data type
119 public TmfDataRequest(Class
<T
> dataType
) {
120 this(dataType
, 0, ALL_DATA
, DEFAULT_BLOCK_SIZE
);
124 * @param dataType the requested data type
125 * @param nbRequested the number of data items requested
127 public TmfDataRequest(Class
<T
> dataType
, int index
) {
128 this(dataType
, index
, ALL_DATA
, DEFAULT_BLOCK_SIZE
);
132 * @param dataType the requested data type
133 * @param index the index (rank) of the first event requested
134 * @param blockSize the number of data items per block
136 public TmfDataRequest(Class
<T
> dataType
, int index
, int nbRequested
) {
137 this(dataType
, index
, nbRequested
, DEFAULT_BLOCK_SIZE
);
141 * @param dataType the requested data type
142 * @param index the index (rank) of the first event requested
143 * @param nbRequested the number of data items requested
144 * @param blockSize the number of data items per block
146 public TmfDataRequest(Class
<T
> dataType
, int index
, int nbRequested
, int blockSize
) {
147 fRequestId
= fRequestNumber
++;
148 fDataType
= dataType
;
150 fNbRequested
= nbRequested
;
151 fBlockSize
= blockSize
;
154 if (Tracer
.isRequestTraced()) Tracer
.traceRequest(this, "created");
160 @SuppressWarnings("unused")
161 private TmfDataRequest(TmfDataRequest
<T
> other
) {
162 this(null, 0, ALL_DATA
, DEFAULT_BLOCK_SIZE
);
165 // ------------------------------------------------------------------------
167 // ------------------------------------------------------------------------
170 * @return the request ID
172 public int getRequestId() {
177 * @return the index of the first event requested
179 public int getIndex() {
184 * @return the number of requested events (ALL_DATA = all)
186 public int getNbRequested() {
191 * @return the block size
193 public int getBlockize() {
198 * @return the number of events read so far
200 public synchronized int getNbRead() {
205 * @return indicates if the request is completed
207 public boolean isRunning() {
208 return fRequestRunning
;
212 * @return indicates if the request is completed
214 public boolean isCompleted() {
215 return fRequestCompleted
;
219 * @return indicates if the request is canceled
221 public boolean isFailed() {
222 return fRequestFailed
;
226 * @return indicates if the request is canceled
228 public boolean isCancelled() {
229 return fRequestCanceled
;
233 * @return the requested data type
235 public Class
<T
> getDataType() {
239 // ------------------------------------------------------------------------
241 // ------------------------------------------------------------------------
244 * Sets the data object to specified value. To be called by the
245 * asynchronous method implementor.
246 * @param data Data value to set.
248 public synchronized void setData(T
[] data
) {
249 fNbRead
+= data
.length
;
254 * Returns the data value, null if not set.
256 public synchronized T
[] getData() {
261 * Handle a block of incoming data. This method is called every time
262 * a block of data becomes available.
264 * - Data items are received in the order they appear in the stream.
265 * - Called by the request processor, in its execution thread, every time a
266 * block of data becomes available.
267 * - Request processor performs a synchronous call to handlePartialResult()
268 * i.e. its execution threads holds until handlePartialData() returns.
269 * - Original data items are disposed of on return i.e. keep a reference
270 * (or a copy) if some persistence is needed between invocations.
271 * - When there is no more data, done() is called.
273 * @param events - an array of events
275 public abstract void handleData();
277 public void handleStarted() {
281 * Handle the completion of the request. It is called when there is no more
282 * data available either because:
283 * - the request completed normally
284 * - the request failed
285 * - the request was canceled
287 * As a convenience, handleXXXX methods are provided. They are meant to be
288 * overridden by the application if it needs to handle these conditions.
290 public void handleCompleted() {
291 if (fRequestFailed
) {
292 if (Tracer
.isRequestTraced()) Tracer
.traceRequest(this, "failed");
295 else if (fRequestCanceled
) {
296 if (Tracer
.isRequestTraced()) Tracer
.traceRequest(this, "cancelled");
300 if (Tracer
.isRequestTraced()) Tracer
.traceRequest(this, "succeeded");
305 public void handleSuccess() {
308 public void handleFailure() {
311 public void handleCancel() {
315 * To suspend the client thread until the request completes (or is
318 * @throws InterruptedException
320 public void waitForCompletion() throws InterruptedException
{
321 synchronized (lock
) {
322 while (!fRequestCompleted
)
328 * Called by the request processor upon starting to service the request.
330 public void start() {
331 if (Tracer
.isRequestTraced()) Tracer
.traceRequest(this, "starting");
333 fRequestRunning
= true;
337 if (Tracer
.isRequestTraced()) Tracer
.traceRequest(this, "started");
341 * Called by the request processor upon completion.
344 if (Tracer
.isRequestTraced()) Tracer
.traceRequest(this, "completing");
346 fRequestRunning
= false;
347 fRequestCompleted
= true;
354 * Called by the request processor upon failure.
358 fRequestFailed
= true;
364 * Called by the request processor upon cancellation.
366 public void cancel() {
368 fRequestCanceled
= true;
373 // ------------------------------------------------------------------------
375 // ------------------------------------------------------------------------
378 // All requests have a unique id
379 public int hashCode() {
380 return getRequestId();
384 public boolean equals(Object other
) {
385 if (other
instanceof TmfDataRequest
<?
>) {
386 TmfDataRequest
<?
> request
= (TmfDataRequest
<?
>) other
;
387 return (request
.fDataType
== fDataType
) &&
388 (request
.fIndex
== fIndex
) &&
389 (request
.fNbRequested
== fNbRequested
);
395 public String
toString() {
396 return "[TmfDataRequest(" + fRequestId
+ "," + fDataType
.getSimpleName()
397 + "," + fIndex
+ "," + fNbRequested
+ "," + fBlockSize
+ ")]";
This page took 0.039193 seconds and 4 git commands to generate.