Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ public class DataProviderManagerTest {
.setProviderType(ProviderType.TIME_GRAPH)
.setId("org.eclipse.tracecompass.internal.tmf.core.statesystem.provider.StateSystemDataProvider");
EXPECTED_KERNEL_DP_DESCRIPTORS.add(builder.build());
builder = new DataProviderDescriptor.Builder();
builder.setName("Raw Events Data")
.setDescription("Show the raw event data in object form for a given trace")
.setProviderType(ProviderType.DATA)
.setId("org.eclipse.tracecompass.tmf.core.model.events.data");
EXPECTED_KERNEL_DP_DESCRIPTORS.add(builder.build());

// UST Trace
builder = new DataProviderDescriptor.Builder();
Expand Down Expand Up @@ -292,6 +298,12 @@ public class DataProviderManagerTest {
.setProviderType(ProviderType.TIME_GRAPH)
.setId("org.eclipse.tracecompass.internal.tmf.core.statesystem.provider.StateSystemDataProvider");
EXPECTED_UST_DP_DESCRIPTORS.add(builder.build());
builder = new DataProviderDescriptor.Builder();
builder.setName("Raw Events Data")
.setDescription("Show the raw event data in object form for a given trace")
.setProviderType(ProviderType.DATA)
.setId("org.eclipse.tracecompass.tmf.core.model.events.data");
EXPECTED_UST_DP_DESCRIPTORS.add(builder.build());

EXPECTED_EXPERIMENT_SET.addAll(EXPECTED_UST_DP_DESCRIPTORS);
EXPECTED_EXPERIMENT_SET.addAll(EXPECTED_KERNEL_DP_DESCRIPTORS);
Expand Down
1 change: 1 addition & 0 deletions tmf/org.eclipse.tracecompass.tmf.core/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ Export-Package: org.eclipse.tracecompass.internal.provisional.tmf.core.model,
org.eclipse.tracecompass.tmf.core.model.annotations,
org.eclipse.tracecompass.tmf.core.model.filters,
org.eclipse.tracecompass.tmf.core.model.genericxy,
org.eclipse.tracecompass.tmf.core.model.object,
org.eclipse.tracecompass.tmf.core.model.timegraph,
org.eclipse.tracecompass.tmf.core.model.tree,
org.eclipse.tracecompass.tmf.core.model.xy,
Expand Down
4 changes: 4 additions & 0 deletions tmf/org.eclipse.tracecompass.tmf.core/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,9 @@
class="org.eclipse.tracecompass.internal.provisional.tmf.core.model.events.TmfEventTableDataProviderFactory"
id="org.eclipse.tracecompass.internal.provisional.tmf.core.model.events.TmfEventTableDataProvider">
</dataProviderFactory>
<dataProviderFactory
class="org.eclipse.tracecompass.internal.provisional.tmf.core.model.events.TmfRawEventsDataProviderFactory"
id="org.eclipse.tracecompass.tmf.core.model.events.data">
</dataProviderFactory>
</extension>
</plugin>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2019 Ericsson
* Copyright (c) 2019, 2025 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
Expand All @@ -14,7 +14,7 @@
import org.eclipse.osgi.util.NLS;

/**
* Message bundle for the new events table messages.
* Message bundle for events data provider messages.
*/
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.provisional.tmf.core.model.events.messages"; //$NON-NLS-1$
Expand All @@ -26,6 +26,14 @@ public class Messages extends NLS {
* The events table data provider help text
*/
public static @Nullable String EventsTableDataProviderFactory_DescriptionText;
/**
* The raw event data title
*/
public static @Nullable String RawEventsDataProvider_Title;
/**
* The raw event data provider help text
*/
public static @Nullable String RawEventsDataProviderFactory_DescriptionText;

static {
// initialize resource bundle
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
/**********************************************************************
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goal of the raw events provider is to get typed data out fast, please add another option for compare as instead of just equals.

* Copyright (c) 2018, 2025 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

package org.eclipse.tracecompass.internal.provisional.tmf.core.model.events;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
import org.eclipse.tracecompass.tmf.core.event.aspect.TmfBaseAspects;
import org.eclipse.tracecompass.tmf.core.model.AbstractTmfTraceDataProvider;
import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
import org.eclipse.tracecompass.tmf.core.model.object.IObjectDataProvider;
import org.eclipse.tracecompass.tmf.core.model.object.ObjectModel;
import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;

/**
* This data provider will return an object representing an array of raw event
* data.
*
* @author Patrick Tasse
*/
public class TmfRawEventsDataProvider extends AbstractTmfTraceDataProvider implements IObjectDataProvider {

/**
* Extension point ID.
*/
public static final String ID = "org.eclipse.tracecompass.tmf.core.model.events.data"; //$NON-NLS-1$

private static final String SELECTION_RANGE = "selection_range"; //$NON-NLS-1$
private static final String START = "start"; //$NON-NLS-1$
private static final String NEXT = "next"; //$NON-NLS-1$
private static final String PREVIOUS = "previous"; //$NON-NLS-1$
private static final String TYPE = "type"; //$NON-NLS-1$
private static final String FIELD = "field"; //$NON-NLS-1$
private static final String COUNT = "count"; //$NON-NLS-1$

/**
* Constructor
*
* @param trace
* A trace on which we are interested to fetch a raw event model
*/
public TmfRawEventsDataProvider(ITmfTrace trace) {
super(trace);
}

@Override
public String getId() {
return ID;
}

@Override
public TmfModelResponse<ObjectModel> fetchData(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
ITmfTrace trace = getTrace();
long rank = 0L;
Long prev = null;
Long next = null;
Object selectionRangeObj = fetchParameters.get(SELECTION_RANGE);
Object nextObj = fetchParameters.get(NEXT);
Object previousObj = fetchParameters.get(PREVIOUS);
Object typeObj = fetchParameters.get(TYPE);
Object fieldObj = fetchParameters.get(FIELD);
Object countObj = fetchParameters.get(COUNT);
if (nextObj instanceof Number nextNum) {
rank = nextNum.longValue();
prev = rank;
previousObj = null;
} else if (previousObj instanceof Number previousNum) {
rank = previousNum.longValue();
next = rank;
nextObj = null;
} else if (selectionRangeObj instanceof Map<?,?> selectionRange) {
if (selectionRange.get(START) instanceof Number start) {
rank = trace.seekEvent(TmfTimestamp.fromNanos(start.longValue())).getRank();
}
nextObj = null;
previousObj = null;
}
Pattern eventTypePattern = (typeObj instanceof String type) ? Pattern.compile(type) : null;
Pattern fieldPattern = (fieldObj instanceof String field) ? Pattern.compile(field) : null;
Integer max = null;
if (countObj instanceof Number count) {
max = count.intValue();
}
if (eventTypePattern == null && fieldPattern == null && previousObj instanceof Number) {
// optimize backward request when no filters specified
if (max == null) {
max = (int) rank;
rank = 0L;
} else if (rank >= max) {
rank = rank - max;
} else {
max = (int) rank;
rank = 0L;
}
// clear previousObj to read forwards
previousObj = null;
}
List<Object> object = new ArrayList<>();
ObjectModel model;
if (previousObj instanceof Number) {
// read backward
while (rank > 0 && (max == null || object.size() < max)) {
rank--;
ITmfContext context = trace.seekEvent(rank);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make a tmf request with filters?

long eventRank = context.getRank();
ITmfEvent event = trace.getNext(context);
if (event == null) {
break;
}
if (eventTypePattern == null || eventTypePattern.matcher(event.getName()).find()) {
Object eventObj = convertEvent(event, eventRank, fieldPattern);
if (eventObj != null) {
object.add(0, eventObj);
}
}
}
model = new ObjectModel(object);
if (rank > 0L) {
model.setPrevious(rank);
}
if (next != null) {
model.setNext(next);
}
} else {
// read forward
ITmfContext context = trace.seekEvent(rank);
while (max == null || object.size() < max) {
long eventRank = context.getRank();
ITmfEvent event = trace.getNext(context);
if (event == null) {
break;
}
if (eventTypePattern == null || eventTypePattern.matcher(event.getName()).find()) {
Object eventObj = convertEvent(event, eventRank, fieldPattern);
if (eventObj != null) {
object.add(eventObj);
}
}
}
model = new ObjectModel(object);
next = context.getRank();
if (trace.getNext(context) != null) {
model.setNext(next);
}
if (prev != null && prev > 0L) {
model.setPrevious(prev);
}
}
return new TmfModelResponse<>(model, ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
}

private static @Nullable Object convertEvent(ITmfEvent event, long rank, @Nullable Pattern fieldPattern) {
Map<String, @Nullable Object> data = new LinkedHashMap<>();

// Add basic event information
data.put("rank", rank); //$NON-NLS-1$
data.put(TmfBaseAspects.getTimestampAspect().getName(), event.getTimestamp().toNanos());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use trace aspects?

data.put(TmfBaseAspects.getEventTypeAspect().getName(), event.getType().getName());
Object contents = convertEventField(event.getContent(), fieldPattern);
if (fieldPattern != null && contents instanceof Map map) {
if (map.isEmpty()) {
return null;
}
}
data.put(TmfBaseAspects.getContentsAspect().getName(), contents);
return data;
}

private static @Nullable Object convertEventField(@Nullable ITmfEventField field, @Nullable Pattern fieldPattern) {
if (field == null) {
return null;
}
Builder<String, @Nullable Object> builder = ImmutableMap.builder();
for (ITmfEventField subField : field.getFields()) {
if (subField == null) {
continue;
}
String name = subField.getName();
if (fieldPattern == null || fieldPattern.matcher(name).find()) {
Object value = subField.getValue();
if (value instanceof ITmfEventField) {
builder.put(name, convertEventField((ITmfEventField) value, null));
} else {
builder.put(name, value);
}
}
}
Object value = field.getValue();
if (value instanceof ITmfEventField) {
value = convertEventField((ITmfEventField) value, null);
}
ImmutableMap<String, @Nullable Object> fields = builder.build();
if (value == null) {
return fields;
} else if (fields.isEmpty()) {
return value;
} else {
return Map.of("value", value, "fields", fields); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**********************************************************************
* Copyright (c) 2025 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

package org.eclipse.tracecompass.internal.provisional.tmf.core.model.events;

import java.util.Collection;
import java.util.Collections;

import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
import org.eclipse.tracecompass.tmf.core.model.DataProviderCapabilities;
import org.eclipse.tracecompass.tmf.core.model.DataProviderDescriptor;
import org.eclipse.tracecompass.tmf.core.model.ITmfDataProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;

/**
* {@link TmfRawEventsDataProvider} factory, uses the data provider extension
* point.
*
* @author Patrick Tasse
*/
public class TmfRawEventsDataProviderFactory implements IDataProviderFactory {

private static final IDataProviderDescriptor DESCRIPTOR =
new DataProviderDescriptor.Builder()
.setId(TmfRawEventsDataProvider.ID)
.setName(NonNullUtils.nullToEmptyString(Messages.RawEventsDataProvider_Title))
.setDescription(NonNullUtils.nullToEmptyString(Messages.RawEventsDataProviderFactory_DescriptionText))
.setProviderType(ProviderType.DATA)
.setCapabilities(new DataProviderCapabilities.Builder().setSelectionRange(true).build())
.build();

@Override
public @Nullable ITmfDataProvider createDataProvider(ITmfTrace trace) {
return new TmfRawEventsDataProvider(trace);
}

@Override
public Collection<IDataProviderDescriptor> getDescriptors(ITmfTrace trace) {
return Collections.singleton(DESCRIPTOR);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
###############################################################################
# Copyright (c) 2019 Ericsson
# Copyright (c) 2019, 2025 Ericsson
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -11,3 +11,5 @@

EventsTableDataProvider_Title=Events Table
EventsTableDataProviderFactory_DescriptionText=Show the raw events in table form for a given trace
RawEventsDataProvider_Title=Raw Events Data
RawEventsDataProviderFactory_DescriptionText=Show the raw event data in object form for a given trace
Loading
Loading