Skip to content

Commit

Permalink
Remove relationshipVisit API and use cursors instead
Browse files Browse the repository at this point in the history
  • Loading branch information
davidegrohmann committed May 8, 2017
1 parent 06380f4 commit e51f528
Show file tree
Hide file tree
Showing 24 changed files with 298 additions and 400 deletions.
Expand Up @@ -73,7 +73,7 @@ public interface PropertyEntry<T extends PropertyContainer>
* @return The value of the property as it was before the transaction * @return The value of the property as it was before the transaction
* started. * started.
*/ */
Object previouslyCommitedValue(); Object previouslyCommittedValue();


/** /**
* Get the value of the modified property. If this {@link PropertyEntry} * Get the value of the modified property. If this {@link PropertyEntry}
Expand Down
Expand Up @@ -200,9 +200,6 @@ long nodesCountIndexed( IndexDescriptor index, long nodeId, Object value )


Object graphGetProperty( int propertyKeyId ); Object graphGetProperty( int propertyKeyId );


<EXCEPTION extends Exception> void relationshipVisit( long relId, RelationshipVisitor<EXCEPTION> visitor )
throws EntityNotFoundException, EXCEPTION;

long nodesGetCount(); long nodesGetCount();


long relationshipsGetCount(); long relationshipsGetCount();
Expand Down
Expand Up @@ -19,7 +19,6 @@
*/ */
package org.neo4j.kernel.api.txstate; package org.neo4j.kernel.api.txstate;


import org.neo4j.kernel.api.exceptions.EntityNotFoundException;
import org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException; import org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException;
import org.neo4j.kernel.api.exceptions.schema.CreateConstraintFailureException; import org.neo4j.kernel.api.exceptions.schema.CreateConstraintFailureException;
import org.neo4j.kernel.impl.api.RelationshipVisitor; import org.neo4j.kernel.impl.api.RelationshipVisitor;
Expand Down Expand Up @@ -55,21 +54,21 @@ public abstract class RelationshipChangeVisitorAdapter implements DiffSetsVisito
/** /**
* Causes {@link #visitAddedRelationship(long, int, long, long)} to be invoked for added relationships. * Causes {@link #visitAddedRelationship(long, int, long, long)} to be invoked for added relationships.
*/ */
public RelationshipChangeVisitorAdapter( ReadableTransactionState txState ) protected RelationshipChangeVisitorAdapter( ReadableTransactionState txState )
{ {
this.added = added( requireNonNull( txState, "ReadableTxState" ) ); this.added = added( requireNonNull( txState, "ReadableTxState" ) );
this.removed = null; this.removed = null;
} }


protected void visitAddedRelationship( long relationshipId ) throws ConstraintValidationException private void visitAddedRelationship( long relationshipId ) throws ConstraintValidationException
{ {
if ( added != null ) if ( added != null )
{ {
added.visit( relationshipId ); added.visit( relationshipId );
} }
} }


protected void visitRemovedRelationship( long relationshipId ) throws ConstraintValidationException private void visitRemovedRelationship( long relationshipId ) throws ConstraintValidationException
{ {
if ( removed != null ) if ( removed != null )
{ {
Expand All @@ -82,10 +81,6 @@ protected void visitAddedRelationship( long relationshipId, int type, long start
{ {
} }


protected void visitRemovedRelationship( long relationshipId, int type, long startNode, long endNode )
{
}

@Override @Override
public final void visitAdded( Long relationshipId ) public final void visitAdded( Long relationshipId )
throws ConstraintValidationException, CreateConstraintFailureException throws ConstraintValidationException, CreateConstraintFailureException
Expand All @@ -108,7 +103,7 @@ public abstract void visit( long relId, int type, long startNode, long endNode )
throws ConstraintValidationException; throws ConstraintValidationException;
} }


DetailVisitor added( final ReadableTransactionState txState ) private DetailVisitor added( final ReadableTransactionState txState )
{ {
return new DetailVisitor() return new DetailVisitor()
{ {
Expand All @@ -129,29 +124,4 @@ public void visit( long relId, int type, long startNode, long endNode )
} }
}; };
} }

DetailVisitor removed( final StoreReadLayer store )
{
return new DetailVisitor()
{
@Override
void visit( long relationshipId ) throws ConstraintValidationException
{
try
{
store.relationshipVisit( relationshipId, this );
}
catch ( EntityNotFoundException e )
{
throw new IllegalStateException( "No RelationshipState for removed relationship!", e );
}
}

@Override
public void visit( long relId, int type, long startNode, long endNode )
{
visitRemovedRelationship( relId, type, startNode, endNode );
}
};
}
} }
Expand Up @@ -24,11 +24,11 @@
import org.neo4j.collection.primitive.PrimitiveIntCollection; import org.neo4j.collection.primitive.PrimitiveIntCollection;
import org.neo4j.collection.primitive.PrimitiveIntSet; import org.neo4j.collection.primitive.PrimitiveIntSet;
import org.neo4j.collection.primitive.PrimitiveIntVisitor; import org.neo4j.collection.primitive.PrimitiveIntVisitor;
import org.neo4j.kernel.api.exceptions.EntityNotFoundException; import org.neo4j.cursor.Cursor;
import org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException; import org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException;
import org.neo4j.kernel.impl.api.CountsRecordState; import org.neo4j.kernel.impl.api.CountsRecordState;
import org.neo4j.kernel.impl.api.RelationshipDataExtractor;
import org.neo4j.storageengine.api.NodeItem; import org.neo4j.storageengine.api.NodeItem;
import org.neo4j.storageengine.api.RelationshipItem;
import org.neo4j.storageengine.api.StorageStatement; import org.neo4j.storageengine.api.StorageStatement;
import org.neo4j.storageengine.api.StoreReadLayer; import org.neo4j.storageengine.api.StoreReadLayer;
import org.neo4j.storageengine.api.txstate.ReadableTransactionState; import org.neo4j.storageengine.api.txstate.ReadableTransactionState;
Expand All @@ -39,7 +39,6 @@


public class TransactionCountingStateVisitor extends TxStateVisitor.Delegator public class TransactionCountingStateVisitor extends TxStateVisitor.Delegator
{ {
private final RelationshipDataExtractor edge = new RelationshipDataExtractor();
private final StoreReadLayer storeLayer; private final StoreReadLayer storeLayer;
private final StorageStatement statement; private final StorageStatement statement;
private final CountsRecordState counts; private final CountsRecordState counts;
Expand Down Expand Up @@ -94,14 +93,15 @@ public void visitCreatedRelationship( long id, int type, long startNode, long en
@Override @Override
public void visitDeletedRelationship( long id ) public void visitDeletedRelationship( long id )
{ {
try try ( Cursor<RelationshipItem> cursor = storeLayer.relationshipCursor( statement, id, null ) )
{ {
storeLayer.relationshipVisit( id, edge ); if ( !cursor.next() )
updateRelationshipCount( edge.startNode(), edge.type(), edge.endNode(), -1 ); {
} throw new IllegalStateException( "Relationship being deleted should exist along with its nodes." );
catch ( EntityNotFoundException e ) }
{
throw new IllegalStateException( "Relationship being deleted should exist along with its nodes.", e ); RelationshipItem relationship = cursor.get();
updateRelationshipCount( relationship.startNode(), relationship.type(), relationship.endNode(), -1 );
} }
super.visitDeletedRelationship( id ); super.visitDeletedRelationship( id );
} }
Expand Down
Expand Up @@ -465,14 +465,6 @@ public PrimitiveLongIterator relationshipsGetAll( KernelStatement state )
return entityReadOperations.relationshipsGetAll( state ); return entityReadOperations.relationshipsGetAll( state );
} }


@Override
public <EXCEPTION extends Exception> void relationshipVisit( KernelStatement statement,
long relId, RelationshipVisitor<EXCEPTION> visitor )
throws EntityNotFoundException, EXCEPTION
{
entityReadOperations.relationshipVisit( statement, relId, visitor );
}

@Override @Override
public Cursor<NodeItem> nodeGetAllCursor( KernelStatement statement ) public Cursor<NodeItem> nodeGetAllCursor( KernelStatement statement )
{ {
Expand Down
Expand Up @@ -234,15 +234,6 @@ public PrimitiveLongIterator relationshipsGetAll( KernelStatement statement )
return entityReadDelegate.relationshipsGetAll( statement ); return entityReadDelegate.relationshipsGetAll( statement );
} }


@Override
public <EXCEPTION extends Exception> void relationshipVisit( KernelStatement statement, long relId,
RelationshipVisitor<EXCEPTION> visitor )
throws EntityNotFoundException, EXCEPTION
{
guard.check( statement );
entityReadDelegate.relationshipVisit( statement, relId, visitor );
}

@Override @Override
public Cursor<NodeItem> nodeGetAllCursor( KernelStatement statement ) public Cursor<NodeItem> nodeGetAllCursor( KernelStatement statement )
{ {
Expand Down
Expand Up @@ -24,6 +24,7 @@
import java.util.Iterator; import java.util.Iterator;
import java.util.function.Function; import java.util.function.Function;


import org.neo4j.cursor.Cursor;
import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.Statement;
import org.neo4j.kernel.api.exceptions.EntityNotFoundException; import org.neo4j.kernel.api.exceptions.EntityNotFoundException;
import org.neo4j.kernel.api.exceptions.InvalidTransactionTypeKernelException; import org.neo4j.kernel.api.exceptions.InvalidTransactionTypeKernelException;
Expand Down Expand Up @@ -57,6 +58,7 @@
import org.neo4j.kernel.impl.api.operations.SchemaStateOperations; import org.neo4j.kernel.impl.api.operations.SchemaStateOperations;
import org.neo4j.kernel.impl.api.operations.SchemaWriteOperations; import org.neo4j.kernel.impl.api.operations.SchemaWriteOperations;
import org.neo4j.kernel.impl.locking.ResourceTypes; import org.neo4j.kernel.impl.locking.ResourceTypes;
import org.neo4j.storageengine.api.RelationshipItem;
import org.neo4j.storageengine.api.lock.ResourceType; import org.neo4j.storageengine.api.lock.ResourceType;
import org.neo4j.storageengine.api.schema.PopulationProgress; import org.neo4j.storageengine.api.schema.PopulationProgress;


Expand Down Expand Up @@ -307,11 +309,14 @@ public long relationshipCreate( KernelStatement state,
public void relationshipDelete( final KernelStatement state, long relationshipId ) public void relationshipDelete( final KernelStatement state, long relationshipId )
throws EntityNotFoundException, AutoIndexingKernelException, InvalidTransactionTypeKernelException throws EntityNotFoundException, AutoIndexingKernelException, InvalidTransactionTypeKernelException
{ {
entityReadDelegate.relationshipVisit( state, relationshipId, try ( Cursor<RelationshipItem> cursor = entityReadDelegate.relationshipCursorById( state, relationshipId ) )
( relId, type, startNode, endNode ) -> lockRelationshipNodes( state, startNode, endNode ) ); {
RelationshipItem relationship = cursor.get();
lockRelationshipNodes( state, relationship.startNode(), relationship.endNode() );
}
acquireExclusiveRelationshipLock( state, relationshipId ); acquireExclusiveRelationshipLock( state, relationshipId );
state.assertOpen(); state.assertOpen();
entityWriteDelegate.relationshipDelete(state, relationshipId); entityWriteDelegate.relationshipDelete( state, relationshipId );
} }


private void lockRelationshipNodes( KernelStatement state, long startNodeId, long endNodeId ) private void lockRelationshipNodes( KernelStatement state, long startNodeId, long endNodeId )
Expand Down
Expand Up @@ -482,14 +482,6 @@ public PrimitiveIntIterator graphGetPropertyKeys()
return dataRead().graphGetPropertyKeys( statement ); return dataRead().graphGetPropertyKeys( statement );
} }


@Override
public <EXCEPTION extends Exception> void relationshipVisit( long relId,
RelationshipVisitor<EXCEPTION> visitor ) throws EntityNotFoundException, EXCEPTION
{
statement.assertOpen();
dataRead().relationshipVisit( statement, relId, visitor );
}

@Override @Override
public long nodesGetCount() public long nodesGetCount()
{ {
Expand Down
Expand Up @@ -1348,20 +1348,6 @@ public int relationshipTypeCount( KernelStatement statement )
} }


// <Legacy index> // <Legacy index>
@Override
public <EXCEPTION extends Exception> void relationshipVisit( KernelStatement statement, long relId,
RelationshipVisitor<EXCEPTION> visitor ) throws EntityNotFoundException, EXCEPTION
{
if ( statement.hasTxStateWithChanges() )
{
if ( statement.txState().relationshipVisit( relId, visitor ) )
{
return;
}
}
storeLayer.relationshipVisit( relId, visitor );
}

@Override @Override
public LegacyIndexHits nodeLegacyIndexGet( KernelStatement statement, String indexName, String key, Object value ) public LegacyIndexHits nodeLegacyIndexGet( KernelStatement statement, String indexName, String key, Object value )
throws LegacyIndexNotFoundKernelException throws LegacyIndexNotFoundKernelException
Expand Down Expand Up @@ -1476,64 +1462,78 @@ public void nodeRemoveFromLegacyIndex( KernelStatement statement, String indexNa


@Override @Override
public void relationshipAddToLegacyIndex( final KernelStatement statement, final String indexName, public void relationshipAddToLegacyIndex( final KernelStatement statement, final String indexName,
final long relationship, final String key, final Object value ) final long relId, final String key, final Object value )
throws EntityNotFoundException, LegacyIndexNotFoundKernelException throws EntityNotFoundException, LegacyIndexNotFoundKernelException
{ {
relationshipVisit( statement, relationship, try ( Cursor<RelationshipItem> cursor = relationshipCursorById( statement, relId ) )
( relId, type, startNode, endNode ) -> statement.legacyIndexTxState().relationshipChanges( indexName ) {
.addRelationship( relationship, key, value, startNode, endNode ) ); RelationshipItem rel = cursor.get();
statement.legacyIndexTxState().relationshipChanges( indexName )
.addRelationship( relId, key, value, rel.startNode(), rel.endNode() );
}
} }


@Override @Override
public void relationshipRemoveFromLegacyIndex( final KernelStatement statement, final String indexName, public void relationshipRemoveFromLegacyIndex( final KernelStatement statement, final String indexName,
long relationship, final String key, final Object value ) long relId, final String key, final Object value )
throws LegacyIndexNotFoundKernelException, EntityNotFoundException throws LegacyIndexNotFoundKernelException, EntityNotFoundException
{ {
try ReadableTransactionState state = statement.hasTxStateWithChanges() ? statement.txState() : null;
try ( Cursor<RelationshipItem> cursor = storeLayer
.relationshipCursor( statement.getStoreStatement(), relId, state ) )
{ {
relationshipVisit( statement, relationship, // Apparently it is OK if the relationship does not exist
( relId, type, startNode, endNode ) -> statement.legacyIndexTxState() if ( cursor.next() )
.relationshipChanges( indexName ) {
.removeRelationship( relId, key, value, startNode, endNode ) ); RelationshipItem rel = cursor.get();
} statement.legacyIndexTxState().relationshipChanges( indexName )
catch ( EntityNotFoundException e ) .removeRelationship( relId, key, value, rel.startNode(), rel.endNode() );
{ // Apparently this is OK }
} }
} }


@Override @Override
public void relationshipRemoveFromLegacyIndex( final KernelStatement statement, final String indexName, public void relationshipRemoveFromLegacyIndex( final KernelStatement statement, final String indexName,
long relationship, final String key ) throws EntityNotFoundException, LegacyIndexNotFoundKernelException long relId, final String key ) throws EntityNotFoundException, LegacyIndexNotFoundKernelException
{ {
try ReadableTransactionState state = statement.hasTxStateWithChanges() ? statement.txState() : null;
try ( Cursor<RelationshipItem> cursor = storeLayer
.relationshipCursor( statement.getStoreStatement(), relId, state ) )
{ {
relationshipVisit( statement, relationship, // Apparently it is OK if the relationship does not exist
( relId, type, startNode, endNode ) -> statement.legacyIndexTxState() if ( cursor.next() )
.relationshipChanges( indexName ).removeRelationship( relId, key, startNode, endNode ) ); {
} RelationshipItem rel = cursor.get();
catch ( EntityNotFoundException e ) statement.legacyIndexTxState().relationshipChanges( indexName )
{ // Apparently this is OK .removeRelationship( relId, key, rel.startNode(), rel.endNode() );
}
} }
} }


@Override @Override
public void relationshipRemoveFromLegacyIndex( final KernelStatement statement, final String indexName, public void relationshipRemoveFromLegacyIndex( final KernelStatement statement, final String indexName,
long relationship ) throws LegacyIndexNotFoundKernelException, EntityNotFoundException long relId ) throws LegacyIndexNotFoundKernelException, EntityNotFoundException
{ {
try
{ ReadableTransactionState state = statement.hasTxStateWithChanges() ? statement.txState() : null;
relationshipVisit( statement, relationship, try ( Cursor<RelationshipItem> cursor = storeLayer
( relId, type, startNode, endNode ) -> statement.legacyIndexTxState() .relationshipCursor( statement.getStoreStatement(), relId, state ) )
.relationshipChanges( indexName ).removeRelationship( relId, startNode, endNode ) );
}
catch ( EntityNotFoundException e )
{ {
// This is a special case which is still OK. This method is called lazily where deleted relationships if ( cursor.next() )
// that still are referenced by a legacy index will be added for removal in this transaction. {
// Ideally we'd want to include start/end node too, but we can't since the relationship doesn't exist. RelationshipItem rel = cursor.get();
// So we do the "normal" remove call on the legacy index transaction changes. The downside is that statement.legacyIndexTxState().relationshipChanges( indexName )
// Some queries on this transaction state that include start/end nodes might produce invalid results. .removeRelationship( relId, rel.startNode(), rel.endNode() );
statement.legacyIndexTxState().relationshipChanges( indexName ).remove( relationship ); }
else
{
// This is a special case which is still OK. This method is called lazily where deleted relationships
// that still are referenced by a legacy index will be added for removal in this transaction.
// Ideally we'd want to include start/end node too, but we can't since the relationship doesn't exist.
// So we do the "normal" remove call on the legacy index transaction changes. The downside is that
// Some queries on this transaction state that include start/end nodes might produce invalid results.
statement.legacyIndexTxState().relationshipChanges( indexName ).remove( relId );
}
} }
} }


Expand Down
Expand Up @@ -83,9 +83,6 @@ long nodesCountIndexed( KernelStatement statement, IndexDescriptor index, long n


PrimitiveLongIterator relationshipsGetAll( KernelStatement state ); PrimitiveLongIterator relationshipsGetAll( KernelStatement state );


<EXCEPTION extends Exception> void relationshipVisit( KernelStatement statement, long relId,
RelationshipVisitor<EXCEPTION> visitor ) throws EntityNotFoundException, EXCEPTION;

Cursor<NodeItem> nodeGetAllCursor( KernelStatement statement ); Cursor<NodeItem> nodeGetAllCursor( KernelStatement statement );


Cursor<NodeItem> nodeCursorById( KernelStatement statement, long nodeId ) throws EntityNotFoundException; Cursor<NodeItem> nodeCursorById( KernelStatement statement, long nodeId ) throws EntityNotFoundException;
Expand Down

0 comments on commit e51f528

Please sign in to comment.