Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extracting common code patterns into Cursor interfaces Extract inner classes Share common code among different classes to avoid duplication
- Loading branch information
1 parent
dd67bd8
commit 621625a
Showing
8 changed files
with
518 additions
and
316 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 104 additions & 0 deletions
104
community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/DegreeCounter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* Copyright (c) 2002-2017 "Neo Technology," | ||
* Network Engine for Objects in Lund AB [http://neotechnology.com] | ||
* | ||
* This file is part of Neo4j. | ||
* | ||
* Neo4j is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.neo4j.kernel.impl.api.store; | ||
|
||
import org.neo4j.kernel.impl.store.InvalidRecordException; | ||
import org.neo4j.kernel.impl.store.RecordCursor; | ||
import org.neo4j.kernel.impl.store.RecordCursors; | ||
import org.neo4j.kernel.impl.store.record.NodeRecord; | ||
import org.neo4j.kernel.impl.store.record.Record; | ||
import org.neo4j.kernel.impl.store.record.RelationshipGroupRecord; | ||
import org.neo4j.kernel.impl.store.record.RelationshipRecord; | ||
import org.neo4j.storageengine.api.Direction; | ||
|
||
import static org.neo4j.kernel.impl.store.record.RecordLoad.CHECK; | ||
import static org.neo4j.kernel.impl.store.record.RecordLoad.FORCE; | ||
|
||
public interface DegreeCounter | ||
{ | ||
default long countByFirstPrevPointer( long relationshipId, RecordCursor<RelationshipRecord> cursor, | ||
NodeRecord nodeRecord, RelationshipRecord relationshipRecord ) | ||
{ | ||
if ( relationshipId == Record.NO_NEXT_RELATIONSHIP.intValue() ) | ||
{ | ||
return 0; | ||
} | ||
cursor.next( relationshipId, relationshipRecord, FORCE ); | ||
if ( relationshipRecord.getFirstNode() == nodeRecord.getId() ) | ||
{ | ||
return relationshipRecord.getFirstPrevRel(); | ||
} | ||
if ( relationshipRecord.getSecondNode() == nodeRecord.getId() ) | ||
{ | ||
return relationshipRecord.getSecondPrevRel(); | ||
} | ||
throw new InvalidRecordException( "Node " + nodeRecord.getId() + " neither start nor end node of " + relationshipRecord ); | ||
} | ||
|
||
default int countRelationshipsInGroup( long groupId, Direction direction, Integer type, NodeRecord nodeRecord, | ||
RelationshipRecord relationshipRecord, RelationshipGroupRecord groupRecord, RecordCursors cursors ) | ||
{ | ||
int count = 0; | ||
while ( groupId != Record.NO_NEXT_RELATIONSHIP.intValue() ) | ||
{ | ||
boolean groupRecordInUse = cursors.relationshipGroup().next( groupId, groupRecord, FORCE ); | ||
if ( groupRecordInUse && ( type == null || groupRecord.getType() == type ) ) | ||
{ | ||
count += nodeDegreeByDirection( direction, nodeRecord, relationshipRecord, groupRecord, cursors ); | ||
if ( type != null ) | ||
{ | ||
// we have read the only type we were interested on, so break the look | ||
break; | ||
} | ||
} | ||
groupId = groupRecord.getNext(); | ||
} | ||
return count; | ||
} | ||
|
||
default long nodeDegreeByDirection( Direction direction, NodeRecord nodeRecord, | ||
RelationshipRecord relationshipRecord, RelationshipGroupRecord groupRecord, RecordCursors cursors ) | ||
{ | ||
RecordCursor<RelationshipRecord> cursor = cursors.relationship(); | ||
long loopCount = countByFirstPrevPointer( groupRecord.getFirstLoop(), cursor, nodeRecord, relationshipRecord ); | ||
switch ( direction ) | ||
{ | ||
case OUTGOING: | ||
{ | ||
long firstOut = groupRecord.getFirstOut(); | ||
return countByFirstPrevPointer( firstOut, cursor, nodeRecord, relationshipRecord ) + loopCount; | ||
} | ||
case INCOMING: | ||
{ | ||
long firstIn = groupRecord.getFirstIn(); | ||
return countByFirstPrevPointer( firstIn, cursor, nodeRecord, relationshipRecord ) + loopCount; | ||
} | ||
case BOTH: | ||
{ | ||
long firstOut = groupRecord.getFirstOut(); | ||
long firstIn = groupRecord.getFirstIn(); | ||
return countByFirstPrevPointer( firstOut, cursor, nodeRecord, relationshipRecord ) + | ||
countByFirstPrevPointer( firstIn, cursor, nodeRecord, relationshipRecord ) + loopCount; | ||
} | ||
default: | ||
throw new IllegalArgumentException( direction.name() ); | ||
} | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/DegreeItemCursor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* | ||
* Copyright (c) 2002-2017 "Neo Technology," | ||
* Network Engine for Objects in Lund AB [http://neotechnology.com] | ||
* | ||
* This file is part of Neo4j. | ||
* | ||
* Neo4j is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.neo4j.kernel.impl.api.store; | ||
|
||
import org.neo4j.collection.primitive.PrimitiveIntIterator; | ||
import org.neo4j.collection.primitive.PrimitiveIntObjectMap; | ||
import org.neo4j.cursor.Cursor; | ||
import org.neo4j.storageengine.api.DegreeItem; | ||
|
||
class DegreeItemCursor implements Cursor<DegreeItem>, DegreeItem | ||
{ | ||
private final PrimitiveIntObjectMap<int[]> degrees; | ||
private PrimitiveIntIterator keys; | ||
|
||
private int type; | ||
private int outgoing; | ||
private int incoming; | ||
|
||
DegreeItemCursor( PrimitiveIntObjectMap<int[]> degrees ) | ||
{ | ||
this.keys = degrees.iterator(); | ||
this.degrees = degrees; | ||
} | ||
|
||
@Override | ||
public void close() | ||
{ | ||
keys = null; | ||
} | ||
|
||
@Override | ||
public int type() | ||
{ | ||
return type; | ||
} | ||
|
||
@Override | ||
public long outgoing() | ||
{ | ||
return outgoing; | ||
} | ||
|
||
@Override | ||
public long incoming() | ||
{ | ||
return incoming; | ||
} | ||
|
||
@Override | ||
public DegreeItem get() | ||
{ | ||
if ( keys == null ) | ||
{ | ||
throw new IllegalStateException(); | ||
} | ||
|
||
return this; | ||
} | ||
|
||
@Override | ||
public boolean next() | ||
{ | ||
if ( keys != null && keys.hasNext() ) | ||
{ | ||
type = keys.next(); | ||
int[] degreeValues = degrees.get( type ); | ||
outgoing = degreeValues[0] + degreeValues[2]; | ||
incoming = degreeValues[1] + degreeValues[2]; | ||
|
||
return true; | ||
} | ||
keys = null; | ||
return false; | ||
} | ||
} |
113 changes: 113 additions & 0 deletions
113
community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/DegreeItemDenseCursor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/* | ||
* Copyright (c) 2002-2017 "Neo Technology," | ||
* Network Engine for Objects in Lund AB [http://neotechnology.com] | ||
* | ||
* This file is part of Neo4j. | ||
* | ||
* Neo4j is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.neo4j.kernel.impl.api.store; | ||
|
||
import org.neo4j.cursor.Cursor; | ||
import org.neo4j.kernel.impl.store.RecordCursor; | ||
import org.neo4j.kernel.impl.store.RecordCursors; | ||
import org.neo4j.kernel.impl.store.record.NodeRecord; | ||
import org.neo4j.kernel.impl.store.record.Record; | ||
import org.neo4j.kernel.impl.store.record.RelationshipGroupRecord; | ||
import org.neo4j.kernel.impl.store.record.RelationshipRecord; | ||
import org.neo4j.storageengine.api.DegreeItem; | ||
|
||
import static org.neo4j.kernel.impl.store.record.RecordLoad.FORCE; | ||
|
||
class DegreeItemDenseCursor implements Cursor<DegreeItem>, DegreeItem, DegreeCounter | ||
{ | ||
private final NodeRecord nodeRecord; | ||
private final RelationshipGroupRecord relationshipGroupRecord; | ||
private final RelationshipRecord relationshipRecord; | ||
private final RecordCursors recordCursors; | ||
|
||
private long groupId; | ||
private int type; | ||
private long outgoing; | ||
private long incoming; | ||
|
||
DegreeItemDenseCursor( long groupId, | ||
NodeRecord nodeRecord, | ||
RelationshipGroupRecord relationshipGroupRecord, | ||
RelationshipRecord relationshipRecord, | ||
RecordCursors recordCursors ) | ||
{ | ||
this.groupId = groupId; | ||
this.nodeRecord = nodeRecord; | ||
this.relationshipGroupRecord = relationshipGroupRecord; | ||
this.relationshipRecord = relationshipRecord; | ||
this.recordCursors = recordCursors; | ||
} | ||
|
||
@Override | ||
public boolean next() | ||
{ | ||
while ( groupId != Record.NO_NEXT_RELATIONSHIP.intValue() ) | ||
{ | ||
boolean groupRecordInUse = recordCursors.relationshipGroup().next( groupId, relationshipGroupRecord, FORCE ); | ||
groupId = relationshipGroupRecord.getNext(); | ||
if ( groupRecordInUse ) | ||
{ | ||
this.type = relationshipGroupRecord.getType(); | ||
|
||
long firstLoop = relationshipGroupRecord.getFirstLoop(); | ||
long firstOut = relationshipGroupRecord.getFirstOut(); | ||
long firstIn = relationshipGroupRecord.getFirstIn(); | ||
|
||
RecordCursor<RelationshipRecord> relationshipCursor = recordCursors.relationship(); | ||
long loop = countByFirstPrevPointer( firstLoop, relationshipCursor, nodeRecord, relationshipRecord ); | ||
this.outgoing = | ||
countByFirstPrevPointer( firstOut, relationshipCursor, nodeRecord, relationshipRecord ) + loop; | ||
this.incoming = | ||
countByFirstPrevPointer( firstIn, relationshipCursor, nodeRecord, relationshipRecord ) + loop; | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
@Override | ||
public void close() | ||
{ | ||
} | ||
|
||
@Override | ||
public DegreeItem get() | ||
{ | ||
return this; | ||
} | ||
|
||
@Override | ||
public int type() | ||
{ | ||
return type; | ||
} | ||
|
||
@Override | ||
public long outgoing() | ||
{ | ||
return outgoing; | ||
} | ||
|
||
@Override | ||
public long incoming() | ||
{ | ||
return incoming; | ||
} | ||
} |
Oops, something went wrong.