Skip to content

Commit

Permalink
Use primitive long diff sets for relationships
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrei Koval committed May 16, 2018
1 parent f3d138a commit 5e2ef5c
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 246 deletions.
Expand Up @@ -19,6 +19,7 @@
*/
package org.neo4j.kernel.impl.api.state;

import org.eclipse.collections.api.iterator.LongIterator;
import org.eclipse.collections.api.map.primitive.MutableIntObjectMap;
import org.eclipse.collections.api.map.primitive.MutableLongObjectMap;
import org.eclipse.collections.api.map.primitive.MutableObjectLongMap;
Expand Down Expand Up @@ -53,7 +54,6 @@
import org.neo4j.kernel.impl.util.diffsets.DiffSets;
import org.neo4j.kernel.impl.util.diffsets.MutableLongDiffSets;
import org.neo4j.kernel.impl.util.diffsets.MutableLongDiffSetsImpl;
import org.neo4j.kernel.impl.util.diffsets.RelationshipDiffSets;
import org.neo4j.storageengine.api.Direction;
import org.neo4j.storageengine.api.NodeItem;
import org.neo4j.storageengine.api.PropertyItem;
Expand All @@ -63,7 +63,6 @@
import org.neo4j.storageengine.api.txstate.NodeState;
import org.neo4j.storageengine.api.txstate.PropertyContainerState;
import org.neo4j.storageengine.api.txstate.ReadableDiffSets;
import org.neo4j.storageengine.api.txstate.ReadableRelationshipDiffSets;
import org.neo4j.storageengine.api.txstate.RelationshipState;
import org.neo4j.storageengine.api.txstate.TxStateVisitor;
import org.neo4j.values.storable.TextValue;
Expand Down Expand Up @@ -106,7 +105,7 @@ public class TxState implements TransactionState, RelationshipVisitor.Home
private DiffSets<ConstraintDescriptor> constraintsChanges;

private RemovalsCountingDiffSets nodes;
private RemovalsCountingRelationshipsDiffSets relationships;
private RemovalsCountingDiffSets relationships;

private MutableObjectLongMap<IndexBackedConstraintDescriptor> createdConstraintIndexesByConstraint;

Expand Down Expand Up @@ -164,9 +163,10 @@ public void accept( final TxStateVisitor visitor )

if ( relationships != null )
{

for ( long relId : relationships.getAdded() )
final LongIterator added = relationships.getAdded().longIterator();
while ( added.hasNext() )
{
final long relId = added.next();
if ( !relationshipVisit( relId, visitor::visitCreatedRelationship ) )
{
throw new IllegalStateException( "No RelationshipState for added relationship!" );
Expand Down Expand Up @@ -626,16 +626,16 @@ private RemovalsCountingDiffSets nodes()
}

@Override
public ReadableRelationshipDiffSets<Long> addedAndRemovedRelationships()
public LongDiffSets addedAndRemovedRelationships()
{
return ReadableRelationshipDiffSets.Empty.ifNull( relationships );
return relationships == null ? LongDiffSets.EMPTY : relationships;
}

private RemovalsCountingRelationshipsDiffSets relationships()
private RemovalsCountingDiffSets relationships()
{
if ( relationships == null )
{
relationships = new RemovalsCountingRelationshipsDiffSets();
relationships = new RemovalsCountingDiffSets();
}
return relationships;
}
Expand Down Expand Up @@ -1090,33 +1090,4 @@ private boolean wasRemoved( long id )
return (removedFromAdded != null && removedFromAdded.contains( id )) || super.isRemoved( id );
}
}

/**
* This class works around the fact that create-delete in the same transaction is a no-op in {@link DiffSets},
* whereas we need to know total number of explicit removals.
*/
private class RemovalsCountingRelationshipsDiffSets extends RelationshipDiffSets<Long>
{
private MutableLongSet removedFromAdded;

@Override
public boolean remove( Long elem )
{
if ( added( false ).remove( elem ) )
{
if ( removedFromAdded == null )
{
removedFromAdded = collectionsFactory.newLongSet();
}
removedFromAdded.add( elem );
return true;
}
return removed( true ).add( elem );
}

private boolean wasRemoved( long id )
{
return (removedFromAdded != null && removedFromAdded.contains( id )) || super.isRemoved( id );
}
}
}
Expand Up @@ -36,7 +36,6 @@
import org.neo4j.graphdb.event.LabelEntry;
import org.neo4j.graphdb.event.PropertyEntry;
import org.neo4j.graphdb.event.TransactionData;
import org.neo4j.helpers.collection.IterableWrapper;
import org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException;
import org.neo4j.internal.kernel.api.exceptions.LabelNotFoundKernelException;
import org.neo4j.internal.kernel.api.exceptions.PropertyKeyIdNotFoundKernelException;
Expand Down Expand Up @@ -239,7 +238,7 @@ private void takeSnapshot()
}
}
} );
for ( long relId : state.addedAndRemovedRelationships().getRemoved() )
state.addedAndRemovedRelationships().getRemoved().each( relId ->
{
Relationship relationshipProxy = relationship( relId );
try ( Cursor<RelationshipItem> relationship = storeStatement.acquireSingleRelationshipCursor( relId ) )
Expand All @@ -257,10 +256,13 @@ private void takeSnapshot()
properties.get().value() ) );
}
}

catch ( PropertyKeyIdNotFoundKernelException e )
{
throw new IllegalStateException( "An entity that does not exist was modified.", e );
}
}
}
}
} );
for ( NodeState nodeState : state.modifiedNodes() )
{
Iterator<StorageProperty> added = nodeState.addedAndChangedProperties();
Expand Down Expand Up @@ -346,16 +348,9 @@ private Iterable<Node> map2Nodes( LongIterable ids )
return ids.asLazy().collect( id -> new NodeProxy( proxySpi, id ) );
}

private Iterable<Relationship> map2Rels( Iterable<Long> ids )
private Iterable<Relationship> map2Rels( LongIterable ids )
{
return new IterableWrapper<Relationship, Long>( ids )
{
@Override
protected Relationship underlyingObjectToObject( Long id )
{
return relationship( id );
}
};
return ids.asLazy().collect( this::relationship );
}

private Value committedValue( NodeState nodeState, int property )
Expand Down
Expand Up @@ -19,21 +19,20 @@
*/
package org.neo4j.kernel.impl.newapi;

import java.util.Set;
import org.eclipse.collections.api.set.primitive.LongSet;
import org.eclipse.collections.impl.factory.primitive.LongSets;

import org.neo4j.internal.kernel.api.RelationshipScanCursor;
import org.neo4j.io.pagecache.PageCursor;
import org.neo4j.kernel.api.txstate.TransactionState;

import static java.util.Collections.emptySet;

class DefaultRelationshipScanCursor extends RelationshipCursor implements RelationshipScanCursor
{
private int type;
private long next;
private long highMark;
private PageCursor pageCursor;
private Set<Long> addedRelationships;
private LongSet addedRelationships;

private final DefaultCursors pool;

Expand All @@ -56,7 +55,7 @@ void scan( int type, Read read )
this.type = type;
highMark = read.relationshipHighMark();
init( read );
this.addedRelationships = emptySet();
this.addedRelationships = LongSets.immutable.empty();
}

void single( long reference, Read read )
Expand All @@ -73,7 +72,7 @@ void single( long reference, Read read )
type = -1;
highMark = NO_ID;
init( read );
this.addedRelationships = emptySet();
this.addedRelationships = LongSets.immutable.empty();
}

@Override
Expand Down Expand Up @@ -181,11 +180,12 @@ private boolean isSingle()
return highMark == NO_ID;
}

@Override
protected void collectAddedTxStateSnapshot()
{
if ( !isSingle() )
{
addedRelationships = read.txState().addedAndRemovedRelationships().getAddedSnapshot();
addedRelationships = read.txState().addedAndRemovedRelationships().getAdded().freeze();
}
}

Expand Down

This file was deleted.

This file was deleted.

0 comments on commit 5e2ef5c

Please sign in to comment.