package org.eclipse.tracecompass.tmf.core.statesystem;
-import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
-
import java.io.File;
import java.io.IOException;
import java.util.Collections;
+import java.util.Map;
import java.util.concurrent.CountDownLatch;
+import org.apache.commons.io.FileUtils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.internal.tmf.core.statesystem.backends.partial.PartialHistoryBackend;
import org.eclipse.tracecompass.internal.tmf.core.statesystem.backends.partial.PartialStateSystem;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
private final CountDownLatch fInitialized = new CountDownLatch(1);
private final Object fRequestSyncObj = new Object();
- @Nullable private ITmfStateSystemBuilder fStateSystem;
- @Nullable private ITmfStateProvider fStateProvider;
- @Nullable private IStateHistoryBackend fHtBackend;
- @Nullable private ITmfEventRequest fRequest;
- @Nullable private TmfTimeRange fTimeRange = null;
+ private @Nullable ITmfStateSystemBuilder fStateSystem;
+ private @Nullable ITmfEventRequest fRequest;
+ private @Nullable TmfTimeRange fTimeRange = null;
private int fNbRead = 0;
+ private boolean fInitializationSucceeded;
+
+ private volatile @Nullable ITmfStateProvider fStateProvider;
/**
* State system backend types
* The trace for which you want the state system
* @param moduleId
* The ID of the state system analysis module
- * @return The state system, or null if there was no match
+ * @return The state system, or null if there was no match or the module was
+ * not initialized correctly
*/
public static @Nullable ITmfStateSystem getStateSystem(ITmfTrace trace, String moduleId) {
TmfStateSystemAnalysisModule module =
}
IStatus status = module.schedule();
if (status.isOK()) {
- module.waitForInitialization();
- return module.getStateSystem();
+ return module.waitForInitialization() ? module.getStateSystem() : null;
}
}
return null;
}
/**
- * Block the calling thread until the analysis module has been initialized.
- * After this method returns, {@link #getStateSystem()} should not return
- * null anymore.
+ * @since 2.0
*/
- public void waitForInitialization() {
+ @Override
+ public boolean waitForInitialization() {
try {
fInitialized.await();
- } catch (InterruptedException e) {}
+ } catch (InterruptedException e) {
+ return false;
+ }
+ return fInitializationSucceeded;
+ }
+
+ /**
+ * @since 2.0
+ */
+ @Override
+ public boolean isQueryable(long ts) {
+ /* Return true if there is no state provider available (the analysis is not being built) */
+ ITmfStateProvider provider = fStateProvider;
+ if (provider == null) {
+ return true;
+ }
+ return ts <= provider.getLatestSafeTime();
}
// ------------------------------------------------------------------------
// TmfAbstractAnalysisModule
// ------------------------------------------------------------------------
+ private @Nullable File getSsFile() {
+ ITmfTrace trace = getTrace();
+ if (trace == null) {
+ return null;
+ }
+ String directory = TmfTraceManager.getSupplementaryFileDir(trace);
+ File htFile = new File(directory + getSsFileName());
+ return htFile;
+ }
+
@Override
protected boolean executeAnalysis(@Nullable final IProgressMonitor monitor) {
IProgressMonitor mon = (monitor == null ? new NullProgressMonitor() : monitor);
try {
/* Get the state system according to backend */
StateSystemBackendType backend = getBackendType();
- String directory;
- File htFile;
ITmfTrace trace = getTrace();
if (trace == null) {
// Analysis was cancelled in the meantime
- fInitialized.countDown();
+ analysisReady(false);
return false;
}
switch (backend) {
- case FULL:
- directory = TmfTraceManager.getSupplementaryFileDir(trace);
- htFile = new File(directory + getSsFileName());
+ case FULL: {
+ File htFile = getSsFile();
+ if (htFile == null) {
+ return false;
+ }
createFullHistory(id, provider, htFile);
+ }
break;
- case PARTIAL:
- directory = TmfTraceManager.getSupplementaryFileDir(trace);
- htFile = new File(directory + getSsFileName());
+ case PARTIAL: {
+ File htFile = getSsFile();
+ if (htFile == null) {
+ return false;
+ }
createPartialHistory(id, provider, htFile);
+ }
break;
case INMEM:
createInMemoryHistory(id, provider);
break;
}
} catch (TmfTraceException e) {
- fInitialized.countDown();
+ analysisReady(false);
return false;
}
return !mon.isCanceled();
}
+ /**
+ * Make the module available and set whether the initialization succeeded or
+ * not. If not, no state system is available and
+ * {@link #waitForInitialization()} should return false.
+ *
+ * @param success
+ * True if the initialization succeeded, false otherwise
+ */
+ private void analysisReady(boolean succeeded) {
+ fInitializationSucceeded = succeeded;
+ fInitialized.countDown();
+ }
+
@Override
protected void canceling() {
ITmfEventRequest req = fRequest;
try {
IStateHistoryBackend backend = StateHistoryBackendFactory.createHistoryTreeBackendExistingFile(
id, htFile, version);
- fHtBackend = backend;
fStateSystem = StateSystemFactory.newStateSystem(backend, false);
- fInitialized.countDown();
+ analysisReady(true);
return;
} catch (IOException e) {
/*
try {
IStateHistoryBackend backend = StateHistoryBackendFactory.createHistoryTreeBackendNewFile(
id, htFile, provider.getVersion(), provider.getStartTime(), QUEUE_SIZE);
- fHtBackend = backend;
fStateSystem = StateSystemFactory.newStateSystem(backend);
provider.assignTargetStateSystem(fStateSystem);
build(provider);
provider.assignTargetStateSystem(realSS);
/* 7 */
- fHtBackend = partialBackend;
fStateSystem = realSS;
build(provider);
*/
private void createNullHistory(String id, ITmfStateProvider provider) {
IStateHistoryBackend backend = StateHistoryBackendFactory.createNullBackend(id);
- fHtBackend = backend;
fStateSystem = StateSystemFactory.newStateSystem(backend);
provider.assignTargetStateSystem(fStateSystem);
build(provider);
*/
private void createInMemoryHistory(String id, ITmfStateProvider provider) {
IStateHistoryBackend backend = StateHistoryBackendFactory.createInMemoryBackend(id, provider.getStartTime());
- fHtBackend = backend;
fStateSystem = StateSystemFactory.newStateSystem(backend);
provider.assignTargetStateSystem(fStateSystem);
build(provider);
if (provider != null) {
provider.dispose();
}
- if (deleteFiles && (fHtBackend != null)) {
- fHtBackend.removeFiles();
+ fStateProvider = null;
+ if (deleteFiles && (fStateSystem != null)) {
+ fStateSystem.removeFiles();
}
}
private void build(ITmfStateProvider provider) {
- if ((fStateSystem == null) || (fHtBackend == null)) {
+ if (fStateSystem == null) {
throw new IllegalArgumentException();
}
* The state system object is now created, we can consider this module
* "initialized" (components can retrieve it and start doing queries).
*/
- fInitialized.countDown();
+ analysisReady(true);
/*
* Block the executeAnalysis() construction is complete (so that the
timeRange,
index,
ITmfEventRequest.ALL_DATA,
- ITmfEventRequest.ExecutionType.BACKGROUND);
+ ITmfEventRequest.ExecutionType.BACKGROUND,
+ TmfStateSystemAnalysisModule.this.getDependencyLevel());
this.sci = sp;
-
- // sci.getTrace() will eventually return a @NonNull
- trace = checkNotNull(sci.getTrace());
+ trace = sci.getTrace();
}
@Override
public void handleCancel() {
super.handleCancel();
- if (isCompleteTrace(trace)) {
- disposeProvider(true);
- }
+ disposeProvider(true);
}
@Override
}
@Override
- public Iterable<ITmfStateSystem> getStateSystems() {
- return checkNotNull(Collections.<ITmfStateSystem> singleton(fStateSystem));
+ public @NonNull Iterable<@NonNull ITmfStateSystem> getStateSystems() {
+ ITmfStateSystemBuilder stateSystem = fStateSystem;
+ if (stateSystem == null) {
+ return Collections.EMPTY_SET;
+ }
+ return Collections.singleton(stateSystem);
}
/**
private static boolean isCompleteTrace(ITmfTrace trace) {
return !(trace instanceof ITmfTraceCompleteness) || ((ITmfTraceCompleteness) trace).isComplete();
}
+
+ // ------------------------------------------------------------------------
+ // ITmfPropertiesProvider
+ // ------------------------------------------------------------------------
+
+ /**
+ * @since 2.0
+ */
+ @Override
+ public @NonNull Map<@NonNull String, @NonNull String> getProperties() {
+ Map<@NonNull String, @NonNull String> properties = super.getProperties();
+
+ StateSystemBackendType backend = getBackendType();
+ properties.put(NonNullUtils.checkNotNull(Messages.TmfStateSystemAnalysisModule_PropertiesBackend), backend.name());
+ switch (backend) {
+ case FULL:
+ case PARTIAL:
+ File htFile = getSsFile();
+ if (htFile != null) {
+ if (htFile.exists()) {
+ properties.put(NonNullUtils.checkNotNull(Messages.TmfStateSystemAnalysisModule_PropertiesFileSize), FileUtils.byteCountToDisplaySize(htFile.length()));
+ } else {
+ properties.put(NonNullUtils.checkNotNull(Messages.TmfStateSystemAnalysisModule_PropertiesFileSize), NonNullUtils.checkNotNull(Messages.TmfStateSystemAnalysisModule_PropertiesAnalysisNotExecuted));
+ }
+ }
+ break;
+ case INMEM:
+ case NULL:
+ default:
+ break;
+
+ }
+ return properties;
+ }
}