Skip to content

Commit

Permalink
Merge pull request #8133 from tinwelint/3.1-track-efsa-free
Browse files Browse the repository at this point in the history
Traces calls to free() in EFSA
  • Loading branch information
chrisvest committed Oct 12, 2016
2 parents 70ef907 + 022af28 commit 582c0c3
Show file tree
Hide file tree
Showing 3 changed files with 251 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@

public class EphemeralFileSystemAbstraction implements FileSystemAbstraction
{
private Clock clock;
private final Clock clock;

interface Positionable
{
Expand Down Expand Up @@ -551,7 +551,7 @@ public long checksum()
for ( File name : names )
{
EphemeralFileData file = files.get( name );
ByteBuffer buf = file.fileAsBuffer.buf;
ByteBuffer buf = file.fileAsBuffer.buf();
buf.position( 0 );
while ( buf.position() < buf.limit() )
{
Expand Down Expand Up @@ -902,7 +902,7 @@ protected byte[] initialValue()
private int size;
private int forcedSize;
private int locked;
private Clock clock;
private final Clock clock;
private long lastModified;

public EphemeralFileData( Clock clock )
Expand Down Expand Up @@ -1108,12 +1108,19 @@ private static class DynamicByteBuffer
private static final int[] SIZES;
private static final byte[] zeroBuffer = new byte[1024];
private ByteBuffer buf;
private Exception freeCall;

public DynamicByteBuffer()
{
buf = allocate( 0 );
}

public ByteBuffer buf()
{
assertNotFreed();
return buf;
}

/** This is a copying constructor, the input buffer is just read from, never stored in 'this'. */
private DynamicByteBuffer( ByteBuffer toClone )
{
Expand Down Expand Up @@ -1145,7 +1152,7 @@ private static int sizeIndexFor( int capacity )

synchronized DynamicByteBuffer copy()
{
return new DynamicByteBuffer( buf ); // invoke "copy constructor"
return new DynamicByteBuffer( buf() ); // invoke "copy constructor"
}

static
Expand Down Expand Up @@ -1199,19 +1206,24 @@ private ByteBuffer allocate( int sizeIndex )

void free()
{
assertNotFreed();
try
{
clear();
}
finally
{
buf = null;
freeCall = new Exception(
"You're most likely seeing this exception because there was an attempt to use this buffer " +
"after it was freed. This stack trace may help you figure out where and why it was freed" );
}
}

synchronized void put( int pos, byte[] bytes, int offset, int length )
{
verifySize( pos + length );
ByteBuffer buf = buf();
try
{
buf.position( pos );
Expand All @@ -1225,12 +1237,14 @@ synchronized void put( int pos, byte[] bytes, int offset, int length )

synchronized void get( int pos, byte[] scratchPad, int i, int howMuchToReadThisTime )
{
ByteBuffer buf = buf();
buf.position( pos );
buf.get( scratchPad, i, howMuchToReadThisTime );
}

synchronized void fillWithZeros( int pos, int bytes )
{
ByteBuffer buf = buf();
buf.position( pos );
while ( bytes > 0 )
{
Expand All @@ -1246,6 +1260,7 @@ synchronized void fillWithZeros( int pos, int bytes )
*/
private void verifySize( int totalAmount )
{
ByteBuffer buf = buf();
if ( buf.capacity() >= totalAmount )
{
return;
Expand All @@ -1259,21 +1274,36 @@ private void verifySize( int totalAmount )
newSize += Math.min( newSize, 1024 * 1024 );
sizeIndex++;
}
int oldPosition = this.buf.position();
ByteBuffer buf = allocate( sizeIndex );
this.buf.position( 0 );
buf.put( this.buf );
this.buf = buf;
this.buf.position( oldPosition );
int oldPosition = buf.position();

// allocate new buffer
ByteBuffer newBuf = allocate( sizeIndex );

// copy contents of current buffer into new buffer
buf.position( 0 );
newBuf.put( buf );

// re-assign buffer to new buffer
newBuf.position( oldPosition );
this.buf = newBuf;
}

public void clear()
{
this.buf.clear();
buf().clear();
}

private void assertNotFreed()
{
if ( this.buf == null )
{
throw new IllegalStateException( "This buffer have been freed", freeCall );
}
}

void dump( OutputStream target, byte[] scratchPad, int size ) throws IOException
{
ByteBuffer buf = buf();
buf.position( 0 );
while ( size > 0 )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@
*/
package org.neo4j.kernel.impl.store.id;

import org.junit.Rule;
import org.junit.Test;

import java.io.File;
import java.nio.ByteBuffer;
import java.util.HashSet;
import java.util.Set;

import org.neo4j.graphdb.mockfs.EphemeralFileSystemAbstraction;
import org.neo4j.io.fs.FileSystemAbstraction;
import org.neo4j.io.fs.StoreChannel;
import org.neo4j.test.rule.fs.EphemeralFileSystemRule;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
Expand All @@ -43,6 +43,9 @@

public class FreeIdKeeperTest
{
@Rule
public final EphemeralFileSystemRule fs = new EphemeralFileSystemRule();

@Test
public void newlyConstructedInstanceShouldReportProperDefaultValues() throws Exception
{
Expand Down Expand Up @@ -100,7 +103,6 @@ public void shouldReturnMinusOneWhenRunningOutOfIds() throws Exception
public void shouldOnlyOverflowWhenThresholdIsReached() throws Exception
{
// Given
FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
StoreChannel channel = spy( fs.open( new File( "id.file" ), "rw" ) );

int threshold = 10;
Expand Down Expand Up @@ -128,7 +130,6 @@ public void shouldOnlyOverflowWhenThresholdIsReached() throws Exception
public void shouldReadBackPersistedIdsWhenAggressiveReuseIsSet() throws Exception
{
// given
FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
StoreChannel channel = fs.open( new File( "id.file" ), "rw" );

int threshold = 10;
Expand All @@ -153,7 +154,6 @@ public void shouldReadBackPersistedIdsWhenAggressiveReuseIsSet() throws Exceptio
public void shouldReadBackManyPersistedIdBatchesWhenAggressiveReuseIsSet() throws Exception
{
// given
FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
StoreChannel channel = fs.open( new File( "id.file" ), "rw" );

int threshold = 10;
Expand Down Expand Up @@ -182,7 +182,6 @@ public void shouldFirstReturnNonPersistedIdsAndThenPersistedOnesWhenAggressiveRe
{
// this is testing the stack property, but from the viewpoint of avoiding unnecessary disk reads
// given
FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
StoreChannel channel = fs.open( new File( "id.file" ), "rw" );

int threshold = 10;
Expand Down Expand Up @@ -219,7 +218,6 @@ public void shouldFirstReturnNonPersistedIdsAndThenPersistedOnesWhenAggressiveRe
public void persistedIdsShouldStillBeCounted() throws Exception
{
// given
FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
StoreChannel channel = fs.open( new File( "id.file" ), "rw" );

int threshold = 10;
Expand Down Expand Up @@ -247,7 +245,6 @@ public void persistedIdsShouldStillBeCounted() throws Exception
public void shouldStoreAndRestoreIds() throws Exception
{
// given
FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
StoreChannel channel = fs.open( new File( "id.file" ), "rw" );

int threshold = 10;
Expand Down Expand Up @@ -291,7 +288,6 @@ public void shouldStoreAndRestoreIds() throws Exception
public void shouldNotReturnNewlyReleasedIdsIfAggressiveIsFalse() throws Exception
{
// given
FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
StoreChannel channel = fs.open( new File( "id.file" ), "rw" );

int threshold = 10;
Expand All @@ -309,7 +305,6 @@ public void shouldNotReturnNewlyReleasedIdsIfAggressiveIsFalse() throws Exceptio
public void shouldNotReturnIdsPersistedDuringThisRunIfAggressiveIsFalse() throws Exception
{
// given
FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
StoreChannel channel = spy( fs.open( new File( "id.file" ), "rw" ) );

int threshold = 10;
Expand All @@ -333,7 +328,6 @@ public void shouldNotReturnIdsPersistedDuringThisRunIfAggressiveIsFalse() throws
public void shouldReturnIdsRestoredAndIgnoreNewlyReleasedIfAggressiveReuseIsFalse() throws Exception
{
// given
FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
StoreChannel channel = fs.open( new File("id.file" ), "rw" );

int threshold = 10;
Expand Down Expand Up @@ -374,7 +368,6 @@ public void shouldReturnNoResultIfIdsAreRestoredAndExhaustedAndThereAreFreeIdsFr
throws Exception
{
// given
FileSystemAbstraction fs = new EphemeralFileSystemAbstraction();
StoreChannel channel = fs.open( new File("id.file" ), "rw" );

int threshold = 10;
Expand Down

0 comments on commit 582c0c3

Please sign in to comment.