@Override public long nextId() { long id; if ( batch == null || (id = batch.nextId()) == -1 ) { IdRange idRange = source.nextIdBatch( batchSize ); while ( IdValidator.hasReservedIdInRange( idRange.getRangeStart(), idRange.getRangeStart() + idRange.getRangeLength() ) ) { idRange = source.nextIdBatch( batchSize ); } batch = new IdRangeIterator( idRange ); id = batch.nextId(); } return id; }
private long nextRangeCandidate() { int offset = currentRangeOffset(); return (offset < length) ? (start + offset) : VALUE_REPRESENTING_NULL; }
@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; } }
@Test public void shouldGetNextIdBatchFromOnlyDefragIdsWhenSomeDefragIdsHaveAlreadyBeenReturned() { // given IdRangeIterator iterator = new IdRange( new long[] {1, 2, 3, 4, 5, 6}, 7, 0 ).iterator(); iterator.nextId(); iterator.nextId(); // when IdRangeIterator subRange = iterator.nextIdBatch( 3 ).iterator(); // then assertEquals( 6, iterator.nextId() ); for ( long i = 0; i < 3; i++ ) { assertEquals( 3 + i, subRange.nextId() ); } assertEquals( VALUE_REPRESENTING_NULL, subRange.nextId() ); }
@Test public void shouldUseDefragIdsFirst() { // given int rangeLength = 1024; IdRangeIterator iterator = new IdRange( new long[] {7, 8, 9}, 1024, rangeLength ).iterator(); // then assertEquals( 7, iterator.nextId() ); assertEquals( 8, iterator.nextId() ); assertEquals( 9, iterator.nextId() ); assertEquals( 1024, iterator.nextId() ); }
@Override public synchronized IdRange nextIdBatch( int size ) { IdRange idBatch = getReusableIdBatch( size ); if ( idBatch.totalSize() > 0 ) { return idBatch; } IdRange range = idQueue.nextIdBatch( size ); if ( range.totalSize() == 0 ) { acquireNextIdBatch(); range = idQueue.nextIdBatch( size ); setHighId( range.getHighId() ); } return range; }
public IdRangeIterator iterator() { return new IdRangeIterator( this ); }
@Test public void shouldGetNextIdBatchFromSomeDefragAndSomeRangeIds() { // given IdRangeIterator iterator = new IdRange( new long[] {1, 2, 3}, 10, 5 ).iterator(); iterator.nextId(); // when IdRangeIterator subRange = iterator.nextIdBatch( 5 ).iterator(); // then assertEquals( 13, iterator.nextId() ); assertEquals( 2, subRange.nextId() ); assertEquals( 3, subRange.nextId() ); assertEquals( 10, subRange.nextId() ); assertEquals( 11, subRange.nextId() ); assertEquals( 12, subRange.nextId() ); assertEquals( VALUE_REPRESENTING_NULL, subRange.nextId() ); }
@Test public void shouldReturnValueRepresentingNullIfWeExhaustIdRange() { // given int rangeLength = 1024; IdRangeIterator iterator = new IdRange( new long[]{}, 0, rangeLength ).iterator(); // when for ( int i = 0; i < rangeLength; i++ ) { iterator.nextId(); } // then assertEquals( IdRangeIterator.VALUE_REPRESENTING_NULL, iterator.nextId() ); }
public IdRangeIterator iterator() { return new IdRangeIterator( this ); }
@Test public void shouldGetNextIdBatchFromSomeRangeIdsWhenThereAreUsedDefragIds() { // given IdRangeIterator iterator = new IdRange( new long[] {0, 1, 2}, 3, 10 ).iterator(); iterator.nextId(); iterator.nextId(); iterator.nextId(); // when IdRangeIterator subRange = iterator.nextIdBatch( 3 ).iterator(); // then assertEquals( 6, iterator.nextId() ); assertEquals( 3, subRange.nextId() ); assertEquals( 4, subRange.nextId() ); assertEquals( 5, subRange.nextId() ); assertEquals( VALUE_REPRESENTING_NULL, subRange.nextId() ); // when subRange = iterator.nextIdBatch( 3 ).iterator(); // then assertEquals( 10, iterator.nextId() ); assertEquals( 7, subRange.nextId() ); assertEquals( 8, subRange.nextId() ); assertEquals( 9, subRange.nextId() ); assertEquals( VALUE_REPRESENTING_NULL, subRange.nextId() ); } }
@Test public void shouldNotHaveAnyGaps() { // given int rangeLength = 1024; IdRangeIterator iterator = new IdRange( new long[]{}, 0, rangeLength ).iterator(); // when Set<Long> seenIds = new HashSet<>(); for ( int i = 0; i < rangeLength; i++ ) { seenIds.add( iterator.nextId() ); if ( i > 0 ) { // then assertTrue( "Missing id " + (i - 1), seenIds.contains( (long) i - 1 ) ); } } }
@Override public long nextId() { long id; if ( batch == null || (id = batch.nextId()) == -1 ) { IdRange idRange = source.nextIdBatch( batchSize ); while ( IdValidator.hasReservedIdInRange( idRange.getRangeStart(), idRange.getRangeStart() + idRange.getRangeLength() ) ) { idRange = source.nextIdBatch( batchSize ); } batch = new IdRangeIterator( idRange ); id = batch.nextId(); } return id; }
@Override public IdRange nextIdBatch( int size ) { int sizeLeft = size; long[] rangeDefrag = EMPTY_LONG_ARRAY; if ( position < defrag.length ) { // There are defragged ids to grab int numberOfDefrags = min( sizeLeft, defrag.length - position ); rangeDefrag = Arrays.copyOfRange( defrag, position, numberOfDefrags + position ); position += numberOfDefrags; sizeLeft -= numberOfDefrags; } long rangeStart = 0; int rangeLength = 0; int rangeOffset = currentRangeOffset(); int rangeAvailable = length - rangeOffset; if ( sizeLeft > 0 && rangeAvailable > 0 ) { rangeStart = start + rangeOffset; rangeLength = min( rangeAvailable, sizeLeft ); position += rangeLength; } return new IdRange( rangeDefrag, rangeStart, rangeLength ); }
@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; } }
@Test public void shouldGetNextIdBatchFromSomeRangeIds() { // given IdRangeIterator iterator = new IdRange( EMPTY_LONG_ARRAY, 0, 20 ).iterator(); iterator.nextId(); // when IdRangeIterator subRange = iterator.nextIdBatch( 5 ).iterator(); // then assertEquals( 6, iterator.nextId() ); assertEquals( 1, subRange.nextId() ); assertEquals( 2, subRange.nextId() ); assertEquals( 3, subRange.nextId() ); assertEquals( 4, subRange.nextId() ); assertEquals( 5, subRange.nextId() ); assertEquals( VALUE_REPRESENTING_NULL, subRange.nextId() ); // when subRange = iterator.nextIdBatch( 2 ).iterator(); // then assertEquals( 9, iterator.nextId() ); assertEquals( 7, subRange.nextId() ); assertEquals( 8, subRange.nextId() ); assertEquals( VALUE_REPRESENTING_NULL, subRange.nextId() ); }
@Override public synchronized long nextId() { long id = getReusableId(); if ( id != IdContainer.NO_RESULT ) { return id; } long nextId = idQueue.nextId(); if ( nextId == VALUE_REPRESENTING_NULL ) { acquireNextIdBatch(); nextId = idQueue.nextId(); } highId = max( highId, nextId + 1 ); return nextId; }
private long nextRangeCandidate() { int offset = currentRangeOffset(); return (offset < length) ? (start + offset) : VALUE_REPRESENTING_NULL; }
@Test public void shouldGetNextIdBatchFromOnlyDefragIds() { // given IdRangeIterator iterator = new IdRange( new long[] {1, 2, 3, 4, 5, 6}, 7, 0 ).iterator(); // when IdRangeIterator subRange = iterator.nextIdBatch( 5 ).iterator(); // then assertEquals( 6, iterator.nextId() ); for ( long i = 0; i < 5; i++ ) { assertEquals( 1 + i, subRange.nextId() ); } assertEquals( VALUE_REPRESENTING_NULL, subRange.nextId() ); }
@Override public IdRange nextIdBatch( int size ) { int sizeLeft = size; long[] rangeDefrag = EMPTY_LONG_ARRAY; if ( position < defrag.length ) { // There are defragged ids to grab int numberOfDefrags = min( sizeLeft, defrag.length - position ); rangeDefrag = Arrays.copyOfRange( defrag, position, numberOfDefrags + position ); position += numberOfDefrags; sizeLeft -= numberOfDefrags; } long rangeStart = 0; int rangeLength = 0; int rangeOffset = currentRangeOffset(); int rangeAvailable = length - rangeOffset; if ( sizeLeft > 0 && rangeAvailable > 0 ) { rangeStart = start + rangeOffset; rangeLength = min( rangeAvailable, sizeLeft ); position += rangeLength; } return new IdRange( rangeDefrag, rangeStart, rangeLength ); }