RoundRobinArrayIndex { public int next( int arrayLength ) { if ( arrayLength == 0 ) { return -1; } int nextOffset; while ( (nextOffset = offset.getAndIncrement()) < 0 ) { offset.compareAndSet( nextOffset + 1, 0 ); } return nextOffset % arrayLength; } RoundRobinArrayIndex();   RoundRobinArrayIndex( int initialOffset ); int next( int arrayLength );  }
@Test void shouldHandleZeroLength() { RoundRobinArrayIndex roundRobinIndex = new RoundRobinArrayIndex(); int index = roundRobinIndex.next( 0 ); assertEquals( -1, index ); }
@Test void shouldReturnIndexesInRoundRobinOrder() { RoundRobinArrayIndex roundRobinIndex = new RoundRobinArrayIndex(); for ( int i = 0; i < 10; i++ ) { int index = roundRobinIndex.next( 10 ); assertEquals( i, index ); } for ( int i = 0; i < 5; i++ ) { int index = roundRobinIndex.next( 5 ); assertEquals( i, index ); } }
@Test void shouldHandleOverflow() { int arrayLength = 10; RoundRobinArrayIndex roundRobinIndex = new RoundRobinArrayIndex( Integer.MAX_VALUE - 1 ); assertEquals( (Integer.MAX_VALUE - 1) % arrayLength, roundRobinIndex.next( arrayLength ) ); assertEquals( Integer.MAX_VALUE % arrayLength, roundRobinIndex.next( arrayLength ) ); assertEquals( 0, roundRobinIndex.next( arrayLength ) ); assertEquals( 1, roundRobinIndex.next( arrayLength ) ); assertEquals( 2, roundRobinIndex.next( arrayLength ) ); }