From 664a3a815e6d8a698a5d78b63f8535771eabe8d0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Lo=C3=AFc=20Prieur-Drevon?= Date: Thu, 15 Sep 2016 11:43:23 -0400 Subject: [PATCH] segment store: introduce a Segment Store Factory and centralize segment stores MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Usage: SegmentStoreFactory.create( data[], flags...); Flags at this moment are "fast, stable and distinct" More flags will come, examples can be "hybrid" or "aggregate" Change-Id: I5eccb4393b52c8f1dc9d423eaa3bb9087425b5e6 Signed-off-by: Loïc Prieur-Drevon Signed-off-by: Matthew Khouzam Reviewed-on: https://git.eclipse.org/r/81504 Reviewed-by: Genevieve Bastien Tested-by: Genevieve Bastien Reviewed-by: Hudson CI Reviewed-by: Jean-Christian Kouame Tested-by: Jean-Christian Kouame --- .../.classpath | 1 - .../META-INF/MANIFEST.MF | 3 +- .../build.properties | 3 +- .../META-INF/MANIFEST.MF | 3 +- .../AbstractSegmentStoreAnalysisModule.java | 6 +- .../core/callgraph/CallGraphAnalysis.java | 6 +- .../.classpath | 1 + .../META-INF/MANIFEST.MF | 1 - .../build.properties | 3 +- .../tests/store/SegmentStoreBenchmark.java | 6 +- .../core/tests}/AbstractTestSegmentStore.java | 12 +- .../core/tests}/ArrayListStoreTest.java | 4 +- .../core/tests}/LazyArrayListStoreTest.java | 5 +- .../core/tests/OldTreeMapStoreTest.java | 47 +++ .../core/tests/SegmentStoreFactoryTest.java | 167 ++++++++++ .../core/tests/TreeMapStoreTest.java | 45 +++ .../core/tests/treemap/TreeMapStoreTest.java | 300 ------------------ .../META-INF/MANIFEST.MF | 4 +- .../core/arraylist}/ArrayListStore.java | 13 +- .../core/arraylist}/LazyArrayListStore.java | 15 +- .../core/arraylist/package-info.java | 11 + .../core/treemap/TreeMapStore.java | 273 ++++++++++++++++ .../core/treemap/package-info.java | 14 + .../core/SegmentStoreFactory.java | 153 +++++++++ .../core/treemap/TreeMapStore.java | 3 + .../XmlPatternSegmentStoreModule.java | 4 +- 26 files changed, 759 insertions(+), 344 deletions(-) rename {analysis/org.eclipse.tracecompass.analysis.timing.core.tests => statesystem/org.eclipse.tracecompass.segmentstore.core.tests}/perf/org/eclipse/tracecompass/analysis/timing/core/tests/store/SegmentStoreBenchmark.java (96%) rename {analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store => statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests}/AbstractTestSegmentStore.java (97%) rename {analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store => statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests}/ArrayListStoreTest.java (86%) rename {analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store => statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests}/LazyArrayListStoreTest.java (85%) create mode 100644 statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/OldTreeMapStoreTest.java create mode 100644 statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/SegmentStoreFactoryTest.java create mode 100644 statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/TreeMapStoreTest.java delete mode 100644 statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/treemap/TreeMapStoreTest.java rename {analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/store => statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist}/ArrayListStore.java (95%) rename {analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/store => statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist}/LazyArrayListStore.java (95%) create mode 100644 statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist/package-info.java create mode 100644 statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/treemap/TreeMapStore.java create mode 100644 statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/treemap/package-info.java create mode 100644 statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/SegmentStoreFactory.java diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/.classpath b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/.classpath index 5870d54435..5480bc8015 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/.classpath +++ b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/.classpath @@ -11,6 +11,5 @@ - diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/META-INF/MANIFEST.MF b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/META-INF/MANIFEST.MF index 53c2e4886c..c3a5e67189 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/META-INF/MANIFEST.MF +++ b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/META-INF/MANIFEST.MF @@ -23,6 +23,5 @@ Import-Package: com.google.common.collect, Export-Package: org.eclipse.tracecompass.analysis.timing.core.tests, org.eclipse.tracecompass.analysis.timing.core.tests.callgraph, org.eclipse.tracecompass.analysis.timing.core.tests.flamegraph, - org.eclipse.tracecompass.analysis.timing.core.tests.segmentstore.statistics, - org.eclipse.tracecompass.analysis.timing.core.tests.store + org.eclipse.tracecompass.analysis.timing.core.tests.segmentstore.statistics Bundle-Activator: org.eclipse.tracecompass.analysis.timing.core.tests.Activator diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/build.properties b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/build.properties index 7583381438..4ceabc1505 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/build.properties +++ b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/build.properties @@ -7,8 +7,7 @@ # http://www.eclipse.org/legal/epl-v10.html ############################################################################### -source.. = src/,\ - perf/ +source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/META-INF/MANIFEST.MF b/analysis/org.eclipse.tracecompass.analysis.timing.core/META-INF/MANIFEST.MF index e45246c1d1..082e6c7805 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core/META-INF/MANIFEST.MF +++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/META-INF/MANIFEST.MF @@ -17,8 +17,7 @@ Require-Bundle: org.eclipse.ui, Export-Package: org.eclipse.tracecompass.analysis.timing.core.segmentstore, org.eclipse.tracecompass.analysis.timing.core.segmentstore.statistics, org.eclipse.tracecompass.internal.analysis.timing.core, - org.eclipse.tracecompass.internal.analysis.timing.core.callgraph;x-friends:="org.eclipse.tracecompass.analysis.timing.ui,org.eclipse.tracecompass.analysis.timing.core.tests", - org.eclipse.tracecompass.internal.analysis.timing.core.store;x-friends:="org.eclipse.tracecompass.analysis.timing.core.tests,org.eclipse.tracecompass.tmf.analysis.xml.core" + org.eclipse.tracecompass.internal.analysis.timing.core.callgraph;x-friends:="org.eclipse.tracecompass.analysis.timing.ui,org.eclipse.tracecompass.analysis.timing.core.tests" Import-Package: com.google.common.annotations;version="15.0.0", com.google.common.collect, com.google.common.hash diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/analysis/timing/core/segmentstore/AbstractSegmentStoreAnalysisModule.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/analysis/timing/core/segmentstore/AbstractSegmentStoreAnalysisModule.java index 597b547e45..0e20dd60f6 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/analysis/timing/core/segmentstore/AbstractSegmentStoreAnalysisModule.java +++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/analysis/timing/core/segmentstore/AbstractSegmentStoreAnalysisModule.java @@ -24,9 +24,9 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.ListenerList; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.common.core.NonNullUtils; -import org.eclipse.tracecompass.internal.analysis.timing.core.store.ArrayListStore; import org.eclipse.tracecompass.segmentstore.core.ISegment; import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; +import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory; import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect; @@ -147,7 +147,7 @@ public abstract class AbstractSegmentStoreAnalysisModule extends TmfAbstractAnal /* Attempt to read the existing file */ try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(file))) { Object[] segmentArray = readObject(ois); - ISegmentStore store = new ArrayListStore<>(NonNullUtils.checkNotNullContents(segmentArray)); + ISegmentStore store = SegmentStoreFactory.createSegmentStore(NonNullUtils.checkNotNullContents(segmentArray)); fSegmentStore = store; sendUpdate(store); return true; @@ -164,7 +164,7 @@ public abstract class AbstractSegmentStoreAnalysisModule extends TmfAbstractAnal } } - ISegmentStore segmentStore = new ArrayListStore<>(); + ISegmentStore segmentStore = SegmentStoreFactory.createSegmentStore(); boolean completed = buildAnalysisSegments(segmentStore, monitor); if (!completed) { return false; diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CallGraphAnalysis.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CallGraphAnalysis.java index e679508037..1d91a2b332 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CallGraphAnalysis.java +++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CallGraphAnalysis.java @@ -23,9 +23,10 @@ import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgr import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider; import org.eclipse.tracecompass.common.core.StreamUtils; import org.eclipse.tracecompass.internal.analysis.timing.core.Activator; -import org.eclipse.tracecompass.internal.analysis.timing.core.store.LazyArrayListStore; import org.eclipse.tracecompass.segmentstore.core.ISegment; import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; +import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory; +import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory.SegmentStoreType; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; @@ -70,7 +71,7 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem /** * Segment store */ - private final ISegmentStore<@NonNull ISegment> fStore = new LazyArrayListStore<>(); + private final ISegmentStore<@NonNull ISegment> fStore; /** * Listeners @@ -97,6 +98,7 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem */ public CallGraphAnalysis() { super(); + fStore = SegmentStoreFactory.createSegmentStore(SegmentStoreType.Fast); } @Override diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/.classpath b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/.classpath index 5480bc8015..5870d54435 100644 --- a/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/.classpath +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/.classpath @@ -11,5 +11,6 @@ + diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/META-INF/MANIFEST.MF b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/META-INF/MANIFEST.MF index fd2596bb8e..1cc1c8516b 100644 --- a/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/META-INF/MANIFEST.MF +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/META-INF/MANIFEST.MF @@ -12,5 +12,4 @@ Require-Bundle: org.junit;bundle-version="4.0.0", org.eclipse.core.resources, org.eclipse.tracecompass.common.core, org.eclipse.tracecompass.segmentstore.core -Export-Package: org.eclipse.tracecompass.segmentstore.core.tests.treemap;x-internal:=true Import-Package: com.google.common.collect diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/build.properties b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/build.properties index 7f8b8a0ab4..e167a69935 100644 --- a/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/build.properties +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/build.properties @@ -10,7 +10,8 @@ # Alexandre Montplaisir - Initial API and implementation ############################################################################### -source.. = src/ +source.. = src/,\ + perf/ output.. = bin/ bin.includes = META-INF/,\ .,\ diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/perf/org/eclipse/tracecompass/analysis/timing/core/tests/store/SegmentStoreBenchmark.java b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/perf/org/eclipse/tracecompass/analysis/timing/core/tests/store/SegmentStoreBenchmark.java similarity index 96% rename from analysis/org.eclipse.tracecompass.analysis.timing.core.tests/perf/org/eclipse/tracecompass/analysis/timing/core/tests/store/SegmentStoreBenchmark.java rename to statesystem/org.eclipse.tracecompass.segmentstore.core.tests/perf/org/eclipse/tracecompass/analysis/timing/core/tests/store/SegmentStoreBenchmark.java index bc1c9143bb..ec61088a30 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/perf/org/eclipse/tracecompass/analysis/timing/core/tests/store/SegmentStoreBenchmark.java +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/perf/org/eclipse/tracecompass/analysis/timing/core/tests/store/SegmentStoreBenchmark.java @@ -14,12 +14,12 @@ import static org.junit.Assert.assertNotNull; import java.util.Random; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.tracecompass.internal.analysis.timing.core.store.ArrayListStore; -import org.eclipse.tracecompass.internal.analysis.timing.core.store.LazyArrayListStore; +import org.eclipse.tracecompass.internal.segmentstore.core.arraylist.ArrayListStore; +import org.eclipse.tracecompass.internal.segmentstore.core.arraylist.LazyArrayListStore; +import org.eclipse.tracecompass.internal.segmentstore.core.treemap.TreeMapStore; import org.eclipse.tracecompass.segmentstore.core.BasicSegment; import org.eclipse.tracecompass.segmentstore.core.ISegment; import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; -import org.eclipse.tracecompass.segmentstore.core.treemap.TreeMapStore; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store/AbstractTestSegmentStore.java b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/AbstractTestSegmentStore.java similarity index 97% rename from analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store/AbstractTestSegmentStore.java rename to statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/AbstractTestSegmentStore.java index 179273cc85..05818af722 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store/AbstractTestSegmentStore.java +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/AbstractTestSegmentStore.java @@ -7,7 +7,7 @@ * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ -package org.eclipse.tracecompass.analysis.timing.core.tests.store; +package org.eclipse.tracecompass.segmentstore.core.tests; import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; import static org.junit.Assert.assertEquals; @@ -42,7 +42,10 @@ import com.google.common.collect.Lists; */ public abstract class AbstractTestSegmentStore { - private ISegmentStore<@NonNull ISegment> fSegmentStore; + /** + * The segment store + */ + protected ISegmentStore<@NonNull ISegment> fSegmentStore; /** * Get the segment store to test @@ -56,7 +59,10 @@ public abstract class AbstractTestSegmentStore { private static final @NonNull ISegment SEGMENT_4_8 = new BasicSegment(4, 8); private static final @NonNull ISegment SEGMENT_6_8 = new BasicSegment(6, 8); private static final @NonNull ISegment SEGMENT_10_14 = new BasicSegment(10, 14); - private static final @NonNull List<@NonNull ISegment> SEGMENTS = ImmutableList.of(SEGMENT_2_6, SEGMENT_4_6, SEGMENT_4_8, SEGMENT_6_8, SEGMENT_10_14); + /** + * A sample segment list + */ + protected static final List<@NonNull ISegment> SEGMENTS = ImmutableList.of(SEGMENT_2_6, SEGMENT_4_6, SEGMENT_4_8, SEGMENT_6_8, SEGMENT_10_14); private static final List<@NonNull ISegment> REVERSE_SEGMENTS = Lists.reverse(SEGMENTS); /** diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store/ArrayListStoreTest.java b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/ArrayListStoreTest.java similarity index 86% rename from analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store/ArrayListStoreTest.java rename to statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/ArrayListStoreTest.java index 0c61c6e25d..23496ea20c 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store/ArrayListStoreTest.java +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/ArrayListStoreTest.java @@ -7,10 +7,10 @@ * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ -package org.eclipse.tracecompass.analysis.timing.core.tests.store; +package org.eclipse.tracecompass.segmentstore.core.tests; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.tracecompass.internal.analysis.timing.core.store.ArrayListStore; +import org.eclipse.tracecompass.internal.segmentstore.core.arraylist.ArrayListStore; import org.eclipse.tracecompass.segmentstore.core.ISegment; import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store/LazyArrayListStoreTest.java b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/LazyArrayListStoreTest.java similarity index 85% rename from analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store/LazyArrayListStoreTest.java rename to statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/LazyArrayListStoreTest.java index 1c99a5b1c4..d41f9e6caf 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/store/LazyArrayListStoreTest.java +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/LazyArrayListStoreTest.java @@ -7,10 +7,10 @@ * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ -package org.eclipse.tracecompass.analysis.timing.core.tests.store; +package org.eclipse.tracecompass.segmentstore.core.tests; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.tracecompass.internal.analysis.timing.core.store.LazyArrayListStore; +import org.eclipse.tracecompass.internal.segmentstore.core.arraylist.LazyArrayListStore; import org.eclipse.tracecompass.segmentstore.core.ISegment; import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; @@ -25,4 +25,5 @@ public class LazyArrayListStoreTest extends AbstractTestSegmentStore { protected ISegmentStore<@NonNull ISegment> getSegmentStore() { return new LazyArrayListStore<>(); } + } \ No newline at end of file diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/OldTreeMapStoreTest.java b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/OldTreeMapStoreTest.java new file mode 100644 index 0000000000..9f7466a288 --- /dev/null +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/OldTreeMapStoreTest.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2016 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +package org.eclipse.tracecompass.segmentstore.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.segmentstore.core.treemap.TreeMapStore; +import org.eclipse.tracecompass.segmentstore.core.BasicSegment; +import org.eclipse.tracecompass.segmentstore.core.ISegment; +import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; +import org.junit.Test; + +/** + * Unit tests for intersecting elements in a TreeMapStore + * + * @author France Lapointe Nguyen + * @deprecated the test is deprecated as the store is deprecated + */ +@Deprecated +public class OldTreeMapStoreTest extends AbstractTestSegmentStore { + + @Override + protected ISegmentStore<@NonNull ISegment> getSegmentStore() { + return new TreeMapStore<>(); + } + + /** + * Try adding duplicate elements, they should be ignored + */ + @Test + public void testNoDuplicateElements() { + for (ISegment segment : SEGMENTS) { + boolean ret = fSegmentStore.add(new BasicSegment(segment.getStart(), segment.getEnd())); + assertFalse(ret); + } + assertEquals(SEGMENTS.size(), fSegmentStore.size()); + } +} \ No newline at end of file diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/SegmentStoreFactoryTest.java b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/SegmentStoreFactoryTest.java new file mode 100644 index 0000000000..8fc9a96fbe --- /dev/null +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/SegmentStoreFactoryTest.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2016 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +package org.eclipse.tracecompass.segmentstore.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.segmentstore.core.BasicSegment; +import org.eclipse.tracecompass.segmentstore.core.ISegment; +import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; +import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory; +import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory.SegmentStoreType; +import org.junit.Test; + +/** + * Segment Store factory test + * + * @author Matthew Khouzam + * + */ +public class SegmentStoreFactoryTest { + + /** + * Simplest create function, should always work + */ + @Test + public void simpleCreate() { + assertNotNull(SegmentStoreFactory.createSegmentStore()); + } + + /** + * Create a fast segment store. Should always return the fastest + * implementation available + */ + @Test + public void createFast() { + assertNotNull(SegmentStoreFactory.createSegmentStore(SegmentStoreType.Fast)); + } + + /** + * Create a stable segment store, should always return a segment store that + * does not change much its performance memory or cpu + */ + @Test + public void createStable() { + assertNotNull(SegmentStoreFactory.createSegmentStore(SegmentStoreType.Stable)); + } + + /** + * Create a "set" like segment store + */ + @Test + public void createDistinct() { + ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore(SegmentStoreType.Distinct); + assertNotNull(fixture); + testDistinct(fixture); + } + + /** + * Make sure mixing flags works + */ + @Test + public void createDistinctFast() { + ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore(SegmentStoreType.Distinct, SegmentStoreType.Fast); + testDistinct(fixture); + } + + /** + * Make sure mixing flags works + */ + @Test + public void createDistinctStable() { + ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore(SegmentStoreType.Distinct, SegmentStoreType.Stable); + testDistinct(fixture); + } + + /** + * Make sure mixing flags works + */ + @Test + public void createDoubleDistinct() { + ISegmentStore<@NonNull ISegment> fixture = SegmentStoreFactory.createSegmentStore(SegmentStoreType.Distinct, SegmentStoreType.Distinct); + assertNotNull(fixture); + testDistinct(fixture); + } + + /** + * Make sure mixing flags works (power set of all types) + */ + @Test + public void createAllDressed() { + testDistinct(SegmentStoreFactory.createSegmentStore(SegmentStoreType.Distinct, SegmentStoreType.Stable, SegmentStoreType.Fast)); + testDistinct(SegmentStoreFactory.createSegmentStore(SegmentStoreType.Distinct, SegmentStoreType.Fast, SegmentStoreType.Stable)); + testDistinct(SegmentStoreFactory.createSegmentStore(SegmentStoreType.Stable, SegmentStoreType.Distinct, SegmentStoreType.Fast)); + testDistinct(SegmentStoreFactory.createSegmentStore(SegmentStoreType.Stable, SegmentStoreType.Fast, SegmentStoreType.Distinct)); + testDistinct(SegmentStoreFactory.createSegmentStore(SegmentStoreType.Fast, SegmentStoreType.Distinct, SegmentStoreType.Stable)); + testDistinct(SegmentStoreFactory.createSegmentStore(SegmentStoreType.Fast, SegmentStoreType.Stable, SegmentStoreType.Distinct)); + } + + /** + * Torture test, add many redundant flags + */ + @SuppressWarnings("null") + @Test + public void createTortureTest() { + Random rnd = new Random(); + List<@NonNull SegmentStoreType> args = new ArrayList<>(); + rnd.setSeed(1234); + int nbValues = SegmentStoreType.values().length; + args.add(SegmentStoreType.Distinct); + for (int i = 0; i < 1000; i++) { + int nextInt = rnd.nextInt(nbValues); + args.add(SegmentStoreType.values()[nextInt]); + } + SegmentStoreType @NonNull [] array = args.toArray(new SegmentStoreType[args.size()]); + assertNotNull(array); + testDistinct(SegmentStoreFactory.createSegmentStore(array)); + } + + /** + * Create a pre-loaded fast segment store + */ + @Test + public void createPreloaded() { + ISegment[] data = new ISegment[1]; + data[0] = new BasicSegment(0, 0); + ISegmentStore<@NonNull ISegment> segmentStore; + segmentStore = SegmentStoreFactory.createSegmentStore(data); + assertNotNull(segmentStore); + assertEquals(1, segmentStore.size()); + segmentStore = SegmentStoreFactory.createSegmentStore(data, SegmentStoreType.Fast); + assertNotNull(segmentStore); + assertEquals(1, segmentStore.size()); + segmentStore = SegmentStoreFactory.createSegmentStore(data, SegmentStoreType.Stable); + assertNotNull(segmentStore); + assertEquals(1, segmentStore.size()); + segmentStore = SegmentStoreFactory.createSegmentStore(data, SegmentStoreType.Distinct); + assertNotNull(segmentStore); + assertEquals(1, segmentStore.size()); + } + + private static void testDistinct(ISegmentStore<@NonNull ISegment> fixture) { + // test adding the same object + ISegment seg = new BasicSegment(0, 0); + fixture.add(seg); + fixture.add(seg); + assertEquals(1, fixture.size()); + fixture.clear(); + // test different equal objects + fixture.add(new BasicSegment(0, 0)); + fixture.add(new BasicSegment(0, 0)); + assertEquals(1, fixture.size()); + } + +} diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/TreeMapStoreTest.java b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/TreeMapStoreTest.java new file mode 100644 index 0000000000..f2f96b919e --- /dev/null +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/TreeMapStoreTest.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2015 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +package org.eclipse.tracecompass.segmentstore.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.internal.segmentstore.core.treemap.TreeMapStore; +import org.eclipse.tracecompass.segmentstore.core.BasicSegment; +import org.eclipse.tracecompass.segmentstore.core.ISegment; +import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; +import org.junit.Test; + +/** + * Test specific behavior for a TreeMapStore segment store. + * + * @author France Lapointe Nguyen + */ +public class TreeMapStoreTest extends AbstractTestSegmentStore { + + @Override + protected ISegmentStore<@NonNull ISegment> getSegmentStore() { + return new TreeMapStore<>(); + } + + /** + * Try adding duplicate elements, they should be ignored + */ + @Test + public void testNoDuplicateElements() { + for (ISegment segment : SEGMENTS) { + boolean ret = fSegmentStore.add(new BasicSegment(segment.getStart(), segment.getEnd())); + assertFalse(ret); + } + assertEquals(SEGMENTS.size(), fSegmentStore.size()); + } +} \ No newline at end of file diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/treemap/TreeMapStoreTest.java b/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/treemap/TreeMapStoreTest.java deleted file mode 100644 index 3acf3ad111..0000000000 --- a/statesystem/org.eclipse.tracecompass.segmentstore.core.tests/src/org/eclipse/tracecompass/segmentstore/core/tests/treemap/TreeMapStoreTest.java +++ /dev/null @@ -1,300 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Ericsson - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - *******************************************************************************/ - -package org.eclipse.tracecompass.segmentstore.core.tests.treemap; - -import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.tracecompass.segmentstore.core.BasicSegment; -import org.eclipse.tracecompass.segmentstore.core.ISegment; -import org.eclipse.tracecompass.segmentstore.core.treemap.TreeMapStore; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; - -/** - * Unit tests for intersecting elements in a TreeMapStore - * - * @author France Lapointe Nguyen - */ -public class TreeMapStoreTest { - - private TreeMapStore<@NonNull ISegment> fSegmentStore; - - private static final @NonNull ISegment SEGMENT_2_6 = new BasicSegment(2, 6); - private static final @NonNull ISegment SEGMENT_4_6 = new BasicSegment(4, 6); - private static final @NonNull ISegment SEGMENT_4_8 = new BasicSegment(4, 8); - private static final @NonNull ISegment SEGMENT_6_8 = new BasicSegment(6, 8); - private static final @NonNull ISegment SEGMENT_10_14 = new BasicSegment(10, 14); - - private static final List SEGMENTS = ImmutableList.of(SEGMENT_2_6, SEGMENT_4_6, SEGMENT_4_8, SEGMENT_6_8, SEGMENT_10_14); - private static final List REVERSE_SEGMENTS = Lists.reverse(SEGMENTS); - - /** - * Initialize data (test vector) that will be tested - */ - @Before - public void setup() { - fSegmentStore = new TreeMapStore<>(); - for (ISegment segment : SEGMENTS) { - fSegmentStore.add(checkNotNull(segment)); - } - } - - /** - * Dispose of the segment store - */ - @After - public void teardown() { - fSegmentStore.dispose(); - } - - /** - * Testing method size() - */ - @Test - public void testSize() { - assertEquals(SEGMENTS.size(), fSegmentStore.size()); - } - - /** - * Test the contains() method. - */ - @Test - public void testContains() { - ISegment otherSegment = new BasicSegment(0, 20); - - assertTrue(fSegmentStore.contains(SEGMENT_2_6)); - assertTrue(fSegmentStore.contains(SEGMENT_4_8)); - assertFalse(fSegmentStore.contains(otherSegment)); - } - - /** - * Test the toArray() method. - */ - @Test - public void testToObjectArray() { - Object[] array = fSegmentStore.toArray(); - - assertEquals(SEGMENTS.size(), array.length); - assertTrue(Arrays.asList(array).containsAll(SEGMENTS)); - } - - /** - * Test the toArray(T[]) method. - */ - @Test - public void testToSpecificArray() { - ISegment[] array = fSegmentStore.toArray(new ISegment[0]); - - assertEquals(SEGMENTS.size(), array.length); - assertTrue(Arrays.asList(array).containsAll(SEGMENTS)); - } - - /** - * Test the toArray(T[]) method with a subtype of ISegment. - */ - @Test - public void testToSpecifyArraySubtype() { - TreeMapStore<@NonNull BasicSegment> tms2 = new TreeMapStore<>(); - BasicSegment otherSegment = new BasicSegment(2, 6); - tms2.add(otherSegment); - BasicSegment[] array = tms2.toArray(new BasicSegment[0]); - - assertEquals(1, array.length); - assertTrue(Arrays.asList(array).contains(otherSegment)); - - tms2.dispose(); - } - - /** - * Try adding duplicate elements, they should be ignored - */ - @Test - public void testNoDuplicateElements() { - for (ISegment segment : SEGMENTS) { - boolean ret = fSegmentStore.add(new BasicSegment(segment.getStart(), segment.getEnd())); - assertFalse(ret); - } - assertEquals(SEGMENTS.size(), fSegmentStore.size()); - } - - /** - * Test the iteration order of the complete segment store. - */ - @Test - public void testIterationOrder() { - int i = 0; - for (ISegment segment : fSegmentStore) { - assertEquals(SEGMENTS.get(i++), segment); - } - } - - /** - * Test the iteration order when the elements are not inserted in sorted - * order. - */ - @Test - public void testIterationOrderNonSortedInsertion() { - /* Prepare the segment store, we don't use the 'fixture' in this test */ - TreeMapStore<@NonNull ISegment> store = new TreeMapStore<>(); - for (ISegment segment : REVERSE_SEGMENTS) { - store.add(checkNotNull(segment)); - } - - /* - * Test each element one by one, the iteration order should follow the - * start times, not the insertion order. - */ - int i = 0; - for (ISegment segment : store) { - assertEquals(SEGMENTS.get(i++), segment); - } - - /* Manually dispose our own store */ - store.dispose(); - } - - /** - * Testing method getIntersectingElements(long start, long end) - */ - @Test - public void testGetIntersectingElementsRange() { - - Iterable intersectingElements; - - /* - * Range that does not include any segment - */ - intersectingElements = fSegmentStore.getIntersectingElements(16, 20); - assertEquals(0, Iterables.size(intersectingElements)); - - /* - * Range start time : Before first segment start time - * Range end time : After last segment end time - */ - intersectingElements = fSegmentStore.getIntersectingElements(1, 15); - assertEquals(5, Iterables.size(intersectingElements)); - - /* - * Range start time : On first segment start time - * Range end time : On last segment end time - */ - intersectingElements = fSegmentStore.getIntersectingElements(2, 14); - assertEquals(5, Iterables.size(intersectingElements)); - - /* - * Range start time : After one segment start time - * Range end time : Before one segment end time - */ - intersectingElements = fSegmentStore.getIntersectingElements(11, 13); - assertEquals(1, Iterables.size(intersectingElements)); - assertEquals(SEGMENT_10_14, Iterables.getOnlyElement(intersectingElements)); - - /* - * Range start time : On one segment start time - * Range end time : On one segment end time - */ - intersectingElements = fSegmentStore.getIntersectingElements(10, 14); - assertEquals(1, Iterables.size(intersectingElements)); - assertEquals(SEGMENT_10_14, Iterables.getOnlyElement(intersectingElements)); - - /* - * Range start time : On last segment end time - * Range end time : After last segment end time - */ - intersectingElements = fSegmentStore.getIntersectingElements(14, 18); - assertEquals(1, Iterables.size(intersectingElements)); - assertEquals(SEGMENT_10_14, Iterables.getOnlyElement(intersectingElements)); - - /* - * Range start time : Before first segment start time - * Range end time : On first segment start time - */ - intersectingElements = fSegmentStore.getIntersectingElements(1, 2); - assertEquals(1, Iterables.size(intersectingElements)); - assertEquals(SEGMENT_2_6, Iterables.getOnlyElement(intersectingElements)); - } - - /** - * Testing method getIntersectingElements(long start, long end) - */ - @Test - public void testGetIntersectingElementsTime() { - - Iterable intersectingElements; - - /* - * Time between segment start time and end time - */ - intersectingElements = fSegmentStore.getIntersectingElements(3); - assertEquals(1, Iterables.size(intersectingElements)); - assertEquals(SEGMENT_2_6, Iterables.getOnlyElement(intersectingElements)); - - /* - * Time on segment start time - */ - intersectingElements = fSegmentStore.getIntersectingElements(2); - assertEquals(1, Iterables.size(intersectingElements)); - assertEquals(SEGMENT_2_6, Iterables.getOnlyElement(intersectingElements)); - - /* - * Time on segment end time - */ - intersectingElements = fSegmentStore.getIntersectingElements(14); - assertEquals(1, Iterables.size(intersectingElements)); - assertEquals(SEGMENT_10_14, Iterables.getOnlyElement(intersectingElements)); - - /* - * Time overlapping many segments - */ - intersectingElements = fSegmentStore.getIntersectingElements(6); - assertEquals(4, Iterables.size(intersectingElements)); - - /* - * Time between segments - */ - intersectingElements = fSegmentStore.getIntersectingElements(9); - assertEquals(0, Iterables.size(intersectingElements)); - - /* - * Time before all segment start time - */ - intersectingElements = fSegmentStore.getIntersectingElements(1); - assertEquals(0, Iterables.size(intersectingElements)); - - /* - * Time after all segment end time - */ - intersectingElements = fSegmentStore.getIntersectingElements(15); - assertEquals(0, Iterables.size(intersectingElements)); - } - - /** - * Testing method getIntersectingElements(long start, long end) - */ - @Test - public void testDispose() { - TreeMapStore<@NonNull ISegment> store = new TreeMapStore<>(); - store.add(SEGMENT_2_6); - store.dispose(); - assertEquals(0, store.size()); - } -} \ No newline at end of file diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core/META-INF/MANIFEST.MF b/statesystem/org.eclipse.tracecompass.segmentstore.core/META-INF/MANIFEST.MF index 4235bc92de..986869cdc6 100644 --- a/statesystem/org.eclipse.tracecompass.segmentstore.core/META-INF/MANIFEST.MF +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-Vendor: %Bundle-Vendor -Bundle-Version: 1.0.0.qualifier +Bundle-Version: 1.1.0.qualifier Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.segmentstore.core;singleton:=true Bundle-Activator: org.eclipse.tracecompass.internal.segmentstore.core.Activator @@ -12,6 +12,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, org.eclipse.tracecompass.common.core Export-Package: org.eclipse.tracecompass.internal.segmentstore.core;x-internal:=true, + org.eclipse.tracecompass.internal.segmentstore.core.arraylist;x-friends:="org.eclipse.tracecompass.segmentstore.core.tests", + org.eclipse.tracecompass.internal.segmentstore.core.treemap;x-friends:="org.eclipse.tracecompass.segmentstore.core.tests", org.eclipse.tracecompass.segmentstore.core, org.eclipse.tracecompass.segmentstore.core.treemap Import-Package: com.google.common.collect;version="12.0.0" diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/store/ArrayListStore.java b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist/ArrayListStore.java similarity index 95% rename from analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/store/ArrayListStore.java rename to statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist/ArrayListStore.java index 2efda3b376..6af292cc97 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/store/ArrayListStore.java +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist/ArrayListStore.java @@ -7,7 +7,7 @@ * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ -package org.eclipse.tracecompass.internal.analysis.timing.core.store; +package org.eclipse.tracecompass.internal.segmentstore.core.arraylist; import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; @@ -26,8 +26,10 @@ import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.segmentstore.core.BasicSegment; import org.eclipse.tracecompass.segmentstore.core.ISegment; import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; +import org.eclipse.tracecompass.segmentstore.core.SegmentComparators; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Ordering; /** * Implementation of an {@link ISegmentStore} using one in-memory @@ -53,13 +55,8 @@ import com.google.common.collect.ImmutableList; */ public class ArrayListStore<@NonNull E extends ISegment> implements ISegmentStore { - private final Comparator COMPARATOR = (o1, o2) -> { - int ret = Long.compare(o1.getStart(), o2.getStart()); - if (ret == 0) { - return Long.compare(o1.getEnd(), o2.getEnd()); - } - return ret; - }; + private final Comparator COMPARATOR = Ordering.from(SegmentComparators.INTERVAL_START_COMPARATOR) + .compound(SegmentComparators.INTERVAL_END_COMPARATOR); private final ReadWriteLock fLock = new ReentrantReadWriteLock(false); diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/store/LazyArrayListStore.java b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist/LazyArrayListStore.java similarity index 95% rename from analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/store/LazyArrayListStore.java rename to statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist/LazyArrayListStore.java index cbe47fe244..d6e6ea3969 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/store/LazyArrayListStore.java +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist/LazyArrayListStore.java @@ -7,7 +7,7 @@ * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ -package org.eclipse.tracecompass.internal.analysis.timing.core.store; +package org.eclipse.tracecompass.internal.segmentstore.core.arraylist; import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; @@ -25,8 +25,10 @@ import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.segmentstore.core.BasicSegment; import org.eclipse.tracecompass.segmentstore.core.ISegment; import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; +import org.eclipse.tracecompass.segmentstore.core.SegmentComparators; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Ordering; /** * Implementation of an {@link ISegmentStore} using one in-memory @@ -56,17 +58,12 @@ public class LazyArrayListStore<@NonNull E extends ISegment> implements ISegment private static final String ERROR_MESSAGE = "Cannot remove from a segment store"; //$NON-NLS-1$ - private final Comparator COMPARATOR = (o1, o2) -> { - int ret = Long.compare(o1.getStart(), o2.getStart()); - if (ret == 0) { - return Long.compare(o1.getEnd(), o2.getEnd()); - } - return ret; - }; + private final Comparator COMPARATOR = Ordering.from(SegmentComparators.INTERVAL_START_COMPARATOR) + .compound(SegmentComparators.INTERVAL_END_COMPARATOR); private final ReentrantLock fLock = new ReentrantLock(false); - private final @NonNull List fStore = new ArrayList<>(); + private final List fStore = new ArrayList<>(); private @Nullable transient Iterable fLastSnapshot = null; diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist/package-info.java b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist/package-info.java new file mode 100644 index 0000000000..75d881be97 --- /dev/null +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/arraylist/package-info.java @@ -0,0 +1,11 @@ +/******************************************************************************* + * Copyright (c) 2016 Polytechnique + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.segmentstore.core.arraylist; diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/treemap/TreeMapStore.java b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/treemap/TreeMapStore.java new file mode 100644 index 0000000000..cd1882e6bd --- /dev/null +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/treemap/TreeMapStore.java @@ -0,0 +1,273 @@ +/******************************************************************************* + * Copyright (c) 2015 EfficiOS Inc., Alexandre Montplaisir and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.segmentstore.core.treemap; + +import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; + +import java.util.Collection; +import java.util.Iterator; +import java.util.TreeMap; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.segmentstore.core.ISegment; +import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; +import org.eclipse.tracecompass.segmentstore.core.SegmentComparators; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Ordering; +import com.google.common.collect.Sets; +import com.google.common.collect.TreeMultimap; + +/** + * Implementation of a {@link ISegmentStore} using in-memory {@link TreeMap}'s. + * This relatively simple implementation holds everything in memory, and as such + * cannot contain too much data. + * + * The TreeMapStore itself is Iterable, and its iteration order will be by + * ascending order of start times. For segments with identical start times, the + * secondary comparator will be the end time. If even those are equal, it will + * defer to the segments' natural ordering ({@link ISegment#compareTo}). + * + * The store's tree maps will not accept duplicate key-value pairs, which means + * that if you want several segments with the same start and end times, make + * sure their compareTo() differentiates them. + * + * Removal operations are not supported. + * + * @param + * The type of segment held in this store + * + * @author Alexandre Montplaisir + */ +public class TreeMapStore<@NonNull E extends ISegment> implements ISegmentStore { + + private final ReadWriteLock fLock = new ReentrantReadWriteLock(false); + + private final TreeMultimap fStartTimesIndex; + private final TreeMultimap fEndTimesIndex; + + private volatile long fSize; + + private @Nullable transient Iterable fLastSnapshot = null; + + /** + * Constructor + */ + public TreeMapStore() { + /* + * For the start times index, the "key comparator" will compare the + * start times as longs directly. This is the primary comparator for its + * tree map. + * + * The secondary "value" comparator will check the end times first, and + * in the event of a tie, defer to the ISegment's Comparable + * implementation, a.k.a. its natural ordering. + * + * The same is done for the end times index, but swapping the first two + * comparators instead. + */ + fStartTimesIndex = TreeMultimap.create( + SegmentComparators.LONG_COMPARATOR, + Ordering.from(SegmentComparators.INTERVAL_END_COMPARATOR).compound(Ordering.natural())); + + fEndTimesIndex = TreeMultimap.create( + SegmentComparators.LONG_COMPARATOR, + Ordering.from(SegmentComparators.INTERVAL_START_COMPARATOR).compound(Ordering.natural())); + + fSize = 0; + } + + // ------------------------------------------------------------------------ + // Methods from Collection + // ------------------------------------------------------------------------ + + @Override + public Iterator iterator() { + fLock.readLock().lock(); + try { + Iterable lastSnapshot = fLastSnapshot; + if (lastSnapshot == null) { + lastSnapshot = ImmutableList.copyOf(fStartTimesIndex.values()); + fLastSnapshot = lastSnapshot; + } + return checkNotNull(lastSnapshot.iterator()); + } finally { + fLock.readLock().unlock(); + } + } + + @Override + public boolean add(@Nullable E val) { + if (val == null) { + throw new IllegalArgumentException(); + } + + fLock.writeLock().lock(); + try { + if (fStartTimesIndex.put(Long.valueOf(val.getStart()), val)) { + fEndTimesIndex.put(Long.valueOf(val.getEnd()), val); + fSize++; + fLastSnapshot = null; + return true; + } + return false; + } finally { + fLock.writeLock().unlock(); + } + } + + @Override + public int size() { + return Long.valueOf(fSize).intValue(); + } + + @Override + public boolean isEmpty() { + return (fSize == 0); + } + + @Override + public boolean contains(@Nullable Object o) { + fLock.readLock().lock(); + try { + return fStartTimesIndex.containsValue(o); + } finally { + fLock.readLock().unlock(); + } + } + + @Override + public boolean containsAll(@Nullable Collection c) { + fLock.readLock().lock(); + try { + return fStartTimesIndex.values().containsAll(c); + } finally { + fLock.readLock().unlock(); + } + } + + @Override + public Object[] toArray() { + fLock.readLock().lock(); + try { + return fStartTimesIndex.values().toArray(); + } finally { + fLock.readLock().unlock(); + } + } + + @Override + public T[] toArray(T[] a) { + fLock.readLock().lock(); + try { + return fStartTimesIndex.values().toArray(a); + } finally { + fLock.readLock().unlock(); + } + } + + @Override + public boolean remove(@Nullable Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(@Nullable Collection c) { + if (c == null) { + throw new IllegalArgumentException(); + } + + fLock.writeLock().lock(); + try { + boolean changed = false; + for (E elem : c) { + if (this.add(elem)) { + changed = true; + } + } + return changed; + } finally { + fLock.writeLock().unlock(); + } + } + + @Override + public boolean removeAll(@Nullable Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(@Nullable Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + fLock.writeLock().lock(); + try { + fSize = 0; + fEndTimesIndex.clear(); + fStartTimesIndex.clear(); + } finally { + fLock.writeLock().unlock(); + } + } + + // ------------------------------------------------------------------------ + // Methods added by ISegmentStore + // ------------------------------------------------------------------------ + + @Override + public Iterable getIntersectingElements(long position) { + /* + * The intervals intersecting 't' are those whose 1) start time is + * *lower* than 't' AND 2) end time is *higher* than 't'. + */ + fLock.readLock().lock(); + try { + Iterable matchStarts = Iterables.concat(fStartTimesIndex.asMap().headMap(position, true).values()); + Iterable matchEnds = Iterables.concat(fEndTimesIndex.asMap().tailMap(position, true).values()); + return checkNotNull(Sets.intersection(Sets.newHashSet(matchStarts), Sets.newHashSet(matchEnds))); + } finally { + fLock.readLock().unlock(); + } + } + + @Override + public Iterable getIntersectingElements(long start, long end) { + fLock.readLock().lock(); + try { + Iterable matchStarts = Iterables.concat(fStartTimesIndex.asMap().headMap(end, true).values()); + Iterable matchEnds = Iterables.concat(fEndTimesIndex.asMap().tailMap(start, true).values()); + return checkNotNull(Sets.intersection(Sets.newHashSet(matchStarts), Sets.newHashSet(matchEnds))); + } finally { + fLock.readLock().unlock(); + } + } + + @Override + public void dispose() { + fLock.writeLock().lock(); + try { + fStartTimesIndex.clear(); + fEndTimesIndex.clear(); + fSize = 0; + } finally { + fLock.writeLock().unlock(); + } + } +} diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/treemap/package-info.java b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/treemap/package-info.java new file mode 100644 index 0000000000..d1da709ba5 --- /dev/null +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/internal/segmentstore/core/treemap/package-info.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2015 EfficiOS Inc. and others + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +@org.eclipse.jdt.annotation.NonNullByDefault +package org.eclipse.tracecompass.internal.segmentstore.core.treemap; diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/SegmentStoreFactory.java b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/SegmentStoreFactory.java new file mode 100644 index 0000000000..fe9d40fed1 --- /dev/null +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/SegmentStoreFactory.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2016 Polytechnique + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Loïc Prieur-Drevon - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.tracecompass.segmentstore.core; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.internal.segmentstore.core.arraylist.ArrayListStore; +import org.eclipse.tracecompass.internal.segmentstore.core.arraylist.LazyArrayListStore; +import org.eclipse.tracecompass.internal.segmentstore.core.treemap.TreeMapStore; + +/** + * Factory to create Segment Stores. + * + * Since segment stores are meant to be accessed using the {@link ISegmentStore} + * interface, you can use this factory to instantiate new ones. + * + * @author Loïc Prieur-Drevon + * @param + * The type of segment held in this store + * @since 1.1 + */ +public final class SegmentStoreFactory { + /** + * Flags to determine the type of SegmentStore to use. + */ + public enum SegmentStoreType { + /** + * Segment Store should be as fast as possible to build and read. + * Performance of individual operations may be slower, but overall the + * speed should be faster. + */ + Fast, + /** + * Segment Store based should have predictable performance. This does + * not mean it's faster, it should not give a surprise random slow down + * though. If it slows down, it will be on the {@link ISegment} that + * slows it down. + */ + Stable, + /** + * Segment Store should contain no duplicate segments + */ + Distinct + } + + private SegmentStoreFactory() { + // Do nothing + } + + /** + * New SegmentStore factory method + * + * @param segmentTypes + * Flags used to determine the type of Segment Store that will be + * created + * + * @return a new {@link ISegmentStore} + */ + public static ISegmentStore createSegmentStore(@Nullable SegmentStoreType... segmentTypes) { + Set<@NonNull SegmentStoreType> segments = getListOfFlags(segmentTypes); + if (segments.contains(SegmentStoreType.Distinct)) { + return createTreeMapStore(); + } + if (segments.contains(SegmentStoreType.Stable)) { + return createArrayListStore(); + } + // default option is the fastest + return createLazyArrayListStore(); + + } + + /** + * New SegmentStore factory method to create store from an array of Objects + * + * @param segmentTypes + * Flags used to determine the type of Segment Store that will be + * created + * @param array + * the {@link Object} array we want the returned segment store to + * contain, {@link Object} are only inserted if they extend + * {@link ISegment} + * @return an {@link ISegmentStore} containing the {@link ISegment}s from + * array. + */ + public static ISegmentStore createSegmentStore(Object[] array, SegmentStoreType... segmentTypes) { + Set<@NonNull SegmentStoreType> segments = getListOfFlags(segmentTypes); + if (segments.contains(SegmentStoreType.Distinct)) { + ISegmentStore store = createTreeMapStore(); + for (Object elem : array) { + if (elem instanceof ISegment) { + store.add((E) elem); // warning from type, it should be fine + } + } + return store; + } + if (segments.contains(SegmentStoreType.Stable)) { + return new ArrayListStore<>(array); + } + // default option is the fastest + return new LazyArrayListStore<>(array); + } + + private static Set<@NonNull SegmentStoreType> getListOfFlags(SegmentStoreType... segmentTypes) { + Set<@NonNull SegmentStoreType> segments = new HashSet<>(); + for(@Nullable SegmentStoreType segmentType : segmentTypes ) { + if(segmentType != null) { + segments.add(segmentType); + } + } + return segments; + } + + /** + * New {@link TreeMapStore} factory method + * + * @return the new Segment Store + */ + private static ISegmentStore createTreeMapStore() { + return new TreeMapStore<>(); + } + + /** + * New {@link ArrayListStore} factory method + * + * @return the new Segment Store + */ + private static ISegmentStore createArrayListStore() { + return new ArrayListStore<>(); + } + + /** + * New {@link LazyArrayListStore} factory method + * + * @return the new Segment Store + */ + private static ISegmentStore createLazyArrayListStore() { + return new LazyArrayListStore<>(); + } + +} diff --git a/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/treemap/TreeMapStore.java b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/treemap/TreeMapStore.java index 452862ff8b..ac301dd8ba 100644 --- a/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/treemap/TreeMapStore.java +++ b/statesystem/org.eclipse.tracecompass.segmentstore.core/src/org/eclipse/tracecompass/segmentstore/core/treemap/TreeMapStore.java @@ -25,6 +25,7 @@ import org.eclipse.jdt.annotation.Nullable; 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.segmentstore.core.SegmentStoreFactory; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -52,7 +53,9 @@ import com.google.common.collect.TreeMultimap; * The type of segment held in this store * * @author Alexandre Montplaisir + * @deprecated Use the {@link SegmentStoreFactory} to create a new segment store */ +@Deprecated public class TreeMapStore<@NonNull E extends ISegment> implements ISegmentStore { private final ReadWriteLock fLock = new ReentrantReadWriteLock(false); diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternSegmentStoreModule.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternSegmentStoreModule.java index c3654f9308..7bc836732b 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternSegmentStoreModule.java +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternSegmentStoreModule.java @@ -19,9 +19,9 @@ import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.analysis.timing.core.segmentstore.AbstractSegmentStoreAnalysisModule; import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener; -import org.eclipse.tracecompass.internal.analysis.timing.core.store.ArrayListStore; import org.eclipse.tracecompass.segmentstore.core.ISegment; import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; +import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory; import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; @@ -38,7 +38,7 @@ public class XmlPatternSegmentStoreModule extends AbstractSegmentStoreAnalysisMo * Fake segment indicated that the last segment have been received */ public static final @NonNull EndSegment END_SEGMENT = new EndSegment(); - private final ISegmentStore<@NonNull ISegment> fSegments = new ArrayListStore<>(); + private final ISegmentStore<@NonNull ISegment> fSegments = SegmentStoreFactory.createSegmentStore(); private final CountDownLatch fFinished = new CountDownLatch(1); private final @NonNull XmlPatternAnalysis fParent; private boolean fSegmentStoreCompleted; -- 2.34.1