@Override public void close() { delegate.close(); }
@Override public long getHighId() { return delegate.getHighId(); }
@Override public void freeId( long id ) { delegate.freeId( id ); }
/** * Sets the high id, i.e. highest id in use + 1 (use this when rebuilding id generator). * * @param highId The high id to set. */ public void setHighId( long highId ) { // This method might get called during recovery, where we don't have a reliable id generator yet, // so ignore these calls and let rebuildIdGenerators() figure out the high id after recovery. IdGenerator generator = this.idGenerator; if ( generator != null ) { //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized ( generator ) { if ( highId > generator.getHighId() ) { generator.setHighId( highId ); } } } }
private void closeStoreFile() throws IOException { try { /* * Note: the closing ordering here is important! * It is the case since we wand to mark the id generator as closed cleanly ONLY IF * also the store file is cleanly shutdown. */ if ( pagedFile != null ) { pagedFile.close(); } if ( idGenerator != null ) { if ( contains( openOptions, DELETE_ON_CLOSE ) ) { idGenerator.delete(); } else { idGenerator.close(); } } } finally { pagedFile = null; } }
@Test public void correctDefragCountWhenHaveIdsInFile() { IdGeneratorImpl.createGenerator( fsr.get(), file, 100, false ); IdGenerator idGenerator = new IdGeneratorImpl( fsr.get(), file, 100, 100, true, IdType.NODE, () -> 100L ); idGenerator.freeId( 5 ); idGenerator.close(); IdGenerator reloadedIdGenerator = new IdGeneratorImpl( fsr.get(), file, 100, 100, true, IdType.NODE, () -> 100L ); assertEquals( 1, reloadedIdGenerator.getDefragCount() ); assertEquals( 5, reloadedIdGenerator.nextId() ); assertEquals( 0, reloadedIdGenerator.getDefragCount() ); }
assertEquals( i, idGenerator.nextId() ); idGenerator.freeId( 1 ); idGenerator.freeId( 3 ); idGenerator.freeId( 5 ); assertEquals( 7L, idGenerator.nextId() ); idGenerator.freeId( 6 ); closeIdGenerator( idGenerator ); idGenerator = new IdGeneratorImpl( fs, idGeneratorFile(), 5, 1000, false, IdType.NODE, () -> 0L ); idGenerator.freeId( 2 ); idGenerator.freeId( 4 ); assertEquals( 1L, idGenerator.nextId() ); idGenerator.freeId( 1 ); assertEquals( 3L, idGenerator.nextId() ); idGenerator.freeId( 3 ); assertEquals( 5L, idGenerator.nextId() ); idGenerator.freeId( 5 ); assertEquals( 6L, idGenerator.nextId() ); idGenerator.freeId( 6 ); assertEquals( 8L, idGenerator.nextId() ); idGenerator.freeId( 8 ); assertEquals( 9L, idGenerator.nextId() ); idGenerator.freeId( 9 ); closeIdGenerator( idGenerator ); idGenerator = new IdGeneratorImpl( fs, idGeneratorFile(), 3, 1000, false, IdType.NODE, () -> 0L ); assertEquals( 6L, idGenerator.nextId() ); assertEquals( 8L, idGenerator.nextId() ); assertEquals( 9L, idGenerator.nextId() ); assertEquals( 1L, idGenerator.nextId() );
@Override public long getNumberOfIdsInUse() { return delegate.getNumberOfIdsInUse(); }
IdGenerator idGenerator = new IdGeneratorImpl( fs, idGeneratorFile(), 1, recordFormat.getMaxId(), false, IdType.NODE, () -> 0L ); idGenerator.setHighId( recordFormat.getMaxId() ); long id = idGenerator.nextId(); assertEquals( recordFormat.getMaxId(), id ); idGenerator.freeId( id ); try idGenerator.nextId(); fail( "Shouldn't be able to get next ID" ); assertEquals( recordFormat.getMaxId() + 1, idGenerator.getHighId() ); id = idGenerator.nextId(); assertEquals( recordFormat.getMaxId(), id ); try idGenerator.nextId();
@Test public void shouldReportCorrectHighId() { // given try ( IdGenerator idGenerator = createIdGenerator( 2 ) ) { assertEquals( 0, idGenerator.getHighId() ); assertEquals( -1, idGenerator.getHighestPossibleIdInUse() ); // when idGenerator.nextId(); // then assertEquals( 1, idGenerator.getHighId() ); assertEquals( 0, idGenerator.getHighestPossibleIdInUse() ); } }
@Test public void makeSureMagicMinusOneCannotBeReturnedEvenIfFreed() { IdGeneratorImpl.createGenerator( fs, idGeneratorFile(), 0, false ); IdGenerator idGenerator = new IdGeneratorImpl( fs, idGeneratorFile(), 1, new NodeRecordFormat().getMaxId(), false, IdType.NODE, () -> 0L ); long magicMinusOne = (long) Math.pow( 2, 32 ) - 1; idGenerator.setHighId( magicMinusOne ); assertEquals( magicMinusOne + 1, idGenerator.nextId() ); idGenerator.freeId( magicMinusOne - 1 ); idGenerator.freeId( magicMinusOne ); closeIdGenerator( idGenerator ); idGenerator = new IdGeneratorImpl( fs, idGeneratorFile(), 1, new NodeRecordFormat().getMaxId(), false, IdType.NODE, () -> 0L ); assertEquals( magicMinusOne - 1, idGenerator.nextId() ); assertEquals( magicMinusOne + 2, idGenerator.nextId() ); closeIdGenerator( idGenerator ); }
private void makeSureMagicMinusOneIsSkipped( RecordFormat format ) { deleteIdGeneratorFile(); IdGeneratorImpl.createGenerator( fs, idGeneratorFile(), 0, false ); IdGenerator idGenerator = new IdGeneratorImpl( fs, idGeneratorFile(), 1, format.getMaxId(), false, IdType.NODE, () -> 0L ); long id = (long) Math.pow( 2, 32 ) - 3; idGenerator.setHighId( id ); assertEquals( id, idGenerator.nextId() ); assertEquals( id + 1, idGenerator.nextId() ); // Here we make sure that id+2 (integer -1) is skipped assertEquals( id + 3, idGenerator.nextId() ); assertEquals( id + 4, idGenerator.nextId() ); assertEquals( id + 5, idGenerator.nextId() ); closeIdGenerator( idGenerator ); }
@Test public void mustOverwriteExistingFileIfRequested() { IdGeneratorImpl.createGenerator( fs, idGeneratorFile(), 0, false ); IdGenerator idGenerator = new IdGeneratorImpl( fs, idGeneratorFile(), 1008, 1000, false, IdType.NODE, () -> 0L ); long[] firstFirstIds = new long[]{idGenerator.nextId(), idGenerator.nextId(), idGenerator.nextId()}; idGenerator.close(); IdGeneratorImpl.createGenerator( fs, idGeneratorFile(), 0, false ); idGenerator = new IdGeneratorImpl( fs, idGeneratorFile(), 1008, 1000, false, IdType.NODE, () -> 0L ); long[] secondFirstIds = new long[]{idGenerator.nextId(), idGenerator.nextId(), idGenerator.nextId()}; idGenerator.close(); // Basically, recreating the id file should be the same as start over with the ids. assertThat( secondFirstIds, is( firstFirstIds ) ); }
@Override public long nextId() { return delegate.nextId(); }
@Override public long getHighestPossibleIdInUse() { return delegate.getHighestPossibleIdInUse(); }
@Override public void setHighId( long id ) { delegate.setHighId( id ); }
@Override public long getDefragCount() { return delegate.getDefragCount(); }
@Override public void delete() { delegate.delete(); } }