use of org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel in project tracecompass by tracecompass.
the class DataDrivenTimeGraphDataProvider method fetchTree.
@Override
public final TmfModelResponse<TmfTreeModel<@NonNull TimeGraphEntryModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
List<TimeGraphEntryModel> entryList = new ArrayList<>();
boolean isComplete = true;
String traceName = String.valueOf(getTrace().getName());
for (ITmfStateSystem ss : fSs) {
isComplete &= ss.waitUntilBuilt(0);
/* Don't query empty state system */
if (ss.getNbAttributes() > 0 && ss.getStartTime() != Long.MIN_VALUE) {
long start = ss.getStartTime();
long end = ss.getCurrentEndTime();
long id = fBaseQuarkToId.row(ss).computeIfAbsent(ITmfStateSystem.ROOT_ATTRIBUTE, s -> sfAtomicId.getAndIncrement());
TimeGraphEntryModel ssEntry = new TimeGraphEntryModel(id, -1, traceName, start, end);
entryList.add(ssEntry);
for (DataDrivenOutputEntry entry : fEntries) {
entryList.addAll(entry.buildEntries(ss, ssEntry.getId(), getTrace(), -1, StringUtils.EMPTY, end, fIdGenerator, fQuarkCallback));
}
}
}
Status status = isComplete ? Status.COMPLETED : Status.RUNNING;
String msg = isComplete ? CommonStatusMessage.COMPLETED : CommonStatusMessage.RUNNING;
TmfTreeModel<@NonNull TimeGraphEntryModel> tree = new TmfTreeModel<>(Collections.emptyList(), entryList);
return new TmfModelResponse<>(tree, status, msg);
}
use of org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel in project tracecompass by tracecompass.
the class DataDrivenOutputEntry method buildEntries.
/**
* Build the actual entries from this entry descriptor
*
* @param ssq
* The base state system to use
* @param parentEntryId
* The ID of the parent time graph entry
* @param trace
* The trace these entries are for, used to get any additional
* state system
* @param prevBaseQuark
* The base quark of the parent
* @param prevRegex
* With recursive entries, this is the result of the previous
* regex that may contain placeholders whose value need to be
* replace in current entry's regex
* @param currentEnd
* The current end time
* @param idGenerator
* A callback used to generate the entry's unique ID
* @param callback
* A callback to register an ID with the state system and quark
* pair
* @return All the newly created entries
*/
public List<TimeGraphEntryModel> buildEntries(ITmfStateSystem ssq, long parentEntryId, ITmfTrace trace, int prevBaseQuark, String prevRegex, long currentEnd, IdGetter idGenerator, QuarkCallback callback) {
// Get the state system to use to populate those entries, by default, it
// is the same as the parent
String specificSs = fAnalysisId;
ITmfStateSystem parentSs = ssq;
ITmfStateSystem ss = parentSs;
int baseQuark = prevBaseQuark;
if (specificSs != null) {
ss = TmfStateSystemAnalysisModule.getStateSystem(trace, specificSs);
baseQuark = ITmfStateSystem.ROOT_ATTRIBUTE;
if (ss == null) {
return Collections.emptyList();
}
}
DataContainer container = SS_TO_CONTAINER.computeIfAbsent(ss, s -> new DataContainer(s));
// Replace any place holders in the path.
// FIXME: Figure out what this really does and better document it
Pattern pattern = Pattern.compile(prevRegex);
String attributePath = prevBaseQuark > 0 ? parentSs.getFullAttributePath(prevBaseQuark) : StringUtils.EMPTY;
Matcher matcher = pattern.matcher(attributePath);
String path = fPath;
if (matcher.find()) {
path = matcher.replaceFirst(path);
}
/* Replace * by .* to have a regex string */
// $NON-NLS-1$//$NON-NLS-2$
String regexName = path.replaceAll("\\*", "(.*)");
/* Get the list of quarks to process with this path */
String[] paths = regexName.split(SPLIT_STRING);
int i = 0;
List<Integer> quarks = Collections.singletonList(baseQuark);
while (i < paths.length) {
List<Integer> subQuarks = new ArrayList<>();
String name = paths[i];
for (int relativeQuark : quarks) {
subQuarks.addAll(ss.getSubAttributes(relativeQuark, false, name));
}
quarks = subQuarks;
i++;
}
Map<Integer, Long> startTimes = new HashMap<>();
Map<Integer, Long> endTimes = new HashMap<>();
long startTime = ss.getStartTime();
try {
Iterable<ITmfStateInterval> iter = ss.query2D(quarks, Arrays.asList(startTime, currentEnd));
for (ITmfStateInterval interval : iter) {
if (interval.getValue() == null) {
/*
* Adjust the start/end time if a null state crosses one and
* only one start/end boundary. Otherwise leave the default
* to state system start/end time.
*/
int quark = interval.getAttribute();
if (!interval.intersects(currentEnd)) {
startTimes.put(quark, interval.getEndTime() + 1);
}
if (!interval.intersects(startTime)) {
endTimes.put(quark, interval.getStartTime());
}
}
}
} catch (StateSystemDisposedException e) {
return Collections.emptyList();
}
/* Process each quark */
DataDrivenStateSystemPath displayPath = fDisplay;
DataDrivenStateSystemPath namePath = fName;
DataDrivenStateSystemPath idPath = fId;
DataDrivenStateSystemPath parentPath = fParent;
Map<String, DataDrivenOutputEntryModel.EntryBuilder> entryMap = new HashMap<>();
List<DataDrivenOutputEntryModel.EntryBuilder> entries = new ArrayList<>();
List<TimeGraphEntryModel> entryList = new ArrayList<>();
for (int quark : quarks) {
long id = idGenerator.getIdFor(ss, quark);
// Get the quark containing the data to display, else there is no display
int displayQuark = ITmfStateSystem.INVALID_ATTRIBUTE;
long entryStart = startTimes.getOrDefault(quark, startTime);
long entryEnd = endTimes.getOrDefault(quark, currentEnd);
if (displayPath != null) {
displayQuark = displayPath.getQuark(quark, container);
if (displayQuark == ITmfStateSystem.INVALID_ATTRIBUTE) {
// The entry has no display quark, do not display
continue;
}
callback.registerQuark(id, ss, displayQuark, fDisplayType);
}
// Get the name of this entry
String name = StringUtils.EMPTY;
if (namePath != null) {
name = getFirstValue(quark, namePath, container);
}
if (name.isEmpty()) {
// Default, use the attribute name as name
name = ss.getAttributeName(quark);
}
// Get the XML internal ID of this entry
String xmlId;
if (idPath != null) {
xmlId = getFirstValue(quark, idPath, container);
} else {
// Use the name as ID
xmlId = name;
}
// Get the parent's internal ID of the entry
String xmlParentId = StringUtils.EMPTY;
if (parentPath != null) {
xmlParentId = getFirstValue(quark, parentPath, container);
}
EntryBuilder entryBuilder = new DataDrivenOutputEntryModel.EntryBuilder(id, parentEntryId, displayQuark, name, xmlId, xmlParentId, entryStart, entryEnd, fDisplayText, fDisplayType);
entryMap.put(xmlId, entryBuilder);
entries.add(entryBuilder);
/* Process the children entry of this entry */
for (DataDrivenOutputEntry subEntry : fChildrenEntries) {
@NonNull String regex = prevRegex.isEmpty() ? regexName : prevRegex + '/' + regexName;
entryList.addAll(subEntry.buildEntries(ss, entryBuilder.getId(), trace, quark, regex, currentEnd, idGenerator, callback));
}
}
// At this point, the parent has been set, so we can build the entries
buildTree(entryMap);
for (EntryBuilder b : entries) {
entryList.add(b.build());
}
return entryList;
}
use of org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel in project tracecompass by tracecompass.
the class DataDrivenXYDataProvider method fetchTree.
@Override
public TmfModelResponse<TmfTreeModel<ITmfTreeDataModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
fLock.readLock().lock();
try {
if (fCached != null) {
return fCached;
}
} finally {
fLock.readLock().unlock();
}
List<ITmfTreeDataModel> entryList = new ArrayList<>();
boolean isComplete = true;
String traceName = String.valueOf(getTrace().getName());
fLock.writeLock().lock();
try {
for (ITmfStateSystem ss : fSs) {
isComplete &= ss.waitUntilBuilt(0);
/* Don't query empty state system */
if (ss.getNbAttributes() > 0 && ss.getStartTime() != Long.MIN_VALUE) {
long start = ss.getStartTime();
long end = ss.getCurrentEndTime();
long id = fBaseQuarkToId.row(ss).computeIfAbsent(ITmfStateSystem.ROOT_ATTRIBUTE, s -> ENTRY_IDS.getAndIncrement());
TimeGraphEntryModel ssEntry = new TimeGraphEntryModel(id, -1, traceName, start, end);
entryList.add(ssEntry);
for (DataDrivenOutputEntry entry : fEntries) {
entryList.addAll(entry.buildEntries(ss, ssEntry.getId(), getTrace(), -1, StringUtils.EMPTY, end, fIdGenerator, fQuarkCallback));
}
}
}
fIdToTitle.clear();
entryList.forEach(e -> fIdToTitle.put(e.getId(), e.getName()));
if (isComplete) {
TmfModelResponse<TmfTreeModel<ITmfTreeDataModel>> tmfModelResponse = new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), entryList), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
fCached = tmfModelResponse;
return tmfModelResponse;
}
return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), entryList), ITmfResponse.Status.RUNNING, CommonStatusMessage.RUNNING);
} finally {
fLock.writeLock().unlock();
}
}
use of org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel in project tracecompass by tracecompass.
the class XmlDataProviderManager method getTimeGraphProvider.
/**
* Create (if necessary) and get the time graph data provider for the
* specified trace and viewElement.
*
* @param trace
* trace for which we are querying a provider
* @param viewElement
* the XML time graph view element for which we are querying a
* provider
* @return the unique instance of a time graph provider for the queried
* parameters
*/
@Nullable
public synchronized ITimeGraphDataProvider<@NonNull TimeGraphEntryModel> getTimeGraphProvider(ITmfTrace trace, Element viewElement) {
if (!viewElement.hasAttribute(ID_ATTRIBUTE)) {
return null;
}
String viewId = viewElement.getAttribute(ID_ATTRIBUTE);
ITimeGraphDataProvider<@NonNull TimeGraphEntryModel> provider = fTimeGraphProviders.get(trace, viewId);
if (provider != null) {
return provider;
}
if (Iterables.any(TmfTraceManager.getInstance().getOpenedTraces(), opened -> TmfTraceManager.getTraceSetWithExperiment(opened).contains(trace))) {
// Create with the trace or experiment first
TmfXmlTimeGraphViewCu tgViewCu = TmfXmlTimeGraphViewCu.compile(new AnalysisCompilationData(), viewElement);
if (tgViewCu != null) {
DataDrivenTimeGraphProviderFactory timeGraphFactory = tgViewCu.generate();
provider = timeGraphFactory.create(trace);
if (provider == null) {
// composite if that's the case
if (trace instanceof TmfExperiment) {
provider = generateExperimentProviderTimeGraph(TmfTraceManager.getTraceSet(trace), viewElement);
}
}
if (provider != null) {
fTimeGraphProviders.put(trace, viewId, provider);
}
return provider;
}
}
return null;
}
use of org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphEntryModel in project tracecompass by tracecompass.
the class EventAnnotationProvider method fetchAnnotations.
@Override
public TmfModelResponse<@NonNull AnnotationModel> fetchAnnotations(Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
List<Long> timeRequested = DataProviderParameterUtils.extractTimeRequested(fetchParameters);
List<@NonNull Long> entries = DataProviderParameterUtils.extractSelectedItems(fetchParameters);
@Nullable Set<@NonNull String> categories = DataProviderParameterUtils.extractSelectedCategories(fetchParameters);
if (timeRequested == null || entries == null) {
return NO_DATA;
}
TmfModelResponse<@NonNull TmfTreeModel<M>> tree = Objects.requireNonNull(fTreeResolver.apply(fetchParameters, monitor));
TmfTreeModel<M> model = tree.getModel();
if (model == null) {
return NO_DATA;
}
Function<M, Integer> keyMapper = entry -> (Integer) Iterables.get(entry.getMetadata().get(fMetadataKey), 0);
Predicate<M> predicate = entry -> {
Collection<@NonNull Object> collection = entry.getMetadata().get(fMetadataKey);
return !collection.isEmpty() && !Objects.equals(Iterables.get(collection, 0), -1);
};
Map<Integer, TimeGraphEntryModel> rowMap = new LinkedHashMap<>();
List<@NonNull M> entries2 = model.getEntries();
entries2.stream().filter(predicate).filter(fAdditionalPredicate).forEach(element -> rowMap.put(keyMapper.apply(element), element));
Map<String, Collection<Annotation>> markers = new LinkedHashMap<>();
TmfTimeRange tr = new TmfTimeRange(TmfTimestamp.fromNanos(timeRequested.get(0)), TmfTimestamp.fromNanos(timeRequested.get(timeRequested.size() - 1)));
EventAnnotationProvider<@NonNull M> lock = this;
synchronized (lock) {
for (ITmfTrace source : fMarkerTraces) {
TmfEventRequest old = fRunningRequests.remove(source);
if (old != null && old.isRunning()) {
old.cancel();
}
}
for (ITmfTrace source : fMarkerTraces) {
if (categories != null && !categories.contains(source.getName())) {
// marker category is filtered out
continue;
}
TmfEventRequest req = new TmfEventRequest(ITmfEvent.class, tr, 0, Integer.MAX_VALUE, ExecutionType.FOREGROUND) {
private int timesliceIndex = 0;
private Set<Object> values = new HashSet<>();
private long next() {
if (timeRequested.size() > timesliceIndex + 1) {
return timeRequested.get(timesliceIndex + 1);
}
return Long.MAX_VALUE;
}
@Override
public void handleData(ITmfEvent event) {
super.handleData(event);
while (event.getTimestamp().toNanos() > next()) {
timesliceIndex++;
values.clear();
if (timesliceIndex >= timeRequested.size() - 1) {
done();
return;
}
}
Object value = TmfTraceUtils.resolveEventAspectOfClassForEvent(event.getTrace(), fAspect, event);
if (value != null && !values.contains(value)) {
values.add(value);
synchronized (markers) {
Collection<Annotation> markerList = markers.computeIfAbsent(String.valueOf(event.getTrace().getName()), string -> new ArrayList<>());
TimeGraphEntryModel entryModel = rowMap.get(value);
if (entryModel != null) {
String name = event.getName();
Map<String, Object> style = new HashMap<>();
style.put(StyleProperties.SYMBOL_TYPE, SymbolType.INVERTED_TRIANGLE);
style.put(StyleProperties.COLOR, getMarkerColor(name));
style.put(StyleProperties.HEIGHT, 0.3);
style.put(StyleProperties.VERTICAL_ALIGN, StyleProperties.VerticalAlign.TOP);
markerList.add(new Annotation(event.getTimestamp().toNanos(), 0L, entryModel.getId(), AnnotationType.CHART, name, new OutputElementStyle(name, style)));
}
}
}
}
private String getMarkerColor(String name) {
// $NON-NLS-1$
return Objects.requireNonNull(fMarkerColorCache.computeIfAbsent(name, label -> Objects.requireNonNull(String.format("#%6x", label.hashCode() & 0xffffff))));
}
};
fRunningRequests.put(source, req);
source.sendRequest(req);
}
try {
for (ITmfTrace source : fMarkerTraces) {
TmfEventRequest req = null;
synchronized (lock) {
req = fRunningRequests.get(source);
}
if (req != null) {
req.waitForCompletion();
fRunningRequests.remove(source);
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// $NON-NLS-1$
return new TmfModelResponse<>(new AnnotationModel(markers), Status.COMPLETED, "");
}
Aggregations