Skip to content

Commit

Permalink
Move degrees and relationshipTypes api out of NodeItem
Browse files Browse the repository at this point in the history
Moved the logic to the EntityReadOperations and StorageLayer
  • Loading branch information
davidegrohmann committed Feb 21, 2017
1 parent c8fba4d commit 4f351ce
Show file tree
Hide file tree
Showing 14 changed files with 498 additions and 670 deletions.
Expand Up @@ -22,6 +22,7 @@
import java.util.Iterator; import java.util.Iterator;


import org.neo4j.collection.primitive.PrimitiveIntIterator; import org.neo4j.collection.primitive.PrimitiveIntIterator;
import org.neo4j.collection.primitive.PrimitiveIntSet;
import org.neo4j.collection.primitive.PrimitiveLongIterator; import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.cursor.Cursor; import org.neo4j.cursor.Cursor;
import org.neo4j.helpers.Strings; import org.neo4j.helpers.Strings;
Expand Down Expand Up @@ -61,6 +62,7 @@
import org.neo4j.kernel.impl.constraints.ConstraintSemantics; import org.neo4j.kernel.impl.constraints.ConstraintSemantics;
import org.neo4j.kernel.impl.locking.LockTracer; import org.neo4j.kernel.impl.locking.LockTracer;
import org.neo4j.kernel.impl.locking.Locks; import org.neo4j.kernel.impl.locking.Locks;
import org.neo4j.storageengine.api.Direction;
import org.neo4j.storageengine.api.NodeItem; import org.neo4j.storageengine.api.NodeItem;
import org.neo4j.storageengine.api.RelationshipItem; import org.neo4j.storageengine.api.RelationshipItem;


Expand Down Expand Up @@ -510,4 +512,22 @@ public boolean nodeExists( KernelStatement statement, long id )
{ {
return entityReadOperations.nodeExists( statement, id ); return entityReadOperations.nodeExists( statement, id );
} }

@Override
public PrimitiveIntSet relationshipTypes( KernelStatement statement, NodeItem nodeItem )
{
return entityReadOperations.relationshipTypes( statement, nodeItem );
}

@Override
public int degree( KernelStatement statement, NodeItem nodeItem, Direction direction )
{
return entityReadOperations.degree( statement, nodeItem, direction );
}

@Override
public int degree( KernelStatement statement, NodeItem nodeItem, Direction direction, int relType )
{
return entityReadOperations.degree( statement, nodeItem, direction, relType );
}
} }
Expand Up @@ -20,6 +20,7 @@
package org.neo4j.kernel.impl.api; package org.neo4j.kernel.impl.api;


import org.neo4j.collection.primitive.PrimitiveIntIterator; import org.neo4j.collection.primitive.PrimitiveIntIterator;
import org.neo4j.collection.primitive.PrimitiveIntSet;
import org.neo4j.collection.primitive.PrimitiveLongIterator; import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.cursor.Cursor; import org.neo4j.cursor.Cursor;
import org.neo4j.kernel.api.exceptions.EntityNotFoundException; import org.neo4j.kernel.api.exceptions.EntityNotFoundException;
Expand All @@ -35,6 +36,7 @@
import org.neo4j.kernel.guard.Guard; import org.neo4j.kernel.guard.Guard;
import org.neo4j.kernel.impl.api.operations.EntityReadOperations; import org.neo4j.kernel.impl.api.operations.EntityReadOperations;
import org.neo4j.kernel.impl.api.operations.EntityWriteOperations; import org.neo4j.kernel.impl.api.operations.EntityWriteOperations;
import org.neo4j.storageengine.api.Direction;
import org.neo4j.storageengine.api.NodeItem; import org.neo4j.storageengine.api.NodeItem;
import org.neo4j.storageengine.api.RelationshipItem; import org.neo4j.storageengine.api.RelationshipItem;


Expand Down Expand Up @@ -336,4 +338,25 @@ public boolean nodeExists( KernelStatement statement, long id )
guard.check( statement ); guard.check( statement );
return entityReadDelegate.nodeExists( statement, id ); return entityReadDelegate.nodeExists( statement, id );
} }

@Override
public PrimitiveIntSet relationshipTypes( KernelStatement statement, NodeItem nodeItem )
{
guard.check( statement );
return entityReadDelegate.relationshipTypes( statement, nodeItem );
}

@Override
public int degree( KernelStatement statement, NodeItem nodeItem, Direction direction )
{
guard.check( statement );
return entityReadDelegate.degree( statement, nodeItem, direction );
}

@Override
public int degree( KernelStatement statement, NodeItem nodeItem, Direction direction, int relType )
{
guard.check( statement );
return entityReadDelegate.degree( statement, nodeItem, direction, relType );
}
} }
Expand Up @@ -37,14 +37,12 @@
import org.neo4j.kernel.api.query.ExecutingQuery; import org.neo4j.kernel.api.query.ExecutingQuery;
import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.LegacyIndexHits; import org.neo4j.kernel.api.LegacyIndexHits;
import org.neo4j.kernel.api.TokenWriteOperations;
import org.neo4j.kernel.api.schema.NodePropertyDescriptor;
import org.neo4j.kernel.api.ProcedureCallOperations; import org.neo4j.kernel.api.ProcedureCallOperations;
import org.neo4j.kernel.api.QueryRegistryOperations; import org.neo4j.kernel.api.QueryRegistryOperations;
import org.neo4j.kernel.api.ReadOperations; import org.neo4j.kernel.api.ReadOperations;
import org.neo4j.kernel.api.schema.RelationshipPropertyDescriptor;
import org.neo4j.kernel.api.SchemaWriteOperations; import org.neo4j.kernel.api.SchemaWriteOperations;
import org.neo4j.kernel.api.StatementConstants; import org.neo4j.kernel.api.StatementConstants;
import org.neo4j.kernel.api.TokenWriteOperations;
import org.neo4j.kernel.api.constraints.NodePropertyConstraint; import org.neo4j.kernel.api.constraints.NodePropertyConstraint;
import org.neo4j.kernel.api.constraints.NodePropertyExistenceConstraint; import org.neo4j.kernel.api.constraints.NodePropertyExistenceConstraint;
import org.neo4j.kernel.api.constraints.PropertyConstraint; import org.neo4j.kernel.api.constraints.PropertyConstraint;
Expand Down Expand Up @@ -72,7 +70,6 @@
import org.neo4j.kernel.api.exceptions.schema.IndexBrokenKernelException; import org.neo4j.kernel.api.exceptions.schema.IndexBrokenKernelException;
import org.neo4j.kernel.api.exceptions.schema.SchemaRuleNotFoundException; import org.neo4j.kernel.api.exceptions.schema.SchemaRuleNotFoundException;
import org.neo4j.kernel.api.exceptions.schema.TooManyLabelsException; import org.neo4j.kernel.api.exceptions.schema.TooManyLabelsException;
import org.neo4j.kernel.api.schema.IndexDescriptor;
import org.neo4j.kernel.api.index.InternalIndexState; import org.neo4j.kernel.api.index.InternalIndexState;
import org.neo4j.kernel.api.proc.BasicContext; import org.neo4j.kernel.api.proc.BasicContext;
import org.neo4j.kernel.api.proc.CallableUserAggregationFunction; import org.neo4j.kernel.api.proc.CallableUserAggregationFunction;
Expand All @@ -82,6 +79,8 @@
import org.neo4j.kernel.api.proc.UserFunctionSignature; import org.neo4j.kernel.api.proc.UserFunctionSignature;
import org.neo4j.kernel.api.properties.DefinedProperty; import org.neo4j.kernel.api.properties.DefinedProperty;
import org.neo4j.kernel.api.properties.Property; import org.neo4j.kernel.api.properties.Property;
import org.neo4j.kernel.api.schema.NodePropertyDescriptor;
import org.neo4j.kernel.api.schema.RelationshipPropertyDescriptor;
import org.neo4j.kernel.api.schema_new.SchemaBoundary; import org.neo4j.kernel.api.schema_new.SchemaBoundary;
import org.neo4j.kernel.api.schema_new.SchemaDescriptorFactory; import org.neo4j.kernel.api.schema_new.SchemaDescriptorFactory;
import org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor; import org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor;
Expand Down Expand Up @@ -113,7 +112,6 @@
import org.neo4j.storageengine.api.schema.SchemaRule; import org.neo4j.storageengine.api.schema.SchemaRule;


import static java.lang.String.format; import static java.lang.String.format;
import static org.neo4j.collection.primitive.Primitive.intSet;
import static org.neo4j.collection.primitive.PrimitiveIntCollections.deduplicate; import static org.neo4j.collection.primitive.PrimitiveIntCollections.deduplicate;


public class OperationsFacade public class OperationsFacade
Expand Down Expand Up @@ -405,7 +403,7 @@ public int nodeGetDegree( long nodeId, Direction direction, int relType ) throws
statement.assertOpen(); statement.assertOpen();
try ( Cursor<NodeItem> node = dataRead().nodeCursorById( statement, nodeId ) ) try ( Cursor<NodeItem> node = dataRead().nodeCursorById( statement, nodeId ) )
{ {
return node.get().degree( direction( direction ), relType ); return dataRead().degree( statement, node.get(), direction( direction ), relType );
} }
} }


Expand All @@ -415,7 +413,7 @@ public int nodeGetDegree( long nodeId, Direction direction ) throws EntityNotFou
statement.assertOpen(); statement.assertOpen();
try ( Cursor<NodeItem> node = dataRead().nodeCursorById( statement, nodeId ) ) try ( Cursor<NodeItem> node = dataRead().nodeCursorById( statement, nodeId ) )
{ {
return node.get().degree( direction( direction ) ); return dataRead().degree( statement, node.get(), direction( direction ) );
} }
} }


Expand All @@ -435,7 +433,7 @@ public PrimitiveIntIterator nodeGetRelationshipTypes( long nodeId ) throws Entit
statement.assertOpen(); statement.assertOpen();
try ( Cursor<NodeItem> node = dataRead().nodeCursorById( statement, nodeId ) ) try ( Cursor<NodeItem> node = dataRead().nodeCursorById( statement, nodeId ) )
{ {
return node.get().relationshipTypes().iterator(); return dataRead().relationshipTypes( statement,node.get() ).iterator();
} }
} }


Expand Down
Expand Up @@ -22,7 +22,9 @@
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;


import org.neo4j.collection.primitive.Primitive;
import org.neo4j.collection.primitive.PrimitiveIntIterator; import org.neo4j.collection.primitive.PrimitiveIntIterator;
import org.neo4j.collection.primitive.PrimitiveIntSet;
import org.neo4j.collection.primitive.PrimitiveLongCollections; import org.neo4j.collection.primitive.PrimitiveLongCollections;
import org.neo4j.collection.primitive.PrimitiveLongIterator; import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.collection.primitive.PrimitiveLongResourceIterator; import org.neo4j.collection.primitive.PrimitiveLongResourceIterator;
Expand Down Expand Up @@ -86,6 +88,7 @@
import org.neo4j.kernel.impl.index.LegacyIndexStore; import org.neo4j.kernel.impl.index.LegacyIndexStore;
import org.neo4j.kernel.impl.util.Validators; import org.neo4j.kernel.impl.util.Validators;
import org.neo4j.register.Register.DoubleLongRegister; import org.neo4j.register.Register.DoubleLongRegister;
import org.neo4j.storageengine.api.Direction;
import org.neo4j.storageengine.api.EntityType; import org.neo4j.storageengine.api.EntityType;
import org.neo4j.storageengine.api.NodeItem; import org.neo4j.storageengine.api.NodeItem;
import org.neo4j.storageengine.api.PropertyItem; import org.neo4j.storageengine.api.PropertyItem;
Expand All @@ -99,6 +102,7 @@
import org.neo4j.storageengine.api.txstate.ReadableDiffSets; import org.neo4j.storageengine.api.txstate.ReadableDiffSets;


import static java.lang.String.format; import static java.lang.String.format;
import static org.neo4j.collection.primitive.PrimitiveIntCollections.filter;
import static org.neo4j.collection.primitive.PrimitiveLongCollections.single; import static org.neo4j.collection.primitive.PrimitiveLongCollections.single;
import static org.neo4j.helpers.collection.Iterators.filter; import static org.neo4j.helpers.collection.Iterators.filter;
import static org.neo4j.helpers.collection.Iterators.iterator; import static org.neo4j.helpers.collection.Iterators.iterator;
Expand All @@ -107,6 +111,7 @@
import static org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor.Filter.GENERAL; import static org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor.Filter.GENERAL;
import static org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor.Filter.UNIQUE; import static org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor.Filter.UNIQUE;
import static org.neo4j.kernel.impl.api.PropertyValueComparison.COMPARE_NUMBERS; import static org.neo4j.kernel.impl.api.PropertyValueComparison.COMPARE_NUMBERS;
import static org.neo4j.kernel.impl.util.Cursors.count;
import static org.neo4j.register.Registers.newDoubleLongRegister; import static org.neo4j.register.Registers.newDoubleLongRegister;
import static org.neo4j.storageengine.api.txstate.TxStateVisitor.EMPTY; import static org.neo4j.storageengine.api.txstate.TxStateVisitor.EMPTY;


Expand Down Expand Up @@ -1615,6 +1620,72 @@ else if ( txState.nodeIsAddedInThisTx( id ) )
return storeLayer.nodeExists( id ); return storeLayer.nodeExists( id );
} }


@Override
public PrimitiveIntSet relationshipTypes( KernelStatement statement, NodeItem node )
{
if ( statement.hasTxStateWithChanges() && statement.txState().nodeIsAddedInThisTx( node.id() ) )
{
return statement.txState().getNodeState( node.id() ).relationshipTypes();
}

// Read types in the current transaction
PrimitiveIntSet types = statement.hasTxStateWithChanges()
? statement.txState().getNodeState( node.id() ).relationshipTypes()
: Primitive.intSet();

// Augment with types stored on disk, minus any types where all rels of that type are deleted
// in current tx.
types.addAll( filter( storeLayer.relationshipTypes( statement.getStoreStatement(), node ).iterator(),
( current ) -> !types.contains( current ) && degree( statement, node, Direction.BOTH, current ) > 0 ) );

return types;
}

@Override
public int degree( KernelStatement statement, NodeItem node, Direction direction )
{
int degree = statement.hasTxStateWithChanges() && statement.txState().nodeIsAddedInThisTx( node.id() )
? 0
: computeDegree( statement, node, direction, null );

return statement.hasTxStateWithChanges() && augmentDegree( statement, node )
? statement.txState().getNodeState( node.id() ).augmentDegree( direction, degree )
: degree;
}

@Override
public int degree( KernelStatement statement, NodeItem node, Direction direction, int relType )
{
int degree = statement.hasTxStateWithChanges() && statement.txState().nodeIsAddedInThisTx( node.id() )
? 0
: computeDegree( statement, node, direction, relType );

return statement.hasTxStateWithChanges() && augmentDegree( statement, node )
? statement.txState().getNodeState( node.id() ).augmentDegree( direction, degree, relType )
: degree;
}

// FIXME: temporary workaround: the node item takes care of the tx state itself, hence don't count it twice!
private boolean augmentDegree( KernelStatement statement, NodeItem node )
{
return node.isDense() || statement.txState().nodeIsAddedInThisTx( node.id() );
}

private int computeDegree( KernelStatement statement, NodeItem node, Direction direction, Integer relType )
{
if ( node.isDense() )
{
return storeLayer.degreeRelationshipsInGroup( statement.getStoreStatement(), node.id(), node.nextGroupId(),
direction, relType );
}
else
{
return count( relType == null
? node.relationships( direction )
: node.relationships( direction, relType ) );
}
}

private static DefinedProperty definedPropertyOrNull( Property existingProperty ) private static DefinedProperty definedPropertyOrNull( Property existingProperty )
{ {
return existingProperty instanceof DefinedProperty ? (DefinedProperty) existingProperty : null; return existingProperty instanceof DefinedProperty ? (DefinedProperty) existingProperty : null;
Expand Down
Expand Up @@ -33,7 +33,6 @@
import org.neo4j.storageengine.api.txstate.NodeState; import org.neo4j.storageengine.api.txstate.NodeState;


import static org.neo4j.collection.primitive.Primitive.intSet; import static org.neo4j.collection.primitive.Primitive.intSet;
import static org.neo4j.collection.primitive.PrimitiveIntCollections.filter;
import static org.neo4j.kernel.impl.store.record.Record.NO_NEXT_RELATIONSHIP; import static org.neo4j.kernel.impl.store.record.Record.NO_NEXT_RELATIONSHIP;
import static org.neo4j.kernel.impl.util.Cursors.empty; import static org.neo4j.kernel.impl.util.Cursors.empty;


Expand Down Expand Up @@ -166,38 +165,6 @@ public Cursor<RelationshipItem> relationships( Direction direction )
return state.augmentNodeRelationshipCursor( cursor, nodeState, direction, null ); return state.augmentNodeRelationshipCursor( cursor, nodeState, direction, null );
} }


@Override
public PrimitiveIntSet relationshipTypes()
{
if ( nodeIsAddedInThisTx )
{
return nodeState.relationshipTypes();
}

// Read types in the current transaction
PrimitiveIntSet types = nodeState.relationshipTypes();

// Augment with types stored on disk, minus any types where all rels of that type are deleted
// in current tx.
types.addAll( filter( cursor.get().relationshipTypes().iterator(),
( current ) -> !types.contains( current ) && degree( Direction.BOTH, current ) > 0 ) );

return types;
}

@Override
public int degree( Direction direction )
{
return nodeState.augmentDegree( direction, nodeIsAddedInThisTx ? 0 : cursor.get().degree( direction ) );
}

@Override
public int degree( Direction direction, int relType )
{
int degree = nodeIsAddedInThisTx ? 0 : cursor.get().degree( direction, relType );
return nodeState.augmentDegree( direction, degree, relType );
}

@Override @Override
public boolean isDense() public boolean isDense()
{ {
Expand Down
Expand Up @@ -20,6 +20,7 @@
package org.neo4j.kernel.impl.api.operations; package org.neo4j.kernel.impl.api.operations;


import org.neo4j.collection.primitive.PrimitiveIntIterator; import org.neo4j.collection.primitive.PrimitiveIntIterator;
import org.neo4j.collection.primitive.PrimitiveIntSet;
import org.neo4j.collection.primitive.PrimitiveLongIterator; import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.cursor.Cursor; import org.neo4j.cursor.Cursor;
import org.neo4j.kernel.api.exceptions.EntityNotFoundException; import org.neo4j.kernel.api.exceptions.EntityNotFoundException;
Expand All @@ -28,6 +29,7 @@
import org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor; import org.neo4j.kernel.api.schema_new.index.NewIndexDescriptor;
import org.neo4j.kernel.impl.api.KernelStatement; import org.neo4j.kernel.impl.api.KernelStatement;
import org.neo4j.kernel.impl.api.RelationshipVisitor; import org.neo4j.kernel.impl.api.RelationshipVisitor;
import org.neo4j.storageengine.api.Direction;
import org.neo4j.storageengine.api.NodeItem; import org.neo4j.storageengine.api.NodeItem;
import org.neo4j.storageengine.api.RelationshipItem; import org.neo4j.storageengine.api.RelationshipItem;


Expand Down Expand Up @@ -147,4 +149,37 @@ Cursor<RelationshipItem> relationshipCursorById( KernelStatement statement, long
long relationshipsGetCount( KernelStatement statement ); long relationshipsGetCount( KernelStatement statement );


boolean nodeExists( KernelStatement statement, long id ); boolean nodeExists( KernelStatement statement, long id );

/**
* Returns the set of types for relationships attached to this node.
*
* @param statement the current kernel statement
* @param nodeItem the node
* @return the set of types for relationships attached to this node.
* @throws IllegalStateException if no current node is selected
*/
PrimitiveIntSet relationshipTypes( KernelStatement statement, NodeItem nodeItem );

/**
* Returns degree, e.g. number of relationships for this node.
*
* @param statement the current kernel statement
* @param nodeItem the node
* @param direction {@link Direction} filter when counting relationships, e.g. only
* {@link Direction#OUTGOING outgoing} or {@link Direction#INCOMING incoming}.
* @return degree of relationships in the given direction.
*/
int degree( KernelStatement statement, NodeItem nodeItem, Direction direction );

/**
* Returns degree, e.g. number of relationships for this node.
*
* @param statement the current kernel statement
* @param nodeItem the node
* @param direction {@link Direction} filter on when counting relationships, e.g. only
* {@link Direction#OUTGOING outgoing} or {@link Direction#INCOMING incoming}.
* @param relType relationship type id to filter when counting relationships.
* @return degree of relationships in the given direction and relationship type.
*/
int degree( KernelStatement statement, NodeItem nodeItem, Direction direction, int relType );
} }

0 comments on commit 4f351ce

Please sign in to comment.