Skip to content

Commit

Permalink
More efficient handling of counting non-dense degree
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusmelke committed Mar 1, 2018
1 parent 29105b8 commit db46356
Show file tree
Hide file tree
Showing 8 changed files with 394 additions and 172 deletions.
Expand Up @@ -38,41 +38,39 @@ public static RelationshipSelectionCursor connectingRelationships( Read read, Cu
long fromNode, Direction direction, long toNode )
{

try ( RelationshipGroupCursor group = cursors.allocateRelationshipGroupCursor() )

int fromDegree = nodeGetDegree( read, fromNode, nodeCursor, cursors, direction );
if ( fromDegree == 0 )
{
int fromDegree = nodeGetDegree( read, fromNode, nodeCursor, group, direction );
if ( fromDegree == 0 )
{
return RelationshipSelectionCursor.EMPTY;
}
return RelationshipSelectionCursor.EMPTY;
}

int toDegree = nodeGetDegree( read, toNode, nodeCursor, group, direction.reverse() );
if ( toDegree == 0 )
{
return RelationshipSelectionCursor.EMPTY;
}
int toDegree = nodeGetDegree( read, toNode, nodeCursor, cursors, direction.reverse() );
if ( toDegree == 0 )
{
return RelationshipSelectionCursor.EMPTY;
}

long startNode;
long endNode;
Direction relDirection;
if ( fromDegree < toDegree )
{
startNode = fromNode;
endNode = toNode;
relDirection = direction;
}
else
{
startNode = toNode;
endNode = fromNode;
relDirection = direction.reverse();
}
long startNode;
long endNode;
Direction relDirection;
if ( fromDegree < toDegree )
{
startNode = fromNode;
endNode = toNode;
relDirection = direction;
}
else
{
startNode = toNode;
endNode = fromNode;
relDirection = direction.reverse();
}

RelationshipSelectionCursor selectionCursor = CompiledCursorUtils
.nodeGetRelationships( read, cursors, nodeCursor, startNode, relDirection );
RelationshipSelectionCursor selectionCursor = CompiledCursorUtils
.nodeGetRelationships( read, cursors, nodeCursor, startNode, relDirection );

return connectingRelationshipsIterator( selectionCursor, endNode );
}
return connectingRelationshipsIterator( selectionCursor, endNode );
}

public static RelationshipSelectionCursor connectingRelationships( Read read, CursorFactory cursors,
Expand Down Expand Up @@ -119,61 +117,59 @@ public static RelationshipSelectionCursor connectingRelationships( Read read, Cu
}
}

static int nodeGetDegree( Read read, long node, NodeCursor nodeCursor, RelationshipGroupCursor group,
static int nodeGetDegree( Read read, long node, NodeCursor nodeCursor, CursorFactory cursors,
Direction direction )
{
read.singleNode( node, nodeCursor );
if ( !nodeCursor.next() )
{
return 0;
}
switch ( direction )
{
case OUTGOING:
return countOutgoing( nodeCursor, group );
case INCOMING:
return countIncoming( nodeCursor, group );
case BOTH:
return countAll( nodeCursor, group );
default:
throw new IllegalStateException( "Unknown direction " + direction );
}
read.singleNode( node, nodeCursor );
if ( !nodeCursor.next() )
{
return 0;
}
switch ( direction )
{
case OUTGOING:
return countOutgoing( nodeCursor, cursors );
case INCOMING:
return countIncoming( nodeCursor, cursors );
case BOTH:
return countAll( nodeCursor, cursors );
default:
throw new IllegalStateException( "Unknown direction " + direction );
}
}

static int nodeGetDegree( Read read, long node, NodeCursor nodeCursor, RelationshipGroupCursor group,
static int nodeGetDegree( Read read, long node, NodeCursor nodeCursor, CursorFactory cursors,
Direction direction, int type )
{
read.singleNode( node, nodeCursor );
if ( !nodeCursor.next() )
{
return 0;
}
switch ( direction )
{
case OUTGOING:
return countOutgoing( nodeCursor, group, type );
case INCOMING:
return countIncoming( nodeCursor, group, type );
case BOTH:
return countAll( nodeCursor, group, type );
default:
throw new IllegalStateException( "Unknown direction " + direction );
}
}
switch ( direction )
{
case OUTGOING:
return countOutgoing( nodeCursor, cursors, type );
case INCOMING:
return countIncoming( nodeCursor, cursors, type );
case BOTH:
return countAll( nodeCursor, cursors, type );
default:
throw new IllegalStateException( "Unknown direction " + direction );
}
}

private static int calculateTotalDegree( Read read, long fromNode, NodeCursor nodeCursor, Direction direction,
int[] relTypes, CursorFactory cursors ) throws EntityNotFoundException
{
try ( RelationshipGroupCursor group = cursors.allocateRelationshipGroupCursor() )
{
int degree = 0;
for ( int relType : relTypes )
{
degree += nodeGetDegree( read, fromNode, nodeCursor, group, direction, relType );
}

return degree;
int degree = 0;
for ( int relType : relTypes )
{
degree += nodeGetDegree( read, fromNode, nodeCursor, cursors, direction, relType );
}

return degree;
}

private static RelationshipSelectionCursor connectingRelationshipsIterator(
Expand Down
Expand Up @@ -82,13 +82,11 @@ public void shouldComputeDegreeWithoutType() throws Exception
{
Read read = tx.dataRead();
CursorFactory cursors = tx.cursors();
try ( NodeCursor nodes = cursors.allocateNodeCursor();
RelationshipGroupCursor group = cursors.allocateRelationshipGroupCursor() )
try ( NodeCursor nodes = cursors.allocateNodeCursor() )
{

assertThat( nodeGetDegree( read, node, nodes, group, OUTGOING ), equalTo( 3 ) );
assertThat( nodeGetDegree( read, node, nodes, group, INCOMING ), equalTo( 2 ) );
assertThat( nodeGetDegree( read, node, nodes, group, BOTH ), equalTo( 4 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, OUTGOING ), equalTo( 3 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, INCOMING ), equalTo( 2 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, BOTH ), equalTo( 4 ) );
}
}
}
Expand Down Expand Up @@ -122,20 +120,19 @@ public void shouldComputeDegreeWithType() throws Exception
{
Read read = tx.dataRead();
CursorFactory cursors = tx.cursors();
try ( NodeCursor nodes = cursors.allocateNodeCursor();
RelationshipGroupCursor group = cursors.allocateRelationshipGroupCursor() )
try ( NodeCursor nodes = cursors.allocateNodeCursor() )
{
assertThat( nodeGetDegree( read, node, nodes, group, OUTGOING, out ), equalTo( 2 ) );
assertThat( nodeGetDegree( read, node, nodes, group, OUTGOING, in ), equalTo( 0 ) );
assertThat( nodeGetDegree( read, node, nodes, group, OUTGOING, loop ), equalTo( 1 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, OUTGOING, out ), equalTo( 2 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, OUTGOING, in ), equalTo( 0 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, OUTGOING, loop ), equalTo( 1 ) );

assertThat( nodeGetDegree( read, node, nodes, group, INCOMING, out ), equalTo( 0 ) );
assertThat( nodeGetDegree( read, node, nodes, group, INCOMING, in ), equalTo( 1 ) );
assertThat( nodeGetDegree( read, node, nodes, group, INCOMING, loop ), equalTo( 1 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, INCOMING, out ), equalTo( 0 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, INCOMING, in ), equalTo( 1 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, INCOMING, loop ), equalTo( 1 ) );

assertThat( nodeGetDegree( read, node, nodes, group, BOTH, out ), equalTo( 2 ) );
assertThat( nodeGetDegree( read, node, nodes, group, BOTH, in ), equalTo( 1 ) );
assertThat( nodeGetDegree( read, node, nodes, group, BOTH, loop ), equalTo( 1 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, BOTH, out ), equalTo( 2 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, BOTH, in ), equalTo( 1 ) );
assertThat( nodeGetDegree( read, node, nodes, cursors, BOTH, loop ), equalTo( 1 ) );
}
}
}
Expand Down
Expand Up @@ -497,35 +497,28 @@ sealed class TransactionBoundQueryContext(val transactionalContext: Transactiona

override def nodeGetDegree(node: Long, dir: SemanticDirection): Int = {
val cursor = nodeCursor
val group = transactionalContext.cursors.allocateRelationshipGroupCursor()
try {
reads().singleNode(node, cursor)
if (!cursor.next()) 0
else {
dir match {
case OUTGOING => Nodes.countOutgoing(cursor, group)
case INCOMING => Nodes.countIncoming(cursor, group)
case BOTH => Nodes.countAll(cursor, group)
case OUTGOING => Nodes.countOutgoing(cursor, transactionalContext.cursors)
case INCOMING => Nodes.countIncoming(cursor, transactionalContext.cursors)
case BOTH => Nodes.countAll(cursor, transactionalContext.cursors)
}
}
}
finally group.close()
}

override def nodeGetDegree(node: Long, dir: SemanticDirection, relTypeId: Int): Int = {
val cursor = nodeCursor
val group = transactionalContext.cursors.allocateRelationshipGroupCursor()
try {
reads().singleNode(node, cursor)
if (!cursor.next()) 0
else {
dir match {
case OUTGOING => Nodes.countOutgoing(cursor, group, relTypeId)
case INCOMING => Nodes.countIncoming(cursor, group, relTypeId)
case BOTH => Nodes.countAll(cursor, group, relTypeId)
}
reads().singleNode(node, cursor)
if (!cursor.next()) 0
else {
dir match {
case OUTGOING => Nodes.countOutgoing(cursor, transactionalContext.cursors, relTypeId)
case INCOMING => Nodes.countIncoming(cursor, transactionalContext.cursors, relTypeId)
case BOTH => Nodes.countAll(cursor, transactionalContext.cursors, relTypeId)
}
} finally group.close()
}
}

override def nodeIsDense(node: Long): Boolean = {
Expand Down

0 comments on commit db46356

Please sign in to comment.