use of org.eclipse.tracecompass.tmf.core.response.TmfModelResponse in project tracecompass by tracecompass.
the class TmfEventTableDataProvider method fetchLines.
@Override
public TmfModelResponse<ITmfVirtualTableModel<EventTableLine>> fetchLines(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
if (!fetchParameters.containsKey(DataProviderParameterUtils.REQUESTED_TABLE_INDEX_KEY) && fetchParameters.containsKey(DataProviderParameterUtils.REQUESTED_TIME_KEY)) {
fetchParameters.put(DataProviderParameterUtils.REQUESTED_TABLE_INDEX_KEY, getTableIndex(fetchParameters));
}
if (!fetchParameters.containsKey(DataProviderParameterUtils.REQUESTED_COLUMN_IDS_KEY)) {
fetchParameters.put(DataProviderParameterUtils.REQUESTED_COLUMN_IDS_KEY, Collections.emptyList());
}
VirtualTableQueryFilter queryFilter = FetchParametersUtils.createVirtualTableQueryFilter(fetchParameters);
if (queryFilter == null) {
return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
}
@Nullable ITmfFilter filter = extractFilter(fetchParameters);
@Nullable ITmfFilter searchFilter = extractSearchFilter(fetchParameters);
@Nullable TmfCollapseFilter collapseFilter = extractCollapseFilter(fetchParameters);
Map<Long, ITmfEventAspect<?>> aspects = getAspectsFromColumnsId(queryFilter.getColumnsId());
if (aspects.isEmpty()) {
return new TmfModelResponse<>(new TmfVirtualTableModel<>(Collections.emptyList(), Collections.emptyList(), queryFilter.getIndex(), 0), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
}
List<Long> columnsIds = new ArrayList<>(aspects.keySet());
if (getTrace().getNbEvents() == 0) {
return new TmfModelResponse<>(new TmfVirtualTableModel<>(columnsIds, Collections.emptyList(), queryFilter.getIndex(), 0), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
}
/*
* Search for the next or previous event starting from the given event index
*/
Object directionValue = fetchParameters.get(TABLE_SEARCH_DIRECTION_KEY);
// ///////////////////////////////////
// TODO remove isFiltered when Theia front-end is updated to use TABLE_SEARCH_DIRECTION_KEY instead
Boolean isFiltered = DataProviderParameterUtils.extractIsFiltered(fetchParameters);
boolean isIndexRequest = isFiltered != null && isFiltered;
if (isIndexRequest && directionValue == null) {
directionValue = Direction.NEXT.name();
}
if (searchFilter != null && directionValue != null) {
Direction direction = directionValue.equals(Direction.PREVIOUS.name()) ? Direction.PREVIOUS : Direction.NEXT;
@Nullable WrappedEvent event = null;
Predicate<@NonNull ITmfEvent> predicate;
if (filter == null) {
predicate = searchFilter::matches;
} else {
predicate = e -> (filter.matches(e) && searchFilter.matches(e));
}
if (direction == Direction.NEXT) {
event = getNextWrappedEventMatching(getTrace(), Math.abs(queryFilter.getIndex()), predicate, monitor);
} else if (direction == Direction.PREVIOUS) {
event = getPreviousWrappedEventMatching(getTrace(), Math.abs(queryFilter.getIndex()), predicate, monitor);
}
List<EventTableLine> lines = new ArrayList<>();
long rank = queryFilter.getIndex();
if (event != null) {
rank = event.getRank();
// create new queryFilter with updated start rank to get number of events starting from first matching event
queryFilter = new VirtualTableQueryFilter(queryFilter.getColumnsId(), rank, queryFilter.getCount());
lines.add(buildEventTableLine(aspects, event.getOriginalEvent(), rank, rank, true));
}
if ((queryFilter.getCount() == 1) || (event == null)) {
/**
* If no event was found or the number of requested events is one
* reply here since all required data for the reply is available.
*/
TmfVirtualTableModel<EventTableLine> model = new TmfVirtualTableModel<>(columnsIds, lines, rank, getTrace().getNbEvents());
return new TmfModelResponse<>(model, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
}
}
/*
* Collect queryFilter.getCount() number of events from start rank
*/
/*
* TODO implement upper limit of queryFilter.getCount() to avoid running out of memory.
* TBD if the check and should be handled here or in the calling methods.
*/
TableEventRequest request;
if (filter != null) {
request = filteredTableRequest(Math.abs(queryFilter.getCount()), queryFilter.getIndex(), aspects, filter, searchFilter, collapseFilter, monitor);
} else {
request = tableRequest(Math.abs(queryFilter.getCount()), queryFilter.getIndex(), aspects, searchFilter, collapseFilter, monitor);
request.setEventCount(getTrace().getNbEvents());
}
getTrace().sendRequest(request);
try {
request.waitForCompletion();
} catch (InterruptedException e) {
return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, NonNullUtils.nullToEmptyString(e.getMessage()));
}
if (request.isCancelled()) {
return new TmfModelResponse<>(null, ITmfResponse.Status.CANCELLED, CommonStatusMessage.TASK_CANCELLED);
}
TmfVirtualTableModel<EventTableLine> model = new TmfVirtualTableModel<>(columnsIds, request.getEventLines(), queryFilter.getIndex(), request.getCurrentCount());
return new TmfModelResponse<>(model, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
}
use of org.eclipse.tracecompass.tmf.core.response.TmfModelResponse 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, "");
}
use of org.eclipse.tracecompass.tmf.core.response.TmfModelResponse in project tracecompass by tracecompass.
the class CustomAnnotationProvider method fetchAnnotationCategories.
@Override
@NonNull
public TmfModelResponse<@NonNull AnnotationCategoriesModel> fetchAnnotationCategories(@NonNull Map<@NonNull String, @NonNull Object> fetchParameters, @Nullable IProgressMonitor monitor) {
Set<@NonNull String> categories = new LinkedHashSet<>();
for (CustomPeriodicAnnotationProvider annotationProvider : fAnnotationProviders) {
TmfModelResponse<@NonNull AnnotationCategoriesModel> response = annotationProvider.fetchAnnotationCategories(fetchParameters, monitor);
AnnotationCategoriesModel model = response.getModel();
if (model != null) {
categories.addAll(model.getAnnotationCategories());
getSubMarkerCategories(categories, annotationProvider.getSubMarkers());
}
}
// $NON-NLS-1$
return new TmfModelResponse<>(new AnnotationCategoriesModel(new ArrayList<>(categories)), Status.COMPLETED, "");
}
use of org.eclipse.tracecompass.tmf.core.response.TmfModelResponse in project tracecompass by tracecompass.
the class BaseDataProviderTimeGraphView method buildEntryList.
@Override
protected void buildEntryList(@NonNull ITmfTrace trace, @NonNull ITmfTrace parentTrace, @NonNull IProgressMonitor monitor) {
ITimeGraphDataProvider<@NonNull TimeGraphEntryModel> dataProvider = DataProviderManager.getInstance().getDataProvider(trace, getProviderId(), ITimeGraphDataProvider.class);
if (dataProvider == null) {
return;
}
ITimeGraphPresentationProvider presentationProvider = getPresentationProvider();
if (presentationProvider instanceof BaseDataProviderTimeGraphPresentationProvider) {
((BaseDataProviderTimeGraphPresentationProvider) presentationProvider).addProvider(dataProvider, getTooltipResolver(dataProvider));
}
boolean complete = false;
while (!complete && !monitor.isCanceled()) {
Map<@NonNull String, @NonNull Object> parameters = getFetchTreeParameters();
TmfModelResponse<TmfTreeModel<@NonNull TimeGraphEntryModel>> response = dataProvider.fetchTree(parameters, monitor);
if (response.getStatus() == ITmfResponse.Status.FAILED) {
// $NON-NLS-1$
Activator.getDefault().logError(getClass().getSimpleName() + " Data Provider failed: " + response.getStatusMessage());
return;
} else if (response.getStatus() == ITmfResponse.Status.CANCELLED) {
return;
}
complete = response.getStatus() == ITmfResponse.Status.COMPLETED;
double factor = 1.0;
TmfTreeModel<@NonNull TimeGraphEntryModel> model = response.getModel();
if (model != null) {
synchronized (fEntries) {
Object scope = (model.getScope() == null) ? dataProvider : model.getScope();
fProviders.put(parentTrace, dataProvider);
fScopes.put(parentTrace, scope);
/*
* The provider may send entries unordered and parents may
* not exist when child is constructor, we'll re-unite
* families at the end
*/
List<TimeGraphEntry> orphaned = new ArrayList<>();
Map<Long, AtomicInteger> indexMap = new HashMap<>();
for (TimeGraphEntryModel entry : model.getEntries()) {
TimeGraphEntry uiEntry = fScopedEntries.get(scope, entry.getId());
if (entry.getParentId() != -1) {
if (uiEntry == null) {
uiEntry = new TimeGraphEntry(entry);
TimeGraphEntry parent = fScopedEntries.get(scope, entry.getParentId());
if (parent != null) {
// TODO: the order of children from different data providers is undefined
int index = indexMap.computeIfAbsent(entry.getParentId(), l -> new AtomicInteger()).getAndIncrement();
parent.addChild(index, uiEntry);
} else {
orphaned.add(uiEntry);
}
fScopedEntries.put(scope, entry.getId(), uiEntry);
} else {
indexMap.computeIfAbsent(entry.getParentId(), l -> new AtomicInteger()).getAndIncrement();
uiEntry.updateModel(entry);
}
} else {
if (entry.getStartTime() != Long.MIN_VALUE) {
setStartTime(Long.min(getStartTime(), entry.getStartTime()));
}
setEndTime(Long.max(getEndTime(), entry.getEndTime() + 1));
if (uiEntry != null) {
uiEntry.updateModel(entry);
} else {
// Do not assume that parentless entries are
// trace entries
uiEntry = new TraceEntry(entry, trace, dataProvider);
fScopedEntries.put(scope, entry.getId(), uiEntry);
addToEntryList(parentTrace, Collections.singletonList(uiEntry));
}
}
fEntries.put(dataProvider, entry.getId(), uiEntry);
fEntryIds.put(uiEntry, dataProvider, entry.getId());
}
// Find missing parents
// Orphans should be inserted before non-orphans
indexMap.clear();
for (TimeGraphEntry orphanedEntry : orphaned) {
TimeGraphEntry parent = fScopedEntries.get(scope, orphanedEntry.getEntryModel().getParentId());
if (parent != null) {
int index = indexMap.computeIfAbsent(parent.getEntryModel().getId(), l -> new AtomicInteger()).getAndIncrement();
parent.addChild(index, orphanedEntry);
}
}
}
long start = getStartTime();
long end = getEndTime();
final long resolution = Long.max(1, (end - start) / getDisplayWidth());
@NonNull Iterable<@NonNull TimeGraphEntry> entries;
synchronized (fEntries) {
entries = ImmutableList.copyOf(fEntries.values());
}
zoomEntries(entries, start, end, resolution, monitor);
}
if (monitor.isCanceled()) {
return;
}
if (parentTrace.equals(getTrace())) {
synchingToTime(getTimeGraphViewer().getSelectionBegin());
refresh();
}
monitor.worked(1);
if (!complete && !monitor.isCanceled()) {
try {
Thread.sleep((long) (BUILD_UPDATE_TIMEOUT * factor));
factor = Math.min(20, factor + 1);
} catch (InterruptedException e) {
// $NON-NLS-1$
Activator.getDefault().logError("Failed to wait for data provider", e);
Thread.currentThread().interrupt();
}
}
}
}
Aggregations