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
* started.
*/
Object previouslyCommitedValue();
Object previouslyCommittedValue();

/**
* 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 );

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

long nodesGetCount();

long relationshipsGetCount();
Expand Down
Expand Up @@ -19,7 +19,6 @@
*/
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.CreateConstraintFailureException;
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.
*/
public RelationshipChangeVisitorAdapter( ReadableTransactionState txState )
protected RelationshipChangeVisitorAdapter( ReadableTransactionState txState )
{
this.added = added( requireNonNull( txState, "ReadableTxState" ) );
this.removed = null;
}

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

protected void visitRemovedRelationship( long relationshipId ) throws ConstraintValidationException
private void visitRemovedRelationship( long relationshipId ) throws ConstraintValidationException
{
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
public final void visitAdded( Long relationshipId )
throws ConstraintValidationException, CreateConstraintFailureException
Expand All @@ -108,7 +103,7 @@ public abstract void visit( long relId, int type, long startNode, long endNode )
throws ConstraintValidationException;
}

DetailVisitor added( final ReadableTransactionState txState )
private DetailVisitor added( final ReadableTransactionState txState )
{
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.PrimitiveIntSet;
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.impl.api.CountsRecordState;
import org.neo4j.kernel.impl.api.RelationshipDataExtractor;
import org.neo4j.storageengine.api.NodeItem;
import org.neo4j.storageengine.api.RelationshipItem;
import org.neo4j.storageengine.api.StorageStatement;
import org.neo4j.storageengine.api.StoreReadLayer;
import org.neo4j.storageengine.api.txstate.ReadableTransactionState;
Expand All @@ -39,7 +39,6 @@

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

RelationshipItem relationship = cursor.get();
updateRelationshipCount( relationship.startNode(), relationship.type(), relationship.endNode(), -1 );
}
super.visitDeletedRelationship( id );
}
Expand Down
Expand Up @@ -465,14 +465,6 @@ public PrimitiveLongIterator relationshipsGetAll( KernelStatement 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
public Cursor<NodeItem> nodeGetAllCursor( KernelStatement statement )
{
Expand Down
Expand Up @@ -234,15 +234,6 @@ public PrimitiveLongIterator relationshipsGetAll( KernelStatement 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
public Cursor<NodeItem> nodeGetAllCursor( KernelStatement statement )
{
Expand Down
Expand Up @@ -24,6 +24,7 @@
import java.util.Iterator;
import java.util.function.Function;

import org.neo4j.cursor.Cursor;
import org.neo4j.kernel.api.Statement;
import org.neo4j.kernel.api.exceptions.EntityNotFoundException;
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.SchemaWriteOperations;
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.schema.PopulationProgress;

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

private void lockRelationshipNodes( KernelStatement state, long startNodeId, long endNodeId )
Expand Down
Expand Up @@ -482,14 +482,6 @@ public PrimitiveIntIterator graphGetPropertyKeys()
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
public long nodesGetCount()
{
Expand Down
Expand Up @@ -1348,20 +1348,6 @@ public int relationshipTypeCount( KernelStatement statement )
}

// <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
public LegacyIndexHits nodeLegacyIndexGet( KernelStatement statement, String indexName, String key, Object value )
throws LegacyIndexNotFoundKernelException
Expand Down Expand Up @@ -1476,64 +1462,78 @@ public void nodeRemoveFromLegacyIndex( KernelStatement statement, String indexNa

@Override
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
{
relationshipVisit( statement, relationship,
( relId, type, startNode, endNode ) -> statement.legacyIndexTxState().relationshipChanges( indexName )
.addRelationship( relationship, key, value, startNode, endNode ) );
try ( Cursor<RelationshipItem> cursor = relationshipCursorById( statement, relId ) )
{
RelationshipItem rel = cursor.get();
statement.legacyIndexTxState().relationshipChanges( indexName )
.addRelationship( relId, key, value, rel.startNode(), rel.endNode() );
}
}

@Override
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
{
try
ReadableTransactionState state = statement.hasTxStateWithChanges() ? statement.txState() : null;
try ( Cursor<RelationshipItem> cursor = storeLayer
.relationshipCursor( statement.getStoreStatement(), relId, state ) )
{
relationshipVisit( statement, relationship,
( relId, type, startNode, endNode ) -> statement.legacyIndexTxState()
.relationshipChanges( indexName )
.removeRelationship( relId, key, value, startNode, endNode ) );
}
catch ( EntityNotFoundException e )
{ // Apparently this is OK
// Apparently it is OK if the relationship does not exist
if ( cursor.next() )
{
RelationshipItem rel = cursor.get();
statement.legacyIndexTxState().relationshipChanges( indexName )
.removeRelationship( relId, key, value, rel.startNode(), rel.endNode() );
}
}
}

@Override
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,
( relId, type, startNode, endNode ) -> statement.legacyIndexTxState()
.relationshipChanges( indexName ).removeRelationship( relId, key, startNode, endNode ) );
}
catch ( EntityNotFoundException e )
{ // Apparently this is OK
// Apparently it is OK if the relationship does not exist
if ( cursor.next() )
{
RelationshipItem rel = cursor.get();
statement.legacyIndexTxState().relationshipChanges( indexName )
.removeRelationship( relId, key, rel.startNode(), rel.endNode() );
}
}
}

@Override
public void relationshipRemoveFromLegacyIndex( final KernelStatement statement, final String indexName,
long relationship ) throws LegacyIndexNotFoundKernelException, EntityNotFoundException
long relId ) throws LegacyIndexNotFoundKernelException, EntityNotFoundException
{
try
{
relationshipVisit( statement, relationship,
( relId, type, startNode, endNode ) -> statement.legacyIndexTxState()
.relationshipChanges( indexName ).removeRelationship( relId, startNode, endNode ) );
}
catch ( EntityNotFoundException e )

ReadableTransactionState state = statement.hasTxStateWithChanges() ? statement.txState() : null;
try ( Cursor<RelationshipItem> cursor = storeLayer
.relationshipCursor( statement.getStoreStatement(), relId, state ) )
{
// 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( relationship );
if ( cursor.next() )
{
RelationshipItem rel = cursor.get();
statement.legacyIndexTxState().relationshipChanges( indexName )
.removeRelationship( relId, rel.startNode(), rel.endNode() );
}
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 );

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

Cursor<NodeItem> nodeGetAllCursor( KernelStatement statement );

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

0 comments on commit e51f528

Please sign in to comment.