diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/SegmentStoreDensityDataProviderTest.java b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/SegmentStoreDensityDataProviderTest.java
new file mode 100644
index 0000000000..28778ce768
--- /dev/null
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/SegmentStoreDensityDataProviderTest.java
@@ -0,0 +1,174 @@
+/**********************************************************************
+ * Copyright (c) 2022 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.analysis.timing.core.tests.segmentstore;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.SegmentStoreDensityDataProvider;
+import org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.SegmentStoreDensityDataProviderFactory;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.model.SeriesModel;
+import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
+import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
+import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
+import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStub;
+import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStubNs;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Tests the {@Link SegmentStoreDensityDataProvider}
+ *
+ * @author Puru Jaiswal
+ */
+public class SegmentStoreDensityDataProviderTest {
+
+ private static ITmfTreeXYDataProvider<@NonNull TmfTreeDataModel> fDataProvider;
+ private static ITmfTreeXYDataProvider<@NonNull TmfTreeDataModel> fDataProviderNullSegments;
+
+ @NonNull
+ private static final TmfXmlTraceStub fTrace = new TmfXmlTraceStubNs();
+ private static final double[] yValues = new double[] { 15.0, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 15.0, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 15.0,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 15.0, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 15.0, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 15.0, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 15.0, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324 };
+ private static final long[] xValues = new long[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5 };
+ private static final long[] xValuesNull = new long[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0 };
+ private static final double[] yValuesNull = new double[] { 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324,
+ 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324, 4.9E-324 };
+ private static final String ID = "org.eclipse.tracecompass.analysis.timing.core.tests.segmentstore";
+
+ /**
+ * Set-up resources
+ *
+ * @throws TmfAnalysisException
+ * Trace exception should not happen
+ */
+ @BeforeClass
+ public static void init() throws TmfAnalysisException {
+ StubSegmentStoreProvider fixture = getValidSegment(fTrace);
+ IDataProviderFactory fp = new SegmentStoreDensityDataProviderFactory();
+ assertNull(fp.createProvider(fTrace));
+ assertNotNull(fp.createProvider(fTrace, ID));
+ assertTrue(fp.getDescriptors(fTrace).isEmpty());
+ fDataProvider = new SegmentStoreDensityDataProvider(fTrace, fixture, ID);
+ StubSegmentStoreProvider fixtureNull = getValidNullSegment(fTrace);
+ IDataProviderFactory fpNullSegment = new SegmentStoreDensityDataProviderFactory();
+ assertNull(fpNullSegment.createProvider(fTrace));
+ assertNotNull(fpNullSegment.createProvider(fTrace, ID));
+ assertTrue(fpNullSegment.getDescriptors(fTrace).isEmpty());
+ fDataProviderNullSegments = new SegmentStoreDensityDataProvider(fTrace, fixtureNull, ID);
+ }
+
+ /**
+ * Disposing resources
+ */
+ @AfterClass
+ public static void clean() {
+ fTrace.dispose();
+ }
+
+ private static @NonNull StubSegmentStoreProvider getValidSegment(@NonNull ITmfTrace trace) throws TmfAnalysisException {
+ StubSegmentStoreProvider fixture = new StubSegmentStoreProvider(false);
+ fixture.setTrace(trace);
+ fixture.schedule();
+ fixture.waitForCompletion();
+ return fixture;
+ }
+
+ private static @NonNull StubSegmentStoreProvider getValidNullSegment(@NonNull ITmfTrace trace) throws TmfAnalysisException {
+ StubSegmentStoreProvider fixture = new StubSegmentStoreProvider(true);
+ fixture.setTrace(trace);
+ fixture.schedule();
+ fixture.waitForCompletion();
+ return fixture;
+ }
+
+ /**
+ * Tests data model returned by the fetch XY
+ */
+ @Test()
+ public void testDataProviderFetchXY() {
+ TimeQueryFilter timeQueryFilter = new TimeQueryFilter(0, 100, 100);
+ TmfModelResponse<@NonNull ITmfXyModel> response = fDataProvider.fetchXY(FetchParametersUtils.timeQueryToMap(timeQueryFilter), null);
+ assertNotNull(response);
+ ITmfXyModel responseModel = response.getModel();
+ assertNotNull(responseModel);
+ SeriesModel seriesResponse = (SeriesModel) responseModel.getSeriesData().toArray()[0];
+ assertTrue(Arrays.equals(yValues, seriesResponse.getData()));
+ assertTrue(Arrays.equals(xValues, seriesResponse.getXAxis()));
+ }
+
+ /**
+ * Tests data model returned by the fetch XY
+ */
+ @Test()
+ public void testDataProviderNullFetchXY() {
+ TimeQueryFilter timeQueryFilter = new TimeQueryFilter(0, 100, 100);
+ TmfModelResponse<@NonNull ITmfXyModel> response = fDataProviderNullSegments.fetchXY(FetchParametersUtils.timeQueryToMap(timeQueryFilter), null);
+ assertNotNull(response);
+ ITmfXyModel responseModel = response.getModel();
+ assertNotNull(responseModel);
+ SeriesModel seriesResponse = (SeriesModel) responseModel.getSeriesData().toArray()[0];
+ assertTrue(Arrays.equals(yValuesNull, seriesResponse.getData()));
+ assertTrue(Arrays.equals(xValuesNull, seriesResponse.getXAxis()));
+ }
+
+ /**
+ * Tests fetch tree of the data provider
+ */
+ @Test()
+ public void testFetchTree() {
+ TimeQueryFilter timeQueryFilter = new TimeQueryFilter(0, 100, 100);
+ TmfModelResponse<@NonNull TmfTreeModel<@NonNull TmfTreeDataModel>> response = fDataProvider.fetchTree(FetchParametersUtils.timeQueryToMap(timeQueryFilter), null);
+ assertNotNull(response);
+ }
+
+ /**
+ * Tests provider ID
+ */
+ @Test
+ public void testID() {
+ assertTrue(fDataProvider.getId().equals(ID));
+ }
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/StubSegmentStoreProvider.java b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/StubSegmentStoreProvider.java
index 7b9ed0263a..e93ba51ae7 100644
--- a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/StubSegmentStoreProvider.java
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/StubSegmentStoreProvider.java
@@ -88,6 +88,29 @@ public StubSegmentStoreProvider() {
fPreFixture = builder.build();
}
+ /**
+ * Constructor to initialize segments
+ *
+ * @param nullSegments
+ * : to decide on null or not null segments
+ */
+ public StubSegmentStoreProvider(boolean nullSegments) {
+ ImmutableList.Builder<@NonNull ISegment> builder = new Builder<>();
+ if (nullSegments) {
+ fPreFixture = builder.build();
+ } else {
+ int previousStartTime = 0;
+ for (int i = 0; i < SIZE; i++) {
+ if (i % 7 == 0) {
+ previousStartTime = i;
+ }
+ ISegment segment = new BasicSegment(previousStartTime, i);
+ builder.add(segment);
+ }
+ fPreFixture = builder.build();
+ }
+ }
+
@Override
protected boolean buildAnalysisSegments(@NonNull ISegmentStore<@NonNull ISegment> segmentStore, @NonNull IProgressMonitor monitor) throws TmfAnalysisException {
return segmentStore.addAll(fPreFixture);
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/plugin.xml b/analysis/org.eclipse.tracecompass.analysis.timing.core/plugin.xml
index b093caabf2..3fc1a71d62 100644
--- a/analysis/org.eclipse.tracecompass.analysis.timing.core/plugin.xml
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/plugin.xml
@@ -30,5 +30,9 @@
class="org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.SegmentStoreTableDataProviderFactory"
id="org.eclipse.tracecompass.analysis.timing.core.segmentstore.SegmentStoreTableDataProvider">
+
+
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/Messages.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/Messages.java
index a600db0af2..0612340967 100644
--- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/Messages.java
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/Messages.java
@@ -139,6 +139,16 @@ public class Messages extends NLS {
*/
public static @Nullable String SegmentStoreTableDataProvider_description;
+ /**
+ * Segment store density title
+ */
+ public static @Nullable String SegmentStoreDensityDataProvider_title;
+
+ /**
+ * Segment store density total
+ */
+ public static @Nullable String SegmentStoreDensity_TotalLabel;
+
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreDensityDataProvider.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreDensityDataProvider.java
new file mode 100644
index 0000000000..0702060721
--- /dev/null
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreDensityDataProvider.java
@@ -0,0 +1,163 @@
+/**********************************************************************
+ * Copyright (c) 2022 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.analysis.timing.core.segmentstore;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.StreamSupport;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
+import org.eclipse.tracecompass.internal.tmf.core.model.TmfXyResponseFactory;
+import org.eclipse.tracecompass.internal.tmf.core.model.filters.FetchParametersUtils;
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.model.AbstractTmfTraceDataProvider;
+import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
+import org.eclipse.tracecompass.tmf.core.model.YModel;
+import org.eclipse.tracecompass.tmf.core.model.filters.TimeQueryFilter;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeModel;
+import org.eclipse.tracecompass.tmf.core.model.xy.ITmfTreeXYDataProvider;
+import org.eclipse.tracecompass.tmf.core.model.xy.ITmfXyModel;
+import org.eclipse.tracecompass.tmf.core.model.xy.IYModel;
+import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
+import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+/**
+ * This data provider will return an XY model based on a query filter. The model
+ * can be used by any viewer to draw density view charts. Model returned is for
+ * analysis using SegmentStore.
+ *
+ * @author Puru Jaiswal
+ */
+public class SegmentStoreDensityDataProvider extends AbstractTmfTraceDataProvider implements ITmfTreeXYDataProvider {
+
+ /**
+ * Extension point ID.
+ */
+ public static final String ID = "org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.SegmentStoreDensityDataProvider"; //$NON-NLS-1$
+ private static final AtomicLong TRACE_IDS = new AtomicLong();
+
+ private final String fID;
+ private final String title = Objects.requireNonNull(Messages.SegmentStoreDensityDataProvider_title);
+ private final ISegmentStoreProvider fProvider;
+ private final long fTotalId = TRACE_IDS.getAndIncrement();
+ private final long fTraceId = TRACE_IDS.getAndIncrement();
+
+ /**
+ * Constructor
+ *
+ * @param trace
+ * trace provider with other properties of trace.
+ * @param provider
+ * segment store provider
+ * @param id
+ * analysis identifier
+ */
+ public SegmentStoreDensityDataProvider(ITmfTrace trace, ISegmentStoreProvider provider, String id) {
+ super(trace);
+ fProvider = provider;
+ fID = id;
+ if (provider instanceof IAnalysisModule) {
+ ((IAnalysisModule) provider).waitForCompletion();
+ }
+ }
+
+ @Override
+ public TmfModelResponse fetchXY(Map fetchParameters, @Nullable IProgressMonitor monitor) {
+ ISegmentStore segmentStore = fProvider.getSegmentStore();
+ if (segmentStore == null) {
+ return TmfXyResponseFactory.createFailedResponse(Objects.requireNonNull(Messages.SegmentStoreDataProvider_SegmentNotAvailable));
+ }
+ TimeQueryFilter queryFilter = FetchParametersUtils.createSelectionTimeQuery(fetchParameters);
+ if (queryFilter == null) {
+ queryFilter = FetchParametersUtils.createTimeQuery(fetchParameters);
+ if (queryFilter == null) {
+ return TmfXyResponseFactory.createFailedResponse(CommonStatusMessage.INCORRECT_QUERY_PARAMETERS);
+ }
+ }
+ return getXyData(segmentStore, queryFilter);
+ }
+
+ private TmfModelResponse getXyData(ISegmentStore segmentStore, TimeQueryFilter queryFilter) {
+ long startTraceTime = queryFilter.getStart();
+ long endTraceTime = queryFilter.getEnd();
+ int width = queryFilter.getTimesRequested().length;
+ Iterable displayData = segmentStore.getIntersectingElements(startTraceTime, endTraceTime);
+
+ IAnalysisModule module = (fProvider instanceof IAnalysisModule) ? (IAnalysisModule) fProvider : null;
+ boolean complete = module != null && module.isQueryable(queryFilter.getEnd());
+
+ Optional maxSegment = StreamSupport.stream(displayData.spliterator(), false).max(SegmentComparators.INTERVAL_LENGTH_COMPARATOR);
+ long maxLength = 1;
+ if (maxSegment.isPresent()) {
+ maxLength = maxSegment.get().getLength();
+ }
+
+ double[] yValues = getYValues(displayData, width, maxLength);
+ long[] xValues = getXValues(width, maxLength);
+ ImmutableList.Builder builder = ImmutableList.builder();
+ String totalName = getTrace().getName() + '/' + Messages.SegmentStoreDensity_TotalLabel;
+ builder.add(new YModel(fTotalId, totalName, yValues));
+ return TmfXyResponseFactory.create(title, xValues, builder.build(), complete);
+ }
+
+ private static long[] getXValues(int width, long maxLength) {
+ double timeWidth = (double) maxLength / (double) width;
+ long[] xValues = new long[width];
+ for (int i = 0; i < width; i++) {
+ xValues[i] = (long) (i * timeWidth);
+ xValues[i] += timeWidth / 2;
+ }
+ return xValues;
+ }
+
+ private static double[] getYValues(Iterable displayData, int width, long maxLength) {
+ double maxFactor = 1.0 / (maxLength + 1.0);
+ double[] yValues = new double[width];
+ Arrays.fill(yValues, Double.MIN_VALUE);
+ for (ISegment segment : displayData) {
+ double xBox = segment.getLength() * maxFactor * width;
+ if (yValues[(int) xBox] < 1) {
+ yValues[(int) xBox] = 1;
+ } else {
+ yValues[(int) xBox]++;
+ }
+ }
+ return yValues;
+ }
+
+ @Override
+ public TmfModelResponse> fetchTree(Map fetchParameters, @Nullable IProgressMonitor monitor) {
+ Builder builder = ImmutableList.builder();
+ builder.add(new TmfTreeDataModel(fTraceId, -1, Collections.singletonList(String.valueOf(getTrace().getName()))));
+ builder.add(new TmfTreeDataModel(fTotalId, fTraceId, Collections.singletonList(Objects.requireNonNull(Messages.SegmentStoreDensity_TotalLabel))));
+ return new TmfModelResponse<>(new TmfTreeModel<>(Collections.emptyList(), builder.build()), ITmfResponse.Status.COMPLETED, CommonStatusMessage.COMPLETED);
+ }
+
+ @Override
+ public String getId() {
+ return fID;
+ }
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreDensityDataProviderFactory.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreDensityDataProviderFactory.java
new file mode 100644
index 0000000000..61290fa344
--- /dev/null
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/SegmentStoreDensityDataProviderFactory.java
@@ -0,0 +1,49 @@
+/**********************************************************************
+ * Copyright (c) 2022 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.analysis.timing.core.segmentstore;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.SegmentStoreAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+
+/**
+ * Generalized {@link SegmentStoreDensityDataProvider} factory using secondary
+ * ID to identify which segment store provider to build it from.
+ *
+ * @author Puru Jaiswal
+ */
+public class SegmentStoreDensityDataProviderFactory implements IDataProviderFactory {
+
+ @Override
+ public @Nullable ITmfTreeDataProvider extends ITmfTreeDataModel> createProvider(ITmfTrace trace) {
+ return null;
+ }
+
+ @Override
+ public @Nullable ITmfTreeDataProvider extends ITmfTreeDataModel> createProvider(ITmfTrace trace, String secondaryId) {
+ IAnalysisModule m = new SegmentStoreAnalysisModule(trace, secondaryId);
+ try {
+ m.setTrace(trace);
+ String composedId = SegmentStoreDensityDataProvider.ID + ":" + secondaryId; //$NON-NLS-1$
+ m.schedule();
+ return new SegmentStoreDensityDataProvider(trace, (ISegmentStoreProvider) m, composedId);
+ } catch (TmfAnalysisException ex) {
+ m.dispose();
+ return null;
+ }
+ }
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/messages.properties b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/messages.properties
index e152a9d982..a6fb225378 100644
--- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/messages.properties
+++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/messages.properties
@@ -28,6 +28,9 @@ SegmentStoreTableDataProvider_description=Show latency table provided by {0}
SegmentStoreScatterGraphDataProvider_title={0} - Latency vs Time
SegmentStoreScatterGraphDataProvider_description=Show latencies provided by {0}
+SegmentStoreDensityDataProvider_title={0} - Function Density
+
+SegmentStoreDensity_TotalLabel=Total
SegmentStoreStatistics_Label=Label
SegmentStoreStatistics_MinLabel=Minimum
SegmentStoreStatistics_MaxLabel=Maximum
diff --git a/releng/org.eclipse.tracecompass.integration.core.tests/src/org/eclipse/tracecompass/integration/core/tests/dataproviders/DataProviderManagerTest.java b/releng/org.eclipse.tracecompass.integration.core.tests/src/org/eclipse/tracecompass/integration/core/tests/dataproviders/DataProviderManagerTest.java
index 07dd477609..5a7a6f7d6e 100644
--- a/releng/org.eclipse.tracecompass.integration.core.tests/src/org/eclipse/tracecompass/integration/core/tests/dataproviders/DataProviderManagerTest.java
+++ b/releng/org.eclipse.tracecompass.integration.core.tests/src/org/eclipse/tracecompass/integration/core/tests/dataproviders/DataProviderManagerTest.java
@@ -86,6 +86,12 @@ public class DataProviderManagerTest {
.setId("org.eclipse.tracecompass.analysis.timing.core.segmentstore.SegmentStoreTableDataProvider:lttng.analysis.futex");
EXPECTED_KERNEL_DP_DESCRIPTORS.add(builder.build());
builder = new DataProviderDescriptor.Builder();
+ builder.setName("Futex Contention Analysis - Function Density")
+ .setDescription("Show function density provided by Analysis module: Futex Contention Analysis")
+ .setProviderType(ProviderType.TREE_TIME_XY)
+ .setId("org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.SegmentStoreDensityDataProvider:lttng.analysis.futex");
+ EXPECTED_KERNEL_DP_DESCRIPTORS.add(builder.build());
+ builder = new DataProviderDescriptor.Builder();
builder.setName("Futex Contention Analysis - Latency vs Time")
.setDescription("Show latencies provided by Analysis module: Futex Contention Analysis")
.setProviderType(ProviderType.TREE_TIME_XY)
@@ -110,6 +116,12 @@ public class DataProviderManagerTest {
.setId("org.eclipse.tracecompass.analysis.timing.core.segmentstore.SegmentStoreTableDataProvider:lttng.analysis.irq");
EXPECTED_KERNEL_DP_DESCRIPTORS.add(builder.build());
builder = new DataProviderDescriptor.Builder();
+ builder.setName("IRQ Analysis - Function Density")
+ .setDescription("Show function density provided by Analysis module: IRQ Analysis")
+ .setProviderType(ProviderType.TREE_TIME_XY)
+ .setId("org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.SegmentStoreDensityDataProvider:lttng.analysis.irq");
+ EXPECTED_KERNEL_DP_DESCRIPTORS.add(builder.build());
+ builder = new DataProviderDescriptor.Builder();
builder.setName("IRQ Analysis - Latency vs Time")
.setDescription("Show latencies provided by Analysis module: IRQ Analysis")
.setProviderType(ProviderType.TREE_TIME_XY)
@@ -140,6 +152,12 @@ public class DataProviderManagerTest {
.setId("org.eclipse.tracecompass.analysis.timing.core.segmentstore.SegmentStoreTableDataProvider:org.eclipse.tracecompass.analysis.os.linux.latency.syscall");
EXPECTED_KERNEL_DP_DESCRIPTORS.add(builder.build());
builder = new DataProviderDescriptor.Builder();
+ builder.setName("System Call Latency - Function Density")
+ .setDescription("Show function density provided by Analysis module: System Call Latency")
+ .setProviderType(ProviderType.TREE_TIME_XY)
+ .setId("org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.SegmentStoreDensityDataProvider:org.eclipse.tracecompass.analysis.os.linux.latency.syscall");
+ EXPECTED_KERNEL_DP_DESCRIPTORS.add(builder.build());
+ builder = new DataProviderDescriptor.Builder();
builder.setName("System Call Latency - Latency vs Time")
.setDescription("Show latencies provided by Analysis module: System Call Latency")
.setProviderType(ProviderType.TREE_TIME_XY)
@@ -190,6 +208,12 @@ public class DataProviderManagerTest {
.setId("org.eclipse.tracecompass.analysis.timing.core.segmentstore.SegmentStoreTableDataProvider:org.eclipse.linuxtools.lttng2.ust.analysis.callstack");
EXPECTED_UST_DP_DESCRIPTORS.add(builder.build());
builder = new DataProviderDescriptor.Builder();
+ builder.setName("LTTng-UST CallStack - Function Density")
+ .setDescription("Show function density provided by Analysis module: LTTng-UST CallStack")
+ .setProviderType(ProviderType.TREE_TIME_XY)
+ .setId("org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.SegmentStoreDensityDataProvider:org.eclipse.linuxtools.lttng2.ust.analysis.callstack");
+ EXPECTED_UST_DP_DESCRIPTORS.add(builder.build());
+ builder = new DataProviderDescriptor.Builder();
builder.setName("LTTng-UST CallStack - Latency vs Time")
.setDescription("Show latencies provided by Analysis module: LTTng-UST CallStack")
.setProviderType(ProviderType.TREE_TIME_XY)