public void freeId( long id ) { freeIdKeeper.freeId( id ); }
@Test public void shouldOnlyOverflowWhenThresholdIsReached() throws Exception { // Given StoreChannel channel = spy( fs.get().open( new File( "id.file" ), OpenMode.READ_WRITE ) ); int batchSize = 10; FreeIdKeeper keeper = getFreeIdKeeperAggressive( channel, batchSize ); reset( channel ); // because we get the position in the constructor, we need to reset all calls on the spy // when // we free 9 ids for ( int i = 0; i < batchSize - 1; i++ ) { keeper.freeId( i ); } // then verifyZeroInteractions( channel ); // when we free one more keeper.freeId( 10 ); // then verify( channel ).writeAll( any( ByteBuffer.class ) ); }
@Test public void persistedIdsShouldStillBeCounted() throws Exception { // given StoreChannel channel = getStoreChannel(); int batchSize = 10; FreeIdKeeper keeper = new FreeIdKeeper( channel, batchSize, true ); // when // we store enough ids to cause overflow to file for ( int i = 0; i < batchSize; i++ ) { keeper.freeId( i ); } // and then some more int extraIds = 3; for ( int i = batchSize; i < batchSize + extraIds; i++ ) { keeper.freeId( i ); } // then // the count should be returned correctly assertEquals( batchSize + extraIds, keeper.getCount() ); }
@Test public void shouldNotReturnIdsPersistedDuringThisRunIfAggressiveIsFalse() throws Exception { // given StoreChannel channel = spy( fs.get().open( new File( "id.file" ), OpenMode.READ_WRITE ) ); int batchSize = 10; FreeIdKeeper keeper = getFreeIdKeeper( channel, batchSize ); // when // enough ids are persisted to overflow for ( int i = 0; i < batchSize; i++ ) { keeper.freeId( i ); } // then // stuff must have been written to disk verify( channel, times( 1 ) ).write( any( ByteBuffer.class ) ); // and no ids can be returned assertEquals( NO_RESULT, keeper.getId() ); }
@Test public void shouldNotReturnNewlyReleasedIdsIfAggressiveIsFalse() throws Exception { // given FreeIdKeeper keeper = getFreeIdKeeper(); // when keeper.freeId( 1 ); long nextFree = keeper.getId(); // then assertEquals( NO_RESULT, nextFree ); }
@Test public void shouldReadBackManyPersistedIdBatchesWhenAggressiveModeIsSet() throws Exception { // given StoreChannel channel = getStoreChannel(); int batchSize = 10; FreeIdKeeper keeper = getFreeIdKeeperAggressive( channel, batchSize ); Set<Long> freeIds = new HashSet<>(); // when // we store enough ids to cause overflow to file, in two batches for ( long i = 0; i < batchSize * 2; i++ ) { keeper.freeId( i ); freeIds.add( i ); } // then // they should be returned assertEquals( freeIds.size(), keeper.getCount() ); for ( int i = batchSize * 2 - 1; i >= 0; i-- ) { assertTrue( freeIds.remove( keeper.getId() ) ); } }
@Test public void allocateBatchWhenHaveLessIdsInMemoryButHaveOnDiskMore() throws IOException { FreeIdKeeper freeIdKeeper = getFreeIdKeeperAggressive( 4 ); for ( long id = 1L; id < 11L; id++ ) { freeIdKeeper.freeId( id ); } long[] ids = freeIdKeeper.getIds( 7 ); assertArrayEquals( new long[]{9L, 10L, 5L, 6L, 7L, 8L, 1L}, ids ); assertEquals( 3, freeIdKeeper.getCount() ); }
@Test public void allocateBatchWhenHaveMoreIdsInMemory() throws IOException { FreeIdKeeper freeIdKeeper = getFreeIdKeeperAggressive(); for ( long id = 1L; id < 7L; id++ ) { freeIdKeeper.freeId( id ); } long[] ids = freeIdKeeper.getIds( 5 ); assertArrayEquals( new long[]{1L, 2L, 3L, 4L, 5L}, ids); assertEquals( 1, freeIdKeeper.getCount() ); }
@Test public void allocateBatchWhenHaveLessIdsInMemory() throws IOException { FreeIdKeeper freeIdKeeper = getFreeIdKeeperAggressive(); for ( long id = 1L; id < 4L; id++ ) { freeIdKeeper.freeId( id ); } long[] ids = freeIdKeeper.getIds( 5 ); assertArrayEquals( new long[]{1L, 2L, 3L}, ids ); assertEquals( 0, freeIdKeeper.getCount() ); }
@Test public void allocateBatchWhenHaveLessIdsInMemoryAndOnDisk() throws IOException { FreeIdKeeper freeIdKeeper = getFreeIdKeeperAggressive( 4 ); for ( long id = 1L; id < 10L; id++ ) { freeIdKeeper.freeId( id ); } long[] ids = freeIdKeeper.getIds( 15 ); assertArrayEquals( new long[]{9L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L}, ids ); assertEquals( 0, freeIdKeeper.getCount() ); }
keeper.freeId( idGen++ );
@Test public void shouldReadBackPersistedIdsWhenAggressiveModeIsSet() throws Exception { // given StoreChannel channel = getStoreChannel(); int batchSize = 10; FreeIdKeeper keeper = getFreeIdKeeperAggressive( channel, batchSize ); // when // we store enough ids to cause overflow to file for ( int i = 0; i < batchSize; i++ ) { keeper.freeId( i ); } // then // they should be returned in order for ( int i = 0; i < batchSize; i++ ) { assertEquals( i, keeper.getId() ); } }
@Test public void shouldReturnMinusOneWhenRunningOutOfIds() throws Exception { // Given FreeIdKeeper keeper = getFreeIdKeeperAggressive(); // when keeper.freeId( 13 ); // then assertEquals( 13, keeper.getId() ); assertEquals( NO_RESULT, keeper.getId() ); assertEquals( NO_RESULT, keeper.getId() ); }
@Test public void freeingAnIdShouldReturnThatIdAndUpdateTheCountWhenAggressiveModeIsSet() throws Exception { // Given FreeIdKeeper keeper = getFreeIdKeeperAggressive(); // when keeper.freeId( 13 ); // then assertEquals( 1, keeper.getCount() ); // when long result = keeper.getId(); // then assertEquals( 13, result ); assertEquals( 0, keeper.getCount() ); }
@Test public void shouldTruncateFileInAggressiveMode() throws Exception { // given StoreChannel channel = getStoreChannel(); int batchSize = 10; FreeIdKeeper keeper = getFreeIdKeeperAggressive( channel, batchSize ); // free 4 batches for ( long i = 0; i < batchSize * 4; i++ ) { keeper.freeId( i ); } assertEquals( channel.size(), 4 * batchSize * Long.BYTES ); // when for ( int i = 0; i < batchSize * 2; i++ ) { keeper.getId(); } // then assertEquals( channel.size(), 2 * batchSize * Long.BYTES ); }