| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.sis.util.collection; |
| |
| import java.util.Date; |
| import java.util.Iterator; |
| import java.util.Comparator; |
| import java.util.Random; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.SortedSet; |
| import org.apache.sis.measure.Range; |
| import org.apache.sis.measure.NumberRange; |
| import static org.apache.sis.util.privy.Constants.MILLISECONDS_PER_DAY; |
| import static org.apache.sis.util.privy.Constants.NANOS_PER_SECOND; |
| |
| // Test dependencies |
| import org.junit.jupiter.api.Test; |
| import static org.junit.jupiter.api.Assertions.*; |
| import org.apache.sis.test.TestCase; |
| import org.apache.sis.test.TestUtilities; |
| import org.apache.sis.test.Benchmark; |
| import static org.apache.sis.test.Assertions.assertSerializedEquals; |
| |
| |
| /** |
| * Tests the {@link RangeSet} implementation. |
| * |
| * @author Martin Desruisseaux (Geomatys) |
| * @author Rémi Maréchal (Geomatys) |
| */ |
| public final class RangeSetTest extends TestCase { |
| /** |
| * Tolerance factor for comparison of floating point numbers. |
| * Actually we expect exact matches, because {@link RangeSet} does not perform any calculation |
| * other than {@code min} and {@code max} - it just stores the values. |
| */ |
| private static final double EPS = 0; |
| |
| /** |
| * Creates a new test case. |
| */ |
| public RangeSetTest() { |
| } |
| |
| /** |
| * Asserts that the two given values are equals to the expected one. |
| * This method is used for testing {@link RangeSet#first()} and {@link RangeSet#last()} |
| * at the same time as the values from the iterator. |
| */ |
| private static void assertEqual(final Range<?> expected, |
| final Range<?> fromIterator, final Range<?> fromGetter) |
| { |
| assertEquals(expected, fromIterator, "Value from iterator"); |
| assertEquals(expected, fromGetter, "Value from getter"); |
| } |
| |
| /** |
| * Verifies the value of {@link RangeSet#contains(Range, boolean)}. |
| * |
| * @param ranges the range set to test. |
| * @param range the range to check for inclusion. |
| * @param exact the expected value in exact mode. |
| * @param included the expected value in non-exact mode. |
| */ |
| private static <E extends Comparable<? super E>> void checkContains(final RangeSet<E> ranges, |
| final Range<E> range, final boolean exact, final boolean included) |
| { |
| assertEquals(exact, ranges.contains(range, true)); |
| assertEquals(included, ranges.contains(range)); |
| } |
| |
| /** |
| * Tests {@link RangeSet#add(Range)} using integer values. |
| */ |
| @Test |
| public void testRangeOfIntegers() { |
| final RangeSet<Integer> ranges = RangeSet.create(Integer.class, true, false); |
| assertTrue(ranges.isEmpty()); |
| /* |
| * Add a singleton element. |
| */ |
| assertTrue(ranges.add(10, 22)); |
| assertEquals(1, ranges.size()); |
| checkContains(ranges, NumberRange.create(10, true, 22, false), true, true); |
| checkContains(ranges, NumberRange.create(10, true, 20, false), false, true); |
| checkContains(ranges, NumberRange.create(10, true, 24, false), false, false); |
| checkContains(ranges, NumberRange.create( 8, true, 20, false), false, false); |
| /* |
| * Add a new element which should be merged with the previous one. |
| */ |
| assertTrue(ranges.add(14, 25)); |
| assertEquals(1, ranges.size()); |
| checkContains(ranges, NumberRange.create(10, true, 22, false), false, true); |
| checkContains(ranges, NumberRange.create(10, true, 25, false), true, true); |
| checkContains(ranges, NumberRange.create(10, true, 25, true ), false, false); |
| /* |
| * Add a new element which is disjoint with other element. |
| */ |
| assertTrue(ranges.add(-5, 5)); |
| assertEquals(2, ranges.size()); |
| checkContains(ranges, NumberRange.create(10, true, 25, false), true, true); |
| checkContains(ranges, NumberRange.create(-5, true, 5, false), true, true); |
| /* |
| * Merge the two ranges together. |
| */ |
| assertTrue(ranges.add(NumberRange.create(5, true, 10, false))); |
| assertEquals(1, ranges.size()); |
| checkContains(ranges, NumberRange.create(10, true, 25, false), false, true); |
| checkContains(ranges, NumberRange.create(-5, true, 5, false), false, true); |
| checkContains(ranges, NumberRange.create(-5, true, 25, false), true, true); |
| /* |
| * Add more ranges. |
| */ |
| assertTrue(ranges.add(40, 50)); |
| assertTrue(ranges.add(30, 35)); |
| assertTrue(ranges.add(NumberRange.create(28, true, 32, false))); |
| assertTrue(ranges.add(-20, -10)); |
| assertTrue(ranges.add(60, 70)); |
| assertEquals(5, ranges.size()); |
| /* |
| * Verify the RangeSet content. |
| */ |
| final Iterator<Range<Integer>> it = ranges.iterator(); |
| assertEqual (NumberRange.create(-20, true, -10, false), it.next(), ranges.first()); |
| assertEquals(NumberRange.create( -5, true, 25, false), it.next()); |
| assertEquals(NumberRange.create( 28, true, 35, false), it.next()); |
| assertEquals(NumberRange.create( 40, true, 50, false), it.next()); |
| assertEqual (NumberRange.create( 60, true, 70, false), it.next(), ranges.last()); |
| assertFalse(it.hasNext()); |
| } |
| |
| /** |
| * Tests {@link RangeSet#add(Range)} using date values. |
| */ |
| @Test |
| public void testRangeOfDates() { |
| final RangeSet<Date> ranges = RangeSet.create(Date.class, true, false); |
| assertTrue(ranges.isEmpty()); |
| /* |
| * Add a singleton range. |
| */ |
| final Date now = new Date(); |
| final Date yesterday = new Date(now.getTime() - MILLISECONDS_PER_DAY); |
| assertTrue(ranges.add(yesterday, now)); |
| assertEquals(1, ranges.size()); |
| checkContains(ranges, new Range<>(Date.class, yesterday, true, now, false), true, true); |
| /* |
| * Add a disjoint range. |
| */ |
| final Date lastWeek = new Date(now.getTime() - 7*MILLISECONDS_PER_DAY); |
| final Date other = new Date(lastWeek.getTime() + 2*MILLISECONDS_PER_DAY); |
| assertTrue(ranges.add(new Range<>(Date.class, lastWeek, true, other, false))); |
| assertEquals(2, ranges.size()); |
| /* |
| * Verify the RangeSet content. |
| */ |
| final Iterator<Range<Date>> it = ranges.iterator(); |
| assertEqual(new Range<>(Date.class, lastWeek, true, other, false), it.next(), ranges.first()); |
| assertEqual(new Range<>(Date.class, yesterday, true, now, false), it.next(), ranges.last()); |
| assertFalse(it.hasNext()); |
| } |
| |
| /** |
| * Tests {@link RangeSet#add(Range)} using string values. |
| */ |
| @Test |
| public void testRangeOfStrings() { |
| final RangeSet<String> ranges = RangeSet.create(String.class, true, false); |
| assertTrue(ranges.isEmpty()); |
| assertTrue(ranges.add("FAA", "FBB")); |
| assertEquals(1, ranges.size()); |
| checkContains(ranges, new Range<>(String.class, "FAA", true, "FBB", false), true, true); |
| /* |
| * Merge the singleton range with the given range. |
| */ |
| assertTrue(ranges.add("FAZ", "FCC")); |
| assertEquals(1, ranges.size()); |
| checkContains(ranges, new Range<>(String.class, "FAA", true, "FCC", false), true, true); |
| /* |
| * Add a disjoint range. |
| */ |
| assertTrue(ranges.add("GAA", "GBB")); |
| assertEquals(2, ranges.size()); |
| /* |
| * Verify the RangeSet content. |
| */ |
| final Iterator<Range<String>> it = ranges.iterator(); |
| assertEqual(new Range<>(String.class, "FAA", true, "FCC", false), it.next(), ranges.first()); |
| assertEqual(new Range<>(String.class, "GAA", true, "GBB", false), it.next(), ranges.last()); |
| assertFalse(it.hasNext()); |
| } |
| |
| /** |
| * Tests {@link RangeSet#comparator()}. |
| */ |
| @Test |
| public void testComparator() { |
| final Comparator<Range<Integer>> comparator = RangeSet.create(Integer.class, true, false).comparator(); |
| @SuppressWarnings({"unchecked","rawtypes"}) // Generic array creation. |
| final Range<Integer>[] sorted = new Range[] { |
| NumberRange.create(-20, true, -10, false), |
| NumberRange.create( -5, true, 25, false), |
| NumberRange.create( 28, true, 35, false), |
| NumberRange.create( 40, true, 50, false), |
| NumberRange.create( 60, true, 70, false) |
| }; |
| final Range<Integer>[] ranges = sorted.clone(); |
| Collections.shuffle(Arrays.asList(ranges)); |
| Arrays.sort(ranges, comparator); |
| assertArrayEquals(sorted, ranges); |
| } |
| |
| /** |
| * Tests the {@link RangeSet#indexOfRange(Comparable)} method. |
| * Opportunistically tests {@link RangeSet#indexOfMin(Comparable)} |
| * and {@link RangeSet#indexOfMax(Comparable)} methods as well. |
| */ |
| @Test |
| public void testIndexOfRange() { |
| final RangeSet<Integer> ranges = RangeSet.create(Integer.class, true, false); |
| assertTrue(ranges.add( 40, 50)); |
| assertTrue(ranges.add( 28, 35)); |
| assertTrue(ranges.add(-20, -10)); |
| assertTrue(ranges.add( 60, 70)); |
| assertTrue(ranges.add( -5, 25)); |
| verifyIndexOf(ranges, -15, 0, 0, 0); |
| verifyIndexOf(ranges, 20, 1, 1, 1); |
| verifyIndexOf(ranges, 28, 2, 2, 2); |
| verifyIndexOf(ranges, 49, 3, 3, 3); |
| verifyIndexOf(ranges, 69, 4, 4, 4); |
| verifyIndexOf(ranges, 70, -1, 4, 4); |
| verifyIndexOf(ranges, 100, -1, 4, 5); |
| verifyIndexOf(ranges, 60, 4, 4, 4); |
| verifyIndexOf(ranges, 59, -1, 3, 4); |
| verifyIndexOf(ranges, 26, -1, 1, 2); |
| verifyIndexOf(ranges, -30, -1, -1, 0); |
| verifyIndexOf(ranges, -20, 0, 0, 0); |
| verifyIndexOf(ranges, -21, -1, -1, 0); |
| } |
| |
| /** |
| * Verifies the result of calling an {@code indexOf(…)} method. |
| * |
| * @param ranges the ranges where to search. |
| * @param value the value to search. |
| * @param index expected result of {@code indedOfRange(…)}. |
| * @param min expected result of {@code indedOfMin(…)}. |
| * @param max expected result of {@code indedOfMax(…)}. |
| */ |
| private static void verifyIndexOf(final RangeSet<Integer> ranges, |
| final int value, final int index, final int min, final int max) |
| { |
| assertEquals(index, ranges.indexOfRange(value)); |
| assertEquals(min, ranges.indexOfMin (value)); |
| assertEquals(max, ranges.indexOfMax (value)); |
| if (index >= 0) { |
| assertTrue(value >= ranges.getMinLong(index)); |
| assertTrue(value < ranges.getMaxLong(index)); |
| } |
| final int s = ranges.size(); |
| if (min >= 0) assertTrue(value >= ranges.getMinLong(min )); |
| if (min+1 < s) assertTrue(value < ranges.getMinLong(min+1)); |
| if (max < s) assertTrue(value <= ranges.getMaxLong(max )); |
| if (max > 0) assertTrue(value > ranges.getMaxLong(max-1)); |
| } |
| |
| /** |
| * Tests the {@link RangeSet#getMinLong(int)}, {@link RangeSet#getMaxLong(int)}, |
| * {@link RangeSet#getMinDouble(int)} and {@link RangeSet#getMaxDouble(int)} methods. |
| */ |
| @Test |
| public void testGetAsPrimitiveType() { |
| final RangeSet<Integer> ranges = RangeSet.create(Integer.class, true, false); |
| assertTrue(ranges.add( -5, 25)); |
| assertTrue(ranges.add(-20, -10)); |
| assertEquals(-20L, ranges.getMinLong(0)); |
| assertEquals(-10L, ranges.getMaxLong(0)); |
| assertEquals( -5L, ranges.getMinLong(1)); |
| assertEquals( 25L, ranges.getMaxLong(1)); |
| assertEquals(-20.0, ranges.getMinDouble(0)); |
| assertEquals(-10.0, ranges.getMaxDouble(0)); |
| assertEquals( -5.0, ranges.getMinDouble(1)); |
| assertEquals( 25.0, ranges.getMaxDouble(1)); |
| } |
| |
| /** |
| * Tests the {@link RangeSet#intersect(Range)} method. The {@code subSet(…)}, {@code headSet(…)} |
| * and {@code tailSet(…)} methods delegate their work to that {@code intersect(…)} method. |
| */ |
| @Test |
| public void testIntersect() { |
| final RangeSet<Integer> ranges = RangeSet.create(Integer.class, true, false); |
| assertTrue(ranges.add(-20, -10)); |
| assertTrue(ranges.add( -5, 25)); |
| assertTrue(ranges.add( 28, 35)); |
| assertTrue(ranges.add( 40, 50)); |
| assertTrue(ranges.add( 60, 70)); |
| final SortedSet<Range<Integer>> subset = ranges.intersect(NumberRange.create(5, true, 45, false)); |
| /* |
| * Verify the content. Note that the first and last ranges |
| * are expected to be intersected with the [5 … 45) range. |
| */ |
| assertEquals(5, ranges.size()); |
| assertEquals(3, subset.size()); |
| Iterator<Range<Integer>> it = subset.iterator(); |
| assertEqual (NumberRange.create( 5, true, 25, false), it.next(), subset.first()); |
| assertEquals(NumberRange.create(28, true, 35, false), it.next()); |
| assertEqual (NumberRange.create(40, true, 45, false), it.next(), subset.last()); |
| assertFalse(it.hasNext()); |
| /* |
| * Add a range and verify the content in the sub-set. |
| * Verify also that the enclosing set changed. |
| */ |
| assertTrue(subset.add(NumberRange.create(35, true, 48, false))); |
| assertEquals(4, ranges.size()); |
| assertEquals(2, subset.size()); |
| it = subset.iterator(); |
| assertEqual(NumberRange.create( 5, true, 25, false), it.next(), subset.first()); |
| assertEqual(NumberRange.create(28, true, 48, false), it.next(), subset.last()); |
| assertFalse(it.hasNext()); |
| } |
| |
| /** |
| * Tests the {@link RangeSet#remove(Comparable, Comparable)} method with integer values. |
| * The test is run for 4 different cases, 3 of them resulting in one range and one case |
| * resulting in 2 ranges. |
| */ |
| @Test |
| public void testRemoveRangeOfIntegers() { |
| final RangeSet<Integer> ranges = RangeSet.create(Integer.class, true, false); |
| assertFalse(ranges.remove(Integer.MIN_VALUE, Integer.MAX_VALUE), "Remove on empty collection should return false."); |
| assertTrue(ranges.add(-20, -10)); |
| /* |
| * A B |
| * Range : [-------------] |
| * Remove : |------------| |
| * RA RB |
| * Expected result : [------| |
| * A RA |
| */ |
| assertTrue(ranges.remove(-15, -5)); |
| assertEquals(1, ranges.size()); |
| Range<Integer> r = ranges.first(); |
| assertEquals(-20, r.getMinValue().intValue()); |
| assertEquals(-15, r.getMaxValue().intValue()); |
| /* |
| * A B |
| * Range : [-------------] |
| * Remove : |------------| |
| * RA RB |
| * Expected result : |-------] |
| * RB B |
| */ |
| assertTrue(ranges.add(-20, -10)); |
| assertEquals(1, ranges.size()); |
| assertTrue(ranges.remove(-25, -15)); |
| assertEquals(1, ranges.size()); |
| r = ranges.first(); |
| assertEquals(-15, r.getMinValue().intValue()); |
| assertEquals(-10, r.getMaxValue().intValue()); |
| /* |
| * A B |
| * Range : [-----------------------] |
| * Remove : |----------| |
| * RA RB |
| * Expected result : [------| |-----] |
| * A RA RB B |
| */ |
| assertTrue(ranges.add(-20, -10)); |
| assertEquals(1, ranges.size()); |
| assertTrue(ranges.remove(-17, -13)); |
| assertEquals(2, ranges.size()); |
| r = ranges.getRange(0); |
| assertEquals(-20, r.getMinValue().intValue()); |
| assertEquals(-17, r.getMaxValue().intValue()); |
| r = ranges.getRange(1); |
| assertEquals(-17, r.getMinValue().intValue()); |
| assertEquals(-13, r.getMaxValue().intValue()); |
| r = ranges.getRange(2); |
| assertEquals(-13, r.getMinValue().intValue()); |
| assertEquals(-10, r.getMaxValue().intValue()); |
| /* |
| * A B |
| * Range : [----------------] |
| * Remove : |----------------------| |
| * RA RB |
| * Expected result : "empty" |
| */ |
| assertTrue(ranges.add(-20, -10)); |
| assertEquals(1, ranges.size()); |
| assertTrue(ranges.remove(-21, -9)); |
| assertTrue(ranges.isEmpty()); |
| } |
| |
| /** |
| * Tests the {@link RangeSet#remove(Comparable, Comparable)} method with double values. |
| * This test uses more ranges than {@link #testRemoveRangeOfIntegers()} did. |
| */ |
| @Test |
| public void testRemoveRangeOfDoubles() { |
| /* |
| * A0 B0 Ai Bi An Bn |
| * Range : [----] ... [-------] ... [-----] |
| * Remove : |---------------| |
| * RA RB |
| * |
| * Expected result : |-----] ... [-----] |
| * RB Bi An Bn |
| */ |
| final RangeSet<Double> ranges = RangeSet.create(Double.class, true, false); |
| assertTrue(ranges.add(-20.2, -10.1)); |
| assertTrue(ranges.add( -9.5, -7.9)); |
| assertTrue(ranges.add( -6.7, -3.3)); |
| assertTrue(ranges.add( -2.4, 1.1)); |
| assertTrue(ranges.add( 1.9, 4.3)); |
| assertTrue(ranges.add( 6.1, 12.7)); |
| assertTrue(ranges.add( 15.3, 21.71)); |
| assertEquals(7, ranges.size()); |
| assertTrue(ranges.remove(-21.0, -1.4)); |
| assertEquals(4, ranges.size()); |
| Range<Double> r = ranges.first(); |
| assertEquals(-1.4, r.getMinValue(), EPS); |
| assertEquals( 1.1, r.getMaxValue(), EPS); |
| r = ranges.last(); |
| assertEquals(15.3, r.getMinValue(), EPS); |
| assertEquals(21.71, r.getMaxValue(), EPS); |
| /* |
| * A0 B0 Ai Bi An Bn |
| * Range : [----] ... [-------] ... [-----] |
| * Remove : |------------------| |
| * RA RB |
| * |
| * Expected result : [-----] ... [---| |
| * A0 B0 Ai RA |
| */ |
| assertTrue(ranges.add(-20.2, -10.1)); |
| assertTrue(ranges.add( -9.5, -7.9)); |
| assertTrue(ranges.add( -6.7, -3.3)); |
| assertTrue(ranges.add( -2.4, 1.1 )); |
| assertEquals(7, ranges.size()); |
| assertTrue(ranges.remove(0.7, 22.3)); |
| assertEquals(4, ranges.size()); |
| r = ranges.first(); |
| assertEquals(-20.2, r.getMinValue(), EPS); |
| assertEquals(-10.1, r.getMaxValue(), EPS); |
| r = ranges.last(); |
| assertEquals(-2.4, r.getMinValue(), EPS); |
| assertEquals( 0.7, r.getMaxValue(), EPS); |
| /* |
| * A0 B0 Ai Bi An Bn |
| * Range : [----] ... [-----------] ... [-----] |
| * Remove : |---| |
| * RA RB |
| * |
| * Expected result : [----] ... [---| |---] ... [-----] |
| * A0 B0 Ai RA RB Bi An Bn |
| */ |
| assertTrue(ranges.add(-2.4, 1.1)); |
| assertTrue(ranges.add( 1.9, 4.3)); |
| assertTrue(ranges.add( 6.1, 12.7)); |
| assertTrue(ranges.add(15.3, 21.71)); |
| assertEquals(7, ranges.size()); |
| assertTrue(ranges.remove(-5.4, -3.9)); |
| assertEquals(8, ranges.size()); |
| r = ranges.getRange(4); |
| assertEquals(-6.7, r.getMinValue(), EPS); |
| assertEquals(-5.4, r.getMaxValue(), EPS); |
| r = ranges.getRange(6); |
| assertEquals(-3.9, r.getMinValue(), EPS); |
| assertEquals(-3.3, r.getMaxValue(), EPS); |
| /* |
| * A0 B0 Ai Bi Aj Bj Ak Bk An Bn |
| * Range : [----] ... [-----] ...[-----] ... [------] ... [-----] |
| * Remove : |---------------------| |
| * RA RB |
| * |
| * Expected result : [----] ... [-- | |-- ] ... [-----] |
| * A0 B0 Ai RA RB Bk An Bn |
| */ |
| assertTrue(ranges.add(-6.7, -3.3)); |
| assertEquals(7, ranges.size()); |
| assertTrue(ranges.remove(-5.4, 3.1)); |
| assertEquals(6, ranges.size()); |
| r = ranges.getRange(4); |
| assertEquals(-6.7, r.getMinValue(), EPS); |
| assertEquals(-5.4, r.getMaxValue(), EPS); |
| r = ranges.getRange(6); |
| assertEquals(3.1, r.getMinValue(), EPS); |
| assertEquals(4.3, r.getMaxValue(), EPS); |
| /* |
| * A0 B0 Ai Bi Ai+1 Bi+1 Ak Bk Ak+1 Bk+1 An Bn |
| * Range : [----] ...[-----] [-----] ... [------] [-----] ... [-----] |
| * Remove : |---------------------| |
| * RA RB |
| * |
| * Expected result : [----] ... [----] [-----] ... [-----] |
| * A0 B0 Ai Bi Ak+1 Bk+1 An Bn |
| */ |
| assertTrue(ranges.add(-6.7, -3.3)); |
| assertTrue(ranges.add(-2.4, 1.1)); |
| assertTrue(ranges.add( 1.9, 4.3)); |
| assertEquals(7, ranges.size()); |
| assertTrue(ranges.remove(-7.1, 5.2)); |
| assertEquals(4, ranges.size()); |
| r = ranges.getRange(2); |
| assertEquals(-9.5, r.getMinValue(), EPS); |
| assertEquals(-7.9, r.getMaxValue(), EPS); |
| r = ranges.getRange(4); |
| assertEquals( 6.1, r.getMinValue(), EPS); |
| assertEquals(12.7, r.getMaxValue(), EPS); |
| /* |
| * A0 B0 An Bn |
| * Range : [----] ... [-----] |
| * Remove : |---------------------| |
| * RA RB |
| * |
| * Expected result : "Empty" |
| */ |
| assertTrue(ranges.add(-6.7, -3.3)); |
| assertTrue(ranges.add(-2.4, 1.1)); |
| assertTrue(ranges.add( 1.9, 4.3)); |
| assertEquals(7, ranges.size()); |
| assertTrue(ranges.remove(-50.5, 45.3)); |
| assertTrue(ranges.isEmpty()); |
| } |
| |
| /** |
| * Tests {@link RangeSet#clone()}. |
| */ |
| @Test |
| public void testClone() { |
| final RangeSet<Integer> ranges = RangeSet.create(Integer.class, true, false); |
| assertTrue(ranges.add(-20, -10)); |
| assertTrue(ranges.add( 40, 50)); |
| final RangeSet<Integer> clone = ranges.clone(); |
| assertEquals(ranges, clone, "The clone shall be equal to the original set."); |
| assertTrue(ranges.add(60, 70)); |
| assertNotEquals(ranges, clone, "Modifying the original set shall not modify the clone."); |
| } |
| |
| /** |
| * Tests serialization. |
| */ |
| @Test |
| public void testSerialization() { |
| final RangeSet<Double> ranges = RangeSet.create(Double.class, true, false); |
| assertTrue(ranges.add(12.0, 12.5)); |
| assertTrue(ranges.add(18.0, 18.5)); |
| assertTrue(ranges.add(19.0, 20.0)); |
| assertNotSame(ranges, assertSerializedEquals(ranges)); |
| } |
| |
| /** |
| * Tests the performance of {@link RangeSet} implementation. This test is not executed |
| * in normal SIS build. We run this test only when the {@link RangeSet} implementation |
| * changed, and we want to test the impact of that change on the performance. |
| * |
| * @throws InterruptedException if the test has been interrupted. |
| */ |
| @Benchmark |
| public void stress() throws InterruptedException { |
| final Random r = TestUtilities.createRandomNumberGenerator(); |
| for (int p=0; p<10; p++) { |
| final long start = System.nanoTime(); |
| final RangeSet<Integer> set = RangeSet.create(Integer.class, true, false); |
| for (int i=0; i<100000; i++) { |
| final int lower = r.nextInt(1000000) - 500; |
| final int upper = lower + r.nextInt(100) + 1; |
| if (r.nextBoolean()) { |
| set.add(lower, upper); |
| } else { |
| set.remove(lower, upper); |
| } |
| } |
| out.print((System.nanoTime() - start) / (float) NANOS_PER_SECOND); |
| out.print(" seconds for a size of "); |
| out.println(set.size()); |
| Thread.sleep(1000); |
| } |
| } |
| } |