Bundle-Activator: org.eclipse.tracecompass.internal.datastore.core.Activator
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
+Eclipse-ExtensibleAPI: true
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.tracecompass.common.core
Export-Package: org.eclipse.tracecompass.internal.datastore.core;x-internal:=true,
org.eclipse.tracecompass.internal.datastore.core.condition;x-internal:=true,
org.eclipse.tracecompass.internal.datastore.core.historytree;x-internal:=true,
org.eclipse.tracecompass.internal.datastore.core.serialization;x-internal:=true,
- org.eclipse.tracecompass.internal.provisional.datastore.core.condition;
- x-friends:="org.eclipse.tracecompass.segmentstore.core,
- org.eclipse.tracecompass.segmentstore.core.tests",
+ org.eclipse.tracecompass.internal.provisional.datastore.core.condition;x-friends:="org.eclipse.tracecompass.segmentstore.core,org.eclipse.tracecompass.segmentstore.core.tests",
org.eclipse.tracecompass.internal.provisional.datastore.core.exceptions,
- org.eclipse.tracecompass.internal.provisional.datastore.core.historytree;
- x-friends:="org.eclipse.tracecompass.segmentstore.core,
- org.eclipse.tracecompass.segmentstore.core.tests",
+ org.eclipse.tracecompass.internal.provisional.datastore.core.historytree;x-friends:="org.eclipse.tracecompass.segmentstore.core,org.eclipse.tracecompass.segmentstore.core.tests",
org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.classic;x-friends:="org.eclipse.tracecompass.statesystem.core,org.eclipse.tracecompass.statesystem.core.tests",
- org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.overlapping;
- x-friends:="org.eclipse.tracecompass.segmentstore.core,
- org.eclipse.tracecompass.segmentstore.core.tests",
- org.eclipse.tracecompass.internal.provisional.datastore.core.interval;
- x-friends:="org.eclipse.tracecompass.segmentstore.core,
- org.eclipse.tracecompass.segmentstore.core.tests",
+ org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.overlapping;x-friends:="org.eclipse.tracecompass.segmentstore.core,org.eclipse.tracecompass.segmentstore.core.tests",
+ org.eclipse.tracecompass.internal.provisional.datastore.core.interval;x-friends:="org.eclipse.tracecompass.segmentstore.core,org.eclipse.tracecompass.segmentstore.core.tests",
org.eclipse.tracecompass.internal.provisional.datastore.core.serialization;
x-friends:="org.eclipse.tracecompass.statesystem.core,
org.eclipse.tracecompass.statesystem.core.tests,
* @return The immutable latest branch
*/
@VisibleForTesting
- final List<N> getLatestBranch() {
+ protected final List<N> getLatestBranch() {
List<N> latestBranchSnapshot = fLatestBranchSnapshot;
if (latestBranchSnapshot == null) {
synchronized (fLatestBranch) {
* closed
*/
@VisibleForTesting
- @NonNull N getNode(int seqNum) throws ClosedChannelException {
+ protected @NonNull N getNode(int seqNum) throws ClosedChannelException {
// First, check in the latest branch if the node is there
for (N node : fLatestBranch) {
if (node.getSequenceNumber() == seqNum) {
* @return The child start value
*/
@VisibleForTesting
- long getChildStart(int index) {
+ protected long getChildStart(int index) {
OverlappingExtraData extraData = getCoreNodeData();
if (extraData != null) {
return extraData.getChildStart(index);
* @return The child end value
*/
@VisibleForTesting
- long getChildEnd(int index) {
+ protected long getChildEnd(int index) {
OverlappingExtraData extraData = getCoreNodeData();
if (extraData != null) {
return extraData.getChildEnd(index);
</classpathentry>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="perf"/>
+ <classpathentry kind="src" path="stubs"/>
<classpathentry kind="output" path="bin"/>
</classpath>
org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.tracecompass.common.core,
- org.eclipse.tracecompass.segmentstore.core
+ org.eclipse.tracecompass.segmentstore.core,
+ org.eclipse.tracecompass.datastore.core
+Export-Package: org.eclipse.tracecompass.analysis.timing.core.tests.store,
+ org.eclipse.tracecompass.segmentstore.core.tests,
+ org.eclipse.tracecompass.segmentstore.core.tests.historytree,
+ org.eclipse.tracecompass.segmentstore.core.tests.htStore;x-internal:=true,
+ org.eclipse.tracecompass.segmentstore.core.tests.interfaces
Import-Package: com.google.common.collect,
+ org.apache.commons.io,
org.eclipse.test.performance
###############################################################################
source.. = src/,\
- perf/
+ perf/,\
+ stubs/
output.. = bin/
bin.includes = META-INF/,\
.,\
about.html
src.includes = about.html
additional.bundles = org.eclipse.jdt.annotation
-jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation
+jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation,\
+ platform:/plugin/org.eclipse.tracecompass.datastore.core.tests
import static org.junit.Assert.assertEquals;
+import java.io.IOException;
+import java.nio.file.Files;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Random;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.test.performance.Performance;
import org.eclipse.test.performance.PerformanceMeter;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
+import org.eclipse.tracecompass.internal.provisional.segmentstore.core.BasicSegment2;
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.SegmentComparators;
+import org.eclipse.tracecompass.segmentstore.core.tests.historytree.HistoryTreeSegmentStoreStub;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(Parameterized.class)
+@NonNullByDefault
public class SegmentStoreBenchmark {
private static final int DEFAULT_SAMPLE = 1000;
private static final int DEFAULT_LOOP_COUNT = 10;
- private final ISegmentStore<@NonNull ISegment> fSegStore;
+ private final ISegmentStore<@NonNull BasicSegment2> fSegStore;
private final String fName;
private final Performance fPerf;
/**
* @return The arrays of parameters
+ * @throws IOException
+ * Exceptions thrown when setting the on-disk backends
*/
@Parameters(name = "{index}: {0}")
- public static Iterable<Object[]> getParameters() {
+ public static Iterable<Object[]> getParameters() throws IOException {
return Arrays.asList(new Object[][] {
{ "Array list store", new ArrayListStore<>() },
{ "Lazy array list store", new LazyArrayListStore<>() },
{ "Treemap store", new TreeMapStore<>() },
+ { "HT store", new HistoryTreeSegmentStoreStub<>(NonNullUtils.checkNotNull(Files.createTempFile("tmpSegStore", null)), 0, BasicSegment2.BASIC_SEGMENT_READ_FACTORY) },
});
}
* @param segStore
* The segment store to fill for the benchmarks
*/
- public SegmentStoreBenchmark(String name, ISegmentStore<@NonNull ISegment> segStore) {
+ public SegmentStoreBenchmark(String name, ISegmentStore<@NonNull BasicSegment2> segStore) {
fSegStore = segStore;
fName = name;
- fPerf = Performance.getDefault();
+ fPerf = NonNullUtils.checkNotNull(Performance.getDefault());
}
/**
pMiterate2.commit();
}
- private static int iterate(Iterable<@NonNull ISegment> store) {
+ private static int iterate(Iterable<@NonNull BasicSegment2> store) {
int count = 0;
- Iterator<@NonNull ISegment> iterator = store.iterator();
+ Iterator<@NonNull BasicSegment2> iterator = store.iterator();
while (iterator.hasNext()) {
count++;
iterator.next();
return count;
}
- private static int sortedIterate(ISegmentStore<@NonNull ISegment> store, @NonNull Comparator<@NonNull ISegment> order) {
- Iterable<@NonNull ISegment> iterable = store.iterator(order);
+ private static int sortedIterate(ISegmentStore<@NonNull BasicSegment2> store, Comparator<ISegment> order) {
+ Iterable<@NonNull BasicSegment2> iterable = store.iterator(order);
return iterate(iterable);
}
- private static void populate(int size, int[] fuzz, ISegmentStore<@NonNull ISegment> store, long low, long high) {
+ private static void populate(int size, int[] fuzz, ISegmentStore<@NonNull BasicSegment2> store, long low, long high) {
for (long i = low; i < high; i++) {
long start = i + fuzz[(int) (i % size)];
- store.add(new BasicSegment(start, start + 10));
+ store.add(new BasicSegment2(start, start + 10));
}
}
}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * 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.analysis.timing.core.tests.store;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Arrays;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.tracecompass.internal.provisional.segmentstore.core.BasicSegment2;
+import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+import org.eclipse.tracecompass.segmentstore.core.tests.historytree.HistoryTreeSegmentStoreStub;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Benchmark the segment store with datasets that are too big to fit in memory
+ *
+ * @author Geneviève Bastien
+ */
+@NonNullByDefault
+public class SegmentStoreBigBenchmark extends SegmentStoreBenchmark {
+
+ /**
+ * Constructor
+ *
+ * @param name
+ * name of the benchmark
+ * @param segStore
+ * The segment store to use
+ */
+ public SegmentStoreBigBenchmark(String name, ISegmentStore<@NonNull BasicSegment2> segStore) {
+ super(name, segStore);
+ }
+
+ /**
+ * @return The arrays of parameters
+ * @throws IOException
+ * Exceptions thrown when setting the on-disk backends
+ */
+ @Parameters(name = "{index}: {0}")
+ public static Iterable<Object[]> getParameters() throws IOException {
+ return Arrays.asList(new Object[][] {
+ { "HT store", new HistoryTreeSegmentStoreStub<>(Files.createTempFile("tmpSegStore", null), 1, BasicSegment2.BASIC_SEGMENT_READ_FACTORY) },
+ });
+ }
+
+ @Override
+ protected long getSegmentStoreSize() {
+ return 100000000;
+ }
+}
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.common.core.NonNullUtils;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTIntervalReader;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.serialization.ISafeByteBufferWriter;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.serialization.SafeByteBufferFactory;
+import org.eclipse.tracecompass.internal.provisional.segmentstore.core.ISegment2;
import org.eclipse.tracecompass.segmentstore.core.BasicSegment;
import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
/**
* The segment store
*/
- protected ISegmentStore<@NonNull ISegment> fSegmentStore;
+ protected final ISegmentStore<@NonNull TestSegment> fSegmentStore;
/**
* Get the segment store to test
*
* @return the segment store
*/
- protected abstract ISegmentStore<@NonNull ISegment> getSegmentStore();
+ protected abstract ISegmentStore<@NonNull TestSegment> getSegmentStore();
/**
* Get the segment store to test with initial data
*
* @return the segment store
*/
- protected abstract ISegmentStore<@NonNull ISegment> getSegmentStore(@NonNull ISegment @NonNull [] data);
+ protected abstract ISegmentStore<@NonNull TestSegment> getSegmentStore(@NonNull TestSegment @NonNull [] data);
- 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 @NonNull TestSegment SEGMENT_2_6 = new TestSegment(2, 6, "test");
+ private static final @NonNull TestSegment SEGMENT_4_6 = new TestSegment(4, 6, "test2");
+ private static final @NonNull TestSegment SEGMENT_4_8 = new TestSegment(4, 8, "test3");
+ private static final @NonNull TestSegment SEGMENT_6_8 = new TestSegment(6, 8, "test");
+ private static final @NonNull TestSegment SEGMENT_10_14 = new TestSegment(10, 14, "test");
/**
* 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);
+ protected static final List<@NonNull TestSegment> SEGMENTS = ImmutableList.of(SEGMENT_2_6, SEGMENT_4_6, SEGMENT_4_8, SEGMENT_6_8, SEGMENT_10_14);
+ private static final List<@NonNull TestSegment> REVERSE_SEGMENTS = Lists.reverse(SEGMENTS);
+
+ /**
+ * A test type of segment that can be serialized with the safe buffers. It
+ * has an extra payload
+ *
+ * @author Geneviève Bastien
+ */
+ protected static final class TestSegment implements ISegment2 {
+
+ /**
+ * The reader for this class
+ */
+ public static final @NonNull IHTIntervalReader<@NonNull TestSegment> DESERIALISER = buffer -> new TestSegment(buffer.getLong(), buffer.getLong(), buffer.getString());
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2242452053089575887L;
+
+ private final long fStart;
+ private final long fEnd;
+ private final @NonNull String fPayload;
+
+ /**
+ * Constructor
+ *
+ * @param start
+ * Start of this segment
+ * @param end
+ * End of this segment
+ * @param payload
+ * Payload
+ */
+ public TestSegment(long start, long end, @NonNull String payload) {
+ fStart = start;
+ fEnd = end;
+ fPayload = payload;
+ }
+
+ @Override
+ public long getStart() {
+ return fStart;
+ }
+
+ @Override
+ public long getEnd() {
+ return fEnd;
+ }
+
+ /**
+ * Get the payload of this segment
+ *
+ * @return The payload
+ */
+ public String getPayload() {
+ return fPayload;
+ }
+
+ @Override
+ public int getSizeOnDisk() {
+ return 2 * Long.BYTES + SafeByteBufferFactory.getStringSizeInBuffer(fPayload);
+ }
+
+ @Override
+ public void writeSegment(@NonNull ISafeByteBufferWriter buffer) {
+ buffer.putLong(fStart);
+ buffer.putLong(fEnd);
+ buffer.putString(fPayload);
+ }
+
+ }
/**
* Constructor
*/
public AbstractTestSegmentStore() {
super();
+ fSegmentStore = getSegmentStore();
+ }
+
+ /**
+ * Asserts that 2 segments are equal. Some backend may not return exactly
+ * the same type of segment so the main assert will be false, but the
+ * segments are in fact identical
+ *
+ * @param expected
+ * The expected segment
+ * @param actual
+ * The actual segment
+ */
+ protected void assertSegmentsEqual(ISegment expected, ISegment actual) {
+ assertEquals(expected, actual);
}
/**
*/
@Before
public void setup() {
- fSegmentStore = getSegmentStore();
- for (ISegment segment : SEGMENTS) {
+ for (TestSegment segment : SEGMENTS) {
fSegmentStore.add(segment);
}
}
*/
@Test
public void testAddAllConstructor() {
- @SuppressWarnings("null")
- ISegmentStore<@NonNull ISegment> other = getSegmentStore(fSegmentStore.toArray(new ISegment[fSegmentStore.size()]));
+ ISegmentStore<@NonNull TestSegment> other = getSegmentStore(fSegmentStore.toArray(new TestSegment[fSegmentStore.size()]));
assertTrue(fSegmentStore.containsAll(other));
assertTrue(other.containsAll(fSegmentStore));
}
*/
@Test
public void testAddAllConstructorOutOfOrder() {
- @SuppressWarnings("null")
- ISegmentStore<@NonNull ISegment> other = getSegmentStore(REVERSE_SEGMENTS.toArray(new ISegment[fSegmentStore.size()]));
+ ISegmentStore<@NonNull TestSegment> other = getSegmentStore(REVERSE_SEGMENTS.toArray(new TestSegment[fSegmentStore.size()]));
assertTrue(fSegmentStore.containsAll(other));
assertTrue(other.containsAll(fSegmentStore));
}
* Test containsAll() method
*/
public void testContainsAll() {
- ISegmentStore<@NonNull ISegment> store = getSegmentStore();
+ ISegmentStore<@NonNull TestSegment> store = getSegmentStore();
store.add(SEGMENT_2_6);
assertTrue(store.containsAll(Collections.emptyList()));
*/
@Test
public void testToSpecifyArraySubtype() {
- ISegmentStore<@NonNull ISegment> tms2 = getSegmentStore();
- BasicSegment otherSegment = new BasicSegment(2, 6);
+ ISegmentStore<@NonNull TestSegment> tms2 = getSegmentStore();
+ TestSegment otherSegment = new TestSegment(2, 6, "test");
tms2.add(otherSegment);
- BasicSegment[] array = tms2.toArray(new BasicSegment[0]);
+ TestSegment[] array = tms2.toArray(new TestSegment[0]);
assertEquals(1, array.length);
assertTrue(Arrays.asList(array).contains(otherSegment));
public void testIterationOrder() {
int i = 0;
for (ISegment segment : fSegmentStore) {
- assertEquals(SEGMENTS.get(i++), segment);
+ assertSegmentsEqual(SEGMENTS.get(i++), segment);
}
}
@Test
public void testIterationOrderNonSortedInsertion() {
/* Prepare the segment store, we don't use the 'fixture' in this test */
- ISegmentStore<@NonNull ISegment> store = getSegmentStore();
- for (ISegment segment : REVERSE_SEGMENTS) {
+ ISegmentStore<@NonNull TestSegment> store = getSegmentStore();
+ for (TestSegment segment : REVERSE_SEGMENTS) {
store.add(checkNotNull(segment));
}
* start times, not the insertion order.
*/
int i = 0;
- for (ISegment segment : store) {
- assertEquals(SEGMENTS.get(i++), segment);
+ for (TestSegment segment : store) {
+ assertSegmentsEqual(SEGMENTS.get(i++), segment);
}
/* Manually dispose our own store */
@Test
public void testGetIntersectingElementsRange() {
- Iterable<ISegment> intersectingElements;
+ Iterable<TestSegment> intersectingElements;
/*
* Range that does not include any segment
*/
intersectingElements = fSegmentStore.getIntersectingElements(11, 13);
assertEquals(1, Iterables.size(intersectingElements));
- assertEquals(SEGMENT_10_14, Iterables.getOnlyElement(intersectingElements));
+ assertSegmentsEqual(SEGMENT_10_14, Iterables.getOnlyElement(intersectingElements));
/*
* Range start time : On one segment start time Range end time : On one
*/
intersectingElements = fSegmentStore.getIntersectingElements(10, 14);
assertEquals(1, Iterables.size(intersectingElements));
- assertEquals(SEGMENT_10_14, Iterables.getOnlyElement(intersectingElements));
+ assertSegmentsEqual(SEGMENT_10_14, Iterables.getOnlyElement(intersectingElements));
/*
* Range start time : On last segment end time Range end time : After
*/
intersectingElements = fSegmentStore.getIntersectingElements(14, 18);
assertEquals(1, Iterables.size(intersectingElements));
- assertEquals(SEGMENT_10_14, Iterables.getOnlyElement(intersectingElements));
+ assertSegmentsEqual(SEGMENT_10_14, Iterables.getOnlyElement(intersectingElements));
/*
* Range start time : Before first segment start time Range end time :
*/
intersectingElements = fSegmentStore.getIntersectingElements(1, 2);
assertEquals(1, Iterables.size(intersectingElements));
- assertEquals(SEGMENT_2_6, Iterables.getOnlyElement(intersectingElements));
+ assertSegmentsEqual(SEGMENT_2_6, Iterables.getOnlyElement(intersectingElements));
}
/**
@Test
public void testGetIntersectingElementsTime() {
- Iterable<ISegment> intersectingElements;
+ Iterable<TestSegment> 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));
+ assertSegmentsEqual(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));
+ assertSegmentsEqual(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));
+ assertSegmentsEqual(SEGMENT_10_14, Iterables.getOnlyElement(intersectingElements));
/*
* Time overlapping many segments
*/
@Test
public void testDispose() {
- ISegmentStore<@NonNull ISegment> store = getSegmentStore();
+ ISegmentStore<@NonNull TestSegment> store = getSegmentStore();
store.add(SEGMENT_2_6);
store.dispose();
assertEquals(0, store.size());
*/
@Test
public void testIterator() {
- Collection<@NonNull ISegment> beforeExpected = ImmutableList.of(SEGMENT_2_6);
- Collection<@NonNull ISegment> afterExpected = ImmutableList.of(SEGMENT_2_6, SEGMENT_4_8);
- Collection<@NonNull ISegment> lastExpected = ImmutableList.of(SEGMENT_2_6, SEGMENT_4_8, SEGMENT_6_8);
- Collection<@NonNull ISegment> fixture = new ArrayList<>();
- ISegmentStore<@NonNull ISegment> store = getSegmentStore();
+ Collection<@NonNull TestSegment> beforeExpected = ImmutableList.of(SEGMENT_2_6);
+ Collection<@NonNull TestSegment> afterExpected = ImmutableList.of(SEGMENT_2_6, SEGMENT_4_8);
+ Collection<@NonNull TestSegment> lastExpected = ImmutableList.of(SEGMENT_2_6, SEGMENT_4_8, SEGMENT_6_8);
+ Collection<@NonNull TestSegment> fixture = new ArrayList<>();
+ ISegmentStore<@NonNull TestSegment> store = getSegmentStore();
// Add one segment to the segment store and iterate
store.add(SEGMENT_2_6);
- for (ISegment item : store) {
+ for (TestSegment item : store) {
fixture.add(item);
}
assertEquals(beforeExpected, fixture);
// Add a second segment to the store and iterate
fixture.clear();
store.add(SEGMENT_4_8);
- for (ISegment item : store) {
+ for (TestSegment item : store) {
fixture.add(item);
}
assertEquals(afterExpected, fixture);
fixture.clear();
// Take an iterator
- Iterator<@NonNull ISegment> iter = store.iterator();
+ Iterator<@NonNull TestSegment> iter = store.iterator();
// Add a third segment to the store and iterate
store.add(SEGMENT_6_8);
- Iterator<@NonNull ISegment> iter2 = store.iterator();
+ Iterator<@NonNull TestSegment> iter2 = store.iterator();
fixture.clear();
- // Make sure the first iterator take has only 2 elements and the second
- // has 3 elements
+ // Make sure the first iterator take has at least 2 elements (depends on
+ // implementation) and the second has 3 elements
while (iter.hasNext()) {
fixture.add(iter.next());
}
- assertEquals(afterExpected, fixture);
+ assertTrue(fixture.size() >= 2);
fixture.clear();
while (iter2.hasNext()) {
fixture.add(iter2.next());
}
/**
- * Test to check ordered iterators
+ * Test to check ordered iterators
*/
@Test
public void testSortedIterator() {
comparators.add(SegmentComparators.INTERVAL_LENGTH_COMPARATOR);
comparators.add(NonNullUtils.checkNotNull(SegmentComparators.INTERVAL_LENGTH_COMPARATOR.reversed()));
- Iterable<ISegment> iterable;
+ Iterable<TestSegment> iterable;
for (Comparator<ISegment> comparator : comparators) {
iterable = fSegmentStore.iterator(comparator);
verifySortedIterable(iterable, 5, comparator);
}
}
- private static void verifySortedIterable(Iterable<ISegment> iterable, int expectedSize, Comparator<ISegment> comparator) {
+ private static void verifySortedIterable(Iterable<TestSegment> iterable, int expectedSize, Comparator<ISegment> comparator) {
// check its size
assertEquals(expectedSize, Iterables.size(iterable));
- Iterator<ISegment> iterator = iterable.iterator();
+ Iterator<TestSegment> iterator = iterable.iterator();
// check the order
ISegment prev, current = iterator.next();
while (iterator.hasNext()) {
*/
@Test(expected = UnsupportedOperationException.class)
public void testRetainAll() {
- ISegmentStore<@NonNull ISegment> store = getSegmentStore();
+ ISegmentStore<@NonNull TestSegment> store = getSegmentStore();
store.add(SEGMENT_2_6);
store.retainAll(Collections.emptyList());
*/
@Test(expected = UnsupportedOperationException.class)
public void testRemove() {
- ISegmentStore<@NonNull ISegment> store = getSegmentStore();
+ ISegmentStore<@NonNull TestSegment> store = getSegmentStore();
store.add(SEGMENT_2_6);
store.remove(SEGMENT_2_6);
*/
@Test(expected = UnsupportedOperationException.class)
public void testRemoveAll() {
- ISegmentStore<@NonNull ISegment> store = getSegmentStore();
+ ISegmentStore<@NonNull TestSegment> store = getSegmentStore();
store.add(SEGMENT_2_6);
store.removeAll(Collections.emptyList());
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.internal.segmentstore.core.arraylist.ArrayListStore;
-import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
/**
public class ArrayListStoreTest extends AbstractTestSegmentStore {
@Override
- protected ISegmentStore<@NonNull ISegment> getSegmentStore() {
+ protected ISegmentStore<@NonNull TestSegment> getSegmentStore() {
return new ArrayListStore<>();
}
@Override
- protected ISegmentStore<@NonNull ISegment> getSegmentStore(@NonNull ISegment @NonNull [] data) {
+ protected ISegmentStore<@NonNull TestSegment> getSegmentStore(@NonNull TestSegment @NonNull [] data) {
return new ArrayListStore<>(data);
}
}
\ No newline at end of file
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.internal.segmentstore.core.arraylist.LazyArrayListStore;
-import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
/**
public class LazyArrayListStoreTest extends AbstractTestSegmentStore {
@Override
- protected ISegmentStore<@NonNull ISegment> getSegmentStore() {
+ protected ISegmentStore<@NonNull TestSegment> getSegmentStore() {
return new LazyArrayListStore<>();
}
@Override
- protected ISegmentStore<@NonNull ISegment> getSegmentStore(@NonNull ISegment @NonNull [] data) {
+ protected ISegmentStore<@NonNull TestSegment> getSegmentStore(@NonNull TestSegment @NonNull [] data) {
return new LazyArrayListStore<>(data);
}
}
\ No newline at end of file
import java.util.Arrays;
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.treemap.TreeMapStore;
import org.junit.Test;
public class OldTreeMapStoreTest extends AbstractTestSegmentStore {
@Override
- protected ISegmentStore<@NonNull ISegment> getSegmentStore() {
+ protected ISegmentStore<@NonNull TestSegment> getSegmentStore() {
return new TreeMapStore<>();
}
@Override
- protected ISegmentStore<@NonNull ISegment> getSegmentStore(@NonNull ISegment @NonNull [] data) {
- TreeMapStore<@NonNull ISegment> treeMapStore = new TreeMapStore<>();
+ protected ISegmentStore<@NonNull TestSegment> getSegmentStore(TestSegment [] data) {
+ TreeMapStore<@NonNull TestSegment> treeMapStore = new TreeMapStore<>();
treeMapStore.addAll(Arrays.asList(data));
return treeMapStore;
}
*/
@Test
public void testNoDuplicateElements() {
- for (ISegment segment : SEGMENTS) {
- boolean ret = fSegmentStore.add(new BasicSegment(segment.getStart(), segment.getEnd()));
+ for (TestSegment segment : SEGMENTS) {
+ boolean ret = fSegmentStore.add(new TestSegment(segment.getStart(), segment.getEnd(), segment.getPayload()));
assertFalse(ret);
}
assertEquals(SEGMENTS.size(), fSegmentStore.size());
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;
public class TreeMapStoreTest extends AbstractTestSegmentStore {
@Override
- protected ISegmentStore<@NonNull ISegment> getSegmentStore() {
+ protected ISegmentStore<@NonNull TestSegment> getSegmentStore() {
return new TreeMapStore<>();
}
- /**
- * The TreeMapStore does not have a bulk loader, if it ever gets one, it should be tested here.
- */
@Override
- protected ISegmentStore<@NonNull ISegment> getSegmentStore(@NonNull ISegment @NonNull [] data) {
- TreeMapStore<@NonNull ISegment> treeMapStore = new TreeMapStore<>();
+ protected ISegmentStore<@NonNull TestSegment> getSegmentStore(@NonNull TestSegment @NonNull [] data) {
+ TreeMapStore<@NonNull TestSegment> treeMapStore = new TreeMapStore<>();
treeMapStore.addAll(Arrays.asList(data));
return treeMapStore;
}
*/
@Test
public void testNoDuplicateElements() {
- for (ISegment segment : SEGMENTS) {
- boolean ret = fSegmentStore.add(new BasicSegment(segment.getStart(), segment.getEnd()));
+ for (TestSegment segment : SEGMENTS) {
+ boolean ret = fSegmentStore.add(new TestSegment(segment.getStart(), segment.getEnd(), segment.getPayload()));
assertFalse(ret);
}
assertEquals(SEGMENTS.size(), fSegmentStore.size());
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * 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.htStore;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+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.tests.AbstractTestSegmentStore;
+import org.eclipse.tracecompass.segmentstore.core.tests.historytree.HistoryTreeSegmentStoreStub;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Unit tests for the history tree segment store. It tests the segment store
+ * specific functionalities.
+ *
+ * @author Loïc Prieur-Drevon
+ * @author Geneviève Bastien
+ */
+@NonNullByDefault
+public class HTStoreTest extends AbstractTestSegmentStore {
+
+ private @Nullable Path fFilePath;
+
+ @Override
+ protected HistoryTreeSegmentStoreStub<@NonNull TestSegment> getSegmentStore() {
+ try {
+ Path tmpFile = Files.createTempFile("tmpSegStore", null);
+ fFilePath = tmpFile;
+ assertNotNull(tmpFile);
+ return new HistoryTreeSegmentStoreStub<>(tmpFile, 1, TestSegment.DESERIALISER);
+ } catch (IOException e) {
+ throw new IllegalStateException("Couldn't create the segment store: " + e.getMessage());
+ }
+ }
+
+ @Override
+ protected ISegmentStore<@NonNull TestSegment> getSegmentStore(@NonNull TestSegment @NonNull [] data) {
+ try {
+ Path tmpFile = Files.createTempFile("tmpSegStore", null);
+ fFilePath = tmpFile;
+ assertNotNull(tmpFile);
+ HistoryTreeSegmentStoreStub<TestSegment> store = new HistoryTreeSegmentStoreStub<>(tmpFile, 1, TestSegment.DESERIALISER);
+ store.addAll(Arrays.asList(data));
+ return store;
+ } catch (IOException e) {
+ throw new IllegalStateException("Couldn't create the segment store: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Dispose of the segment store
+ */
+ @Override
+ @After
+ public void teardown() {
+ fSegmentStore.dispose();
+ // Delete the temp file
+ if (Files.exists(fFilePath)) {
+ try {
+ Files.delete(fFilePath);
+ } catch (IOException e) {
+ throw new IllegalStateException("Error deleting the file: " + e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Overrides the assert equals to compare 2 segments. The HT segments are
+ * not identical to the original segments.
+ *
+ * @param expected
+ * The expected segment
+ * @param actual
+ * The actual segment
+ */
+ @Override
+ protected void assertSegmentsEqual(@Nullable ISegment expected, @Nullable ISegment actual) {
+ assertNotNull(expected);
+ assertNotNull(actual);
+ assertEquals(expected.getStart(), actual.getStart());
+ assertEquals(expected.getEnd(), actual.getEnd());
+ assertEquals(expected.getLength(), actual.getLength());
+ }
+
+ @Override
+ @Test
+ public void testIterationOrderNonSortedInsertion() {
+ /** The segments are not sorted, so this test does not apply */
+ }
+
+ @Override
+ @Test(expected = UnsupportedOperationException.class)
+ public void testToSpecifyArraySubtype() {
+ super.testToSpecifyArraySubtype();
+ }
+
+ @Override
+ @Test(expected = UnsupportedOperationException.class)
+ public void testToObjectArray() {
+ super.testToObjectArray();
+ }
+
+ @Override
+ @Test(expected = UnsupportedOperationException.class)
+ public void testToSpecificArray() {
+ super.testToSpecificArray();
+ }
+
+ @Override
+ @Test(expected = UnsupportedOperationException.class)
+ public void testAddAllConstructor() {
+ super.testAddAllConstructor();
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * 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.htStore;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Comparator;
+import java.util.Iterator;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.AbstractHistoryTree;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.overlapping.AbstractOverlappingHistoryTreeTestBase;
+import org.eclipse.tracecompass.internal.provisional.segmentstore.core.BasicSegment2;
+import org.eclipse.tracecompass.internal.segmentstore.core.segmentHistoryTree.SegmentHistoryTree;
+import org.eclipse.tracecompass.internal.segmentstore.core.segmentHistoryTree.SegmentTreeNode;
+import org.eclipse.tracecompass.segmentstore.core.tests.historytree.SegmentHistoryTreeStub;
+import org.junit.Test;
+
+import com.google.common.collect.Iterators;
+
+/**
+ * Test the segment history tree itself, using a stub history tree with stub
+ * nodes
+ *
+ * @author Geneviève Bastien
+ */
+@NonNullByDefault
+public class SegmentHistoryTreeTest extends AbstractOverlappingHistoryTreeTestBase<BasicSegment2, SegmentTreeNode<BasicSegment2>> {
+
+ private static final BasicSegment2 DEFAULT_OBJECT = new BasicSegment2(0, 0);
+
+ @Override
+ protected SegmentHistoryTreeStub<BasicSegment2> createHistoryTree(@NonNull File stateHistoryFile, int blockSize, int maxChildren, int providerVersion, long treeStart)
+ throws IOException {
+ return new SegmentHistoryTreeStub<>(stateHistoryFile,
+ blockSize,
+ maxChildren,
+ providerVersion,
+ treeStart,
+ BasicSegment2.BASIC_SEGMENT_READ_FACTORY);
+ }
+
+ @Override
+ protected SegmentHistoryTreeStub<BasicSegment2> createHistoryTree(@NonNull File existingStateFile, int expectedProviderVersion) throws IOException {
+ return new SegmentHistoryTreeStub<>(existingStateFile, expectedProviderVersion,
+ BasicSegment2.BASIC_SEGMENT_READ_FACTORY);
+ }
+
+ @Override
+ protected BasicSegment2 createInterval(long start, long end) {
+ return new BasicSegment2(start, end);
+ }
+
+ @Override
+ protected long fillValues(@NonNull AbstractHistoryTree<@NonNull BasicSegment2, SegmentTreeNode<@NonNull BasicSegment2>> ht, int fillSize, long start) {
+ int nbValues = fillSize / DEFAULT_OBJECT.getSizeOnDisk();
+ for (int i = 0; i < nbValues; i++) {
+ ht.insert(createInterval(start + i, start + i + 1));
+ }
+ return start + nbValues;
+ }
+
+ /**
+ * Test the {@link SegmentHistoryTree#isEmpty()} method
+ */
+ @Test
+ public void testIsEmpty() {
+ long start = 10L;
+ SegmentHistoryTreeStub<BasicSegment2> oht = (SegmentHistoryTreeStub<BasicSegment2>) setupSmallTree(3, start);
+
+ assertTrue(oht.isEmpty());
+
+ // Add one element, the tree should not be empty anymore
+ oht.insert(createInterval(start, start + 1));
+ assertFalse(oht.isEmpty());
+
+ /* Fill a first node */
+ SegmentTreeNode<BasicSegment2> node = oht.getLatestLeaf();
+ long time = fillValues(oht, node.getNodeFreeSpace(), start);
+
+ /*
+ * Add an element that will create a sibling and a root node, the root
+ * node should be empty but not the tree
+ */
+ oht.insert(createInterval(time, time + 1));
+ assertFalse(oht.isEmpty());
+ }
+
+ /**
+ * Test the {@link SegmentHistoryTree#size()} method
+ *
+ * @throws IOException
+ * Exceptions during the test
+ */
+ @Test
+ public void testSizeAndIterator() throws IOException {
+ long start = 10L;
+ SegmentHistoryTreeStub<BasicSegment2> oht = (SegmentHistoryTreeStub<BasicSegment2>) setupSmallTree(3, start);
+
+ int nbSegments = 0;
+ assertEquals(nbSegments, oht.size());
+
+ // Add one element, the tree have one element
+ oht.insert(createInterval(start, start + 1));
+ nbSegments++;
+ assertEquals(nbSegments, oht.size());
+
+ /* Fill a first node */
+ SegmentTreeNode<BasicSegment2> node = oht.getLatestLeaf();
+ nbSegments += node.getNodeFreeSpace() / DEFAULT_OBJECT.getSizeOnDisk();
+ long time = fillValues(oht, node.getNodeFreeSpace(), start);
+ assertEquals(nbSegments, oht.size());
+
+ /*
+ * Add an element that will create a sibling and a root node, the root
+ * node should be empty but not the tree
+ */
+ oht.insert(createInterval(time, time + 1));
+ nbSegments++;
+ // Add some intervals that will go in the top node
+ oht.insert(createInterval(start, time));
+ oht.insert(createInterval(start, start + 10));
+ nbSegments += 2;
+ assertEquals(nbSegments, oht.size());
+
+ /*
+ * Fill the latest node
+ */
+ node = oht.getLatestLeaf();
+ nbSegments += node.getNodeFreeSpace() / DEFAULT_OBJECT.getSizeOnDisk();
+ time = fillValues(oht, node.getNodeFreeSpace(), start);
+ assertEquals(nbSegments, oht.size());
+
+ // Close the tree
+ oht.closeTree(oht.getTreeEnd());
+
+ // Create a reader history tree
+ oht = (SegmentHistoryTreeStub<BasicSegment2>) createHistoryTreeReader();
+ assertEquals(nbSegments, oht.size());
+
+ // Test the iterator on that tree
+ Iterator<BasicSegment2> iterator = oht.iterator();
+ assertNotNull(iterator);
+ int count = Iterators.size(iterator);
+ assertEquals(nbSegments, count);
+
+ // Test the intersecting elements
+ Iterable<BasicSegment2> intersectingElements = oht.getIntersectingElements(start, time);
+ count = 0;
+ // While doing this iterator, count the number of segments of a smaller
+ // time range, it will be needed later
+ long rangeStart = (long) (start + (time - start) * 0.4);
+ long rangeEnd = (long) (time - (time - start) * 0.4);
+ int nbInRange = 0;
+ for (BasicSegment2 segment : intersectingElements) {
+ count++;
+ if (segment.getStart() <= rangeEnd && rangeStart <= segment.getEnd()) {
+ nbInRange++;
+ }
+ }
+ assertEquals(nbSegments, count);
+
+ // Test intersecting elements for a time range
+ count = Iterators.size(oht.getIntersectingElements(rangeStart, rangeEnd).iterator());
+ assertEquals(nbInRange, count);
+
+ // Test intersecting elements with start time ordering
+ Comparator<BasicSegment2> cmp = NonNullUtils.checkNotNull(Comparator.comparing(BasicSegment2::getStart));
+ assertSortedIteration(oht, rangeStart, rangeEnd, cmp, nbInRange);
+
+ // Test intersecting elements with end time ordering
+ cmp = NonNullUtils.checkNotNull(Comparator.comparing(BasicSegment2::getEnd));
+ assertSortedIteration(oht, rangeStart, rangeEnd, cmp, nbInRange);
+
+ // Test intersecting elements with duration ordering
+ cmp = NonNullUtils.checkNotNull(Comparator.comparing(BasicSegment2::getLength));
+ assertSortedIteration(oht, rangeStart, rangeEnd, cmp, nbInRange);
+ }
+
+ private static void assertSortedIteration(SegmentHistoryTreeStub<@NonNull BasicSegment2> oht, long rangeStart, long rangeEnd, Comparator<@NonNull BasicSegment2> cmp, int nbInRange) {
+ int count = 0;
+ BasicSegment2 prev = DEFAULT_OBJECT;
+ for (BasicSegment2 segment : oht.getIntersectingElements(rangeStart, rangeEnd, cmp)) {
+ count++;
+ assertTrue("Segment comparison at " + count, cmp.compare(prev, segment) <= 0);
+ }
+ assertEquals(nbInRange, count);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * 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.htStore;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.AbstractHistoryTree.IHTNodeFactory;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.HTCoreNodeTest;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.HTNode;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTIntervalReader;
+import org.eclipse.tracecompass.internal.provisional.segmentstore.core.BasicSegment2;
+import org.eclipse.tracecompass.internal.segmentstore.core.segmentHistoryTree.SegmentTreeNode;
+import org.eclipse.tracecompass.segmentstore.core.tests.historytree.SegmentTreeNodeStub;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Tests the segment history tree core node. It extends the unit tests of the
+ * node from the datastore.
+ *
+ * @author Geneviève Bastien
+ */
+@NonNullByDefault
+@RunWith(Parameterized.class)
+public class SegmentTreeCoreNodeTest extends HTCoreNodeTest<BasicSegment2, SegmentTreeNodeStub> {
+
+ /**
+ * A factory to create base objects for test
+ */
+ private static final ObjectFactory<BasicSegment2> BASE_SEGMENT_FACTORY = (s, e) -> new BasicSegment2(s, e);
+
+ /**
+ * Constructor
+ *
+ * @param name
+ * The name of the test
+ * @param headerSize
+ * The size of the header for this node type
+ * @param factory
+ * The node factory to use
+ * @param objReader
+ * The factory to read element data from disk
+ * @param objFactory
+ * The factory to create objects for this tree
+ * @throws IOException
+ * Any exception occurring with the file
+ */
+ public SegmentTreeCoreNodeTest(String name,
+ int headerSize,
+ IHTNodeFactory<BasicSegment2, SegmentTreeNodeStub> factory,
+ IHTIntervalReader<BasicSegment2> objReader,
+ ObjectFactory<BasicSegment2> objFactory) throws IOException {
+ super(name, headerSize, factory, objReader, objFactory);
+ }
+
+ /**
+ * @return The arrays of parameters
+ */
+ @Parameters(name = "{index}: {0}")
+ public static Iterable<Object[]> getParameters() {
+ return Arrays.asList(new Object[][] {
+ { "Segment tree core node",
+ HTNode.COMMON_HEADER_SIZE + Integer.BYTES + Integer.BYTES * NB_CHILDREN + 6 * Long.BYTES * NB_CHILDREN,
+ SegmentTreeNodeStub.NODE_FACTORY,
+ BasicSegment2.BASIC_SEGMENT_READ_FACTORY,
+ BASE_SEGMENT_FACTORY },
+ });
+ }
+
+ /**
+ * Test the specific methods of this node type
+ */
+ @Test
+ public void testSpecifics() {
+ long start = 10L;
+ int shortLen = 10;
+ int longLen = 50;
+ SegmentTreeNodeStub stub = newNode(0, -1, start);
+
+ // Verify the default values
+ assertEquals(start, stub.getMaxStart());
+ assertEquals(Long.MAX_VALUE, stub.getMinEnd());
+ assertEquals(Long.MAX_VALUE, stub.getShortest());
+ assertEquals(0, stub.getLongest());
+
+ // Add a new element and verify the data
+ BasicSegment2 segment = new BasicSegment2(start, start + shortLen);
+ stub.add(segment);
+ assertEquals(start, stub.getMaxStart());
+ assertEquals(start + shortLen, stub.getMinEnd());
+ assertEquals(shortLen, stub.getShortest());
+ assertEquals(shortLen, stub.getLongest());
+
+ // Add a new element and verify the data: longest length and max start
+ // should be updated
+ segment = new BasicSegment2(start + shortLen, start + longLen);
+ stub.add(segment);
+ assertEquals(start + shortLen, stub.getMaxStart());
+ assertEquals(start + shortLen, stub.getMinEnd());
+ assertEquals(shortLen, stub.getShortest());
+ assertEquals(longLen - shortLen, stub.getLongest());
+
+ }
+
+ /**
+ * Test the specific methods to retrieve data from the children of this node
+ */
+ @Test
+ public void testChildren() {
+ long start = 10L;
+ int shortLen = 10;
+ int longLen = 50;
+
+ // Create 2 nodes and link a child to the parent
+ SegmentTreeNodeStub parentStub = newNode(0, -1, start);
+ SegmentTreeNodeStub stub = newNode(0, -1, start);
+
+ parentStub.linkNewChild(stub);
+
+ // Verify the default values
+ assertEquals(start, parentStub.getMaxStart(0));
+ assertEquals(Long.MAX_VALUE, parentStub.getMinEnd(0));
+ assertEquals(Long.MAX_VALUE, parentStub.getShortest(0));
+ assertEquals(0, parentStub.getLongest(0));
+
+ // Add a few segments to the child and verify its own data
+ BasicSegment2 segment = new BasicSegment2(start, start + shortLen);
+ stub.add(segment);
+ segment = new BasicSegment2(start + shortLen, start + longLen);
+ stub.add(segment);
+
+ assertEquals(start + shortLen, stub.getMaxStart());
+ assertEquals(start + shortLen, stub.getMinEnd());
+ assertEquals(shortLen, stub.getShortest());
+ assertEquals(longLen - shortLen, stub.getLongest());
+
+ // Close the child node
+ stub.closeThisNode(start + longLen);
+ // It should update the parent's data on this node...
+ assertEquals(start + shortLen, parentStub.getMaxStart(0));
+ assertEquals(start + shortLen, parentStub.getMinEnd(0));
+ assertEquals(shortLen, parentStub.getShortest(0));
+ assertEquals(longLen - shortLen, parentStub.getLongest(0));
+
+ // ... but not the parent's own data
+ assertEquals(start, parentStub.getMaxStart());
+ assertEquals(Long.MAX_VALUE, parentStub.getMinEnd());
+ assertEquals(Long.MAX_VALUE, parentStub.getShortest());
+ assertEquals(0, parentStub.getLongest());
+ }
+
+ /**
+ * Test the {@link SegmentTreeNode#selectNextChildren(org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition)} method
+ */
+ @Test
+ public void testIntersectingChildren() {
+ long start = 10L;
+ long step = 1000;
+
+ // Create a parent node and link 3 children nodes that will overlap
+ SegmentTreeNodeStub parentStub = newNode(0, -1, start);
+ SegmentTreeNodeStub stub = newNode(1, 0, start);
+ SegmentTreeNodeStub stub2 = newNode(2, 0, start + step);
+ SegmentTreeNodeStub stub3 = newNode(3, 0, start + 2 * step);
+
+ // Add the children to the parent
+ parentStub.linkNewChild(stub);
+ parentStub.linkNewChild(stub2);
+ parentStub.linkNewChild(stub3);
+
+ // Close child nodes
+ stub.closeThisNode(start + 2 * step);
+ stub2.closeThisNode(start + 3 * step);
+ stub3.closeThisNode(start + 4 * step);
+
+ // All 3 nodes should be returned for the whole time range
+ Collection<Integer> children = parentStub.selectNextChildren(TimeRangeCondition.forContinuousRange(0L, Long.MAX_VALUE));
+ assertArrayEquals(ImmutableSet.of(stub.getSequenceNumber(), stub2.getSequenceNumber(), stub3.getSequenceNumber()).toArray(), children.toArray());
+
+ // All 3 nodes should be returned from start + step to start + 3*step
+ children = parentStub.selectNextChildren(TimeRangeCondition.forContinuousRange(start + step, start + 3 * step));
+ assertArrayEquals(ImmutableSet.of(stub.getSequenceNumber(), stub2.getSequenceNumber(), stub3.getSequenceNumber()).toArray(), children.toArray());
+
+ // Test a range that is entirely within first node and intersects the
+ // beginning of node 2
+ children = parentStub.selectNextChildren(TimeRangeCondition.forContinuousRange(start + step - 2, start + 2 * step - 2));
+ assertArrayEquals(ImmutableSet.of(stub.getSequenceNumber(), stub2.getSequenceNumber()).toArray(), children.toArray());
+
+ // Test a range that is entirely third node and intersects the
+ // end of node 2
+ children = parentStub.selectNextChildren(TimeRangeCondition.forContinuousRange(start + 3 * step - 2, start + 4 * step - 2));
+ assertArrayEquals(ImmutableSet.of(stub2.getSequenceNumber(), stub3.getSequenceNumber()).toArray(), children.toArray());
+
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * 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.htStore;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.AbstractHistoryTree.IHTNodeFactory;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.HTNode;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.HTNodeTest;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTIntervalReader;
+import org.eclipse.tracecompass.internal.provisional.segmentstore.core.BasicSegment2;
+import org.eclipse.tracecompass.segmentstore.core.tests.historytree.SegmentTreeNodeStub;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Tests the segment history tree leaf node. It extends the unit tests of the
+ * node from the datastore.
+ *
+ * @author Geneviève Bastien
+ */
+@NonNullByDefault
+@RunWith(Parameterized.class)
+public class SegmentTreeNodeTest extends HTNodeTest<BasicSegment2, SegmentTreeNodeStub> {
+
+ /**
+ * A factory to create base objects for test
+ */
+ private static final ObjectFactory<BasicSegment2> BASE_SEGMENT_FACTORY = (s, e) -> new BasicSegment2(s, e);
+
+ /**
+ * Constructor
+ *
+ * @param name
+ * The name of the test
+ * @param headerSize
+ * The size of the header for this node type
+ * @param factory
+ * The node factory to use
+ * @param objReader
+ * The factory to read element data from disk
+ * @param objFactory
+ * The factory to create objects for this tree
+ * @throws IOException
+ * Any exception occurring with the file
+ */
+ public SegmentTreeNodeTest(String name,
+ int headerSize,
+ IHTNodeFactory<BasicSegment2, SegmentTreeNodeStub> factory,
+ IHTIntervalReader<BasicSegment2> objReader,
+ ObjectFactory<BasicSegment2> objFactory) throws IOException {
+ super(name, headerSize, factory, objReader, objFactory);
+ }
+
+ /**
+ * @return The arrays of parameters
+ */
+ @Parameters(name = "{index}: {0}")
+ public static Iterable<Object[]> getParameters() {
+ return Arrays.asList(new Object[][] {
+ { "Segment tree node",
+ HTNode.COMMON_HEADER_SIZE,
+ SegmentTreeNodeStub.NODE_FACTORY,
+ BasicSegment2.BASIC_SEGMENT_READ_FACTORY,
+ BASE_SEGMENT_FACTORY
+ },
+ });
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * 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.historytree;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTIntervalReader;
+import org.eclipse.tracecompass.internal.provisional.segmentstore.core.ISegment2;
+import org.eclipse.tracecompass.internal.segmentstore.core.segmentHistoryTree.HistoryTreeSegmentStore;
+
+/**
+ * Base stub class, that resolves the node type of the tree to the stub node
+ *
+ * @author Geneviève Bastien
+ *
+ * @param <E>
+ * The type of segments accepted in this store
+ */
+public class HistoryTreeSegmentStoreStub<E extends ISegment2> extends HistoryTreeSegmentStore<E> {
+
+ /**
+ * Constructor for new history files. Use this when creating a new history
+ * from scratch.
+ *
+ * @param newStateFile
+ * The filename/location where to store the state history (Should
+ * end in .ht)
+ * @param startTime
+ * The earliest time stamp that will be stored in the history
+ * @param factory
+ * Factory to read history tree objects from the backend
+ * @throws IOException
+ * Thrown if we can't create the file for some reason
+ */
+ public HistoryTreeSegmentStoreStub(Path newStateFile,
+ long startTime,
+ IHTIntervalReader<E> factory) throws IOException {
+ super(newStateFile, factory);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * 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.historytree;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.IHistoryTree;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTIntervalReader;
+import org.eclipse.tracecompass.internal.provisional.segmentstore.core.ISegment2;
+import org.eclipse.tracecompass.internal.segmentstore.core.segmentHistoryTree.SegmentHistoryTree;
+import org.eclipse.tracecompass.internal.segmentstore.core.segmentHistoryTree.SegmentTreeNode;
+
+/**
+ * A stub segment history tree that extends the base segment history tree and
+ * the stub nodes
+ *
+ * @author Geneviève Bastien
+ * @param <E>
+ * The type of segments that goes in this tree
+ */
+public class SegmentHistoryTreeStub<E extends ISegment2> extends SegmentHistoryTree<E> {
+
+ private int fLastInsertionIndex;
+
+ /**
+ * Minimum size a block of this tree should have
+ */
+ public static final int MINIMUM_BLOCK_SIZE = IHistoryTree.TREE_HEADER_SIZE;
+
+ /**
+ * Constructor
+ *
+ * @param stateHistoryFile
+ * The name of the history file
+ * @param blockSize
+ * The size of each "block" on disk in bytes. One node will
+ * always fit in one block. It should be at least 4096.
+ * @param maxChildren
+ * The maximum number of children allowed per core (non-leaf)
+ * node.
+ * @param providerVersion
+ * The version of the state provider. If a file already exists,
+ * and their versions match, the history file will not be rebuilt
+ * uselessly.
+ * @param treeStart
+ * The start time of the history
+ * @param intervalReader
+ * typed ISegment to allow access to the readSegment methods
+ * @throws IOException
+ * If an error happens trying to open/write to the file
+ * specified in the config
+ */
+ public SegmentHistoryTreeStub(File stateHistoryFile,
+ int blockSize,
+ int maxChildren,
+ int providerVersion,
+ long treeStart,
+ IHTIntervalReader<E> intervalReader) throws IOException {
+
+ super(stateHistoryFile,
+ blockSize,
+ maxChildren,
+ providerVersion,
+ treeStart,
+ intervalReader);
+ }
+
+ /**
+ * "Reader" constructor : instantiate a SHTree from an existing tree file on
+ * disk
+ *
+ * @param existingStateFile
+ * Path/filename of the history-file we are to open
+ * @param expProviderVersion
+ * The expected version of the state provider
+ * @param factory
+ * typed ISegment to allow access to the readSegment methods
+ * @throws IOException
+ * If an error happens reading the file
+ */
+ public SegmentHistoryTreeStub(File existingStateFile, int expProviderVersion, IHTIntervalReader<E> factory) throws IOException {
+ super(existingStateFile, expProviderVersion, factory);
+ }
+
+ @Override
+ protected void informInsertingAtDepth(int depth) {
+ fLastInsertionIndex = depth;
+ }
+
+ /**
+ * Get the index in the current branch where the last element was inserted
+ *
+ * @return The index in the branch of the last insertion
+ */
+ public int getLastInsertionLocation() {
+ return fLastInsertionIndex;
+ }
+
+ @Override
+ public SegmentTreeNode<E> getLatestLeaf() {
+ return super.getLatestLeaf();
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * 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.historytree;
+
+import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.AbstractHistoryTree.IHTNodeFactory;
+import org.eclipse.tracecompass.internal.provisional.segmentstore.core.BasicSegment2;
+import org.eclipse.tracecompass.internal.segmentstore.core.segmentHistoryTree.SegmentTreeNode;
+
+/**
+ * A stub segment tree node to expose some functionalities of the segment tree
+ * nodet to better unit test them
+ *
+ * @author Geneviève Bastien
+ */
+public class SegmentTreeNodeStub extends SegmentTreeNode<BasicSegment2> {
+
+ /** Factory to create nodes of this type */
+ public static final IHTNodeFactory<BasicSegment2, SegmentTreeNodeStub> NODE_FACTORY =
+ (t, b, m, seq, p, start) -> new SegmentTreeNodeStub(t, b, m, seq, p, start);
+
+ /**
+ * Constructor
+ *
+ * @param type
+ * The type of this node
+ * @param blockSize
+ * The size (in bytes) of a serialized node on disk
+ * @param maxChildren
+ * The maximum allowed number of children per node
+ * @param seqNumber
+ * The (unique) sequence number assigned to this particular node
+ * @param parentSeqNumber
+ * The sequence number of this node's parent node
+ * @param start
+ * The start of the current node
+ */
+ public SegmentTreeNodeStub(NodeType type, int blockSize, int maxChildren,
+ int seqNumber, int parentSeqNumber, long start) {
+ super(type, blockSize, maxChildren, seqNumber, parentSeqNumber, start);
+ }
+
+ @Override
+ public long getChildStart(int index) {
+ return super.getChildStart(index);
+ }
+
+ @Override
+ public long getChildEnd(int index) {
+ return super.getChildEnd(index);
+ }
+
+ @Override
+ public long getMaxStart(int index) {
+ return super.getMaxStart(index);
+ }
+
+ @Override
+ public long getMinEnd(int index) {
+ return super.getMinEnd(index);
+ }
+
+ @Override
+ public long getShortest(int index) {
+ return super.getShortest(index);
+ }
+
+ @Override
+ public long getLongest(int index) {
+ return super.getLongest(index);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 École Polytechnique de Montréal
+ *
+ * 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.segmentstore.core.tests.historytree;