Commit | Line | Data |
---|---|---|
8c8bf09f | 1 | /******************************************************************************* |
e73a4ba5 | 2 | * Copyright (c) 2009, 2013 Ericsson, École Polytechnique de Montréal |
ce2388e0 | 3 | * |
8c8bf09f ASL |
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 | |
ce2388e0 | 8 | * |
8c8bf09f ASL |
9 | * Contributors: |
10 | * Francois Chouinard - Initial API and implementation | |
0316808c | 11 | * Francois Chouinard - Updated as per TMF Trace Model 1.0 |
ea271da6 PT |
12 | * Patrick Tasse - Updated for removal of context clone |
13 | * Patrick Tasse - Updated for ranks in experiment location | |
e73a4ba5 | 14 | * Geneviève Bastien - Added support of experiment synchronization |
8c8bf09f ASL |
15 | *******************************************************************************/ |
16 | ||
9e0640dc | 17 | package org.eclipse.linuxtools.tmf.core.trace; |
8c8bf09f | 18 | |
e73a4ba5 | 19 | import java.io.File; |
032ecd45 | 20 | import java.nio.ByteBuffer; |
e73a4ba5 | 21 | |
a1091415 | 22 | import org.eclipse.core.resources.IFile; |
12c155f5 | 23 | import org.eclipse.core.resources.IProject; |
828e5592 | 24 | import org.eclipse.core.resources.IResource; |
e73a4ba5 | 25 | import org.eclipse.core.runtime.CoreException; |
a94410d9 MK |
26 | import org.eclipse.core.runtime.IStatus; |
27 | import org.eclipse.core.runtime.Status; | |
e73a4ba5 | 28 | import org.eclipse.linuxtools.internal.tmf.core.Activator; |
9e0640dc FC |
29 | import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentContext; |
30 | import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentLocation; | |
31 | import org.eclipse.linuxtools.internal.tmf.core.trace.TmfLocationArray; | |
e73a4ba5 | 32 | import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; |
72f1e62a | 33 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; |
0316808c | 34 | import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; |
5419a136 | 35 | import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; |
6c13869b | 36 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; |
faa38350 PT |
37 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; |
38 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal; | |
e73a4ba5 GB |
39 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSynchronizedSignal; |
40 | import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm; | |
41 | import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationManager; | |
3bd46eef AM |
42 | import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; |
43 | import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; | |
44 | import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; | |
032ecd45 MAL |
45 | import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable; |
46 | import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer; | |
47 | import org.eclipse.linuxtools.tmf.core.trace.indexer.TmfBTreeTraceIndexer; | |
a3db8436 | 48 | import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; |
8c8bf09f ASL |
49 | |
50 | /** | |
9e0640dc | 51 | * TmfExperiment presents a time-ordered, unified view of a set of ITmfTrace:s |
cbdacf03 | 52 | * that are part of a tracing experiment. |
4b7b3670 FC |
53 | * |
54 | * @version 1.0 | |
55 | * @author Francois Chouinard | |
8c8bf09f | 56 | */ |
032ecd45 | 57 | public class TmfExperiment extends TmfTrace implements ITmfEventParser, ITmfPersistentlyIndexable { |
8c8bf09f | 58 | |
c32744d6 FC |
59 | // ------------------------------------------------------------------------ |
60 | // Constants | |
61 | // ------------------------------------------------------------------------ | |
62 | ||
e73a4ba5 GB |
63 | /** |
64 | * The file name of the Synchronization | |
65 | * | |
66 | * @since 3.0 | |
67 | */ | |
68 | public final static String SYNCHRONIZATION_FILE_NAME = "synchronization.bin"; //$NON-NLS-1$ | |
69 | ||
9e0640dc FC |
70 | /** |
71 | * The default index page size | |
72 | */ | |
73 | public static final int DEFAULT_INDEX_PAGE_SIZE = 5000; | |
c32744d6 | 74 | |
8c8bf09f ASL |
75 | // ------------------------------------------------------------------------ |
76 | // Attributes | |
77 | // ------------------------------------------------------------------------ | |
78 | ||
9e0640dc FC |
79 | /** |
80 | * The set of traces that constitute the experiment | |
81 | */ | |
6256d8ad | 82 | protected ITmfTrace[] fTraces; |
8c8bf09f | 83 | |
9e0640dc FC |
84 | /** |
85 | * The set of traces that constitute the experiment | |
86 | */ | |
87 | private boolean fInitialized = false; | |
a1091415 | 88 | |
9e0640dc FC |
89 | /** |
90 | * The experiment bookmarks file | |
91 | */ | |
92 | private IFile fBookmarksFile; | |
828e5592 | 93 | |
8c8bf09f | 94 | // ------------------------------------------------------------------------ |
9e0640dc | 95 | // Construction |
8c8bf09f ASL |
96 | // ------------------------------------------------------------------------ |
97 | ||
9e0640dc | 98 | /** |
e73a4ba5 GB |
99 | * @param type |
100 | * the event type | |
101 | * @param id | |
102 | * the experiment id | |
103 | * @param traces | |
104 | * the experiment set of traces | |
9e0640dc | 105 | */ |
6256d8ad | 106 | public TmfExperiment(final Class<? extends ITmfEvent> type, final String id, final ITmfTrace[] traces) { |
99504bb8 | 107 | this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, null); |
96c6806f PT |
108 | } |
109 | ||
99504bb8 GB |
110 | /** |
111 | * Constructor of experiment taking type, path, traces and resource | |
112 | * | |
113 | * @param type | |
114 | * the event type | |
115 | * @param id | |
116 | * the experiment id | |
117 | * @param traces | |
118 | * the experiment set of traces | |
119 | * @param resource | |
120 | * the resource associated to the experiment | |
121 | */ | |
122 | public TmfExperiment(final Class<? extends ITmfEvent> type, final String id, final ITmfTrace[] traces, IResource resource) { | |
123 | this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, resource); | |
124 | } | |
125 | ||
8c8bf09f | 126 | /** |
e73a4ba5 GB |
127 | * @param type |
128 | * the event type | |
129 | * @param path | |
130 | * the experiment path | |
131 | * @param traces | |
132 | * the experiment set of traces | |
133 | * @param indexPageSize | |
134 | * the experiment index page size | |
8c8bf09f | 135 | */ |
6256d8ad | 136 | public TmfExperiment(final Class<? extends ITmfEvent> type, final String path, final ITmfTrace[] traces, final int indexPageSize) { |
99504bb8 GB |
137 | this(type, path, traces, indexPageSize, null); |
138 | } | |
139 | ||
140 | /** | |
141 | * Full constructor of an experiment, taking the type, path, traces, | |
142 | * indexPageSize and resource | |
143 | * | |
144 | * @param type | |
145 | * the event type | |
146 | * @param path | |
147 | * the experiment path | |
148 | * @param traces | |
149 | * the experiment set of traces | |
150 | * @param indexPageSize | |
151 | * the experiment index page size | |
152 | * @param resource | |
153 | * the resource associated to the experiment | |
154 | */ | |
155 | public TmfExperiment(final Class<? extends ITmfEvent> type, final String path, final ITmfTrace[] traces, final int indexPageSize, IResource resource) { | |
0316808c FC |
156 | setCacheSize(indexPageSize); |
157 | setStreamingInterval(0); | |
0316808c | 158 | setParser(this); |
032ecd45 | 159 | fTraces = traces; |
0316808c | 160 | try { |
99504bb8 | 161 | super.initialize(resource, path, type); |
0316808c FC |
162 | } catch (TmfTraceException e) { |
163 | e.printStackTrace(); | |
164 | } | |
8c8bf09f | 165 | |
e73a4ba5 GB |
166 | if (resource != null) { |
167 | try { | |
168 | this.synchronizeTraces(); | |
169 | } catch (TmfTraceException e) { | |
170 | Activator.logError("Error synchronizing experiment", e); //$NON-NLS-1$ | |
171 | } | |
172 | } | |
8c8bf09f | 173 | } |
a79913eb | 174 | |
032ecd45 MAL |
175 | @Override |
176 | protected ITmfTraceIndexer createIndexer(int interval) { | |
177 | if (getCheckpointSize() > 0) { | |
178 | return new TmfBTreeTraceIndexer(this, interval); | |
179 | } | |
180 | return super.createIndexer(interval); | |
181 | } | |
182 | ||
8c8bf09f | 183 | /** |
ff4ed569 | 184 | * Clears the experiment |
8c8bf09f ASL |
185 | */ |
186 | @Override | |
a79913eb FC |
187 | public synchronized void dispose() { |
188 | ||
77551cc2 FC |
189 | // Clean up the index if applicable |
190 | if (getIndexer() != null) { | |
191 | getIndexer().dispose(); | |
192 | } | |
b5ee6881 | 193 | |
a79913eb | 194 | if (fTraces != null) { |
9b749023 | 195 | for (final ITmfTrace trace : fTraces) { |
a79913eb | 196 | trace.dispose(); |
9b749023 | 197 | } |
a79913eb FC |
198 | fTraces = null; |
199 | } | |
2fb2eb37 | 200 | super.dispose(); |
8c8bf09f ASL |
201 | } |
202 | ||
9e0640dc FC |
203 | // ------------------------------------------------------------------------ |
204 | // ITmfTrace - Initializers | |
205 | // ------------------------------------------------------------------------ | |
206 | ||
9e0640dc | 207 | @Override |
6256d8ad | 208 | public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) { |
9e0640dc FC |
209 | } |
210 | ||
a94410d9 MK |
211 | /** |
212 | * @since 2.0 | |
213 | */ | |
9e0640dc | 214 | @Override |
a94410d9 MK |
215 | public IStatus validate(final IProject project, final String path) { |
216 | return Status.OK_STATUS; | |
9e0640dc FC |
217 | } |
218 | ||
8c8bf09f | 219 | // ------------------------------------------------------------------------ |
e31e01e8 | 220 | // Accessors |
8c8bf09f ASL |
221 | // ------------------------------------------------------------------------ |
222 | ||
f0c0d2c2 AM |
223 | /** |
224 | * Get the traces contained in this experiment. | |
225 | * | |
226 | * @return The array of contained traces | |
227 | */ | |
6256d8ad | 228 | public ITmfTrace[] getTraces() { |
a79913eb | 229 | return fTraces; |
8c8bf09f ASL |
230 | } |
231 | ||
8c8bf09f | 232 | /** |
cbdacf03 FC |
233 | * Returns the timestamp of the event at the requested index. If none, |
234 | * returns null. | |
9b749023 | 235 | * |
e73a4ba5 GB |
236 | * @param index |
237 | * the event index (rank) | |
0d9a6d76 | 238 | * @return the corresponding event timestamp |
3bd46eef | 239 | * @since 2.0 |
8c8bf09f | 240 | */ |
cbdacf03 | 241 | public ITmfTimestamp getTimestamp(final int index) { |
0316808c | 242 | final ITmfContext context = seekEvent(index); |
c32744d6 | 243 | final ITmfEvent event = getNext(context); |
4c9f2944 | 244 | context.dispose(); |
a79913eb | 245 | return (event != null) ? event.getTimestamp() : null; |
8c8bf09f ASL |
246 | } |
247 | ||
9e0640dc FC |
248 | /** |
249 | * Set the file to be used for bookmarks on this experiment | |
9b749023 | 250 | * |
e73a4ba5 GB |
251 | * @param file |
252 | * the bookmarks file | |
9e0640dc FC |
253 | */ |
254 | public void setBookmarksFile(final IFile file) { | |
255 | fBookmarksFile = file; | |
256 | } | |
07671572 | 257 | |
9e0640dc FC |
258 | /** |
259 | * Get the file used for bookmarks on this experiment | |
9b749023 | 260 | * |
9e0640dc FC |
261 | * @return the bookmarks file or null if none is set |
262 | */ | |
263 | public IFile getBookmarksFile() { | |
264 | return fBookmarksFile; | |
a79913eb FC |
265 | } |
266 | ||
49e2f79a FC |
267 | // ------------------------------------------------------------------------ |
268 | // Request management | |
269 | // ------------------------------------------------------------------------ | |
270 | ||
e6809677 PT |
271 | /** |
272 | * @since 2.0 | |
3bd44ac8 | 273 | */ |
49e2f79a | 274 | @Override |
fd3f1eff | 275 | public synchronized ITmfContext armRequest(final ITmfEventRequest request) { |
9b749023 | 276 | |
6a953367 BH |
277 | // Make sure we have something to read from |
278 | if (fTraces == null) { | |
279 | return null; | |
280 | } | |
9b749023 | 281 | |
fd3f1eff AM |
282 | if (!TmfTimestamp.BIG_BANG.equals(request.getRange().getStartTime()) |
283 | && request.getIndex() == 0) { | |
284 | final ITmfContext context = seekEvent(request.getRange().getStartTime()); | |
285 | request.setStartIndex((int) context.getRank()); | |
49e2f79a | 286 | return context; |
5419a136 | 287 | |
49e2f79a FC |
288 | } |
289 | ||
5419a136 | 290 | return seekEvent(request.getIndex()); |
49e2f79a FC |
291 | } |
292 | ||
a79913eb | 293 | // ------------------------------------------------------------------------ |
9f584e4c FC |
294 | // ITmfTrace trace positioning |
295 | // ------------------------------------------------------------------------ | |
296 | ||
a3db8436 AM |
297 | /** |
298 | * @since 3.0 | |
299 | */ | |
a79913eb | 300 | @Override |
1e1bef82 | 301 | public synchronized ITmfContext seekEvent(final ITmfLocation location) { |
a79913eb | 302 | // Validate the location |
9e0640dc | 303 | if (location != null && !(location instanceof TmfExperimentLocation)) { |
a79913eb | 304 | return null; // Throw an exception? |
9e0640dc FC |
305 | } |
306 | // Make sure we have something to read from | |
307 | if (fTraces == null) { | |
a79913eb | 308 | return null; |
9e0640dc | 309 | } |
8f50c396 | 310 | |
ea271da6 PT |
311 | // Initialize the location array if necessary |
312 | TmfLocationArray locationArray = ((location == null) ? | |
313 | new TmfLocationArray(fTraces.length) : | |
314 | ((TmfExperimentLocation) location).getLocationInfo()); | |
315 | ||
316 | ITmfLocation[] locations = locationArray.getLocations(); | |
317 | long[] ranks = locationArray.getRanks(); | |
318 | ||
a79913eb | 319 | // Create and populate the context's traces contexts |
ea271da6 | 320 | final TmfExperimentContext context = new TmfExperimentContext(fTraces.length); |
9b635e61 | 321 | |
d62bb185 | 322 | // Position the traces |
ea271da6 | 323 | long rank = 0; |
a79913eb FC |
324 | for (int i = 0; i < fTraces.length; i++) { |
325 | // Get the relevant trace attributes | |
ea271da6 PT |
326 | final ITmfContext traceContext = fTraces[i].seekEvent(locations[i]); |
327 | context.getContexts()[i] = traceContext; | |
328 | traceContext.setRank(ranks[i]); | |
329 | locations[i] = traceContext.getLocation(); // update location after seek | |
330 | context.getEvents()[i] = fTraces[i].getNext(traceContext); | |
331 | rank += ranks[i]; | |
a79913eb | 332 | } |
8f50c396 | 333 | |
a79913eb | 334 | // Finalize context |
ea271da6 | 335 | context.setLocation(new TmfExperimentLocation(new TmfLocationArray(locations, ranks))); |
a79913eb | 336 | context.setLastTrace(TmfExperimentContext.NO_TRACE); |
ea271da6 | 337 | context.setRank(rank); |
49e2f79a | 338 | |
9b749023 | 339 | return context; |
a79913eb | 340 | } |
9f584e4c | 341 | |
3bd44ac8 FC |
342 | // ------------------------------------------------------------------------ |
343 | // ITmfTrace - SeekEvent operations (returning a trace context) | |
344 | // ------------------------------------------------------------------------ | |
345 | ||
c76c54bb | 346 | @Override |
0316808c | 347 | public ITmfContext seekEvent(final double ratio) { |
91f6e587 | 348 | final ITmfContext context = seekEvent(Math.round(ratio * getNbEvents())); |
c76c54bb FC |
349 | return context; |
350 | } | |
351 | ||
a3db8436 AM |
352 | /** |
353 | * @since 3.0 | |
354 | */ | |
a79913eb | 355 | @Override |
1e1bef82 | 356 | public double getLocationRatio(final ITmfLocation location) { |
9e0640dc | 357 | if (location instanceof TmfExperimentLocation) { |
ea271da6 PT |
358 | long rank = 0; |
359 | TmfLocationArray locationArray = ((TmfExperimentLocation) location).getLocationInfo(); | |
360 | for (int i = 0; i < locationArray.size(); i++) { | |
361 | rank += locationArray.getRank(i); | |
362 | } | |
363 | return (double) rank / getNbEvents(); | |
9e0640dc FC |
364 | } |
365 | return 0.0; | |
c76c54bb FC |
366 | } |
367 | ||
a3db8436 AM |
368 | /** |
369 | * @since 3.0 | |
370 | */ | |
a79913eb | 371 | @Override |
1e1bef82 | 372 | public ITmfLocation getCurrentLocation() { |
ea271da6 PT |
373 | // never used |
374 | return null; | |
a79913eb | 375 | } |
c76c54bb | 376 | |
9e0640dc FC |
377 | // ------------------------------------------------------------------------ |
378 | // ITmfTrace trace positioning | |
379 | // ------------------------------------------------------------------------ | |
380 | ||
07671572 | 381 | @Override |
6256d8ad | 382 | public synchronized ITmfEvent parseEvent(final ITmfContext context) { |
ea271da6 PT |
383 | final ITmfContext tmpContext = seekEvent(context.getLocation()); |
384 | final ITmfEvent event = getNext(tmpContext); | |
07671572 FC |
385 | return event; |
386 | } | |
a79913eb | 387 | |
0316808c | 388 | @Override |
6256d8ad | 389 | public synchronized ITmfEvent getNext(ITmfContext context) { |
a79913eb FC |
390 | |
391 | // Validate the context | |
9e0640dc | 392 | if (!(context instanceof TmfExperimentContext)) { |
a79913eb | 393 | return null; // Throw an exception? |
9e0640dc | 394 | } |
0e8c76f8 BH |
395 | |
396 | // Make sure that we have something to read from | |
397 | if (fTraces == null) { | |
398 | return null; | |
399 | } | |
400 | ||
a87cc4ef | 401 | TmfExperimentContext expContext = (TmfExperimentContext) context; |
a79913eb | 402 | |
e73a4ba5 GB |
403 | // If an event was consumed previously, first get the next one from that |
404 | // trace | |
cbdacf03 | 405 | final int lastTrace = expContext.getLastTrace(); |
a79913eb | 406 | if (lastTrace != TmfExperimentContext.NO_TRACE) { |
cbdacf03 | 407 | final ITmfContext traceContext = expContext.getContexts()[lastTrace]; |
c32744d6 | 408 | expContext.getEvents()[lastTrace] = fTraces[lastTrace].getNext(traceContext); |
a79913eb | 409 | expContext.setLastTrace(TmfExperimentContext.NO_TRACE); |
a79913eb FC |
410 | } |
411 | ||
412 | // Scan the candidate events and identify the "next" trace to read from | |
413 | int trace = TmfExperimentContext.NO_TRACE; | |
a4115405 | 414 | ITmfTimestamp timestamp = TmfTimestamp.BIG_CRUNCH; |
0316808c | 415 | for (int i = 0; i < fTraces.length; i++) { |
cbdacf03 | 416 | final ITmfEvent event = expContext.getEvents()[i]; |
a79913eb | 417 | if (event != null && event.getTimestamp() != null) { |
cbdacf03 | 418 | final ITmfTimestamp otherTS = event.getTimestamp(); |
a79913eb FC |
419 | if (otherTS.compareTo(timestamp, true) < 0) { |
420 | trace = i; | |
421 | timestamp = otherTS; | |
422 | } | |
423 | } | |
424 | } | |
a87cc4ef | 425 | |
6256d8ad | 426 | ITmfEvent event = null; |
07671572 | 427 | if (trace != TmfExperimentContext.NO_TRACE) { |
6256d8ad | 428 | event = expContext.getEvents()[trace]; |
408e65d2 FC |
429 | if (event != null) { |
430 | updateAttributes(expContext, event.getTimestamp()); | |
408e65d2 FC |
431 | expContext.increaseRank(); |
432 | expContext.setLastTrace(trace); | |
17324c9a FC |
433 | final ITmfContext traceContext = expContext.getContexts()[trace]; |
434 | ||
ea271da6 PT |
435 | // Update the experiment location |
436 | TmfLocationArray locationArray = new TmfLocationArray( | |
437 | ((TmfExperimentLocation) expContext.getLocation()).getLocationInfo(), | |
438 | trace, traceContext.getLocation(), traceContext.getRank()); | |
439 | expContext.setLocation(new TmfExperimentLocation(locationArray)); | |
17324c9a | 440 | |
408e65d2 FC |
441 | processEvent(event); |
442 | } | |
07671572 | 443 | } |
a87cc4ef | 444 | |
a87cc4ef | 445 | return event; |
a79913eb FC |
446 | } |
447 | ||
66262ad8 BH |
448 | /** |
449 | * @since 2.0 | |
450 | */ | |
451 | @Override | |
452 | public ITmfTimestamp getInitialRangeOffset() { | |
453 | if ((fTraces == null) || (fTraces.length == 0)) { | |
454 | return super.getInitialRangeOffset(); | |
455 | } | |
456 | ||
457 | ITmfTimestamp initTs = TmfTimestamp.BIG_CRUNCH; | |
458 | for (int i = 0; i < fTraces.length; i++) { | |
459 | ITmfTimestamp ts = fTraces[i].getInitialRangeOffset(); | |
460 | if (ts.compareTo(initTs) < 0) { | |
461 | initTs = ts; | |
462 | } | |
463 | } | |
464 | return initTs; | |
465 | } | |
466 | ||
e73a4ba5 GB |
467 | /** |
468 | * Synchronizes the traces of an experiment. By default it only tries to | |
469 | * read a synchronization file if it exists | |
470 | * | |
471 | * @return The synchronization object | |
472 | * @throws TmfTraceException | |
473 | * propagate TmfTraceExceptions | |
474 | * @since 3.0 | |
475 | */ | |
476 | public synchronized SynchronizationAlgorithm synchronizeTraces() throws TmfTraceException { | |
477 | return synchronizeTraces(false); | |
478 | } | |
479 | ||
480 | /** | |
481 | * Synchronizes the traces of an experiment. | |
482 | * | |
483 | * @param doSync | |
484 | * Whether to actually synchronize or just try opening a sync | |
485 | * file | |
486 | * @return The synchronization object | |
487 | * @throws TmfTraceException | |
488 | * propagate TmfTraceExceptions | |
489 | * @since 3.0 | |
490 | */ | |
491 | public synchronized SynchronizationAlgorithm synchronizeTraces(boolean doSync) throws TmfTraceException { | |
492 | ||
493 | /* Set up the path to the synchronization file we'll use */ | |
494 | IResource resource = this.getResource(); | |
495 | String supplDirectory = null; | |
496 | ||
497 | try { | |
498 | /* get the directory where the file will be stored. */ | |
499 | if (resource != null) { | |
500 | supplDirectory = resource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER); | |
501 | } | |
502 | } catch (CoreException e) { | |
503 | throw new TmfTraceException(e.toString(), e); | |
504 | } | |
505 | ||
506 | final File syncFile = (supplDirectory != null) ? new File(supplDirectory + File.separator + SYNCHRONIZATION_FILE_NAME) : null; | |
507 | ||
508 | final SynchronizationAlgorithm syncAlgo = SynchronizationManager.synchronizeTraces(syncFile, fTraces, doSync); | |
509 | ||
510 | final TmfTraceSynchronizedSignal signal = new TmfTraceSynchronizedSignal(this, syncAlgo); | |
511 | ||
512 | /* Broadcast in separate thread to prevent deadlock */ | |
513 | new Thread() { | |
514 | @Override | |
515 | public void run() { | |
516 | broadcast(signal); | |
517 | } | |
518 | }.start(); | |
519 | ||
520 | return syncAlgo; | |
521 | } | |
522 | ||
a79913eb | 523 | @Override |
3b38ea61 | 524 | @SuppressWarnings("nls") |
5419a136 | 525 | public synchronized String toString() { |
a79913eb FC |
526 | return "[TmfExperiment (" + getName() + ")]"; |
527 | } | |
8c8bf09f ASL |
528 | |
529 | // ------------------------------------------------------------------------ | |
9e0640dc | 530 | // Streaming support |
8c8bf09f ASL |
531 | // ------------------------------------------------------------------------ |
532 | ||
1b70b6dc | 533 | private synchronized void initializeStreamingMonitor() { |
9e0640dc FC |
534 | |
535 | if (fInitialized) { | |
828e5592 | 536 | return; |
9e0640dc | 537 | } |
828e5592 PT |
538 | fInitialized = true; |
539 | ||
1b70b6dc | 540 | if (getStreamingInterval() == 0) { |
0316808c | 541 | final ITmfContext context = seekEvent(0); |
cbdacf03 | 542 | final ITmfEvent event = getNext(context); |
4c9f2944 | 543 | context.dispose(); |
9b749023 | 544 | if (event == null) { |
1b70b6dc | 545 | return; |
9b749023 | 546 | } |
4593bd5b | 547 | final TmfTimeRange timeRange = new TmfTimeRange(event.getTimestamp(), TmfTimestamp.BIG_CRUNCH); |
faa38350 | 548 | final TmfTraceRangeUpdatedSignal signal = new TmfTraceRangeUpdatedSignal(this, this, timeRange); |
828e5592 PT |
549 | |
550 | // Broadcast in separate thread to prevent deadlock | |
551 | new Thread() { | |
552 | @Override | |
553 | public void run() { | |
554 | broadcast(signal); | |
555 | } | |
556 | }.start(); | |
1b70b6dc PT |
557 | return; |
558 | } | |
559 | ||
9e0640dc | 560 | final Thread thread = new Thread("Streaming Monitor for experiment " + getName()) { //$NON-NLS-1$ |
bcbea6a6 | 561 | private ITmfTimestamp safeTimestamp = null; |
6be2d5cc | 562 | private ITmfTimestamp lastSafeTimestamp = null; |
bcbea6a6 | 563 | private TmfTimeRange timeRange = null; |
1b70b6dc PT |
564 | |
565 | @Override | |
566 | public void run() { | |
fc7cd0be | 567 | while (!executorIsShutdown()) { |
9e0640dc | 568 | if (!getIndexer().isIndexing()) { |
a4115405 FC |
569 | ITmfTimestamp startTimestamp = TmfTimestamp.BIG_CRUNCH; |
570 | ITmfTimestamp endTimestamp = TmfTimestamp.BIG_BANG; | |
6256d8ad | 571 | for (final ITmfTrace trace : fTraces) { |
9b749023 | 572 | if (trace.getStartTime().compareTo(startTimestamp) < 0) { |
1b70b6dc | 573 | startTimestamp = trace.getStartTime(); |
9b749023 AM |
574 | } |
575 | if (trace.getStreamingInterval() != 0 && trace.getEndTime().compareTo(endTimestamp) > 0) { | |
1b70b6dc | 576 | endTimestamp = trace.getEndTime(); |
9b749023 | 577 | } |
1b70b6dc | 578 | } |
6be2d5cc | 579 | if (safeTimestamp != null && (lastSafeTimestamp == null || safeTimestamp.compareTo(lastSafeTimestamp, false) > 0)) { |
1b70b6dc | 580 | timeRange = new TmfTimeRange(startTimestamp, safeTimestamp); |
6be2d5cc | 581 | lastSafeTimestamp = safeTimestamp; |
9b749023 | 582 | } else { |
1b70b6dc | 583 | timeRange = null; |
9b749023 | 584 | } |
1b70b6dc PT |
585 | safeTimestamp = endTimestamp; |
586 | if (timeRange != null) { | |
faa38350 PT |
587 | final TmfTraceRangeUpdatedSignal signal = |
588 | new TmfTraceRangeUpdatedSignal(TmfExperiment.this, TmfExperiment.this, timeRange); | |
1b70b6dc PT |
589 | broadcast(signal); |
590 | } | |
591 | } | |
592 | try { | |
593 | Thread.sleep(getStreamingInterval()); | |
cbdacf03 | 594 | } catch (final InterruptedException e) { |
1b70b6dc PT |
595 | e.printStackTrace(); |
596 | } | |
597 | } | |
598 | } | |
599 | }; | |
600 | thread.start(); | |
601 | } | |
602 | ||
1b70b6dc PT |
603 | @Override |
604 | public long getStreamingInterval() { | |
605 | long interval = 0; | |
6256d8ad | 606 | for (final ITmfTrace trace : fTraces) { |
1b70b6dc | 607 | interval = Math.max(interval, trace.getStreamingInterval()); |
9b749023 | 608 | } |
1b70b6dc PT |
609 | return interval; |
610 | } | |
611 | ||
8c8bf09f ASL |
612 | // ------------------------------------------------------------------------ |
613 | // Signal handlers | |
614 | // ------------------------------------------------------------------------ | |
615 | ||
faa38350 | 616 | @Override |
9e0640dc | 617 | @TmfSignalHandler |
faa38350 | 618 | public void traceOpened(TmfTraceOpenedSignal signal) { |
9e0640dc | 619 | if (signal.getTrace() == this) { |
faa38350 | 620 | initializeStreamingMonitor(); |
9e0640dc | 621 | } |
a1091415 PT |
622 | } |
623 | ||
c4767854 AM |
624 | /** |
625 | * @since 3.0 | |
626 | */ | |
032ecd45 MAL |
627 | @Override |
628 | public synchronized int getCheckpointSize() { | |
629 | int totalCheckpointSize = 0; | |
630 | try { | |
631 | if (fTraces != null) { | |
632 | for (final ITmfTrace trace : fTraces) { | |
633 | if (!(trace instanceof ITmfPersistentlyIndexable)) { | |
634 | return 0; | |
635 | } | |
636 | ||
637 | ITmfPersistentlyIndexable persistableIndexTrace = (ITmfPersistentlyIndexable) trace; | |
638 | int currentTraceCheckpointSize = persistableIndexTrace.getCheckpointSize(); | |
639 | if (currentTraceCheckpointSize <= 0) { | |
640 | return 0; | |
641 | } | |
642 | totalCheckpointSize += currentTraceCheckpointSize; | |
643 | totalCheckpointSize += 8; // each entry in the TmfLocationArray has a rank in addition of the location | |
644 | } | |
645 | } | |
646 | } catch (UnsupportedOperationException e) { | |
647 | return 0; | |
648 | } | |
649 | ||
650 | return totalCheckpointSize; | |
651 | } | |
652 | ||
c4767854 AM |
653 | /** |
654 | * @since 3.0 | |
655 | */ | |
032ecd45 MAL |
656 | @Override |
657 | public ITmfLocation restoreLocation(ByteBuffer bufferIn) { | |
658 | ITmfLocation[] locations = new ITmfLocation[fTraces.length]; | |
659 | long[] ranks = new long[fTraces.length]; | |
660 | for (int i = 0; i < fTraces.length; ++i) { | |
661 | final ITmfTrace trace = fTraces[i]; | |
662 | locations[i] = ((ITmfPersistentlyIndexable) trace).restoreLocation(bufferIn); | |
663 | ranks[i] = bufferIn.getLong(); | |
664 | } | |
665 | TmfLocationArray arr = new TmfLocationArray(locations, ranks); | |
666 | TmfExperimentLocation l = new TmfExperimentLocation(arr); | |
667 | return l; | |
668 | } | |
669 | ||
4dc47e28 | 670 | } |