diff --git a/community/index/src/main/java/org/neo4j/index/gbptree/GBPTree.java b/community/index/src/main/java/org/neo4j/index/gbptree/GBPTree.java index 94a28816e3cf3..ee34e34be23a9 100644 --- a/community/index/src/main/java/org/neo4j/index/gbptree/GBPTree.java +++ b/community/index/src/main/java/org/neo4j/index/gbptree/GBPTree.java @@ -297,7 +297,7 @@ private PagedFile openOrCreate( PageCache pageCache, File indexFile, { readMeta( indexFile, layout, pagedFile ); pagedFile = mapWithCorrectPageSize( pageCache, indexFile, pagedFile ); - readState( pagedFile ); + loadState( pagedFile ); return pagedFile; } catch ( Throwable t ) @@ -332,39 +332,46 @@ private PagedFile openOrCreate( PageCache pageCache, File indexFile, } } - private void readState( PagedFile pagedFile ) throws IOException + private void loadState( PagedFile pagedFile ) throws IOException { - try ( PageCursor cursor = pagedFile.io( 0L /*ignored*/, PagedFile.PF_SHARED_WRITE_LOCK ) ) + Pair states = readStatePages( pagedFile ); + TreeState state = TreeStatePair.selectNewestValidState( states ); + rootId = state.rootId(); + lastId = state.lastId(); + generation = Generation.generation( state.stableGeneration(), state.unstableGeneration() ); + } + + private void writeState( PagedFile pagedFile ) throws IOException + { + Pair states = readStatePages( pagedFile ); + TreeState oldestState = TreeStatePair.selectOldestOrInvalid( states ); + long pageToOverwrite = oldestState.pageId(); + try ( PageCursor cursor = pagedFile.io( pageToOverwrite, PagedFile.PF_SHARED_WRITE_LOCK ) ) { - Pair states = TreeStatePair.readStatePages( - cursor, IdSpace.STATE_PAGE_A, IdSpace.STATE_PAGE_B ); + PageCursorUtil.goTo( cursor, "state page", pageToOverwrite ); + TreeState.write( cursor, stableGeneration( generation ), unstableGeneration( generation ), rootId, lastId ); checkOutOfBounds( cursor ); - - TreeState state = TreeStatePair.selectNewestValidState( states ); - rootId = state.rootId(); - lastId = state.lastId(); - generation = Generation.generation( state.stableGeneration(), state.unstableGeneration() ); } } - private void writeState( PagedFile pagedFile ) throws IOException + private Pair readStatePages( PagedFile pagedFile ) throws IOException { - try ( PageCursor cursor = pagedFile.io( 0L /*ignored*/, PagedFile.PF_SHARED_WRITE_LOCK ) ) + Pair states; + try ( PageCursor cursor = pagedFile.io( 0L /*ignored*/, PagedFile.PF_SHARED_READ_LOCK ) ) { - Pair states = TreeStatePair.readStatePages( - cursor, IdSpace.STATE_PAGE_A, IdSpace.STATE_PAGE_B ); + do + { + states = TreeStatePair.readStatePages( + cursor, IdSpace.STATE_PAGE_A, IdSpace.STATE_PAGE_B ); + } while ( cursor.shouldRetry() ); checkOutOfBounds( cursor ); - TreeState oldestState = TreeStatePair.selectOldestOrInvalid( states ); - long pageToOverwrite = oldestState.pageId(); - PageCursorUtil.goTo( cursor, "state page", pageToOverwrite ); - cursor.setOffset( 0 ); - TreeState.write( cursor, stableGeneration( generation ), unstableGeneration( generation ), rootId, lastId ); } + return states; } - private static PageCursor openMetaPageCursor( PagedFile pagedFile ) throws IOException + private static PageCursor openMetaPageCursor( PagedFile pagedFile, int pfFlags ) throws IOException { - PageCursor metaCursor = pagedFile.io( IdSpace.META_PAGE_ID, PagedFile.PF_SHARED_WRITE_LOCK ); + PageCursor metaCursor = pagedFile.io( IdSpace.META_PAGE_ID, pfFlags ); PageCursorUtil.goTo( metaCursor, "meta page", IdSpace.META_PAGE_ID ); return metaCursor; } @@ -376,7 +383,7 @@ private void readMeta( File indexFile, Layout layout, PagedFile paged long layoutIdentifier; int majorVersion; int minorVersion; - try ( PageCursor metaCursor = openMetaPageCursor( pagedFile ) ) + try ( PageCursor metaCursor = openMetaPageCursor( pagedFile, PagedFile.PF_SHARED_READ_LOCK ) ) { do { @@ -405,7 +412,7 @@ private void readMeta( File indexFile, Layout layout, PagedFile paged private void writeMeta( Layout layout, PagedFile pagedFile ) throws IOException { - try ( PageCursor metaCursor = openMetaPageCursor( pagedFile ) ) + try ( PageCursor metaCursor = openMetaPageCursor( pagedFile, PagedFile.PF_SHARED_WRITE_LOCK ) ) { metaCursor.putInt( pageSize ); metaCursor.putLong( layout.identifier() );