Skip to content

Commit

Permalink
Make the record formats report decoding errors through the page curso…
Browse files Browse the repository at this point in the history
…r setCursorError mechanism.
  • Loading branch information
chrisvest committed May 20, 2016
1 parent 0ca712b commit 2afb91a
Show file tree
Hide file tree
Showing 39 changed files with 505 additions and 233 deletions.
Expand Up @@ -299,7 +299,8 @@ public abstract class PageCursor implements AutoCloseable
public abstract boolean checkAndClearBoundsFlag();

/**
* Check if a cursor error has been set, and if so, remove it from the cursor and throw it.
* Check if a cursor error has been set on this or any linked cursor, and if so, remove it from the cursor
* and throw it as a {@link CursorException}.
*/
public abstract void checkAndClearCursorError() throws CursorException;

Expand All @@ -321,6 +322,12 @@ public abstract class PageCursor implements AutoCloseable
*/
public abstract void setCursorError( String message );

/**
* Unconditionally clear any error condition that has been set on this or any linked cursor, without throwing an
* exception.
*/
public abstract void clearCursorError();

/**
* Open a new page cursor with the same pf_flags as this cursor, as if calling the {@link PagedFile#io(long, int)}
* on the relevant paged file. This cursor will then also delegate to the linked cursor when checking
Expand Down
Expand Up @@ -470,6 +470,13 @@ public void setCursorError( String message )
cursor( 0 ).setCursorError( message );
}

@Override
public void clearCursorError()
{
first.clearCursorError();
second.clearCursorError();
}

@Override
public PageCursor openLinkedCursor( long pageId )
{
Expand Down
Expand Up @@ -155,6 +155,12 @@ public void setCursorError( String message )
delegate.setCursorError( message );
}

@Override
public void clearCursorError()
{
delegate.clearCursorError();
}

@Override
public PageCursor openLinkedCursor( long pageId )
{
Expand Down
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.io.pagecache.impl.muninn;

import org.neo4j.io.pagecache.CursorException;

/**
* This exception is used to indicate in the stack trace, whether or not
* {@link MuninnPageCursor#usePreciseCursorErrorStackTraces} is enabled.
*
* This is useful because it allows us to clearly see how much we can trust the stack traces for decoding errors.
*/
final class CursorExceptionWithPreciseStackTrace extends CursorException
{
public CursorExceptionWithPreciseStackTrace( String message )
{
super( message );
}
}
Expand Up @@ -21,6 +21,7 @@

import java.io.File;
import java.io.IOException;
import java.util.Objects;

import org.neo4j.concurrent.BinaryLatch;
import org.neo4j.io.pagecache.CursorException;
Expand All @@ -38,6 +39,9 @@ abstract class MuninnPageCursor extends PageCursor
private static final boolean tracePinnedCachePageId =
flag( MuninnPageCursor.class, "tracePinnedCachePageId", false );

private static final boolean usePreciseCursorErrorStackTraces =
flag( MuninnPageCursor.class, "usePreciseCursorErrorStackTraces", true );

// Size of the respective primitive types in bytes.
private static final int SIZE_OF_BYTE = Byte.BYTES;
private static final int SIZE_OF_SHORT = Short.BYTES;
Expand All @@ -60,7 +64,10 @@ abstract class MuninnPageCursor extends PageCursor
private int filePageSize;
private int offset;
private boolean outOfBounds;
private String cursorExceptionMessage;
// This is a String with the exception message if usePreciseCursorErrorStackTraces is false, otherwise it is a
// CursorExceptionWithPreciseStackTrace with the message and stack trace pointing more or less directly at the
// offending code.
private Object cursorException;

MuninnPageCursor( long victimPage )
{
Expand Down Expand Up @@ -104,7 +111,7 @@ public final void reset( MuninnPage page )
@Override
public final boolean next( long pageId ) throws IOException
{
if ( currentPageId == nextPageId )
if ( currentPageId == pageId )
{
return true;
}
Expand Down Expand Up @@ -166,7 +173,7 @@ void clearPageState()
pageSize = 0; // make all future bound checks fail
page = null; // make all future page navigation fail
currentPageId = UNBOUND_PAGE_ID;
cursorExceptionMessage = null;
cursorException = null;
}

@Override
Expand Down Expand Up @@ -708,18 +715,26 @@ public void checkAndClearCursorError() throws CursorException
MuninnPageCursor cursor = this;
do
{
String message = cursor.cursorExceptionMessage;
if ( message != null )
Object error = cursor.cursorException;
if ( error != null )
{
clearCursorError( cursor );
throw new CursorException( message );
if ( usePreciseCursorErrorStackTraces )
{
throw (CursorExceptionWithPreciseStackTrace) error;
}
else
{
throw new CursorException( (String) error );
}
}
cursor = cursor.linkedCursor;
}
while ( cursor != null );
}

protected void clearCursorError()
@Override
public void clearCursorError()
{
clearCursorError( this );
}
Expand All @@ -728,7 +743,7 @@ private void clearCursorError( MuninnPageCursor cursor )
{
while ( cursor != null )
{
cursor.cursorExceptionMessage = null;
cursor.cursorException = null;
cursor = cursor.linkedCursor;
}
}
Expand All @@ -742,6 +757,14 @@ public void raiseOutOfBounds()
@Override
public void setCursorError( String message )
{
this.cursorExceptionMessage = message;
Objects.requireNonNull( message );
if ( usePreciseCursorErrorStackTraces )
{
this.cursorException = new CursorExceptionWithPreciseStackTrace( message );
}
else
{
this.cursorException = message;
}
}
}
Expand Up @@ -371,20 +371,26 @@ public boolean shouldRetry() throws IOException
IllegalStateException.class );
if ( state.hasPreparedInconsistentRead() )
{
delegate.shouldRetry();
delegate.setOffset( 0 );
resetDelegate();
return true;
}
if ( state.hasInconsistentRead() )
{
delegate.shouldRetry();
delegate.setOffset( 0 );
resetDelegate();
return true;
}
boolean retry = delegate.shouldRetry();
return retry || (linkedCursor != null && linkedCursor.shouldRetry());
}

private void resetDelegate() throws IOException
{
delegate.shouldRetry();
delegate.setOffset( 0 );
delegate.checkAndClearBoundsFlag();
delegate.clearCursorError();
}

@Override
public int copyTo( int sourceOffset, PageCursor targetCursor, int targetOffset, int lengthInBytes )
{
Expand Down Expand Up @@ -424,6 +430,12 @@ public void setCursorError( String message )
delegate.setCursorError( message );
}

@Override
public void clearCursorError()
{
delegate.clearCursorError();
}

@Override
public PageCursor openLinkedCursor( long pageId )
{
Expand Down
Expand Up @@ -291,6 +291,12 @@ public void setCursorError( String message )
delegate.setCursorError( message );
}

@Override
public void clearCursorError()
{
delegate.clearCursorError();
}

@Override
public PageCursor openLinkedCursor( long pageId )
{
Expand Down

0 comments on commit 2afb91a

Please sign in to comment.