ss: Move plugins to Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / request / TmfCoalescedEventRequest.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2014 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 * Alexandre Montplaisir - Merge with TmfCoalescedDataRequest
12 *******************************************************************************/
13
14 package org.eclipse.linuxtools.internal.tmf.core.request;
15
16 import java.util.ArrayList;
17 import java.util.List;
18
19 import org.eclipse.linuxtools.internal.tmf.core.TmfCoreTracer;
20 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
21 import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
22 import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
23 import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
24 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
25
26 /**
27 * The TMF coalesced event request
28 *
29 * @author Francois Chouinard
30 * @since 3.0
31 */
32 public class TmfCoalescedEventRequest extends TmfEventRequest {
33
34 // ------------------------------------------------------------------------
35 // Attributes
36 // ------------------------------------------------------------------------
37
38 /** The list of coalesced requests */
39 private final List<ITmfEventRequest> fRequests = new ArrayList<>();
40
41 /**
42 * We do not use super.fRange, because in the case of coalesced requests,
43 * the global range can be modified as sub-request are added.
44 */
45 private TmfTimeRange fRange;
46
47 // ------------------------------------------------------------------------
48 // Constructor
49 // ------------------------------------------------------------------------
50
51 /**
52 * Request 'n' events of a given type for the given time range (given
53 * priority). Events are returned in blocks of the given size.
54 *
55 * @param dataType
56 * The requested data type
57 * @param range
58 * The range of the request. You can use
59 * {@link TmfTimeRange#ETERNITY} to request all events.
60 * @param index
61 * The index of the first event to retrieve. Use '0' to start at
62 * the beginning.
63 * @param nbRequested
64 * The number of events requested. You can use
65 * {@link TmfEventRequest#ALL_DATA} to request all events.
66 * @param priority
67 * The requested execution priority
68 */
69 public TmfCoalescedEventRequest(Class<? extends ITmfEvent> dataType,
70 TmfTimeRange range,
71 long index,
72 int nbRequested,
73 ExecutionType priority) {
74 super(ITmfEvent.class, null, index, nbRequested, priority);
75 fRange = range;
76
77 if (TmfCoreTracer.isRequestTraced()) {
78 String type = getClass().getName();
79 type = type.substring(type.lastIndexOf('.') + 1);
80 @SuppressWarnings("nls")
81 String message = "CREATED "
82 + (getExecType() == ITmfEventRequest.ExecutionType.BACKGROUND ? "(BG)" : "(FG)")
83 + " Type=" + type + " Index=" + getIndex() + " NbReq=" + getNbRequested()
84 + " Range=" + getRange()
85 + " DataType=" + getDataType().getSimpleName();
86 TmfCoreTracer.traceRequest(this, message);
87 }
88 }
89
90 @Override
91 public TmfTimeRange getRange() {
92 return fRange;
93 }
94
95 // ------------------------------------------------------------------------
96 // Management
97 // ------------------------------------------------------------------------
98
99 /**
100 * Add a request to this one.
101 *
102 * @param request
103 * The request to add
104 */
105 public void addRequest(ITmfEventRequest request) {
106 fRequests.add(request);
107 merge(request);
108 }
109
110 /**
111 * Check if a request is compatible with the current coalesced one
112 *
113 * @param request
114 * The request to verify
115 * @return If the request is compatible, true or false
116 */
117 public boolean isCompatible(ITmfEventRequest request) {
118 if (request.getExecType() == getExecType() &&
119 ranksOverlap(request) &&
120 timeRangesOverlap(request)) {
121 return true;
122 }
123 return false;
124 }
125
126 private boolean ranksOverlap(ITmfEventRequest request) {
127 long start = request.getIndex();
128 long end = start + request.getNbRequested();
129
130 // Return true if either the start or end index falls within
131 // the coalesced request boundaries
132 return (start <= (fIndex + fNbRequested + 1) && (end >= fIndex - 1));
133 }
134
135 private boolean timeRangesOverlap(ITmfEventRequest request) {
136 ITmfTimestamp startTime = request.getRange().getStartTime();
137 ITmfTimestamp endTime = request.getRange().getEndTime();
138 return (startTime.compareTo(endTime) <= 0) &&
139 (fRange.getStartTime().compareTo(fRange.getEndTime()) <= 0);
140 }
141
142 private void merge(ITmfEventRequest request) {
143 long start = request.getIndex();
144 long end = Math.min(start + request.getNbRequested(), ITmfEventRequest.ALL_DATA);
145
146 if (start < fIndex) {
147 if (fNbRequested != ITmfEventRequest.ALL_DATA) {
148 fNbRequested += (fIndex - start);
149 }
150 fIndex = start;
151 }
152 if ((request.getNbRequested() == ITmfEventRequest.ALL_DATA) ||
153 (fNbRequested == ITmfEventRequest.ALL_DATA)) {
154 fNbRequested = ITmfEventRequest.ALL_DATA;
155 } else {
156 fNbRequested = (int) Math.max(end - fIndex, fNbRequested);
157 }
158
159 ITmfTimestamp startTime = request.getRange().getStartTime();
160 ITmfTimestamp endTime = request.getRange().getEndTime();
161 if (!fRange.contains(startTime) && fRange.getStartTime().compareTo(startTime) > 0) {
162 fRange = new TmfTimeRange(startTime, fRange.getEndTime());
163 }
164 if (!fRange.contains(endTime) && fRange.getEndTime().compareTo(endTime) < 0) {
165 fRange = new TmfTimeRange(fRange.getStartTime(), endTime);
166 }
167 }
168
169 /**
170 * @return The list of IDs of the sub-requests
171 */
172 @SuppressWarnings("nls")
173 public String getSubRequestIds() {
174 StringBuffer result = new StringBuffer("[");
175 for (int i = 0; i < fRequests.size(); i++) {
176 if (i != 0) {
177 result.append(", ");
178 }
179 result.append(fRequests.get(i).getRequestId());
180 }
181 result.append("]");
182 return result.toString();
183 }
184
185 // ------------------------------------------------------------------------
186 // ITmfEventRequest
187 // ------------------------------------------------------------------------
188
189 @Override
190 public void handleData(ITmfEvent data) {
191 super.handleData(data);
192 long index = getIndex() + getNbRead() - 1;
193 for (ITmfEventRequest request : fRequests) {
194 long start = request.getIndex();
195 if (!request.isCompleted() && index >= start && request.getNbRead() < request.getNbRequested()) {
196 ITmfTimestamp ts = data.getTimestamp();
197 if (request.getRange().contains(ts)) {
198 if (request.getDataType().isInstance(data)) {
199 request.handleData(data);
200 }
201 }
202 }
203 }
204 }
205
206 @Override
207 public void start() {
208 for (ITmfEventRequest request : fRequests) {
209 if (!request.isCompleted()) {
210 request.start();
211 }
212 }
213 super.start();
214 }
215
216 @Override
217 public void done() {
218 for (ITmfEventRequest request : fRequests) {
219 if (!request.isCompleted()) {
220 request.done();
221 }
222 }
223 super.done();
224 }
225
226 @Override
227 public void fail() {
228 for (ITmfEventRequest request : fRequests) {
229 request.fail();
230 }
231 super.fail();
232 }
233
234 @Override
235 public void cancel() {
236 for (ITmfEventRequest request : fRequests) {
237 if (!request.isCompleted()) {
238 request.cancel();
239 }
240 }
241 super.cancel();
242 }
243
244 @Override
245 public synchronized boolean isCompleted() {
246 // Firstly, check if coalescing request is completed
247 if (super.isCompleted()) {
248 return true;
249 }
250
251 // Secondly, check if all sub-requests are finished
252 if (fRequests.size() > 0) {
253 // If all sub requests are completed the coalesced request is
254 // treated as completed, too.
255 for (ITmfEventRequest request : fRequests) {
256 if (!request.isCompleted()) {
257 return false;
258 }
259 }
260 return true;
261 }
262
263 // Coalescing request is not finished if there are no sub-requests
264 return false;
265 }
266
267 @Override
268 public synchronized boolean isCancelled() {
269 // Firstly, check if coalescing request is canceled
270 if (super.isCancelled()) {
271 return true;
272 }
273
274 // Secondly, check if all sub-requests are canceled
275 if (fRequests.size() > 0) {
276 // If all sub requests are canceled the coalesced request is
277 // treated as completed, too.
278 for (ITmfEventRequest request : fRequests) {
279 if (!request.isCancelled()) {
280 return false;
281 }
282 }
283 return true;
284 }
285
286 // Coalescing request is not canceled if there are no sub-requests
287 return false;
288
289 }
290
291 // ------------------------------------------------------------------------
292 // Object
293 // ------------------------------------------------------------------------
294
295 @Override
296 // All requests have a unique id
297 public int hashCode() {
298 return super.hashCode();
299 }
300
301 @Override
302 public boolean equals(Object other) {
303 if (other instanceof TmfCoalescedEventRequest) {
304 TmfCoalescedEventRequest request = (TmfCoalescedEventRequest) other;
305 return (request.getDataType() == getDataType()) &&
306 (request.getIndex() == getIndex()) &&
307 (request.getNbRequested() == getNbRequested()) &&
308 (request.getRange().equals(fRange));
309 }
310 return false;
311 }
312
313 @Override
314 @SuppressWarnings("nls")
315 public String toString() {
316 return "[TmfCoalescedEventRequest(" + getRequestId() + "," + getDataType().getSimpleName()
317 + "," + getExecType() + "," + getRange() + "," + getIndex() + "," + getNbRequested()
318 + ", " + fRequests.toString() + ")]";
319 }
320
321 }
This page took 0.053622 seconds and 5 git commands to generate.