Skip to content

Commit

Permalink
Split page cache tracer into page cache tracer and page cursor tracer…
Browse files Browse the repository at this point in the history
…. Cleanup interfaces. Tests are in best case compilable.
  • Loading branch information
MishaDemianenko committed Feb 27, 2017
1 parent e73c83b commit 39b6036
Show file tree
Hide file tree
Showing 22 changed files with 739 additions and 425 deletions.
Expand Up @@ -27,9 +27,9 @@
import org.neo4j.io.pagecache.CursorException; import org.neo4j.io.pagecache.CursorException;
import org.neo4j.io.pagecache.PageCursor; import org.neo4j.io.pagecache.PageCursor;
import org.neo4j.io.pagecache.PageSwapper; import org.neo4j.io.pagecache.PageSwapper;
import org.neo4j.io.pagecache.tracing.PageCacheTracer;
import org.neo4j.io.pagecache.tracing.PageFaultEvent; import org.neo4j.io.pagecache.tracing.PageFaultEvent;
import org.neo4j.io.pagecache.tracing.PinEvent; import org.neo4j.io.pagecache.tracing.PinEvent;
import org.neo4j.io.pagecache.tracing.cursor.DefaultPageCursorTracer;
import org.neo4j.unsafe.impl.internal.dragons.UnsafeUtil; import org.neo4j.unsafe.impl.internal.dragons.UnsafeUtil;


import static org.neo4j.io.pagecache.PagedFile.PF_SHARED_WRITE_LOCK; import static org.neo4j.io.pagecache.PagedFile.PF_SHARED_WRITE_LOCK;
Expand All @@ -54,7 +54,6 @@ abstract class MuninnPageCursor extends PageCursor
private final long victimPage; private final long victimPage;
protected MuninnPagedFile pagedFile; protected MuninnPagedFile pagedFile;
protected PageSwapper swapper; protected PageSwapper swapper;
protected PageCacheTracer tracer;
protected MuninnPage page; protected MuninnPage page;
protected PinEvent pinEvent; protected PinEvent pinEvent;
protected long pageId; protected long pageId;
Expand All @@ -72,6 +71,8 @@ abstract class MuninnPageCursor extends PageCursor
// offending code. // offending code.
private Object cursorException; private Object cursorException;


private DefaultPageCursorTracer pageCursorTracer = new DefaultPageCursorTracer();

MuninnPageCursor( long victimPage ) MuninnPageCursor( long victimPage )
{ {
this.victimPage = victimPage; this.victimPage = victimPage;
Expand All @@ -81,7 +82,7 @@ abstract class MuninnPageCursor extends PageCursor
final void initialiseFile( MuninnPagedFile pagedFile ) final void initialiseFile( MuninnPagedFile pagedFile )
{ {
this.swapper = pagedFile.swapper; this.swapper = pagedFile.swapper;
this.tracer = pagedFile.tracer; this.pageCursorTracer.init( pagedFile.tracer );
} }


final void initialiseFlags( MuninnPagedFile pagedFile, long pageId, int pf_flags ) final void initialiseFlags( MuninnPagedFile pagedFile, long pageId, int pf_flags )
Expand Down Expand Up @@ -131,6 +132,7 @@ public final void close()
if ( cursor.pagedFile != null ) if ( cursor.pagedFile != null )
{ {
cursor.unpinCurrentPage(); cursor.unpinCurrentPage();
cursor.pageCursorTracer.reportEvents();
cursor.releaseCursor(); cursor.releaseCursor();
// We null out the pagedFile field to allow it and its (potentially big) translation table to be garbage // We null out the pagedFile field to allow it and its (potentially big) translation table to be garbage
// collected when the file is unmapped, since the cursors can stick around in thread local caches, etc. // collected when the file is unmapped, since the cursors can stick around in thread local caches, etc.
Expand Down Expand Up @@ -209,7 +211,7 @@ public final File getCurrentFile()
*/ */
protected void pin( long filePageId, boolean writeLock ) throws IOException protected void pin( long filePageId, boolean writeLock ) throws IOException
{ {
pinEvent = tracer.beginPin( writeLock, filePageId, swapper ); pinEvent = pageCursorTracer.beginPin( writeLock, filePageId, swapper );
int chunkId = MuninnPagedFile.computeChunkId( filePageId ); int chunkId = MuninnPagedFile.computeChunkId( filePageId );
// The chunkOffset is the addressing offset into the chunk array object for the relevant array slot. Using // The chunkOffset is the addressing offset into the chunk array object for the relevant array slot. Using
// this, we can access the array slot with Unsafe. // this, we can access the array slot with Unsafe.
Expand Down
Expand Up @@ -27,5 +27,5 @@
public interface AutoCloseablePageCacheTracerEvent extends AutoCloseable public interface AutoCloseablePageCacheTracerEvent extends AutoCloseable
{ {
@Override @Override
public void close(); void close();
} }
Expand Up @@ -36,52 +36,6 @@
*/ */
public class DefaultPageCacheTracer implements PageCacheTracer public class DefaultPageCacheTracer implements PageCacheTracer
{ {
private static final MethodHandle beginPinMH;
private static final SwitchPoint beginPinSwitchPoint;
static
{
try
{
// A hidden setting to have pin/unpin monitoring enabled from the start by default.
// NOTE: This flag is documented in jmx.asciidoc
boolean alwaysEnabled = packageFlag( DefaultPageCacheTracer.class, "tracePinUnpin", false );

MethodType type = MethodType.methodType( PinEvent.class );
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle monitoredPinMH = lookup.findVirtual( DefaultPageCacheTracer.class, "beginTracingPin", type );
if ( alwaysEnabled )
{
beginPinMH = monitoredPinMH;
beginPinSwitchPoint = null;
}
else
{
MethodHandle nullPinMH = lookup.findVirtual( DefaultPageCacheTracer.class, "beginNullPin", type );
beginPinSwitchPoint = new SwitchPoint();
beginPinMH = beginPinSwitchPoint.guardWithTest( nullPinMH, monitoredPinMH );
}
}
catch ( Exception e )
{
throw new AssertionError( "Unexpected MethodHandle initiation error", e );
}
}

/**
* Enable monitoring of page pins and unpins, which is disabled by default for
* performance reasons.
*
* This is a one-way operation; once monitoring of pinning and unpinning has been
* enabled, it cannot be disabled again without restarting the JVM.
*/
public static void enablePinUnpinTracing()
{
if ( beginPinSwitchPoint != null && !beginPinSwitchPoint.hasBeenInvalidated() )
{
SwitchPoint.invalidateAll( new SwitchPoint[]{ beginPinSwitchPoint } );
}
}

protected final AtomicLong faults = new AtomicLong(); protected final AtomicLong faults = new AtomicLong();
protected final AtomicLong evictions = new AtomicLong(); protected final AtomicLong evictions = new AtomicLong();
protected final AtomicLong pins = new AtomicLong(); protected final AtomicLong pins = new AtomicLong();
Expand Down Expand Up @@ -178,77 +132,6 @@ public void close()
} }
}; };


private final PageFaultEvent pageFaultEvent = new PageFaultEvent()
{
@Override
public void addBytesRead( long bytes )
{
bytesRead.getAndAdd( bytes );
}

@Override
public void done()
{
faults.getAndIncrement();
}

@Override
public void done( Throwable throwable )
{
done();
}

@Override
public EvictionEvent beginEviction()
{
return evictionEvent;
}

@Override
public void setCachePageId( int cachePageId )
{
}
};

private final PinEvent pinTracingEvent = new PinEvent()
{
@Override
public void setCachePageId( int cachePageId )
{
}

@Override
public PageFaultEvent beginPageFault()
{
return pageFaultEvent;
}

@Override
public void done()
{
unpins.getAndIncrement();
}
};

private final PinEvent nullPinEvent = new PinEvent()
{
@Override
public void setCachePageId( int cachePageId )
{
}

@Override
public PageFaultEvent beginPageFault()
{
return pageFaultEvent;
}

@Override
public void done()
{
}
};

private final MajorFlushEvent majorFlushEvent = new MajorFlushEvent() private final MajorFlushEvent majorFlushEvent = new MajorFlushEvent()
{ {
@Override @Override
Expand Down Expand Up @@ -281,38 +164,6 @@ public EvictionRunEvent beginPageEvictions( int pageCountToEvict )
return evictionRunEvent; return evictionRunEvent;
} }


@Override
public PinEvent beginPin( boolean writeLock, long filePageId, PageSwapper swapper )
{
try
{
return (PinEvent) beginPinMH.invokeExact( this );
}
catch ( Throwable throwable )
{
throw new AssertionError( "Unexpected MethodHandle error", throwable );
}
}

/**
* Invoked through beginPinMH.
*/
@SuppressWarnings( "UnusedDeclaration" )
private PinEvent beginNullPin()
{
return nullPinEvent;
}

/**
* Invoked through beginPinMH.
*/
@SuppressWarnings( "UnusedDeclaration" )
private PinEvent beginTracingPin()
{
pins.getAndIncrement();
return pinTracingEvent;
}

@Override @Override
public MajorFlushEvent beginFileFlush( PageSwapper swapper ) public MajorFlushEvent beginFileFlush( PageSwapper swapper )
{ {
Expand Down Expand Up @@ -384,4 +235,28 @@ public long evictionExceptions()
{ {
return evictionExceptions.get(); return evictionExceptions.get();
} }

@Override
public void pins( long pins )
{
this.pins.getAndAdd( pins );
}

@Override
public void unpins( long unpins )
{
this.unpins.getAndAdd( unpins );
}

@Override
public void faults( long faults )
{
this.faults.getAndAdd( faults );
}

@Override
public void bytesRead( long bytesRead )
{
this.bytesRead.getAndAdd( bytesRead );
}
} }
Expand Up @@ -68,26 +68,26 @@ public void close()
/** /**
* The file page id the evicted page was bound to. * The file page id the evicted page was bound to.
*/ */
public void setFilePageId( long filePageId ); void setFilePageId( long filePageId );


/** /**
* The swapper the evicted page was bound to. * The swapper the evicted page was bound to.
*/ */
public void setSwapper( PageSwapper swapper ); void setSwapper( PageSwapper swapper );


/** /**
* Eviction implies an opportunity to flush. * Eviction implies an opportunity to flush.
*/ */
public FlushEventOpportunity flushEventOpportunity(); FlushEventOpportunity flushEventOpportunity();


/** /**
* Indicates that the eviction caused an exception to be thrown. * Indicates that the eviction caused an exception to be thrown.
* This can happen if some kind of IO error occurs. * This can happen if some kind of IO error occurs.
*/ */
public void threwException( IOException exception ); void threwException( IOException exception );


/** /**
* The cache page id of the evicted page. * The cache page id of the evicted page.
*/ */
public void setCachePageId( int cachePageId ); void setCachePageId( int cachePageId );
} }
Expand Up @@ -47,5 +47,5 @@ public void close()
/** /**
* An eviction is started as part of this eviction run. * An eviction is started as part of this eviction run.
*/ */
public EvictionEvent beginEviction(); EvictionEvent beginEviction();
} }
Expand Up @@ -31,17 +31,10 @@ public interface FlushEventOpportunity
/** /**
* A FlushEventOpportunity that only returns the FlushEvent.NULL. * A FlushEventOpportunity that only returns the FlushEvent.NULL.
*/ */
FlushEventOpportunity NULL = new FlushEventOpportunity() FlushEventOpportunity NULL = ( filePageId, cachePageId, swapper ) -> FlushEvent.NULL;
{
@Override
public FlushEvent beginFlush( long filePageId, int cachePageId, PageSwapper swapper )
{
return FlushEvent.NULL;
}
};


/** /**
* Begin flushing the given page. * Begin flushing the given page.
*/ */
public FlushEvent beginFlush( long filePageId, int cachePageId, PageSwapper swapper ); FlushEvent beginFlush( long filePageId, int cachePageId, PageSwapper swapper );
} }
Expand Up @@ -44,5 +44,5 @@ public void close()
/** /**
* Mass-flushing obviously imply flushing opportunities. * Mass-flushing obviously imply flushing opportunities.
*/ */
public FlushEventOpportunity flushEventOpportunity(); FlushEventOpportunity flushEventOpportunity();
} }
Expand Up @@ -52,12 +52,6 @@ public EvictionRunEvent beginPageEvictions( int pageCountToEvict )
return EvictionRunEvent.NULL; return EvictionRunEvent.NULL;
} }


@Override
public PinEvent beginPin( boolean writeLock, long filePageId, PageSwapper swapper )
{
return PinEvent.NULL;
}

@Override @Override
public MajorFlushEvent beginFileFlush( PageSwapper swapper ) public MajorFlushEvent beginFileFlush( PageSwapper swapper )
{ {
Expand Down Expand Up @@ -130,6 +124,26 @@ public long evictionExceptions()
return 0; return 0;
} }


@Override
public void pins( long pins )
{
}

@Override
public void unpins( long unpins )
{
}

@Override
public void faults( long faults )
{
}

@Override
public void bytesRead( long bytesRead )
{
}

@Override @Override
public String toString() public String toString()
{ {
Expand All @@ -156,11 +170,6 @@ public String toString()
**/ **/
EvictionRunEvent beginPageEvictions( int pageCountToEvict ); EvictionRunEvent beginPageEvictions( int pageCountToEvict );


/**
* A page is to be pinned.
*/
PinEvent beginPin( boolean writeLock, long filePageId, PageSwapper swapper );

/** /**
* A PagedFile wants to flush all its bound pages. * A PagedFile wants to flush all its bound pages.
*/ */
Expand All @@ -170,4 +179,12 @@ public String toString()
* The PageCache wants to flush all its bound pages. * The PageCache wants to flush all its bound pages.
*/ */
MajorFlushEvent beginCacheFlush(); MajorFlushEvent beginCacheFlush();

void pins( long pins );

void unpins( long unpins );

void faults( long faults );

void bytesRead( long bytesRead );
} }

0 comments on commit 39b6036

Please sign in to comment.