/*******************************************************************************
- * Copyright (c) 2015 École Polytechnique de Montréal
+ * Copyright (c) 2015, 2016 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
COLUMN_PROCESS
};
- private final Table<ITmfTrace, Object, List<ILinkEvent>> fLinks = NonNullUtils.checkNotNull(HashBasedTable.create());
+ private final Table<ITmfTrace, Object, List<ILinkEvent>> fLinks = HashBasedTable.create();
/** The trace to entry list hash map */
- private final Table<ITmfTrace, Object, TmfGraphStatistics> fObjectStatistics = NonNullUtils.checkNotNull(HashBasedTable.create());
+ private final Table<ITmfTrace, Object, TmfGraphStatistics> fObjectStatistics = HashBasedTable.create();
private final CriticalPathContentProvider fContentProvider = new CriticalPathContentProvider();
public void visit(TmfEdge link, boolean horizontal) {
if (horizontal) {
Object parent = fGraph.getParentOf(link.getVertexFrom());
- CriticalPathEntry entry = checkNotNull(fRootList.get(parent));
+ CriticalPathEntry entry = fRootList.get(parent);
TimeEvent ev = new TimeEvent(entry, link.getVertexFrom().getTs(), link.getDuration(),
getMatchingState(link.getType()).ordinal());
entry.addEvent(ev);
}
}
- private Map<Object, Map<Object, CriticalPathEntry>> workerMaps = new HashMap<>();
- private Map<Object, List<TimeGraphEntry>> workerEntries = new HashMap<>();
- private Map<Object, List<ILinkEvent>> linkMap = new HashMap<>();
+ private class BuildThread extends Thread {
+ private final ITmfTrace fBuildTrace;
+ private final IProgressMonitor fMonitor;
+
+ public BuildThread(final ITmfTrace trace) {
+ super("Critical path view build"); //$NON-NLS-1$
+ fBuildTrace = trace;
+ fMonitor = new NullProgressMonitor();
+ }
+
+ @Override
+ public void run() {
+ try {
+ CriticalPathModule module = Iterables.<@Nullable CriticalPathModule> getFirst(
+ TmfTraceUtils.getAnalysisModulesOfClass(fBuildTrace, CriticalPathModule.class),
+ null);
+ if (module == null) {
+ return;
+ }
+ module.schedule();
+ if (module.waitForCompletion(fMonitor)) {
+ refresh();
+ }
+
+ } finally {
+ fSyncLock.lock();
+ fBuildThread = null;
+ fSyncLock.unlock();
+ }
+ }
+
+ public void cancel() {
+ fMonitor.setCanceled(true);
+ }
+ }
+
+ private final Lock fSyncLock = new ReentrantLock();
+ private final Map<Object, Map<Object, CriticalPathEntry>> workerMaps = new HashMap<>();
+ private final Map<Object, List<TimeGraphEntry>> workerEntries = new HashMap<>();
+ private final Map<Object, List<ILinkEvent>> linkMap = new HashMap<>();
private @Nullable Object fCurrentObject;
+ private @Nullable BuildThread fBuildThread = null;
@Override
public ITimeGraphEntry[] getElements(@Nullable Object inputElement) {
list.add(defaultParent);
}
- for (TimeGraphEntry entry : list) {
- buildStatusEvents(trace, (CriticalPathEntry) NonNullUtils.checkNotNull(entry));
- }
workerEntries.put(worker, list);
}
TmfTraceUtils.getAnalysisModulesOfClass(trace, CriticalPathModule.class),
null);
if (module == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("View requires an analysis module"); //$NON-NLS-1$
}
- module.schedule();
- if (!module.waitForCompletion()) {
- return null;
- }
final TmfGraph graph = module.getCriticalPath();
return graph;
}
CriticalPathModule module = Iterables.<@Nullable CriticalPathModule> getFirst(
TmfTraceUtils.getAnalysisModulesOfClass(trace, CriticalPathModule.class), null);
if (module == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("View requires an analysis module"); //$NON-NLS-1$
}
final TmfGraph graph = module.getCriticalPath();
@Override
public void dispose() {
-
+ fSyncLock.lock();
+ try {
+ BuildThread buildThread = fBuildThread;
+ if (buildThread != null) {
+ buildThread.cancel();
+ }
+ } finally {
+ fSyncLock.unlock();
+ }
}
@Override
public void inputChanged(@Nullable Viewer viewer, @Nullable Object oldInput, @Nullable Object newInput) {
+ // The input has changed, the critical path will be re-computed,
+ // wait for the analysis to be finished, then call the refresh
+ // method of the view
+ if (!(newInput instanceof List)) {
+ return;
+ }
+ List<?> list = (List<?>) newInput;
+ if (list.isEmpty()) {
+ return;
+ }
+ final ITmfTrace trace = getTrace();
+ if (trace == null) {
+ return;
+ }
+
+ fSyncLock.lock();
+ try {
+ BuildThread buildThread = fBuildThread;
+ if (buildThread != null) {
+ buildThread.cancel();
+ }
+ buildThread = new BuildThread(trace);
+ buildThread.start();
+ fBuildThread = buildThread;
+ } finally {
+ fSyncLock.unlock();
+ }
}
@Override
return state;
}
- private void buildStatusEvents(ITmfTrace trace, CriticalPathEntry entry) {
-
- long start = trace.getStartTime().getValue();
- long end = trace.getEndTime().getValue() + 1;
- long resolution = Math.max(1, (end - start) / getDisplayWidth());
- List<ITimeEvent> eventList = getEventList(entry, entry.getStartTime(), entry.getEndTime(), resolution, new NullProgressMonitor());
-
- entry.setZoomedEventList(eventList);
-
- redraw();
-
- for (ITimeGraphEntry child : entry.getChildren()) {
- buildStatusEvents(trace, (CriticalPathEntry) child);
- }
- }
-
@Override
- protected void buildEventList(@NonNull ITmfTrace trace, @NonNull ITmfTrace parentTrace, @NonNull IProgressMonitor monitor) {
+ protected void buildEntryList(@NonNull ITmfTrace trace, @NonNull ITmfTrace parentTrace, @NonNull IProgressMonitor monitor) {
/* This class uses a content provider instead */
}
protected @Nullable List<ITimeEvent> getEventList(TimeGraphEntry entry,
long startTime, long endTime, long resolution,
IProgressMonitor monitor) {
-
- final long realStart = Math.max(startTime, entry.getStartTime());
- final long realEnd = Math.min(endTime, entry.getEndTime());
- if (realEnd <= realStart) {
- return null;
- }
- List<ITimeEvent> eventList = null;
- entry.setZoomedEventList(null);
- Iterator<ITimeEvent> iterator = entry.getTimeEventsIterator();
- eventList = new ArrayList<>();
-
- while (iterator.hasNext()) {
- ITimeEvent event = iterator.next();
- /* is event visible */
- if (intersects(realStart, realEnd, NonNullUtils.checkNotNull(event))) {
- eventList.add(event);
- }
- }
- return eventList;
- }
-
- private static boolean intersects(final long realStart, final long realEnd, ITimeEvent event) {
- return ((event.getTime() >= realStart) && (event.getTime() <= realEnd)) ||
- ((event.getTime() + event.getDuration() > realStart) &&
- (event.getTime() + event.getDuration() < realEnd));
+ /*
+ * The event list is built in the HorizontalLinksVisitor. This is called
+ * only from the zoom thread and only for the CriticalPathBaseEntry.
+ */
+ return null;
}
@Override