Skip to content

Commit

Permalink
Make RelationshipCursor::hasProperties tx-state aware
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusmelke committed May 18, 2018
1 parent cf6f254 commit 5400f6c
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 9 deletions.
Expand Up @@ -49,6 +49,7 @@
import static org.neo4j.internal.kernel.api.RelationshipTransactionStateTestBase.RelationshipDirection.LOOP; import static org.neo4j.internal.kernel.api.RelationshipTransactionStateTestBase.RelationshipDirection.LOOP;
import static org.neo4j.internal.kernel.api.RelationshipTransactionStateTestBase.RelationshipDirection.OUT; import static org.neo4j.internal.kernel.api.RelationshipTransactionStateTestBase.RelationshipDirection.OUT;
import static org.neo4j.values.storable.Values.NO_VALUE; import static org.neo4j.values.storable.Values.NO_VALUE;
import static org.neo4j.values.storable.Values.longValue;
import static org.neo4j.values.storable.Values.stringValue; import static org.neo4j.values.storable.Values.stringValue;


@SuppressWarnings( "Duplicates" ) @SuppressWarnings( "Duplicates" )
Expand Down Expand Up @@ -1269,6 +1270,98 @@ private Map<String,Integer> modifyStartNodeRelationships( RelationshipTestSuppor
return expectedCounts; return expectedCounts;
} }


@Test
public void hasPropertiesShouldSeeNewlyCreatedProperties() throws Exception
{
// Given
long relationship;
try ( Transaction tx = session.beginTransaction() )
{
Write write = tx.dataWrite();
int token = tx.tokenWrite().relationshipTypeGetOrCreateForName( "R" );
relationship = write.relationshipCreate( write.nodeCreate(),
token,
write.nodeCreate() );
tx.success();
}

// Then
try ( Transaction tx = session.beginTransaction() )
{
try ( RelationshipScanCursor cursor = tx.cursors().allocateRelationshipScanCursor() )
{
tx.dataRead().singleRelationship( relationship, cursor );
assertTrue( cursor.next() );
assertFalse( cursor.hasProperties() );
tx.dataWrite().relationshipSetProperty( relationship,
tx.tokenWrite().propertyKeyGetOrCreateForName( "prop" ),
stringValue( "foo" ) );
assertTrue( cursor.hasProperties() );
}
}
}

@Test
public void hasPropertiesShouldSeeNewlyCreatedPropertiesOnNewlyCreatedRelationship() throws Exception
{
try ( Transaction tx = session.beginTransaction() )
{
Write write = tx.dataWrite();
int token = tx.tokenWrite().relationshipTypeGetOrCreateForName( "R" );
long relationship = write.relationshipCreate( write.nodeCreate(), token, write.nodeCreate() );
try ( RelationshipScanCursor cursor = tx.cursors().allocateRelationshipScanCursor() )
{
tx.dataRead().singleRelationship( relationship, cursor );
assertTrue( cursor.next() );
assertFalse( cursor.hasProperties() );
tx.dataWrite().relationshipSetProperty( relationship,
tx.tokenWrite().propertyKeyGetOrCreateForName( "prop" ),
stringValue( "foo" ) );
assertTrue( cursor.hasProperties() );
}
}
}

@Test
public void hasPropertiesShouldSeeNewlyRemovedProperties() throws Exception
{
// Given
long relationship;
int prop1, prop2, prop3;
try ( Transaction tx = session.beginTransaction() )
{
Write write = tx.dataWrite();
int token = tx.tokenWrite().relationshipTypeGetOrCreateForName( "R" );
relationship = write.relationshipCreate( write.nodeCreate(), token, write.nodeCreate() );
prop1 = tx.tokenWrite().propertyKeyGetOrCreateForName( "prop1" );
prop2 = tx.tokenWrite().propertyKeyGetOrCreateForName( "prop2" );
prop3 = tx.tokenWrite().propertyKeyGetOrCreateForName( "prop3" );
tx.dataWrite().relationshipSetProperty( relationship, prop1, longValue( 1 ) );
tx.dataWrite().relationshipSetProperty( relationship, prop2, longValue( 2 ) );
tx.dataWrite().relationshipSetProperty( relationship, prop3, longValue( 3 ) );
tx.success();
}

// Then
try ( Transaction tx = session.beginTransaction() )
{
try ( RelationshipScanCursor cursor = tx.cursors().allocateRelationshipScanCursor() )
{
tx.dataRead().singleRelationship( relationship, cursor );
assertTrue( cursor.next() );

assertTrue( cursor.hasProperties() );
tx.dataWrite().relationshipRemoveProperty( relationship, prop1 );
assertTrue( cursor.hasProperties() );
tx.dataWrite().relationshipRemoveProperty( relationship, prop2 );
assertTrue( cursor.hasProperties() );
tx.dataWrite().relationshipRemoveProperty( relationship, prop3 );
assertFalse( cursor.hasProperties() );
}
}
}


private void relateNTimes( int nRelationshipsInStore, int type, long n1, long n2, Transaction tx ) private void relateNTimes( int nRelationshipsInStore, int type, long n1, long n2, Transaction tx )
throws KernelException throws KernelException
{ {
Expand Down
Expand Up @@ -35,11 +35,9 @@ class DefaultRelationshipScanCursor extends RelationshipCursor implements Relati
private PageCursor pageCursor; private PageCursor pageCursor;
private Set<Long> addedRelationships; private Set<Long> addedRelationships;


private final DefaultCursors pool;

DefaultRelationshipScanCursor( DefaultCursors pool ) DefaultRelationshipScanCursor( DefaultCursors pool )
{ {
this.pool = pool; super(pool);
} }


void scan( int type, Read read ) void scan( int type, Read read )
Expand Down Expand Up @@ -142,6 +140,7 @@ private boolean containsRelationship( TransactionState txs )
@Override @Override
public void close() public void close()
{ {
super.close();
if ( !isClosed() ) if ( !isClosed() )
{ {
read = null; read = null;
Expand Down
Expand Up @@ -122,7 +122,6 @@ private static FilterState fromRelationshipDirection( RelationshipDirection dire
private Record buffer; private Record buffer;
private PageCursor pageCursor; private PageCursor pageCursor;
private final DefaultRelationshipGroupCursor group; private final DefaultRelationshipGroupCursor group;
private final DefaultCursors pool;
private GroupState groupState; private GroupState groupState;
private FilterState filterState; private FilterState filterState;
private boolean filterStore; private boolean filterStore;
Expand All @@ -132,8 +131,8 @@ private static FilterState fromRelationshipDirection( RelationshipDirection dire


DefaultRelationshipTraversalCursor( DefaultRelationshipGroupCursor group, DefaultCursors pool ) DefaultRelationshipTraversalCursor( DefaultRelationshipGroupCursor group, DefaultCursors pool )
{ {
super(pool);
this.group = group; this.group = group;
this.pool = pool;
} }


/* /*
Expand Down Expand Up @@ -482,6 +481,7 @@ private boolean traversingDenseNode()
@Override @Override
public void close() public void close()
{ {
super.close();
if ( !isClosed() ) if ( !isClosed() )
{ {
read = null; read = null;
Expand Down
Expand Up @@ -27,13 +27,16 @@


abstract class RelationshipCursor extends RelationshipRecord implements RelationshipDataAccessor, RelationshipVisitor<RuntimeException> abstract class RelationshipCursor extends RelationshipRecord implements RelationshipDataAccessor, RelationshipVisitor<RuntimeException>
{ {
Read read;
private boolean hasChanges; private boolean hasChanges;
private boolean checkHasChanges; private boolean checkHasChanges;
private PropertyCursor propertyCursor;
final DefaultCursors pool;
Read read;


RelationshipCursor() RelationshipCursor( DefaultCursors pool )
{ {
super( NO_ID ); super( NO_ID );
this.pool = pool;
} }


protected void init( Read read ) protected void init( Read read )
Expand All @@ -57,7 +60,16 @@ public int type()
@Override @Override
public boolean hasProperties() public boolean hasProperties()
{ {
return nextProp != DefaultPropertyCursor.NO_ID; if (read.hasTxStateWithChanges())
{
PropertyCursor cursor = propertyCursor();
properties( cursor );
return cursor.next();
}
else
{
return nextProp != DefaultPropertyCursor.NO_ID;
}
} }


@Override @Override
Expand Down Expand Up @@ -118,7 +130,7 @@ protected boolean hasChanges()
} }


// Load transaction state using RelationshipVisitor // Load transaction state using RelationshipVisitor
protected void loadFromTxState( long reference ) void loadFromTxState( long reference )
{ {
read.txState().relationshipVisit( reference, this ); read.txState().relationshipVisit( reference, this );
} }
Expand All @@ -130,4 +142,22 @@ public void visit( long relationshipId, int typeId, long startNodeId, long endNo
setId( relationshipId ); setId( relationshipId );
initialize( true, NO_ID, startNodeId, endNodeId, typeId, NO_ID, NO_ID, NO_ID, NO_ID, false, false ); initialize( true, NO_ID, startNodeId, endNodeId, typeId, NO_ID, NO_ID, NO_ID, NO_ID, false, false );
} }

private PropertyCursor propertyCursor()
{
if ( propertyCursor == null )
{
propertyCursor = pool.allocatePropertyCursor();
}
return propertyCursor;
}

void close()
{
if ( propertyCursor != null )
{
propertyCursor.close();
propertyCursor = null;
}
}
} }

0 comments on commit 5400f6c

Please sign in to comment.