1 /*******************************************************************************
2 * Copyright (c) 2009 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
.event
.TmfTimeRange
;
18 * <b><u>TmfDataRequest</u></b>
20 * TmfDataRequests are used to obtain blocks of contiguous data from a data
21 * provider, either all the data within a given time window or n elements
22 * starting at a specific timestamp. Open ranges can be used, especially for
23 * continuous streaming.
25 * The request is processed asynchronously by an ITmfRequestProcessor and,
26 * as blocks of data become available, the callback handleData() is
27 * invoked, synchronously, for each block. When returning from the callback,
28 * the data instances go out of scope and become eligible for gc. It is
29 * is thus the responsibility of the requester to either copy or keep a
30 * reference to the data it wishes to track specifically.
32 * This data block approach is necessary to avoid busting the heap for very
33 * large trace files. The block size is configurable.
35 * The ITmfRequestProcessor indicates that the request is completed by
36 * calling done(). The request can be canceled at any time with cancel().
39 *<pre><code><i>TmfTimeWindow range = new TmfTimewindow(...);
40 *TmfDataRequest<DataType[]> request = new TmfDataRequest<DataType[]>(range, 0, NB_EVENTS, BLOCK_SIZE) {
41 * public void handleData() {
42 * DataType[] data = request.getData();
43 * for (DataType e : data) {
47 * public void handleSuccess() {
51 * public void handleFailure() {
55 * public void handleCancel() {
60 *fProcessor.process(request, true);
63 * TODO: Consider extending DataRequestMonitor from DSF concurrency plugin.
64 * The main issue is the slicing of the result in blocks and continuous
65 * streams. This would require using a thread executor and to carefully
66 * look at setData() and getData().
68 * TODO: Implement request failures (codes, etc...)
70 public class TmfDataRequest
<V
> {
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_EVENTS
= -1;
82 // ========================================================================
84 // ========================================================================
86 private final int fIndex
; // The index (order) of the requested event
87 private final TmfTimeRange fRange
; // The requested events time range
88 private final int fNbRequestedEvents
; // The number of events to read (-1 == all in the range)
89 private final int fBlockSize
; // The maximum number of events per chunk
90 private int fNbEvents
; // The number of events read so far
92 private Object lock
= new Object();
93 private boolean fRequestCompleted
= false;
94 private boolean fRequestFailed
= false;
95 private boolean fRequestCanceled
= false;
97 private V
[] fData
; // Data object
99 // ========================================================================
101 // ========================================================================
107 public TmfDataRequest(int index
, int nbEvents
) {
108 this(null, index
, nbEvents
, DEFAULT_BLOCK_SIZE
);
111 public TmfDataRequest(int index
, int nbEvents
, int blockSize
) {
112 this(null, index
, nbEvents
, blockSize
);
118 public TmfDataRequest(TmfTimeRange range
) {
119 this(range
, 0, ALL_EVENTS
, DEFAULT_BLOCK_SIZE
);
126 public TmfDataRequest(TmfTimeRange range
, int nbEvents
) {
127 this(range
, 0, nbEvents
, DEFAULT_BLOCK_SIZE
);
132 * @param blockSize Size of the largest blocks expected
134 public TmfDataRequest(TmfTimeRange range
, int nbEvents
, int blockSize
) {
135 this(range
, 0, nbEvents
, blockSize
);
142 * @param blockSize Size of the largest blocks expected
144 private TmfDataRequest(TmfTimeRange range
, int index
, int nbEvents
, int blockSize
) {
147 fNbRequestedEvents
= nbEvents
;
148 fBlockSize
= blockSize
;
152 // ========================================================================
154 // ========================================================================
159 public int getIndex() {
164 * @return the requested time range
166 public TmfTimeRange
getRange() {
171 * @return the number of requested events (-1 = all)
173 public int getNbRequestedEvents() {
174 return fNbRequestedEvents
;
178 * @return the block size
180 public int getBlockize() {
185 * @return the number of events read so far
187 public int getNbEvents() {
192 * @return indicates if the request is completed
194 public boolean isCompleted() {
195 return fRequestCompleted
;
199 * @return indicates if the request is canceled
201 public boolean isFailed() {
202 return fRequestFailed
;
206 * @return indicates if the request is canceled
208 public boolean isCancelled() {
209 return fRequestCanceled
;
212 // ========================================================================
214 // ========================================================================
217 * Sets the data object to specified value. To be called by the
218 * asynchronous method implementor.
219 * @param data Data value to set.
221 public synchronized void setData(V
[] data
) {
222 fNbEvents
+= data
.length
;
227 * Returns the data value, null if not set.
229 public synchronized V
[] getData() {
234 * Handle a block of incoming data. This method is called every time
235 * a block of data becomes available.
237 * - Data items are received in the order they appear in the stream.
238 * - Called by the request processor, in its execution thread, every time a
239 * block of data becomes available.
240 * - Request processor performs a synchronous call to handlePartialResult()
241 * i.e. its execution threads holds until handlePartialData() returns.
242 * - Original data items are disposed of on return i.e. keep a reference
243 * (or a copy) if some persistence is needed between invocations.
244 * - When there is no more data, done() is called.
246 * @param events - an array of events
248 public void handleData() {
252 * Handle the completion of the request. It is called when there is no more
253 * data available either because:
254 * - the request completed normally
255 * - the request failed
256 * - the request was canceled
258 * As a convenience, handleXXXX methods are provided. They are meant to be
259 * overridden by the application if it needs to handle these conditions.
261 public void handleCompleted() {
262 if (fRequestFailed
) {
265 else if (fRequestCanceled
) {
273 public void handleSuccess() {
276 public void handleFailure() {
279 public void handleCancel() {
283 * To suspend the client thread until the request completes (or is
286 * @throws InterruptedException
288 public void waitForCompletion() {
289 synchronized (lock
) {
290 while (!fRequestCompleted
)
293 } catch (InterruptedException e
) {
300 * Called by the request processor upon completion.
304 fRequestCompleted
= true;
311 * Called by the request processor upon failure.
315 fRequestFailed
= true;
321 * Called by the request processor upon cancellation.
323 public void cancel() {
325 fRequestCanceled
= true;
This page took 0.038349 seconds and 5 git commands to generate.