Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
timing.core: add Segment Store Density Provider
Currently for the function density views there is no data provider for it and the logic for data and UI are in the same file, to improve the efficiency a data provider is created for function density views. [Added] SegmentStoreDensityDataProvider{Factory} for density views. Change-Id: I3b6521b5e9aab90669f61315e804f9e326807a5b Signed-off-by: Puru Jaiswal <puru.jaiswal@ericsson.com> Reviewed-on: https://git.eclipse.org/r/c/tracecompass/org.eclipse.tracecompass/+/194660 Tested-by: Marco Miller <marco.miller@ericsson.com> Reviewed-by: Marco Miller <marco.miller@ericsson.com>
- Loading branch information
1 parent
ae8f8cc
commit 55905e7
Showing
8 changed files
with
450 additions
and
0 deletions.
There are no files selected for viewing
174 changes: 174 additions & 0 deletions
174
...ecompass/analysis/timing/core/tests/segmentstore/SegmentStoreDensityDataProviderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
163 changes: 163 additions & 0 deletions
163
...cecompass/internal/analysis/timing/core/segmentstore/SegmentStoreDensityDataProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<TmfTreeDataModel> { | ||
|
||
/** | ||
* 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<ITmfXyModel> fetchXY(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) { | ||
ISegmentStore<ISegment> 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<ITmfXyModel> getXyData(ISegmentStore<ISegment> segmentStore, TimeQueryFilter queryFilter) { | ||
long startTraceTime = queryFilter.getStart(); | ||
long endTraceTime = queryFilter.getEnd(); | ||
int width = queryFilter.getTimesRequested().length; | ||
Iterable<ISegment> displayData = segmentStore.getIntersectingElements(startTraceTime, endTraceTime); | ||
|
||
IAnalysisModule module = (fProvider instanceof IAnalysisModule) ? (IAnalysisModule) fProvider : null; | ||
boolean complete = module != null && module.isQueryable(queryFilter.getEnd()); | ||
|
||
Optional<ISegment> 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<IYModel> 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<ISegment> 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<TmfTreeModel<TmfTreeDataModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) { | ||
Builder<TmfTreeDataModel> 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; | ||
} | ||
} |
Oops, something went wrong.