### Question:
IdRangeIterator implements IdSequence { @Override public long nextId() { try { if ( position < defrag.length ) { return defrag[position]; } long candidate = nextRangeCandidate(); if ( IdValidator.isReservedId( candidate ) ) { position++; candidate = nextRangeCandidate(); } return candidate; } finally { ++position; } } IdRangeIterator( IdRange idRange ); @Override long nextId(); @Override IdRange nextIdBatch( int size ); @Override String toString(); static final IdRangeIterator EMPTY_ID_RANGE_ITERATOR; static final long VALUE_REPRESENTING_NULL; }### Answer:
@Test public void shouldReturnValueRepresentingNullIfWeExhaustIdRange() { int rangeLength = 1024; IdRangeIterator iterator = new IdRange( new long[]{}, 0, rangeLength ).iterator(); for ( int i = 0; i < rangeLength; i++ ) { iterator.nextId(); } assertEquals( IdRangeIterator.VALUE_REPRESENTING_NULL, iterator.nextId() ); }
@Test public void shouldNotHaveAnyGaps() { int rangeLength = 1024; IdRangeIterator iterator = new IdRange( new long[]{}, 0, rangeLength ).iterator(); Set<Long> seenIds = new HashSet<>(); for ( int i = 0; i < rangeLength; i++ ) { seenIds.add( iterator.nextId() ); if ( i > 0 ) { assertTrue( "Missing id " + (i - 1), seenIds.contains( (long) i - 1 ) ); } } }
@Test public void shouldUseDefragIdsFirst() { int rangeLength = 1024; IdRangeIterator iterator = new IdRange( new long[] {7, 8, 9}, 1024, rangeLength ).iterator(); assertEquals( 7, iterator.nextId() ); assertEquals( 8, iterator.nextId() ); assertEquals( 9, iterator.nextId() ); assertEquals( 1024, iterator.nextId() ); }