diff --git a/community/index/src/main/java/org/neo4j/index/internal/gbptree/GBPTree.java b/community/index/src/main/java/org/neo4j/index/internal/gbptree/GBPTree.java index c715a55d5d6d..48b1a905f256 100644 --- a/community/index/src/main/java/org/neo4j/index/internal/gbptree/GBPTree.java +++ b/community/index/src/main/java/org/neo4j/index/internal/gbptree/GBPTree.java @@ -921,7 +921,7 @@ void printTree( boolean printValues, boolean printPosition, boolean printState ) try ( PageCursor cursor = openRootCursor( PagedFile.PF_SHARED_READ_LOCK ) ) { new TreePrinter<>( bTreeNode, layout, stableGeneration( generation ), unstableGeneration( generation ) ) - .printTree( cursor, System.out, printValues, printPosition, printState ); + .printTree( cursor, cursor, System.out, printValues, printPosition, printState ); } } diff --git a/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreePrinter.java b/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreePrinter.java index 8253ce6155f9..5c88fc743466 100644 --- a/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreePrinter.java +++ b/community/index/src/main/java/org/neo4j/index/internal/gbptree/TreePrinter.java @@ -33,7 +33,7 @@ /** * Utility class for printing a {@link GBPTree}, either whole or sub-tree. */ -class TreePrinter +class TreePrinter { private final TreeNode node; private final Layout layout; @@ -54,13 +54,14 @@ class TreePrinter * Will print sub-tree from that point. Leaves cursor at same page as when called. No guarantees on offset. * * @param cursor {@link PageCursor} placed at root of tree or sub-tree. + * @param writeCursor Currently active {@link PageCursor write cursor} in tree. * @param out target to print tree at. * @param printPosition whether or not to include positional (slot number) information. * @param printState whether or not to also print state pages * @throws IOException on page cache access error. */ - void printTree( PageCursor cursor, PrintStream out, boolean printValues, boolean printPosition, boolean printState ) - throws IOException + void printTree( PageCursor cursor, PageCursor writeCursor, PrintStream out, boolean printValues, boolean printPosition, + boolean printState ) throws IOException { if ( printState ) { @@ -71,7 +72,7 @@ void printTree( PageCursor cursor, PrintStream out, boolean printValues, boolean out.println( "StateA: " + statePair.getLeft() ); out.println( "StateB: " + statePair.getRight() ); } - assertOnTreeNode( cursor ); + assertOnTreeNode( select( cursor, writeCursor ) ); // Traverse the tree int level = 0; @@ -82,13 +83,13 @@ void printTree( PageCursor cursor, PrintStream out, boolean printValues, boolean long leftmostSibling = cursor.getCurrentPageId(); // Go right through all siblings - printLevel( cursor, out, printValues, printPosition ); + printLevel( cursor, writeCursor, out, printValues, printPosition ); // Then go back to the left-most node on this level TreeNode.goTo( cursor, "back", leftmostSibling ); } // And continue down to next level if this level was an internal level - while ( goToLeftmostChild( cursor ) ); + while ( goToLeftmostChild( cursor, writeCursor ) ); } void printTreeNode( PageCursor cursor, PrintStream out, boolean printValues, boolean printPosition, @@ -104,7 +105,8 @@ void printTreeNode( PageCursor cursor, PrintStream out, boolean printValues, boo { cursor.setCursorException( "Unexpected keyCount " + keyCount ); } - } while ( cursor.shouldRetry() ); + } + while ( cursor.shouldRetry() ); if ( printHeader ) { @@ -114,7 +116,8 @@ void printTreeNode( PageCursor cursor, PrintStream out, boolean printValues, boo { generation = TreeNode.generation( cursor ); - } while ( cursor.shouldRetry() ); + } + while ( cursor.shouldRetry() ); String treeNodeType = isLeaf ? "leaf" : "internal"; out.print( format( "{%d,%s,generation=%d,keyCount=%d}", cursor.getCurrentPageId(), treeNodeType, generation, keyCount ) ); @@ -179,10 +182,11 @@ void printTreeNode( PageCursor cursor, PrintStream out, boolean printValues, boo out.println(); } - private boolean goToLeftmostChild( PageCursor cursor ) throws IOException + private boolean goToLeftmostChild( PageCursor readCursor, PageCursor writeCursor ) throws IOException { boolean isInternal; long leftmostSibling = -1; + PageCursor cursor = select( readCursor, writeCursor ); do { isInternal = TreeNode.isInternal( cursor ); @@ -195,18 +199,18 @@ private boolean goToLeftmostChild( PageCursor cursor ) throws IOException if ( isInternal ) { - TreeNode.goTo( cursor, "child", leftmostSibling ); + TreeNode.goTo( readCursor, "child", leftmostSibling ); } return isInternal; } - private void printLevel( PageCursor cursor, PrintStream out, boolean printValues, boolean printPosition ) + private void printLevel( PageCursor readCursor, PageCursor writeCursor, PrintStream out, boolean printValues, boolean printPosition ) throws IOException { long rightSibling = -1; do { - + PageCursor cursor = select( readCursor, writeCursor ); printTreeNode( cursor, out, printValues, printPosition, false ); do @@ -217,9 +221,14 @@ private void printLevel( PageCursor cursor, PrintStream out, boolean printValues if ( TreeNode.isNode( rightSibling ) ) { - TreeNode.goTo( cursor, "right sibling", rightSibling ); + TreeNode.goTo( readCursor, "right sibling", rightSibling ); } } while ( TreeNode.isNode( rightSibling ) ); } + + private static PageCursor select( PageCursor readCursor, PageCursor writeCursor ) + { + return readCursor.getCurrentPageId() == writeCursor.getCurrentPageId() ? writeCursor : readCursor; + } } diff --git a/community/index/src/test/java/org/neo4j/index/internal/gbptree/InternalTreeLogicTest.java b/community/index/src/test/java/org/neo4j/index/internal/gbptree/InternalTreeLogicTest.java index 78a2a25f6145..dcac90705c96 100644 --- a/community/index/src/test/java/org/neo4j/index/internal/gbptree/InternalTreeLogicTest.java +++ b/community/index/src/test/java/org/neo4j/index/internal/gbptree/InternalTreeLogicTest.java @@ -1529,7 +1529,7 @@ private void printTree() throws IOException { long currentPageId = cursor.getCurrentPageId(); cursor.next( rootId ); - new TreePrinter<>( node, layout, stableGeneration, unstableGeneration ).printTree( cursor, System.out, true, true, true ); + new TreePrinter<>( node, layout, stableGeneration, unstableGeneration ).printTree( cursor, cursor, System.out, true, true, true ); cursor.next( currentPageId ); }