/* * 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(); } }