Skip to content

Commit

Permalink
Skip unused property records when reading chain
Browse files Browse the repository at this point in the history
To be able to increase property read throughput our reads should be more
tolerant to concurrent updates of the same property chains. One of the
steps - skip already removed properties.

To do that store property cursor will skip unused records and will read and
build chain of only used records. Exception that record is not in used will not
be thrown anymore.

Co-authored-by: @MishaDemianenko
  • Loading branch information
lutovich committed May 10, 2016
1 parent 3f4151f commit 36add50
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 71 deletions.
Expand Up @@ -23,7 +23,6 @@

import org.neo4j.cursor.Cursor;
import org.neo4j.function.Consumer;
import org.neo4j.graphdb.NotFoundException;
import org.neo4j.io.pagecache.PageCursor;
import org.neo4j.kernel.api.cursor.PropertyItem;
import org.neo4j.kernel.impl.locking.Lock;
Expand Down Expand Up @@ -66,35 +65,33 @@ public boolean next()
return true;
}

if ( nextPropertyRecordId == Record.NO_NEXT_PROPERTY.intValue() )
while ( nextPropertyRecordId != Record.NO_NEXT_PROPERTY.intValue() )
{
return false;
}

long currentPropertyRecordId = nextPropertyRecordId;
try ( PageCursor cursor = propertyStore.newReadCursor( currentPropertyRecordId ) )
{
int offset = cursor.getOffset();
do
try ( PageCursor cursor = propertyStore.newReadCursor( nextPropertyRecordId ) )
{
cursor.setOffset( offset );
nextPropertyRecordId = readNextPropertyRecordId( cursor );
int offset = cursor.getOffset();
do
{
cursor.setOffset( offset );
nextPropertyRecordId = readNextPropertyRecordId( cursor );

payload.clear();
payload.init( cursor );
}
while ( cursor.shouldRetry() );
}
catch ( IOException e )
{
throw new UnderlyingStorageException( e );
}

payload.clear();
payload.init( cursor );
if ( payload.next() )
{
return true;
}
while ( cursor.shouldRetry() );
}
catch ( IOException e )
{
throw new UnderlyingStorageException( e );
}

if ( !payload.next() )
{
throw new NotFoundException( "Property record with id " + currentPropertyRecordId + " not in use" );
}
return true;
return false;
}

@Override
Expand Down
Expand Up @@ -87,6 +87,7 @@ class StorePropertyPayloadCursor

private final long[] data = new long[MAX_NUMBER_OF_PAYLOAD_LONG_ARRAY];
private int position = INITIAL_POSITION;
private boolean exhausted;

StorePropertyPayloadCursor( DynamicStringStore stringStore, DynamicArrayStore arrayStore )
{
Expand All @@ -105,6 +106,7 @@ void init( PageCursor cursor )
void clear()
{
position = INITIAL_POSITION;
exhausted = false;
buffer = cachedBuffer;
// Array of data should be filled with '0' because it is possible to call next() without calling init().
// In such case 'false' should be returned, which might not be the case if there is stale data in the buffer.
Expand All @@ -113,6 +115,11 @@ void clear()

boolean next()
{
if ( exhausted )
{
return false;
}

if ( position == INITIAL_POSITION )
{
position = 0;
Expand All @@ -121,11 +128,13 @@ boolean next()
{
position += currentBlocksUsed();
}
if ( position >= data.length )

if ( position >= data.length || type() == null )
{
exhausted = true;
return false;
}
return type() != null;
return true;
}

PropertyType type()
Expand Down

0 comments on commit 36add50

Please sign in to comment.