/* * The MIT License * * Copyright (c) 2012 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 picard.util; import htsjdk.samtools.util.CloseableIterator; import htsjdk.samtools.util.MergingIterator; import org.testng.Assert; import org.testng.annotations.Test; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; import java.util.Queue; public class MergingIteratorTest { private static class QueueBackedIterator<T> implements CloseableIterator<T> { private final Iterator<T> backing; QueueBackedIterator(final Queue<T> queue) { this.backing = queue.iterator(); } @Override public void close() { // no-op } @Override public boolean hasNext() { return backing.hasNext(); } @Override public T next() { return backing.next(); } @Override public void remove() { backing.remove(); } } private static final Comparator<Integer> INTEGER_COMPARATOR = new Comparator<Integer>() { @Override public int compare(Integer integer, Integer integer2) { return integer - integer2; } }; @Test public void testOrderingAndCompleteness() { final Queue<Integer> queueOne = new LinkedList<Integer>(); queueOne.add(1); queueOne.add(3); queueOne.add(5); final Queue<Integer> queueTwo = new LinkedList<Integer>(); queueTwo.add(2); queueTwo.add(4); queueTwo.add(6); final Queue<Integer> queueThree = new LinkedList<Integer>(); queueThree.add(0); queueThree.add(1); final Collection<CloseableIterator<Integer>> iterators = new ArrayList<CloseableIterator<Integer>>(3); Collections.addAll( iterators, new QueueBackedIterator<Integer>(queueOne), new QueueBackedIterator<Integer>(queueTwo), new QueueBackedIterator<Integer>(queueThree)); final MergingIterator<Integer> mergingIterator = new MergingIterator<Integer>( INTEGER_COMPARATOR, iterators); int count = 0; int last = -1; while (mergingIterator.hasNext()) { final Integer integer = mergingIterator.next(); count++; if (integer == 1) Assert.assertTrue(integer >= last); else Assert.assertTrue(integer > last); last = integer; } Assert.assertEquals(queueOne.size() + queueTwo.size() + queueThree.size(), count); } @Test public void testIteratorsOfUnevenLength() { final Queue<Integer> queueOne = new LinkedList<Integer>(); queueOne.add(1); queueOne.add(3); queueOne.add(5); queueOne.add(7); queueOne.add(9); queueOne.add(11); queueOne.add(13); final Queue<Integer> queueTwo = new LinkedList<Integer>(); queueTwo.add(2); final Collection<CloseableIterator<Integer>> iterators = new ArrayList<CloseableIterator<Integer>>(3); Collections.addAll( iterators, new QueueBackedIterator<Integer>(queueOne), new QueueBackedIterator<Integer>(queueTwo)); final MergingIterator<Integer> mergingIterator = new MergingIterator<Integer>( INTEGER_COMPARATOR, iterators); int count = 0; int last = -1; while (mergingIterator.hasNext()) { final Integer integer = mergingIterator.next(); count++; Assert.assertTrue(integer > last); last = integer; } Assert.assertEquals(queueOne.size() + queueTwo.size(), count); } @Test(expectedExceptions = IllegalStateException.class) public void testOutOfOrderIterators() { final Queue<Integer> queueOne = new LinkedList<Integer>(); queueOne.add(1); queueOne.add(3); final Queue<Integer> queueTwo = new LinkedList<Integer>(); queueTwo.add(4); queueTwo.add(2); final Collection<CloseableIterator<Integer>> iterators = new ArrayList<CloseableIterator<Integer>>(3); Collections.addAll( iterators, new QueueBackedIterator<Integer>(queueOne), new QueueBackedIterator<Integer>(queueTwo)); final MergingIterator<Integer> mergingIterator = new MergingIterator<Integer>( INTEGER_COMPARATOR, iterators); Assert.assertEquals(mergingIterator.next().intValue(), 1); Assert.assertEquals(mergingIterator.next().intValue(), 3); Assert.assertEquals(mergingIterator.next().intValue(), 4); mergingIterator.next(); // fails, because the next element would be "2" } }