private static final double NO_ERROR = 0.0;
private static final double ERROR = 0.000001;
+ private static final double APPROX_ERROR = 0.0001;
- private static void testOnlineVsOffline(List<@NonNull BasicSegment> fixture) {
- SegmentStoreStatistics sss = getSegStoreStat(fixture);
- OfflineStatisticsCalculator osc = new OfflineStatisticsCalculator(fixture);
- assertEquals("Average", osc.getAvg(), sss.getAverage(), ERROR);
- assertEquals("Standard Deviation", osc.getStdDev(), sss.getStdDev(), ERROR);
- assertEquals("Min", osc.getMin(), sss.getMin());
- assertEquals("Max", osc.getMax(), sss.getMax());
- assertEquals("Min Segment", osc.getMin(), sss.getMinSegment().getLength());
- assertEquals("Max Segment", osc.getMax(), sss.getMaxSegment().getLength());
+ private static void testOnlineVsOffline(List<@NonNull ISegment> fixture) {
+ validate(new OfflineStatisticsCalculator(fixture), getSegStoreStat(fixture));
}
/**
*/
@Test
public void climbTest() {
- List<@NonNull BasicSegment> fixture = new ArrayList<>();
+ List<@NonNull ISegment> fixture = new ArrayList<>();
for (int i = 0; i < MEDIUM_AMOUNT_OF_SEGMENTS; i++) {
fixture.add(createDummySegment(i, i * 2));
}
testOnlineVsOffline(fixture);
}
- private static SegmentStoreStatistics getSegStoreStat(List<@NonNull BasicSegment> fixture) {
+ private static SegmentStoreStatistics getSegStoreStat(List<@NonNull ISegment> fixture) {
SegmentStoreStatistics sss = new SegmentStoreStatistics();
for (ISegment seg : fixture) {
sss.update(seg);
*/
@Test
public void decrementingTest() {
- List<@NonNull BasicSegment> fixture = new ArrayList<>();
+ List<@NonNull ISegment> fixture = new ArrayList<>();
for (int i = MEDIUM_AMOUNT_OF_SEGMENTS; i >= 0; i--) {
fixture.add(createDummySegment(i, i * 2));
}
*/
@Test
public void smallTest() {
- List<@NonNull BasicSegment> fixture = new ArrayList<>();
+ List<@NonNull ISegment> fixture = new ArrayList<>();
for (int i = 1; i >= 0; i--) {
fixture.add(createDummySegment(i, i * 2));
}
*/
@Test
public void largeTest() {
- List<@NonNull BasicSegment> fixture = new ArrayList<>();
+ List<@NonNull ISegment> fixture = new ArrayList<>();
for (int i = 1; i <= LARGE_AMOUNT_OF_SEGMENTS; i++) {
fixture.add(createDummySegment(i, i * 2));
}
public void noiseTest() {
Random rnd = new Random();
rnd.setSeed(1234);
- List<@NonNull BasicSegment> fixture = new ArrayList<>();
+ List<@NonNull ISegment> fixture = new ArrayList<>();
for (int i = 1; i <= LARGE_AMOUNT_OF_SEGMENTS; i++) {
int start = Math.abs(rnd.nextInt(100000000));
int end = start + Math.abs(rnd.nextInt(1000000));
public void gaussianNoiseTest() {
Random rnd = new Random();
rnd.setSeed(1234);
- List<@NonNull BasicSegment> fixture = new ArrayList<>();
+ List<@NonNull ISegment> fixture = new ArrayList<>();
for (int i = 1; i <= LARGE_AMOUNT_OF_SEGMENTS; i++) {
int start = Math.abs(rnd.nextInt(100000000));
final int delta = Math.abs(rnd.nextInt(1000));
testOnlineVsOffline(fixture);
}
+ /**
+ * Test statistics nodes being merged. Two contiguous blocks.
+ */
+ @Test
+ public void mergeStatisticsNodesTest() {
+ // calculates stats for all the segments
+ SegmentStoreStatistics expected = new SegmentStoreStatistics();
+ // calculates stats for half of the segments
+ SegmentStoreStatistics a = new SegmentStoreStatistics();
+ // calculates stats for another half of the segments
+ SegmentStoreStatistics b = new SegmentStoreStatistics();
+ List<@NonNull ISegment> fixture = new ArrayList<>();
+ for (int i = 0; i < 10; i++) {
+ ISegment seg = new BasicSegment(i, i * 2 + 2);
+ expected.update(seg);
+ a.update(seg);
+ fixture.add(seg);
+ }
+ for (int i = 0; i < 10; i++) {
+ ISegment seg = new BasicSegment(i, i * 2 + 2);
+ expected.update(seg);
+ b.update(seg);
+ fixture.add(seg);
+ }
+ a.merge(b);
+ OfflineStatisticsCalculator offlineExpected = new OfflineStatisticsCalculator(fixture);
+ // Compare the expected stats with the offline algorithm
+ validate(offlineExpected, expected);
+ // Compare the results of the merge with the expected results
+ validate(expected, a);
+ }
+
+ /**
+ * Test statistics nodes being merged. Two random blocks.
+ */
+ @Test
+ public void mergeStatisticsRandomNodesTest() {
+ // calculates stats for all the segments
+ SegmentStoreStatistics expected = new SegmentStoreStatistics();
+ // calculates stats for half of the segments, randomly
+ SegmentStoreStatistics a = new SegmentStoreStatistics();
+ // calculates stats for the other half of the segments
+ SegmentStoreStatistics b = new SegmentStoreStatistics();
+ List<@NonNull ISegment> fixture = new ArrayList<>();
+ Random rnd = new Random();
+ rnd.setSeed(10);
+ int size = rnd.nextInt(1000);
+ int size2 = rnd.nextInt(1000);
+ for (int i = 0; i < size; i++) {
+ int start = Math.abs(rnd.nextInt(100000000));
+ final int delta = Math.abs(rnd.nextInt(1000));
+ int end = start + delta * delta;
+ ISegment seg = new BasicSegment(start, end);
+ expected.update(seg);
+ a.update(seg);
+ fixture.add(seg);
+ }
+ for (int i = 0; i < size2; i++) {
+ int start = Math.abs(rnd.nextInt(100000000));
+ final int delta = Math.abs(rnd.nextInt(1000));
+ int end = start + delta * delta;
+ ISegment seg = new BasicSegment(start, end);
+ expected.update(seg);
+ b.update(seg);
+ fixture.add(seg);
+ }
+ a.merge(b);
+ assertEquals(size + size2, a.getNbSegments());
+ OfflineStatisticsCalculator offlineExpected = new OfflineStatisticsCalculator(fixture);
+ // Compare the expected stats with the offline algorithm
+ validate(offlineExpected, expected);
+ // Compare the results of the merge with the expected results
+ validate(expected, a);
+ }
+
+ /**
+ * Test statistics nodes being merged. Two overlapping blocks.
+ */
+ @Test
+ public void mergeStatisticsOverlappingNodesTest() {
+ // calculates stats for all the segments
+ SegmentStoreStatistics expected = new SegmentStoreStatistics();
+ // calculates stats for half of the segments
+ SegmentStoreStatistics a = new SegmentStoreStatistics();
+ // calculates stats for the other half of the segments
+ SegmentStoreStatistics b = new SegmentStoreStatistics();
+ List<@NonNull ISegment> fixture = new ArrayList<>();
+ for (int i = 0; i < 100; i++) {
+ BasicSegment seg = new BasicSegment(i, i * 2 + 2);
+ expected.update(seg);
+ if ((i & 2) != 0) {
+ a.update(seg);
+ } else {
+ b.update(seg);
+ }
+ fixture.add(seg);
+ }
+ a.merge(b);
+ OfflineStatisticsCalculator offlineExpected = new OfflineStatisticsCalculator(fixture);
+ validate(offlineExpected, expected);
+ validate(expected, a);
+ }
+
+ private static @NonNull SegmentStoreStatistics fillSmallStatistics() {
+ SegmentStoreStatistics stats = new SegmentStoreStatistics();
+ for (int i = 0; i < 10; i++) {
+ BasicSegment seg = new BasicSegment(i, i * 2 + 2);
+ stats.update(seg);
+ }
+ return stats;
+ }
+
+ /**
+ * Test statistics nodes being merged. corner cases.
+ */
+ @Test
+ public void mergeStatisticsCorenerCaseNodesTest() {
+ ISegment segment = new BasicSegment(1, 5);
+
+ // Control statistics, not to be modified
+ SegmentStoreStatistics noSegments = new SegmentStoreStatistics();
+ SegmentStoreStatistics oneSegment = new SegmentStoreStatistics();
+ oneSegment.update(segment);
+
+ // The segment store statistics to test
+ SegmentStoreStatistics testStats = new SegmentStoreStatistics();
+ SegmentStoreStatistics testStats2 = new SegmentStoreStatistics();
+
+ // Test merging empty stats on a non-empty one
+ testStats.update(segment);
+ testStats.merge(testStats2);
+ validate(oneSegment, testStats);
+ validate(noSegments, testStats2);
+
+ // Test merging on an empty stats
+ testStats2.merge(testStats);
+ validate(oneSegment, testStats);
+ validate(oneSegment, testStats2);
+
+ // Fill a small segment store and add the one extra segment to it
+ SegmentStoreStatistics expected = fillSmallStatistics();
+ expected.update(segment);
+
+ // Test merging stats with only 1 segment
+ testStats = fillSmallStatistics();
+ testStats.merge(testStats2);
+ validate(oneSegment, testStats2);
+ validate(expected, testStats);
+
+ // Test merging on stats with only 1 segment
+ testStats = fillSmallStatistics();
+ testStats2.merge(testStats);
+ validate(fillSmallStatistics(), testStats);
+ validate(expected, testStats2);
+
+ }
+
+ private static void validate(SegmentStoreStatistics expected, SegmentStoreStatistics toBeTested) {
+ assertEquals("# of Segments", expected.getNbSegments(), toBeTested.getNbSegments());
+ assertEquals("Total duration", expected.getTotal(), toBeTested.getTotal(), ERROR * expected.getTotal());
+ assertEquals("Average", expected.getAverage(), toBeTested.getAverage(), ERROR * expected.getAverage());
+ assertEquals("Min", expected.getMin(), toBeTested.getMin());
+ assertEquals("Max", expected.getMax(), toBeTested.getMax());
+ assertEquals("Min Segment", expected.getMinSegment().getLength(), toBeTested.getMinSegment().getLength());
+ assertEquals("Max Segment", expected.getMaxSegment().getLength(), toBeTested.getMaxSegment().getLength());
+ assertEquals("Standard Deviation", expected.getStdDev(), toBeTested.getStdDev(), APPROX_ERROR * expected.getStdDev());
+ }
+
+ private static void validate(OfflineStatisticsCalculator osc, SegmentStoreStatistics sss) {
+ assertEquals("# of Segments", osc.count(), sss.getNbSegments());
+ assertEquals("Total duration", osc.getTotal(), sss.getTotal(), ERROR * osc.getTotal());
+ assertEquals("Average", osc.getAvg(), sss.getAverage(), ERROR * osc.getAvg());
+ assertEquals("Min", osc.getMin(), sss.getMin());
+ assertEquals("Max", osc.getMax(), sss.getMax());
+ assertEquals("Min Segment", osc.getMin(), sss.getMinSegment().getLength());
+ assertEquals("Max Segment", osc.getMax(), sss.getMaxSegment().getLength());
+ assertEquals("Standard Deviation", osc.getStdDev(), sss.getStdDev(), ERROR * osc.getStdDev());
+ }
+
private static @NonNull BasicSegment createDummySegment(int start, int end) {
return new BasicSegment(start, end);
}