Add missing $NON-NLS
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf / src / org / eclipse / linuxtools / tmf / component / TmfDataProvider.java
CommitLineData
8c8bf09f
ASL
1/*******************************************************************************
2 * Copyright (c) 2009, 2010 Ericsson
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.component;
14
8c8bf09f
ASL
15import java.util.Vector;
16import java.util.concurrent.BlockingQueue;
17import java.util.concurrent.LinkedBlockingQueue;
9b635e61 18import java.util.concurrent.SynchronousQueue;
8c8bf09f 19
ce785d7d 20import org.eclipse.linuxtools.tmf.Tracer;
8c8bf09f 21import org.eclipse.linuxtools.tmf.event.TmfData;
951d134a 22import org.eclipse.linuxtools.tmf.request.ITmfDataRequest;
9b635e61 23import org.eclipse.linuxtools.tmf.request.ITmfDataRequest.ExecutionType;
951d134a 24import org.eclipse.linuxtools.tmf.request.TmfCoalescedDataRequest;
8c8bf09f
ASL
25import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
26import org.eclipse.linuxtools.tmf.request.TmfRequestExecutor;
27import org.eclipse.linuxtools.tmf.signal.TmfEndSynchSignal;
28import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
29import org.eclipse.linuxtools.tmf.signal.TmfStartSynchSignal;
30import org.eclipse.linuxtools.tmf.trace.ITmfContext;
31
32/**
33 * <b><u>TmfProvider</u></b>
34 * <p>
35 * The TmfProvider<T> is a provider for a data of type <T>.
36 * <p>
37 * This abstract class implements the housekeeking methods to register/
38 * deregister the event provider and to handle generically the event requests.
39 * <p>
40 * The concrete class can either re-implement processRequest() entirely or
41 * just implement the hooks (initializeContext() and getNext()).
42 * <p>
43 * TODO: Add support for providing multiple data types.
44 */
951d134a 45public abstract class TmfDataProvider<T extends TmfData> extends TmfComponent implements ITmfDataProvider<T> {
8c8bf09f 46
550d787e
FC
47 // ------------------------------------------------------------------------
48 // Constants
49 // ------------------------------------------------------------------------
50
9b635e61 51// private static final ITmfDataRequest.ExecutionType SHORT = ITmfDataRequest.ExecutionType.SHORT;
550d787e
FC
52// private static final ITmfDataRequest.ExecutionType LONG = ITmfDataRequest.ExecutionType.LONG;
53
54 // ------------------------------------------------------------------------
55 //
56 // ------------------------------------------------------------------------
57
8c8bf09f 58 final protected Class<T> fType;
550d787e 59 final protected boolean fLogData;
cb866e08 60 final protected boolean fLogError;
8c8bf09f 61
b12f4544 62 public static final int DEFAULT_BLOCK_SIZE = 50000;
8c8bf09f 63 public static final int DEFAULT_QUEUE_SIZE = 1000;
f6b14ce2 64
8c8bf09f
ASL
65 protected final int fQueueSize;
66 protected final BlockingQueue<T> fDataQueue;
67 protected final TmfRequestExecutor fExecutor;
68
550d787e 69 private int fSignalDepth = 0;
045df77d 70 private final Object fLock = new Object();
951d134a 71
c1c69938
FC
72 private int fRequestPendingCounter = 0;
73
8c8bf09f 74 // ------------------------------------------------------------------------
951d134a 75 // Constructors
8c8bf09f
ASL
76 // ------------------------------------------------------------------------
77
78 public TmfDataProvider(String name, Class<T> type) {
79 this(name, type, DEFAULT_QUEUE_SIZE);
80 }
81
82 protected TmfDataProvider(String name, Class<T> type, int queueSize) {
83 super(name);
fc6ccf6f 84 fType = type;
ce785d7d 85 fQueueSize = queueSize;
9b635e61 86 fDataQueue = (fQueueSize > 1) ? new LinkedBlockingQueue<T>(fQueueSize) : new SynchronousQueue<T>();
ce785d7d
FC
87
88 fExecutor = new TmfRequestExecutor();
550d787e
FC
89 fSignalDepth = 0;
90
cb866e08
FC
91 fLogData = Tracer.isEventTraced();
92 fLogError = Tracer.isErrorTraced();
54d55ced
FC
93
94 TmfProviderManager.register(fType, this);
9b635e61 95// if (Tracer.isComponentTraced()) Tracer.traceComponent(this, "started");
ce785d7d 96}
377f1ad8 97
ce785d7d
FC
98 public TmfDataProvider(TmfDataProvider<T> other) {
99 super(other);
100 fType = other.fType;
101 fQueueSize = other.fQueueSize;
9b635e61 102 fDataQueue = (fQueueSize > 1) ? new LinkedBlockingQueue<T>(fQueueSize) : new SynchronousQueue<T>();
ce785d7d
FC
103
104 fExecutor = new TmfRequestExecutor();
550d787e
FC
105 fSignalDepth = 0;
106
cb866e08
FC
107 fLogData = Tracer.isEventTraced();
108 fLogError = Tracer.isErrorTraced();
377f1ad8
WB
109 }
110
fc6ccf6f 111 @Override
2fb2eb37 112 public void dispose() {
8c8bf09f 113 TmfProviderManager.deregister(fType, this);
54d55ced 114 fExecutor.stop();
2fb2eb37 115 super.dispose();
3d62f8b7 116// if (Tracer.isComponentTraced()) Tracer.traceComponent(this, "stopped");
8c8bf09f
ASL
117 }
118
119 public int getQueueSize() {
120 return fQueueSize;
121 }
122
ff4ed569
FC
123 public Class<?> getType() {
124 return fType;
125 }
126
8c8bf09f
ASL
127 // ------------------------------------------------------------------------
128 // ITmfRequestHandler
129 // ------------------------------------------------------------------------
130
d4011df2 131 @Override
550d787e 132 public void sendRequest(final ITmfDataRequest<T> request) {
045df77d 133 synchronized(fLock) {
9b635e61
FC
134 if (fSignalDepth > 0) {
135 coalesceDataRequest(request);
136 } else {
137 dispatchRequest(request);
550d787e 138 }
951d134a
FC
139 }
140 }
141
142 /**
143 * This method queues the coalesced requests.
144 *
145 * @param thread
146 */
d4011df2 147 @Override
c1c69938 148 public void fireRequest() {
045df77d 149 synchronized(fLock) {
c1c69938
FC
150 if (fRequestPendingCounter > 0) {
151 return;
152 }
153 if (fPendingCoalescedRequests.size() > 0) {
154 for (TmfDataRequest<T> request : fPendingCoalescedRequests) {
155 dispatchRequest(request);
156 }
157 fPendingCoalescedRequests.clear();
550d787e 158 }
951d134a 159 }
951d134a 160 }
c1c69938
FC
161
162 /**
163 * Increments/decrements the pending requests counters and fires
164 * the request if necessary (counter == 0). Used for coalescing
165 * requests accross multiple TmfDataProvider.
166 *
167 * @param isIncrement
168 */
169 @Override
170 public void notifyPendingRequest(boolean isIncrement) {
171 synchronized(fLock) {
172 if (isIncrement) {
173 if (fSignalDepth > 0) {
174 fRequestPendingCounter++;
175 }
176 } else {
177 if (fRequestPendingCounter > 0) {
178 fRequestPendingCounter--;
179 }
180
181 // fire request if all pending requests are received
182 if (fRequestPendingCounter == 0) {
183 fireRequest();
184 }
185 }
186 }
187 }
951d134a
FC
188
189 // ------------------------------------------------------------------------
190 // Coalescing (primitive test...)
191 // ------------------------------------------------------------------------
8c8bf09f 192
951d134a 193 protected Vector<TmfCoalescedDataRequest<T>> fPendingCoalescedRequests = new Vector<TmfCoalescedDataRequest<T>>();
8c8bf09f 194
550d787e 195 protected void newCoalescedDataRequest(ITmfDataRequest<T> request) {
045df77d 196 synchronized(fLock) {
f9673903
FC
197 TmfCoalescedDataRequest<T> coalescedRequest = new TmfCoalescedDataRequest<T>(
198 fType, request.getIndex(), request.getNbRequested(),request.getExecType());
550d787e 199 coalescedRequest.addRequest(request);
9b635e61 200 if (Tracer.isRequestTraced()) {
3b38ea61
FC
201 Tracer.traceRequest(request, "coalesced with " + coalescedRequest.getRequestId()); //$NON-NLS-1$
202 Tracer.traceRequest(coalescedRequest, "added " + request.getRequestId()); //$NON-NLS-1$
9b635e61 203 }
550d787e
FC
204 fPendingCoalescedRequests.add(coalescedRequest);
205 }
951d134a 206 }
8c8bf09f 207
045df77d
FC
208 protected void coalesceDataRequest(ITmfDataRequest<T> request) {
209 synchronized(fLock) {
550d787e
FC
210 for (TmfCoalescedDataRequest<T> req : fPendingCoalescedRequests) {
211 if (req.isCompatible(request)) {
212 req.addRequest(request);
9b635e61 213 if (Tracer.isRequestTraced()) {
3b38ea61
FC
214 Tracer.traceRequest(request, "coalesced with " + req.getRequestId()); //$NON-NLS-1$
215 Tracer.traceRequest(req, "added " + request.getRequestId()); //$NON-NLS-1$
9b635e61 216 }
550d787e
FC
217 return;
218 }
951d134a 219 }
550d787e 220 newCoalescedDataRequest(request);
8c8bf09f 221 }
8c8bf09f
ASL
222 }
223
951d134a
FC
224 // ------------------------------------------------------------------------
225 // Request processing
226 // ------------------------------------------------------------------------
227
9b635e61 228 private void dispatchRequest(final ITmfDataRequest<T> request) {
f6b14ce2 229 if (request.getExecType() == ExecutionType.FOREGROUND)
9b635e61
FC
230 queueRequest(request);
231 else
f6b14ce2 232 queueBackgroundRequest(request, DEFAULT_BLOCK_SIZE, true);
9b635e61
FC
233 }
234
2fb2eb37 235 protected void queueRequest(final ITmfDataRequest<T> request) {
9aae0442 236
045df77d
FC
237 if (fExecutor.isShutdown()) {
238 request.cancel();
239 return;
240 }
241
f9673903 242 final TmfDataProvider<T> provider = this;
550d787e 243
8c8bf09f 244 // Process the request
9b635e61 245 TmfThread thread = new TmfThread(request.getExecType()) {
8c8bf09f
ASL
246
247 @Override
248 public void run() {
249
3b38ea61 250 if (Tracer.isRequestTraced()) Tracer.traceRequest(request, "started"); //$NON-NLS-1$
9b635e61 251
8c8bf09f 252 // Extract the generic information
550d787e 253 request.start();
8c8bf09f 254 int nbRequested = request.getNbRequested();
8c8bf09f
ASL
255 int nbRead = 0;
256
257 // Initialize the execution
258 ITmfContext context = armRequest(request);
259 if (context == null) {
550d787e 260 request.cancel();
8c8bf09f
ASL
261 return;
262 }
263
550d787e
FC
264 try {
265 // Get the ordered events
3b38ea61 266 if (Tracer.isRequestTraced()) Tracer.trace("Request #" + request.getRequestId() + " is being serviced by " + provider.getName()); //$NON-NLS-1$//$NON-NLS-2$
550d787e 267 T data = getNext(context);
3b38ea61 268 if (Tracer.isRequestTraced()) Tracer.trace("Request #" + request.getRequestId() + " read first event"); //$NON-NLS-1$ //$NON-NLS-2$
550d787e
FC
269 while (data != null && !isCompleted(request, data, nbRead))
270 {
f9673903
FC
271 if (fLogData) Tracer.traceEvent(provider, request, data);
272 request.handleData(data);
273
550d787e 274 // To avoid an unnecessary read passed the last data requested
f9673903 275 if (++nbRead < nbRequested) {
550d787e 276 data = getNext(context);
3d62f8b7 277 if (Tracer.isRequestTraced() && (data == null || data.isNullRef())) {
3b38ea61 278 Tracer.trace("Request #" + request.getRequestId() + " end of data"); //$NON-NLS-1$//$NON-NLS-2$
3d62f8b7 279 }
550d787e
FC
280 }
281 }
c1c69938
FC
282
283 if (request.isCancelled()) {
284 request.cancel();
285 }
286 else {
287 request.done();
288 }
9b635e61 289
3b38ea61 290 if (Tracer.isRequestTraced()) Tracer.traceRequest(request, "completed"); //$NON-NLS-1$
550d787e
FC
291 }
292 catch (Exception e) {
3b38ea61 293 if (Tracer.isRequestTraced()) Tracer.traceRequest(request, "exception (failed)"); //$NON-NLS-1$
550d787e 294 request.fail();
8c8bf09f 295 }
8c8bf09f
ASL
296 }
297 };
3d62f8b7 298
5c00c0b7 299 fExecutor.execute(thread);
3d62f8b7 300
3b38ea61 301 if (Tracer.isRequestTraced()) Tracer.traceRequest(request, "queued"); //$NON-NLS-1$
8c8bf09f
ASL
302 }
303
f6b14ce2
FC
304 // By default, same behavior as a foreground request
305 protected void queueBackgroundRequest(final ITmfDataRequest<T> request, final int blockSize, boolean indexing) {
9b635e61
FC
306 queueRequest(request);
307 }
308
951d134a
FC
309 /**
310 * Initialize the provider based on the request. The context is
311 * provider specific and will be updated by getNext().
312 *
313 * @param request
314 * @return an application specific context; null if request can't be serviced
315 */
2fb2eb37 316 public abstract ITmfContext armRequest(ITmfDataRequest<T> request);
3d62f8b7
FC
317 public abstract T getNext(ITmfContext context);
318
8c8bf09f
ASL
319 /**
320 * Checks if the data meets the request completion criteria.
321 *
322 * @param request
323 * @param data
324 * @return
325 */
2fb2eb37 326 public boolean isCompleted(ITmfDataRequest<T> request, T data, int nbRead) {
36548af3 327 return request.isCompleted() || nbRead >= request.getNbRequested() || data.isNullRef();
8c8bf09f
ASL
328 }
329
951d134a
FC
330 // ------------------------------------------------------------------------
331 // Signal handlers
332 // ------------------------------------------------------------------------
333
8c8bf09f 334 @TmfSignalHandler
045df77d
FC
335 public void startSynch(TmfStartSynchSignal signal) {
336 synchronized (fLock) {
337 fSignalDepth++;
338 }
8c8bf09f
ASL
339 }
340
341 @TmfSignalHandler
045df77d
FC
342 public void endSynch(TmfEndSynchSignal signal) {
343 synchronized (fLock) {
344 fSignalDepth--;
345 if (fSignalDepth == 0) {
c1c69938 346 fireRequest();
045df77d
FC
347 }
348 }
8c8bf09f
ASL
349 }
350
351}
This page took 0.047662 seconds and 5 git commands to generate.