Skip to content

Commit

Permalink
Use page cursor for reading records from the relationship group store
Browse files Browse the repository at this point in the history
  • Loading branch information
davidegrohmann committed May 8, 2017
1 parent abc1d44 commit 5579212
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 56 deletions.
Expand Up @@ -19,14 +19,17 @@
*/
package org.neo4j.kernel.impl.api.store;

import java.io.IOException;
import java.util.function.Consumer;
import java.util.function.IntPredicate;

import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.io.pagecache.PageCursor;
import org.neo4j.kernel.impl.locking.LockService;
import org.neo4j.kernel.impl.store.InvalidRecordException;
import org.neo4j.kernel.impl.store.RecordCursors;
import org.neo4j.kernel.impl.store.RelationshipGroupStore;
import org.neo4j.kernel.impl.store.RelationshipStore;
import org.neo4j.kernel.impl.store.UnderlyingStorageException;
import org.neo4j.kernel.impl.store.record.Record;
import org.neo4j.kernel.impl.store.record.RelationshipGroupRecord;
import org.neo4j.kernel.impl.store.record.RelationshipRecord;
Expand All @@ -47,26 +50,28 @@
public class StoreNodeRelationshipCursor extends StoreAbstractIteratorRelationshipCursor
{
private final RelationshipGroupRecord groupRecord;
private final RelationshipGroupStore relationshipGroupStore;
private final Consumer<StoreNodeRelationshipCursor> instanceCache;
private final PageCursor groupStorePageCursor;

private boolean isDense;
private long relationshipId;
private long fromNodeId;
private Direction direction;
private IntPredicate allowedTypes;
private int groupChainIndex;
private boolean end;
private final RecordCursors cursors;

public StoreNodeRelationshipCursor( RelationshipStore relationshipStore,
RelationshipGroupRecord groupRecord,
RelationshipGroupStore relationshipGroupStore,
Consumer<StoreNodeRelationshipCursor> instanceCache,
RecordCursors cursors,
LockService lockService )
{
super( relationshipStore, lockService );
this.groupRecord = groupRecord;
this.relationshipGroupStore = relationshipGroupStore;
this.groupRecord = relationshipGroupStore.newRecord();
this.groupStorePageCursor = relationshipGroupStore.newPageCursor();
this.instanceCache = instanceCache;
this.cursors = cursors;
}

public StoreNodeRelationshipCursor init( boolean isDense, long firstRelId, long fromNodeId, Direction direction,
Expand Down Expand Up @@ -97,7 +102,7 @@ private StoreNodeRelationshipCursor init( boolean isDense, long firstRelId, long

if ( isDense && relationshipId != Record.NO_NEXT_RELATIONSHIP.intValue() )
{
cursors.relationshipGroup().next( firstRelId, groupRecord, FORCE );
readGroupRecord( firstRelId );
relationshipId = nextChainStart();
}
else
Expand All @@ -108,6 +113,19 @@ private StoreNodeRelationshipCursor init( boolean isDense, long firstRelId, long
return this;
}

private void readGroupRecord( long id )
{
try
{
groupRecord.clear();
relationshipGroupStore.readIntoRecord( id, groupRecord, FORCE, groupStorePageCursor );
}
catch ( IOException e )
{
throw new UnderlyingStorageException( e );
}
}

private PrimitiveLongIterator addedNodeRelationships( long fromNodeId, Direction direction,
int[] allowedTypes, ReadableTransactionState state )
{
Expand Down Expand Up @@ -237,7 +255,7 @@ private long nextChainStart()
// Go to the next group
if ( !NULL_REFERENCE.is( groupRecord.getNext() ) )
{
cursors.relationshipGroup().next( groupRecord.getNext(), groupRecord, FORCE );
readGroupRecord( groupRecord.getNext() );
}
else
{
Expand Down Expand Up @@ -311,4 +329,11 @@ public String toString()
return String
.format( "RelationShipItem[id=%d, type=%d, start=%d, end=%d]", id(), type(), startNode(), endNode() );
}

@Override
public void dispose()
{
super.dispose();
groupStorePageCursor.close();
}
}
Expand Up @@ -28,11 +28,7 @@
import org.neo4j.kernel.impl.locking.Lock;
import org.neo4j.kernel.impl.locking.LockService;
import org.neo4j.kernel.impl.store.NeoStores;
import org.neo4j.kernel.impl.store.NodeStore;
import org.neo4j.kernel.impl.store.RecordCursors;
import org.neo4j.kernel.impl.store.RecordStore;
import org.neo4j.kernel.impl.store.RelationshipStore;
import org.neo4j.kernel.impl.store.record.RelationshipGroupRecord;
import org.neo4j.kernel.impl.util.InstanceCache;
import org.neo4j.storageengine.api.Direction;
import org.neo4j.storageengine.api.NodeItem;
Expand Down Expand Up @@ -60,12 +56,9 @@ public class StoreStatement implements StorageStatement
private final InstanceCache<StorePropertyCursor> propertyCursorCache;
private final InstanceCache<StoreSinglePropertyCursor> singlePropertyCursorCache;
private final NeoStores neoStores;
private final NodeStore nodeStore;
private final RelationshipStore relationshipStore;
private final Supplier<IndexReaderFactory> indexReaderFactorySupplier;
private final RecordCursors recordCursors;
private final Supplier<LabelScanReader> labelScanStore;
private final RecordStore<RelationshipGroupRecord> relationshipGroupStore;
private final RecordCursors recordCursors;

private IndexReaderFactory indexReaderFactory;
private LabelScanReader labelScanReader;
Expand All @@ -79,42 +72,39 @@ public StoreStatement( NeoStores neoStores, Supplier<IndexReaderFactory> indexRe
this.neoStores = neoStores;
this.indexReaderFactorySupplier = indexReaderFactory;
this.labelScanStore = labelScanReaderSupplier;
this.nodeStore = neoStores.getNodeStore();
this.relationshipStore = neoStores.getRelationshipStore();
this.relationshipGroupStore = neoStores.getRelationshipGroupStore();
this.recordCursors = new RecordCursors( neoStores );

nodeCursor = new InstanceCache<NodeCursor>()
{
@Override
protected NodeCursor create()
{
return new NodeCursor( nodeStore, this, lockService );
return new NodeCursor( neoStores.getNodeStore(), this, lockService );
}
};
singleRelationshipCursor = new InstanceCache<StoreSingleRelationshipCursor>()
{
@Override
protected StoreSingleRelationshipCursor create()
{
return new StoreSingleRelationshipCursor( relationshipStore, this, lockService );
return new StoreSingleRelationshipCursor( neoStores.getRelationshipStore(), this, lockService );
}
};
iteratorRelationshipCursor = new InstanceCache<StoreIteratorRelationshipCursor>()
{
@Override
protected StoreIteratorRelationshipCursor create()
{
return new StoreIteratorRelationshipCursor( relationshipStore, this, lockService );
return new StoreIteratorRelationshipCursor( neoStores.getRelationshipStore(), this, lockService );
}
};
nodeRelationshipsCursor = new InstanceCache<StoreNodeRelationshipCursor>()
{
@Override
protected StoreNodeRelationshipCursor create()
{
return new StoreNodeRelationshipCursor( relationshipStore,
relationshipGroupStore.newRecord(), this, recordCursors, lockService );
return new StoreNodeRelationshipCursor( neoStores.getRelationshipStore(),
neoStores.getRelationshipGroupStore(), this, lockService );
}
};
propertyCursorCache = new InstanceCache<StorePropertyCursor>()
Expand Down Expand Up @@ -147,7 +137,7 @@ public void acquire()
public Cursor<NodeItem> acquireNodeCursor( ReadableTransactionState state )
{
neoStores.assertOpen();
return nodeCursor.get().init( new AllNodeProgression( nodeStore ), state );
return nodeCursor.get().init( new AllNodeProgression( neoStores.getNodeStore() ), state );
}

@Override
Expand Down Expand Up @@ -178,7 +168,7 @@ public Cursor<RelationshipItem> acquireNodeRelationshipCursor( boolean isDense,
public Cursor<RelationshipItem> relationshipsGetAllCursor( ReadableTransactionState state )
{
neoStores.assertOpen();
return iteratorRelationshipCursor.get().init( new AllIdIterator( relationshipStore ), state );
return iteratorRelationshipCursor.get().init( new AllIdIterator( neoStores.getRelationshipStore() ), state );
}

@Override
Expand Down
Expand Up @@ -396,7 +396,7 @@ private DynamicStringStore getPropertyKeyTokenNamesStore()
return (DynamicStringStore) getStore( StoreType.PROPERTY_KEY_TOKEN_NAME );
}

public RecordStore<RelationshipGroupRecord> getRelationshipGroupStore()
public RelationshipGroupStore getRelationshipGroupStore()
{
return (RelationshipGroupStore) getStore( StoreType.RELATIONSHIP_GROUP );
}
Expand Down
Expand Up @@ -113,7 +113,6 @@
import org.neo4j.kernel.impl.store.NodeStore;
import org.neo4j.kernel.impl.store.PropertyKeyTokenStore;
import org.neo4j.kernel.impl.store.PropertyStore;
import org.neo4j.kernel.impl.store.RecordCursors;
import org.neo4j.kernel.impl.store.RecordStore;
import org.neo4j.kernel.impl.store.RelationshipStore;
import org.neo4j.kernel.impl.store.RelationshipTypeTokenStore;
Expand Down Expand Up @@ -212,14 +211,12 @@ public Label apply( long from )
private final RelationshipTypeTokenStore relationshipTypeTokenStore;
private final PropertyKeyTokenStore propertyKeyTokenStore;
private final PropertyStore propertyStore;
private final RecordStore<RelationshipGroupRecord> relationshipGroupStore;
private final SchemaStore schemaStore;
private final NeoStoreIndexStoreView indexStoreView;

private final LabelTokenStore labelTokenStore;
private final Locks.Client noopLockClient = new NoOpClient();
private final long maxNodeId;
private final RecordCursors cursors;

public BatchInserterImpl( final File storeDir, final FileSystemAbstraction fileSystem,
Map<String, String> stringParams, Iterable<KernelExtensionFactory<?>> kernelExtensions ) throws IOException
Expand Down Expand Up @@ -266,7 +263,7 @@ public BatchInserterImpl( final File storeDir, final FileSystemAbstraction fileS
relationshipTypeTokenStore = neoStores.getRelationshipTypeTokenStore();
propertyKeyTokenStore = neoStores.getPropertyKeyTokenStore();
propertyStore = neoStores.getPropertyStore();
relationshipGroupStore = neoStores.getRelationshipGroupStore();
RecordStore<RelationshipGroupRecord> relationshipGroupStore = neoStores.getRelationshipGroupStore();
schemaStore = neoStores.getSchemaStore();
labelTokenStore = neoStores.getLabelTokenStore();

Expand Down Expand Up @@ -305,7 +302,6 @@ public BatchInserterImpl( final File storeDir, final FileSystemAbstraction fileS

flushStrategy = new BatchedFlushStrategy( recordAccess, config.get( GraphDatabaseSettings
.batch_inserter_batch_size ) );
cursors = new RecordCursors( neoStores );
}

private Map<String, String> getDefaultParams()
Expand Down Expand Up @@ -904,7 +900,7 @@ public Map<String, Object> getNodeProperties( long nodeId )
public Iterable<Long> getRelationshipIds( long nodeId )
{
flushStrategy.forceFlush();
return new BatchRelationshipIterable<Long>( neoStores, nodeId, cursors )
return new BatchRelationshipIterable<Long>( neoStores, nodeId )
{
@Override
protected Long nextFrom( long relId, int type, long startNode, long endNode )
Expand All @@ -918,7 +914,7 @@ protected Long nextFrom( long relId, int type, long startNode, long endNode )
public Iterable<BatchRelationship> getRelationships( long nodeId )
{
flushStrategy.forceFlush();
return new BatchRelationshipIterable<BatchRelationship>( neoStores, nodeId, cursors )
return new BatchRelationshipIterable<BatchRelationship>( neoStores, nodeId )
{
@Override
protected BatchRelationship nextFrom( long relId, int type, long startNode, long endNode )
Expand Down Expand Up @@ -972,7 +968,6 @@ public void shutdown()
}
finally
{
cursors.close();
neoStores.close();

try
Expand Down
Expand Up @@ -27,11 +27,9 @@
import org.neo4j.kernel.impl.store.InvalidRecordException;
import org.neo4j.kernel.impl.store.NeoStores;
import org.neo4j.kernel.impl.store.NodeStore;
import org.neo4j.kernel.impl.store.RecordCursors;
import org.neo4j.kernel.impl.store.RecordStore;
import org.neo4j.kernel.impl.store.RelationshipGroupStore;
import org.neo4j.kernel.impl.store.RelationshipStore;
import org.neo4j.kernel.impl.store.record.NodeRecord;
import org.neo4j.kernel.impl.store.record.RelationshipGroupRecord;

import static org.neo4j.kernel.impl.locking.LockService.NO_LOCK_SERVICE;
import static org.neo4j.kernel.impl.store.record.RecordLoad.NORMAL;
Expand All @@ -41,13 +39,12 @@ abstract class BatchRelationshipIterable<T> implements Iterable<T>
{
private final StoreNodeRelationshipCursor relationshipCursor;

BatchRelationshipIterable( NeoStores neoStores, long nodeId, RecordCursors cursors )
BatchRelationshipIterable( NeoStores neoStores, long nodeId )
{
RelationshipStore relationshipStore = neoStores.getRelationshipStore();
RecordStore<RelationshipGroupRecord> relationshipGroupStore = neoStores.getRelationshipGroupStore();
RelationshipGroupRecord relationshipGroupRecord = relationshipGroupStore.newRecord();
this.relationshipCursor = new StoreNodeRelationshipCursor( relationshipStore, relationshipGroupRecord,
cursor -> {}, cursors, NO_LOCK_SERVICE );
RelationshipGroupStore relationshipGroupStore = neoStores.getRelationshipGroupStore();
this.relationshipCursor = new StoreNodeRelationshipCursor( relationshipStore, relationshipGroupStore,
cursor -> {}, NO_LOCK_SERVICE );

// TODO There's an opportunity to reuse lots of instances created here, but this isn't a
// critical path instance so perhaps not necessary a.t.m.
Expand Down

0 comments on commit 5579212

Please sign in to comment.