package org.limewire.collection; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Random; import junit.framework.Test; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.limewire.util.BaseTestCase; import org.limewire.util.ByteUtils; /** * Unit tests for <code>IntervalSet</code>. */ public class IntervalSetTest extends BaseTestCase { private static final Log LOG = LogFactory.getLog(IntervalSetTest.class); private IntervalSet iSet; private Interval interval; private List list; private Iterator iter; public IntervalSetTest(String name) { super(name); } public static Test suite() { return buildTestSuite(IntervalSetTest.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } @Override public void setUp() { iSet = new IntervalSet(); } public void testDecode() throws Exception { // file is [0,1023], all verified iSet.decode(1024, 1); assertEquals(1, iSet.getNumberOfIntervals()); assertEquals(0, iSet.getFirst().getLow()); assertEquals(1023, iSet.getFirst().getHigh()); // file is [0,1024], all verified iSet.clear(); iSet.decode(1025, 1); assertEquals(1, iSet.getNumberOfIntervals()); assertEquals(0, iSet.getFirst().getLow()); assertEquals(1024, iSet.getFirst().getHigh()); // file is [0,1024], verified only [0-1023] iSet.clear(); iSet.decode(1025, 2); assertEquals(1, iSet.getNumberOfIntervals()); assertEquals(0, iSet.getFirst().getLow()); assertEquals(1023, iSet.getFirst().getHigh()); // examples from the wiki page // http://www.limewire.org/wiki/index.php?title=HashTreeRangeEncoding // file is [0, 10 * 1024 -1], verified is [0, 4 * 1024 -1] iSet.clear(); iSet.decode(10 * 1024, 4); assertEquals(1, iSet.getNumberOfIntervals()); assertEquals(0, iSet.getFirst().getLow()); assertEquals(4 * 1024 - 1, iSet.getFirst().getHigh()); // same file, range [4 * 1024, 10 * 1024 - 1] iSet.clear(); iSet.decode(10 * 1024, 5, 12); assertEquals(1, iSet.getNumberOfIntervals()); assertEquals(4 * 1024, iSet.getFirst().getLow()); assertEquals(10 * 1024 - 1, iSet.getFirst().getHigh()); // 20k file, ranges [0,16k] and [19k,20k] iSet.clear(); iSet.decode(20 * 1024, 2); assertEquals(1, iSet.getNumberOfIntervals()); assertEquals(0 * 1024, iSet.getFirst().getLow()); assertEquals(16 * 1024 - 1, iSet.getFirst().getHigh()); iSet.decode(20 * 1024, 51); assertEquals(2, iSet.getNumberOfIntervals()); assertEquals(0 * 1024, iSet.getFirst().getLow()); assertEquals(16 * 1024 - 1, iSet.getFirst().getHigh()); assertEquals(19 * 1024, iSet.getLast().getLow()); assertEquals(20 * 1024 - 1, iSet.getLast().getHigh()); // add node 12 and we have the full file iSet.decode(20 * 1024, 12); assertEquals(1, iSet.getNumberOfIntervals()); assertEquals(0 * 1024, iSet.getFirst().getLow()); assertEquals(20 * 1024 - 1, iSet.getFirst().getHigh()); } public void testEncode() throws Exception { // file is [0,1023], all verified iSet.add(new Interval(0, 1023)); Collection<Integer> encoded = iSet.encode(1024); assertEquals(1, encoded.size()); assertTrue(encoded.contains(1)); // file is [0,1024], verified only [0,1023] encoded = iSet.encode(1025); assertEquals(1, encoded.size()); assertTrue(encoded.contains(2)); // file is [0,1024] all verified iSet.add(new Interval(1024)); encoded = iSet.encode(1025); assertEquals(1, encoded.size()); assertTrue(encoded.toString(), encoded.contains(1)); // empty file will be empty regardless of size iSet.clear(); encoded = iSet.encode(1000); assertEquals(0, encoded.size()); encoded = iSet.encode(2025); assertEquals(0, encoded.size()); // examples from the wiki page // http://www.limewire.org/wiki/index.php?title=HashTreeRangeEncoding // file is [0, 10 * 1024 -1], verified is [0, 4 * 1024 -1] iSet.add(new Interval(0, 4 * 1024 - 1)); encoded = iSet.encode(11 * 1024); assertEquals(encoded.toString(), 1, encoded.size()); assertTrue(encoded.toString(), encoded.contains(4)); // same file, range [4 * 1024, 10 * 1024 - 1] iSet.clear(); iSet.add(new Interval(4 * 1024, 10 * 1024 - 1)); encoded = iSet.encode(11 * 1024); assertEquals(encoded.toString(), 2, encoded.size()); assertTrue(encoded.toString(), encoded.contains(5)); assertTrue(encoded.toString(), encoded.contains(12)); // 20k file, ranges [0,16k] and [19k,20k] iSet.clear(); iSet.add(new Interval(0, 16 * 1024 - 1)); iSet.add(new Interval(19 * 1024, 20 * 1024 - 1)); encoded = iSet.encode(20 * 1024); assertEquals(encoded.toString(), 2, encoded.size()); assertTrue(encoded.toString(), encoded.contains(2)); assertTrue(encoded.toString(), encoded.contains(51)); } public void testSmallRangesIgnored() throws Exception { iSet.add(new Interval(0, 100)); // small range in beginning iSet.add(new Interval(10 * 1024, 20 * 1024 - 1)); // large range iSet.add(new Interval(30 * 1024, 30 * 1024 + 99)); // small range at end Collection<Integer> encoded = iSet.encode(30 * 1024 + 100); IntervalSet decoded = new IntervalSet(); for (int i : encoded) decoded.decode(30 * 1024 + 100, i); // small range at beginning is gone, the rest are there assertEquals(2, decoded.getNumberOfIntervals()); assertTrue(decoded.contains(new Interval(10 * 1024, 20 * 1024 - 1))); assertTrue(decoded.contains(new Interval(30 * 1024, 30 * 1024 + 99))); // a non-allignable end range should be ignored too iSet.clear(); iSet.add(new Interval(1025, 1199)); // too small to be alligned encoded = iSet.encode(1200); assertTrue(encoded.isEmpty()); iSet.clear(); iSet.add(new Interval(0, 1023)); encoded = iSet.encode(1024); assertEquals(1, encoded.size()); assertTrue(encoded.contains(1)); iSet.clear(); iSet.add(new Interval(0, 1022)); encoded = iSet.encode(1024); assertEquals(0, encoded.size()); } public void testRangesAlligned() throws Exception { iSet.add(new Interval(500, 2500)); Collection<Integer> encoded = iSet.encode(3 * 1024); IntervalSet decoded = new IntervalSet(); for (int i : encoded) decoded.decode(3 * 1024, i); // only one range - [1024, 2047] assertEquals(1, decoded.getNumberOfIntervals()); assertEquals(1024, decoded.getFirst().getLow()); assertEquals(2047, decoded.getFirst().getHigh()); // repeat test with long values iSet.clear(); long longBase = 0x1FFFFFFC00L; iSet.add(Range.createRange(longBase + 500, longBase + 2500)); encoded = iSet.encode(longBase + 3 * 1024); decoded = new IntervalSet(); for (int i : encoded) decoded.decode(longBase + 3 * 1024, i); assertEquals(1, decoded.getNumberOfIntervals()); assertEquals(longBase + 1024, decoded.getFirst().getLow()); assertEquals(longBase + 2047, decoded.getFirst().getHigh()); // repeat with end range iSet.clear(); iSet.add(Range.createRange(900, 1099)); encoded = iSet.encode(1100); decoded = new IntervalSet(); for (int i : encoded) decoded.decode(1100, i); assertEquals(1, decoded.getNumberOfIntervals()); assertEquals(1024, decoded.getFirst().getLow()); assertEquals(1099, decoded.getFirst().getHigh()); // test LWC-1229 // [low -- 1kb boundary -- high], high - low < 2048 iSet.clear(); iSet.add(Range.createRange(2, 1026)); encoded = iSet.encode(2000); assertEquals(0, encoded.size()); } // getNumberOfIntervals is used in pretty much every // test, so it should be tested first public void testGetNumberOfIntervals() { iSet = IntervalSet.createSingletonSet(0, 4); iSet.add(new Interval(17)); iSet.add(new Interval(20)); iSet.add(new Interval(28)); iSet.add(new Interval(31, 32)); // [0-4], [17-17], [20-20], [28-28], [31-32] assertEquals(5, iSet.getNumberOfIntervals()); iSet = new IntervalSet(); assertEquals(0, iSet.getNumberOfIntervals()); iSet.add(new Interval(17, 192000)); assertEquals(1, iSet.getNumberOfIntervals()); iSet.delete(new Interval(129)); assertEquals(2, iSet.getNumberOfIntervals()); } public void testCreateSingletonSet() { iSet = IntervalSet.createSingletonSet(17, 28417); assertEquals(1, iSet.getNumberOfIntervals()); assertEquals(new Interval(17, 28417), iSet.getFirst()); } public void testBasic() throws Exception { iSet = new IntervalSet(); interval = new Interval(40, 45); iSet.add(interval); assertEquals("add method broken", 1, iSet.getNumberOfIntervals()); assertEquals("getSize() broken", 6, iSet.getSize()); iter = iSet.getNeededIntervals(100); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 0, interval.getLow()); assertEquals("getNeededInterval broken", 39, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 46, interval.getLow()); assertEquals("getNeededInterval broken", 99, interval.getHigh()); } public void testLowerBoundaryColation() throws Exception { iSet.add(new Interval(40, 45)); interval = new Interval(35, 39); iSet.add(interval); assertEquals("lower boundry colating failed", 1, iSet.getNumberOfIntervals()); interval = getIntervalAt(0); assertEquals("lower boundry colating failed", 45, interval.getHigh()); assertEquals("lower boundry colating failed", 35, interval.getLow()); assertEquals("getSize() broken", 11, iSet.getSize()); } public void testLowerOverlapColation() throws Exception { iSet.add(new Interval(35, 45)); interval = new Interval(30, 37); iSet.add(interval); assertEquals("lower overlap colating failed", 1, iSet.getNumberOfIntervals()); interval = getIntervalAt(0); assertEquals("lower boundry colating failed", 45, interval.getHigh()); assertEquals("lower boundry colating failed", 30, interval.getLow()); } public void testLowerNonOverlap() throws Exception { iSet.add(new Interval(30, 45)); interval = new Interval(20, 25); iSet.add(interval); assertEquals("lower non-overlap add failed", 2, iSet.getNumberOfIntervals()); assertEquals("getSize() broken", 22, iSet.getSize()); iter = iSet.getNeededIntervals(100); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 0, interval.getLow()); assertEquals("getNeededInterval broken", 19, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 26, interval.getLow()); assertEquals("getNeededInterval broken", 29, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 46, interval.getLow()); assertEquals("getNeededInterval broken", 99, interval.getHigh()); } public void testUpperNonOverlap() throws Exception { iSet.add(new Interval(20, 25)); iSet.add(new Interval(30, 45)); interval = new Interval(50, 60); iSet.add(interval); assertEquals("upper non-overlap add failed", 3, iSet.getNumberOfIntervals()); assertEquals("getSize() broken", 33, iSet.getSize()); iter = iSet.getNeededIntervals(100); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 0, interval.getLow()); assertEquals("getNeededInterval broken", 19, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 26, interval.getLow()); assertEquals("getNeededInterval broken", 29, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 46, interval.getLow()); assertEquals("getNeededInterval broken", 49, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 61, interval.getLow()); assertEquals("getNeededInterval broken", 99, interval.getHigh()); } public void testGetOverlapIntervalsMidRange() throws Exception { // ////////////////getOverlapIntervals tests////////// // Note: Test all the cases for getOverlapIntervals, before continuing // Case a iSet.add(new Interval(20, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 60)); interval = new Interval(23, 32); list = iSet.getOverlapIntervals(interval); assertEquals("getOverlapIntervals broken", 2, list.size()); interval = (Interval) list.get(0);// first interval assertEquals("getOverlapIntervals broken", 23, interval.getLow()); assertEquals("getOverlapIntervals broken", 25, interval.getHigh()); interval = (Interval) list.get(1); assertEquals("getOverlapIntervals broken", 30, interval.getLow()); assertEquals("getOverlapIntervals broken", 32, interval.getHigh()); } public void testGetOverlapIntervalsBoundary() throws Exception { // Case a.1 iSet.add(new Interval(20, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 60)); interval = new Interval(25, 30); list = iSet.getOverlapIntervals(interval); assertEquals("getOverlapIntervals broken", 2, list.size()); interval = (Interval) list.get(0);// first interval assertEquals("getOverlapIntervals broken", 25, interval.getLow()); assertEquals("getOverlapIntervals broken", 25, interval.getHigh()); interval = (Interval) list.get(1); assertEquals("getOverlapIntervals broken", 30, interval.getLow()); assertEquals("getOverlapIntervals broken", 30, interval.getHigh()); } public void testGetOverlapIntervalsLowRange() throws Exception { // Case b iSet.add(new Interval(20, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 60)); interval = new Interval(16, 23); list = iSet.getOverlapIntervals(interval); assertEquals("getOverlapIntervals broken", 1, list.size()); interval = (Interval) list.get(0); assertEquals("getOverlapIntervals broken", 20, interval.getLow()); assertEquals("getOverlapIntervals broken", 23, interval.getHigh()); } public void testGetOverlapIntervalsLowBoundary() throws Exception { // case b.1 iSet.add(new Interval(20, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 60)); interval = new Interval(16, 20); list = iSet.getOverlapIntervals(interval); assertEquals("getOverlapIntervals broken", 1, list.size()); interval = (Interval) list.get(0); assertEquals("getOverlapIntervals broken", 20, interval.getLow()); assertEquals("getOverlapIntervals broken", 20, interval.getHigh()); } public void testGetOverlapIntervalsHighRange() throws Exception { // case c iSet.add(new Interval(20, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 60)); interval = new Interval(23, 29); list = iSet.getOverlapIntervals(interval); assertEquals("getOverlapIntervals broken", 1, list.size()); interval = (Interval) list.get(0); assertEquals("getOverlapIntervals broken", 23, interval.getLow()); assertEquals("getOverlapIntervals broken", 25, interval.getHigh()); } public void testGetOverlapIntervalsHighBoundary() throws Exception { // case c.1 iSet.add(new Interval(20, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 60)); interval = new Interval(25, 29); list = iSet.getOverlapIntervals(interval); assertEquals("getOverlapIntervals broken", 1, list.size()); interval = (Interval) list.get(0); assertEquals("getOverlapIntervals broken", 25, interval.getLow()); assertEquals("getOverlapIntervals broken", 25, interval.getHigh()); } public void testGetOverlapIntervalsNoRange() throws Exception { // case d iSet.add(new Interval(20, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 60)); interval = new Interval(13, 19); list = iSet.getOverlapIntervals(interval); assertEquals("reported false overlap", 0, list.size()); // case e interval = new Interval(26, 29); list = iSet.getOverlapIntervals(interval); assertEquals("reported false overlap", 0, list.size()); } public void testGetOverlapIntervalsMidAllRanges() throws Exception { // case f iSet.add(new Interval(20, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 60)); interval = new Interval(23, 53); list = iSet.getOverlapIntervals(interval); assertEquals("getOverlapIntervals broken", 3, list.size()); interval = (Interval) list.get(0); assertEquals(23, interval.getLow()); assertEquals(25, interval.getHigh()); interval = (Interval) list.get(1); assertEquals(30, interval.getLow()); assertEquals(45, interval.getHigh()); interval = (Interval) list.get(2); assertEquals(50, interval.getLow()); assertEquals(53, interval.getHigh()); } public void testGetOverlapIntervalsAllRanges() throws Exception { // case g iSet.add(new Interval(20, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 60)); interval = new Interval(16, 65); list = iSet.getOverlapIntervals(interval); assertEquals("getOverlapIntervals broken", 3, list.size()); interval = (Interval) list.get(0); assertEquals(20, interval.getLow()); assertEquals(25, interval.getHigh()); interval = (Interval) list.get(1); assertEquals(30, interval.getLow()); assertEquals(45, interval.getHigh()); interval = (Interval) list.get(2); assertEquals(50, interval.getLow()); assertEquals(60, interval.getHigh()); } public void testAddHighColation() throws Exception { // /OK, back to testing add. iSet = IntervalSet.createSingletonSet(20, 25); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 60)); interval = new Interval(54, 70); iSet.add(interval); assertEquals(3, iSet.getNumberOfIntervals()); interval = getIntervalAt(2); assertEquals(50, interval.getLow()); assertEquals(70, interval.getHigh()); assertEquals("getSize() broken", 43, iSet.getSize()); } public void testAddHighBoundaryColation() throws Exception { iSet = IntervalSet.createSingletonSet(20, 25); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 70)); interval = new Interval(71, 75); iSet.add(interval); assertEquals(3, iSet.getNumberOfIntervals()); interval = getIntervalAt(2); assertEquals(50, interval.getLow()); assertEquals(75, interval.getHigh()); assertEquals("getSize() broken", 48, iSet.getSize()); // test some boundry conditions [20-25],[30-45],[50-75] interval = new Interval(75, 80); iSet.add(interval); assertEquals(3, iSet.getNumberOfIntervals()); interval = getIntervalAt(2); assertEquals(50, interval.getLow()); assertEquals(80, interval.getHigh()); } public void testAddLowBoundaryColation() { iSet = IntervalSet.createSingletonSet(20, 25); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 80)); interval = new Interval(15, 20); iSet.add(interval); assertEquals(3, iSet.getNumberOfIntervals()); interval = getIntervalAt(0); assertEquals(15, interval.getLow()); assertEquals(25, interval.getHigh()); assertEquals("getSize() broken", 58, iSet.getSize()); } public void testGetNeededIntervals() { iSet = IntervalSet.createSingletonSet(15, 25); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 80)); iter = iSet.getNeededIntervals(100); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 0, interval.getLow()); assertEquals("getNeededInterval broken", 14, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 26, interval.getLow()); assertEquals("getNeededInterval broken", 29, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 46, interval.getLow()); assertEquals("getNeededInterval broken", 49, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 81, interval.getLow()); assertEquals("getNeededInterval broken", 99, interval.getHigh()); } public void testAddOverlappingInterval() { iSet.add(new Interval(15, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(50, 80)); interval = new Interval(49, 81); iSet.add(interval); assertEquals(3, iSet.getNumberOfIntervals()); interval = getIntervalAt(2); assertEquals(49, interval.getLow()); assertEquals(81, interval.getHigh()); assertEquals("getSize() broken", 60, iSet.getSize()); } public void testAddInternalInterval() { iSet.add(new Interval(15, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(49, 81)); interval = new Interval(55, 60); iSet.add(interval); assertEquals(3, iSet.getNumberOfIntervals()); interval = getIntervalAt(2); assertEquals(49, interval.getLow()); assertEquals(81, interval.getHigh()); } public void testAddFullBetweenInterval() { iSet.add(new Interval(15, 25)); iSet.add(new Interval(30, 45)); iSet.add(new Interval(49, 81)); interval = new Interval(26, 29); iSet.add(interval); assertEquals(2, iSet.getNumberOfIntervals()); interval = getIntervalAt(0); assertEquals(15, interval.getLow()); assertEquals(45, interval.getHigh()); iter = iSet.getNeededIntervals(100); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 0, interval.getLow()); assertEquals("getNeededInterval broken", 14, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 46, interval.getLow()); assertEquals("getNeededInterval broken", 48, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 82, interval.getLow()); assertEquals("getNeededInterval broken", 99, interval.getHigh()); } public void testGetNeededIntervalsAgain() { iSet.add(new Interval(15, 45)); iSet.add(new Interval(49, 81)); interval = new Interval(3, 5); iSet.add(interval); interval = new Interval(7, 9); iSet.add(interval); iter = iSet.getNeededIntervals(100); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 0, interval.getLow()); assertEquals("getNeededInterval broken", 2, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 6, interval.getLow()); assertEquals("getNeededInterval broken", 6, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 10, interval.getLow()); assertEquals("getNeededInterval broken", 14, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 46, interval.getLow()); assertEquals("getNeededInterval broken", 48, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 82, interval.getLow()); assertEquals("getNeededInterval broken", 99, interval.getHigh()); } public void testAddFullLowCoveringInterval() { iSet.add(new Interval(3, 5)); iSet.add(new Interval(7, 9)); iSet.add(new Interval(15, 45)); iSet.add(new Interval(49, 81)); assertEquals(4, iSet.getNumberOfIntervals()); interval = new Interval(2, 17); iSet.add(interval); assertEquals(2, iSet.getNumberOfIntervals()); interval = getIntervalAt(0); assertEquals(2, interval.getLow()); assertEquals(45, interval.getHigh()); assertEquals("getSize() broken", 77, iSet.getSize()); } public void testAddCoverFromMiddle() { iSet.add(new Interval(2, 45)); iSet.add(new Interval(49, 81)); interval = new Interval(40, 50); iSet.add(interval); assertEquals(1, iSet.getNumberOfIntervals()); // {[2-81]} interval = getIntervalAt(0); assertEquals(2, interval.getLow()); assertEquals(81, interval.getHigh()); assertEquals("getSize() broken", 80, iSet.getSize()); iter = iSet.getNeededIntervals(100); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 0, interval.getLow()); assertEquals("getNeededInterval broken", 1, interval.getHigh()); interval = (Interval) iter.next(); assertEquals("getNeededInterval broken", 82, interval.getLow()); assertEquals("getNeededInterval broken", 99, interval.getHigh()); } public void testGetNeededWithNoneAndSome() { iSet.clear(); iSet.add(new Interval(0, 5)); iter = iSet.getNeededIntervals(6); assertTrue(!iter.hasNext()); iSet.add(new Interval(6, 10)); iter = iSet.getNeededIntervals(20); interval = (Interval) iter.next(); assertEquals(11, interval.getLow()); assertEquals(19, interval.getHigh()); assertTrue(!iter.hasNext()); } public void testSetUpForDelete() { // test delete() method iSet.clear(); iSet.add(new Interval(0, 4)); iSet.add(new Interval(8, 12)); iSet.add(new Interval(16, 20)); iSet.add(new Interval(24)); iSet.add(new Interval(28, 32)); iSet.add(new Interval(36, 40)); // [0-4], [8-12], [16-20], [24-24], [28-32], [36-40] assertEquals(6, iSet.getNumberOfIntervals()); iter = iSet.getAllIntervals(); interval = (Interval) iter.next(); assertEquals(0, interval.getLow()); assertEquals(4, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(8, interval.getLow()); assertEquals(12, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(16, interval.getLow()); assertEquals(20, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(24, interval.getLow()); assertEquals(24, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(28, interval.getLow()); assertEquals(32, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(36, interval.getLow()); assertEquals(40, interval.getHigh()); } public void testDeleteNothing() { iSet.add(new Interval(0, 4)); iSet.add(new Interval(8, 12)); iSet.add(new Interval(16, 20)); iSet.add(new Interval(24, 24)); iSet.add(new Interval(28, 32)); iSet.add(new Interval(36, 40)); iSet.delete(new Interval(5, 7)); assertEquals(6, iSet.getNumberOfIntervals()); iter = iSet.getAllIntervals(); interval = (Interval) iter.next(); assertEquals(0, interval.getLow()); assertEquals(4, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(8, interval.getLow()); assertEquals(12, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(16, interval.getLow()); assertEquals(20, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(24, interval.getLow()); assertEquals(24, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(28, interval.getLow()); assertEquals(32, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(36, interval.getLow()); assertEquals(40, interval.getHigh()); } public void testDeleteBoundaries() { iSet.add(new Interval(0, 4)); iSet.add(new Interval(8, 12)); iSet.add(new Interval(16, 20)); iSet.add(new Interval(24, 24)); iSet.add(new Interval(28, 32)); iSet.add(new Interval(36, 40)); iSet.delete(new Interval(12, 16)); assertEquals(6, iSet.getNumberOfIntervals()); iter = iSet.getAllIntervals(); interval = (Interval) iter.next(); assertEquals(0, interval.getLow()); assertEquals(4, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(8, interval.getLow()); assertEquals(11, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(17, interval.getLow()); assertEquals(20, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(24, interval.getLow()); assertEquals(24, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(28, interval.getLow()); assertEquals(32, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(36, interval.getLow()); assertEquals(40, interval.getHigh()); } public void testDeleteFullInterval() { iSet.add(new Interval(0, 4)); iSet.add(new Interval(8, 11)); iSet.add(new Interval(17, 20)); iSet.add(new Interval(24, 24)); iSet.add(new Interval(28, 32)); iSet.add(new Interval(36, 40)); iSet.delete(new Interval(24, 25)); assertEquals(5, iSet.getNumberOfIntervals()); iter = iSet.getAllIntervals(); interval = (Interval) iter.next(); assertEquals(0, interval.getLow()); assertEquals(4, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(8, interval.getLow()); assertEquals(11, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(17, interval.getLow()); assertEquals(20, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(28, interval.getLow()); assertEquals(32, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(36, interval.getLow()); assertEquals(40, interval.getHigh()); } public void testDeleteSplitsIntoTwo() { iSet.add(new Interval(0, 4)); iSet.add(new Interval(8, 11)); iSet.add(new Interval(17, 20)); iSet.add(new Interval(28, 32)); iSet.add(new Interval(36, 40)); iSet.delete(new Interval(29, 30)); assertEquals(6, iSet.getNumberOfIntervals()); iter = iSet.getAllIntervals(); interval = (Interval) iter.next(); assertEquals(0, interval.getLow()); assertEquals(4, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(8, interval.getLow()); assertEquals(11, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(17, interval.getLow()); assertEquals(20, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(28, interval.getLow()); assertEquals(28, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(31, interval.getLow()); assertEquals(32, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(36, interval.getLow()); assertEquals(40, interval.getHigh()); } public void testDeleteFullUpper() { iSet.add(new Interval(0, 4)); iSet.add(new Interval(8, 11)); iSet.add(new Interval(17, 20)); iSet.add(new Interval(28, 28)); iSet.add(new Interval(31, 32)); iSet.add(new Interval(36, 40)); iSet.delete(new Interval(35, 41)); assertEquals(5, iSet.getNumberOfIntervals()); iter = iSet.getAllIntervals(); interval = (Interval) iter.next(); assertEquals(0, interval.getLow()); assertEquals(4, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(8, interval.getLow()); assertEquals(11, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(17, interval.getLow()); assertEquals(20, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(28, interval.getLow()); assertEquals(28, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(31, interval.getLow()); assertEquals(32, interval.getHigh()); } public void testDeleteIntervalSet() { iSet.add(new Interval(0, 4)); iSet.add(new Interval(8, 11)); iSet.add(new Interval(17, 20)); iSet.add(new Interval(28, 28)); iSet.add(new Interval(31, 32)); IntervalSet toDelete = new IntervalSet(); toDelete.add(new Interval(8, 15)); toDelete.add(new Interval(18, 19)); iSet.delete(toDelete); assertEquals(5, iSet.getNumberOfIntervals()); iter = iSet.getAllIntervals(); interval = (Interval) iter.next(); assertEquals(0, interval.getLow()); assertEquals(4, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(17, interval.getLow()); assertEquals(17, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(20, interval.getLow()); assertEquals(20, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(28, interval.getLow()); assertEquals(28, interval.getHigh()); interval = (Interval) iter.next(); assertEquals(31, interval.getLow()); assertEquals(32, interval.getHigh()); } public void testDeleteLarge() throws Exception { // to test the narrowRange method we need a min number of intervals for (int i = 0; i < IntervalSet.LINEAR * 2 + 4; i += 2) iSet.add(Range.createRange(0x1L << i, (0x1L << (i + 1)) - 1)); assertGreaterThan(IntervalSet.LINEAR, iSet.getNumberOfIntervals()); iSet.delete(new Interval(20, 80)); List<Range> listr = iSet.getAllIntervalsAsList(); assertEquals(1, listr.get(0).getLow()); assertEquals(1, listr.get(0).getHigh()); assertEquals(4, listr.get(1).getLow()); assertEquals(7, listr.get(1).getHigh()); assertEquals(16, listr.get(2).getLow()); assertEquals(19, listr.get(2).getHigh()); assertEquals(81, listr.get(3).getLow()); assertEquals(127, listr.get(3).getHigh()); // the rest unchanged for (int i = 4; i < listr.size(); i++) { assertEquals(0x1L << (i * 2), listr.get(i).getLow()); assertEquals((0x1L << (i * 2 + 1)) - 1, listr.get(i).getHigh()); } } public void testGetFirstAndIsEmpty() { iSet = IntervalSet.createSingletonSet(0, 4); iSet.add(new Interval(17)); iSet.add(new Interval(20)); iSet.add(new Interval(28)); iSet.add(new Interval(31, 32)); // [0-4], [17-17], [20-20], [28-28], [31-32] assertEquals(new Interval(0, 4), iSet.getFirst()); iSet.delete(iSet.getFirst()); assertFalse(iSet.isEmpty()); assertEquals(new Interval(17, 17), iSet.getFirst()); iSet.delete(iSet.getFirst()); assertFalse(iSet.isEmpty()); assertEquals(new Interval(20, 20), iSet.getFirst()); iSet.delete(iSet.getFirst()); assertFalse(iSet.isEmpty()); assertEquals(new Interval(28, 28), iSet.getFirst()); iSet.delete(iSet.getFirst()); assertFalse(iSet.isEmpty()); assertEquals(new Interval(31, 32), iSet.getFirst()); iSet.delete(iSet.getFirst()); assertTrue(iSet.isEmpty()); try { iSet.getFirst(); fail("expected exception"); } catch (NoSuchElementException nsee) { } } public void testGetLast() { iSet = IntervalSet.createSingletonSet(0, 4); iSet.add(new Interval(17)); iSet.add(new Interval(20)); iSet.add(new Interval(28)); iSet.add(new Interval(31, 32)); // [0-4], [17-17], [20-20], [28-28], [31-32] assertEquals(5, iSet.getNumberOfIntervals()); assertEquals(new Interval(31, 32), iSet.getLast()); iSet.delete(iSet.getLast()); assertEquals(new Interval(28, 28), iSet.getLast()); iSet.delete(iSet.getLast()); assertEquals(new Interval(20, 20), iSet.getLast()); iSet.delete(iSet.getLast()); assertEquals(new Interval(17, 17), iSet.getLast()); iSet.delete(iSet.getLast()); assertEquals(new Interval(0, 4), iSet.getLast()); iSet.delete(iSet.getLast()); try { iSet.getLast(); fail("expected exception"); } catch (NoSuchElementException nsee) { } } public void testInvert() { iSet = new IntervalSet(); // no intervals assertEquals(0, iSet.getNumberOfIntervals()); IntervalSet inverted = iSet.invert(100); assertEquals(1, inverted.getAllIntervalsAsList().size()); assertEquals(new Interval(0, 99), inverted.getAllIntervals().next()); iSet.add(new Interval(0, 100)); inverted = iSet.invert(0); assertEquals(0, inverted.getAllIntervalsAsList().size()); iSet.clear(); iSet.add(new Interval(10, 20)); iSet.add(new Interval(50, 60)); inverted = iSet.invert(100); assertEquals(3, inverted.getNumberOfIntervals()); List<Range> invl = inverted.getAllIntervalsAsList(); assertEquals(0, invl.get(0).getLow()); assertEquals(9, invl.get(0).getHigh()); assertEquals(21, invl.get(1).getLow()); assertEquals(49, invl.get(1).getHigh()); assertEquals(61, invl.get(2).getLow()); assertEquals(99, invl.get(2).getHigh()); inverted = iSet.invert(50); assertEquals(2, inverted.getNumberOfIntervals()); invl = inverted.getAllIntervalsAsList(); assertEquals(0, invl.get(0).getLow()); assertEquals(9, invl.get(0).getHigh()); assertEquals(21, invl.get(1).getLow()); assertEquals(49, invl.get(1).getHigh()); } public void testClone() throws CloneNotSupportedException { iSet = IntervalSet.createSingletonSet(0, 100); // [0-100] assertEquals(1, iSet.getNumberOfIntervals()); IntervalSet clone = iSet.clone(); assertEquals(1, clone.getAllIntervalsAsList().size()); assertEquals(new Interval(0, 100), clone.getAllIntervals().next()); clone.delete(clone.getFirst()); assertEquals(0, clone.getAllIntervalsAsList().size()); assertEquals(1, iSet.getNumberOfIntervals()); assertEquals(new Interval(0, 100), getIntervalAt(0)); } public void testToBytes() throws Exception { IntervalSet set = new IntervalSet(); Random r = new Random(); for (int i = 1; i < 10; i++) { int low = Math.abs(r.nextInt(100)); Interval inter = new Interval(low, low + i); set.add(inter); } IntervalSet.ByteIntervals asByte = set.toBytes(); assertEquals(0, asByte.longs.length); IntervalSet set2 = IntervalSet.parseBytes(asByte.ints, asByte.longs); assertEquals(set.getSize(), set2.getSize()); assertEquals(set.getAllIntervalsAsList(), set2.getAllIntervalsAsList()); // test long ranges set.add(Range.createRange(0xFFFFFFFFF0l, 0xFFFFFFFFFFl)); asByte = set.toBytes(); assertEquals(10, asByte.longs.length); // check manually assertEquals(0xFFFFFFFFF0l, ByteUtils.beb2long(asByte.longs, 0, 5)); assertEquals(0xFFFFFFFFFFl, ByteUtils.beb2long(asByte.longs, 5, 5)); // and check parsing set2 = IntervalSet.parseBytes(asByte.ints, asByte.longs); assertEquals(set.getSize(), set2.getSize()); assertEquals(set.getAllIntervalsAsList(), set2.getAllIntervalsAsList()); // the large interval will be last Range large = set2.getLast(); assertEquals(0xFFFFFFFFF0l, large.getLow()); assertEquals(0xFFFFFFFFFFl, large.getHigh()); } // Test failure cases from beta testing public void testContains() { LOG.info("-- testing contains()"); iSet = IntervalSet.createSingletonSet(1542374, 1572863); iSet.add(new Interval(1645963, 1835007)); iSet.add(new Interval(2077669, 2228223)); assertTrue(iSet.contains(new Interval(1542374, 1543397))); } public void testContainsAny() throws Exception { iSet.add(new Interval(10, 20)); assertTrue(iSet.containsAny(new Interval(0, 10))); assertTrue(iSet.containsAny(new Interval(20, 30))); assertTrue(iSet.containsAny(new Interval(0, 30))); assertTrue(iSet.containsAny(new Interval(15, 16))); } // /// Private helper methods ///// private Interval getIntervalAt(int i) { return (Interval) iSet.getAllIntervalsAsList().get(i); } }