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