/*
* The MIT License
*
* Copyright (c) 2010 The Broad Institute
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package htsjdk.samtools.util;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.Iterator;
/**
* @author alecw@broadinstitute.org
*/
public class IntervalTreeTest {
@Test
public void testNoMatches()
{
// Test empty tree
final IntervalTree<String> intervalTree = new IntervalTree<String>();
Iterator<IntervalTree.Node<String>> results = intervalTree.overlappers(1, 500);
Assert.assertEquals(countElements(results), 0, "Testing with no left-hand set failed.");
// Test no matches at all
intervalTree.put(1, 400, "foo");
intervalTree.put(600, 800, "foo2");
results = intervalTree.overlappers(450, 599);
Assert.assertEquals(countElements(results), 0, "Testing with no overlaps at all.");
}
private int countElements(final Iterator<IntervalTree.Node<String>> it) {
int ret = 0;
while (it.hasNext()) {
++ret;
it.next();
}
return ret;
}
@Test
public void testMatches()
{
final IntervalTree<String> intervalTree = new IntervalTree<String>();
intervalTree.put(1, 10, "foo1");
intervalTree.put(2, 9, "foo2");
intervalTree.put(3, 8, "foo3");
intervalTree.put(4, 7, "foo4");
intervalTree.put(5, 6, "foo5");
intervalTree.put(1, 9, "foo6");
// Single match
Assert.assertEquals(countElements(intervalTree.overlappers(10, 10)), 1, "Test single overlap");
Assert.assertTrue(iteratorContains(intervalTree.overlappers(10, 10), "foo1"), "Test single overlap for correct overlapee");
// Multiple matches
Assert.assertEquals(countElements(intervalTree.overlappers(7, 8)), 5, "Test multiple overlap");
Assert.assertTrue(iteratorContains(intervalTree.overlappers(7, 8), "foo1"), "Test multiple overlap for correct overlapees");
Assert.assertTrue(iteratorContains(intervalTree.overlappers(7, 8), "foo2"), "Test multiple overlap for correct overlapees");
Assert.assertTrue(iteratorContains(intervalTree.overlappers(7, 8), "foo3"), "Test multiple overlap for correct overlapees");
Assert.assertTrue(iteratorContains(intervalTree.overlappers(7, 8), "foo4"), "Test multiple overlap for correct overlapees");
Assert.assertTrue(iteratorContains(intervalTree.overlappers(7, 8), "foo6"), "Test multiple overlap for correct overlapees");
Assert.assertTrue(!iteratorContains(intervalTree.overlappers(7, 8), "foo5"), "Test multiple overlap for correct overlapees");
}
private boolean iteratorContains(final Iterator<IntervalTree.Node<String>> nodeIterator, final String s) {
while (nodeIterator.hasNext()) {
if (nodeIterator.next().getValue().equals(s)) {
return true;
}
}
return false;
}
@Test
public void testNearEnds()
{
final IntervalTree<String> intervalTree = new IntervalTree<String>();
intervalTree.put(10, 20, "foo");
Assert.assertEquals(countElements(intervalTree.overlappers(10, 10)), 1, "Test overlap (no buffers) at near end exactly");
Assert.assertEquals(countElements(intervalTree.overlappers(9, 10)), 1, "Test overlap (no buffers) at near end exactly");
Assert.assertEquals(countElements(intervalTree.overlappers(9, 9)), 0, "Test just before overlap (no buffers)");
Assert.assertEquals(countElements(intervalTree.overlappers(20, 20)), 1, "Test overlap (no buffers) at far end exactly");
Assert.assertEquals(countElements(intervalTree.overlappers(20, 21)), 1, "Test overlap (no buffers) at far end exactly");
Assert.assertEquals(countElements(intervalTree.overlappers(21, 21)), 0, "Test just beyond overlap (no buffers)");
}
@Test
public void performanceTest()
{
final IntervalTree<String> intervalTree = new IntervalTree<String>();
final long start = System.currentTimeMillis();
for (int i = 1; i <= 50000; i++) intervalTree.put(i, i, "frob");
System.out.println("Time to construct a tree with 50000 nodes: " + (System.currentTimeMillis() - start) + " milliseconds" );
final long end = System.currentTimeMillis() + 10000;
int count = 0;
while (System.currentTimeMillis() < end) {
intervalTree.overlappers(17000, 17099);
++count;
}
System.out.println("Queried for the same 100-length mapping " + count + " times in 10 seconds.");
}
@Test
public void testHandlingOfDuplicateMappings()
{
final IntervalTree<String> intervalTree = new IntervalTree<String>();
intervalTree.put(1, 10, "foo1");
// This call replaces foo1 with foo2
Assert.assertEquals(intervalTree.put(1, 10, "foo2"), "foo1");
intervalTree.put(2, 8, "foo3");
Assert.assertEquals(countElements(intervalTree.overlappers(3, 5)), 2);
Assert.assertFalse(iteratorContains(intervalTree.overlappers(3, 5), "foo1"));
Assert.assertTrue(iteratorContains(intervalTree.overlappers(3, 5), "foo2"));
Assert.assertTrue(iteratorContains(intervalTree.overlappers(3, 5), "foo3"));
}
/**
* Test of PIC-123
*/
@Test
public void testRemove() {
int[][] adds = {
{46129744, 46129978},
{46393843, 46394077},
{46260491, 46260725},
{46402360, 46402594},
{46369255, 46369464},
{46293772, 46293981},
{46357687, 46357896},
{46431752, 46431961},
{46429997, 46430206},
{46404026, 46404192},
{46390511, 46390677},
{46090593, 46090759},
{46045352, 46045518},
{46297633, 46297799},
{46124297, 46124463},
{46395291, 46395504},
{46439072, 46439240},
{46400792, 46400959},
{46178616, 46178851},
{46129747, 46129982},
{46396546, 46396781},
{46112353, 46112588},
{46432996, 46433231},
{46399109, 46399344},
{46372058, 46372292},
{46386826, 46387060},
{46381795, 46382029},
{46179789, 46180023},
{46394409, 46394643},
{46376176, 46376429},
{46389943, 46390177},
{46433654, 46433888},
{46379440, 46379674},
{46391117, 46391351},
};
IntervalTree<String> intervalTree = new IntervalTree<String>();
for (int[] add : adds) {
intervalTree.put(add[0], add[1], "frob");
}
Assert.assertEquals(intervalTree.remove(46402360, 46402594), "frob");
intervalTree.checkMaxEnds();
}
}