@Override public IdRange nextIdBatch( int size ) { while ( IdValidator.hasReservedIdInRange( nextId, nextId + size ) ) { nextId += size; } long startId = nextId; nextId += size; return new IdRange( EMPTY_LONG_ARRAY, startId, size ); }
@Override public IdRange nextIdBatch( int batchSize ) { calls++; try { return new IdRange( EMPTY_LONG_ARRAY, nextId, batchSize ); } finally { nextId += batchSize; } }
public IdRange getReusableIdBatch( int maxSize ) { long[] tmpIdArr = new long[maxSize]; int count = 0; while ( count < maxSize ) { long id = freeIdKeeper.getId(); if ( id == NO_RESULT ) { break; } tmpIdArr[count++] = id; } long[] defragIdArr = count == maxSize ? tmpIdArr : Arrays.copyOfRange( tmpIdArr, 0, count ); return new IdRange( defragIdArr, 0, 0 ); }
@Override public synchronized IdRange nextIdBatch( int size ) { assertStillOpen(); long[] reusableIds = idContainer.getReusableIds( size ); int sizeLeftForRange = size - reusableIds.length; long start = highId; setHighId( start + sizeLeftForRange ); return new IdRange( reusableIds, start, sizeLeftForRange ); }
@Override public synchronized IdRange nextIdBatch( int size ) { long[] defragIds = PrimitiveLongCollections.EMPTY_LONG_ARRAY; if ( freeList != null && !freeList.isEmpty() ) { defragIds = new long[min( size, freeList.size() )]; for ( int i = 0; i < defragIds.length; i++ ) { defragIds[i] = freeList.poll(); } size -= defragIds.length; } return new IdRange( defragIds, nextId.getAndAdd( size ), size ); }
@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 ); }
@Test public void shouldContinueThroughEmptyIdBatch() { // given IdSequence idSource = mock( IdSequence.class ); Iterator<IdRange> ranges = asList( new IdRange( EMPTY_LONG_ARRAY, 0, BATCH_SIZE ), new IdRange( EMPTY_LONG_ARRAY, BATCH_SIZE, 0 ), new IdRange( EMPTY_LONG_ARRAY, BATCH_SIZE, BATCH_SIZE ) ).iterator(); when( idSource.nextIdBatch( anyInt() ) ).thenAnswer( invocation -> ranges.next() ); RenewableBatchIdSequence ids = new RenewableBatchIdSequence( idSource, BATCH_SIZE, excessIds::add ); // when/then for ( long expectedId = 0; expectedId < BATCH_SIZE * 2; expectedId++ ) { assertEquals( expectedId, ids.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 ) ); } } }
@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() ); }
@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() ); }
@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() ); }
@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 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 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() ); }
@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() ); } }
@Override public IdRange nextIdBatch( int size ) { while ( IdValidator.hasReservedIdInRange( nextId, nextId + size ) ) { nextId += size; } long startId = nextId; nextId += size; return new IdRange( EMPTY_LONG_ARRAY, startId, size ); }
public IdRange getReusableIdBatch( int maxSize ) { long[] tmpIdArr = new long[maxSize]; int count = 0; while ( count < maxSize ) { long id = freeIdKeeper.getId(); if ( id == NO_RESULT ) { break; } tmpIdArr[count++] = id; } long[] defragIdArr = count == maxSize ? tmpIdArr : Arrays.copyOfRange( tmpIdArr, 0, count ); return new IdRange( defragIdArr, 0, 0 ); }
private IdRange respectingHighId( IdRange idRange ) { int adjustment = 0; long originalRangeStart = idRange.getRangeStart(); if ( highId > originalRangeStart ) { adjustment = (int) (highId - originalRangeStart); } long rangeStart = max( this.highId, originalRangeStart ); int rangeLength = idRange.getRangeLength() - adjustment; if ( rangeLength <= 0 ) { throw new IllegalStateException( "IdAllocation state is probably corrupted or out of sync with the cluster. " + "Local highId is " + highId + " and allocation range is " + idRange ); } return new IdRange( idRange.getDefragIds(), rangeStart, rangeLength ); }
@Override public synchronized IdRange nextIdBatch( int size ) { assertStillOpen(); long[] reusableIds = idContainer.getReusableIds( size ); int sizeLeftForRange = size - reusableIds.length; long start = highId; setHighId( start + sizeLeftForRange ); return new IdRange( reusableIds, start, sizeLeftForRange ); }
IdAllocation acquireIds( IdType idType ) { while ( true ) { long firstUnallocated = idAllocationStateMachine.firstUnallocated( idType ); ReplicatedIdAllocationRequest idAllocationRequest = new ReplicatedIdAllocationRequest( me, idType, firstUnallocated, allocationSizes.get( idType ) ); if ( replicateIdAllocationRequest( idType, idAllocationRequest ) ) { IdRange idRange = new IdRange( EMPTY_LONG_ARRAY, firstUnallocated, allocationSizes.get( idType ) ); return new IdAllocation( idRange, -1, 0 ); } else { log.info( "Retrying ID generation due to conflict. Request was: " + idAllocationRequest ); } } }