Skip to content

Commit

Permalink
Refactor references: turn relationship reference encoding into enum
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed Jan 24, 2018
1 parent f35307e commit a3cdf7f
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 235 deletions.
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2002-2018 "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.newapi;

import static org.neo4j.kernel.impl.store.record.AbstractBaseRecord.NO_ID;

class GroupReferenceEncoding
{
private static final long DIRECT = 0x1000_0000_0000_0000L;

/**
* Encode a relationship id as a group reference.
*/
static long encodeRelationship( long relationshipId )
{
return relationshipId | DIRECT | References.FLAG_MARKER;
}

/**
* Check whether a group reference is an encoded relationship id.
*/
static boolean isRelationship( long groupReference )
{
assert groupReference != NO_ID;
return (groupReference & References.FLAG_MASK) == DIRECT;
}
}
Expand Up @@ -151,13 +151,13 @@ public void properties( PropertyCursor cursor )
@Override
public long relationshipGroupReference()
{
return isDense() ? getNextRel() : References.Group.encodeRelationship( getNextRel() );
return isDense() ? getNextRel() : GroupReferenceEncoding.encodeRelationship( getNextRel() );
}

@Override
public long allRelationshipsReference()
{
return isDense() ? References.Relationship.encodeFromGroup( getNextRel() ) : getNextRel();
return isDense() ? RelationshipReferenceEncoding.encodeGroup( getNextRel() ) : getNextRel();
}

@Override
Expand Down
Expand Up @@ -49,13 +49,7 @@
import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.ValueGroup;

import static org.neo4j.kernel.impl.newapi.References.Group.isRelationship;
import static org.neo4j.kernel.impl.newapi.References.Relationship.isFilter;
import static org.neo4j.kernel.impl.newapi.References.Relationship.isGroup;
import static org.neo4j.kernel.impl.newapi.References.Relationship.isNoIncoming;
import static org.neo4j.kernel.impl.newapi.References.Relationship.isNoLoop;
import static org.neo4j.kernel.impl.newapi.References.Relationship.isNoOutgoing;
import static org.neo4j.kernel.impl.newapi.References.Relationship.isTxStateFilter;
import static org.neo4j.kernel.impl.newapi.GroupReferenceEncoding.isRelationship;
import static org.neo4j.kernel.impl.newapi.References.clearEncoding;
import static org.neo4j.kernel.impl.newapi.RelationshipDirection.INCOMING;
import static org.neo4j.kernel.impl.newapi.RelationshipDirection.LOOP;
Expand Down Expand Up @@ -287,41 +281,45 @@ public final void relationships(
* This means that we need reference encodings (flags) for cases: 1, 3, 4, 5
*/
ktx.assertOpen();
if ( reference == NO_ID ) // there are no relationships for this node

int relationshipType;
RelationshipReferenceEncoding encoding = RelationshipReferenceEncoding.parseEncoding( reference );

switch ( encoding )
{
// still initiate cursor in case there are tx-state additions
case NONE: // this is a normal relationship reference
((RelationshipTraversalCursor) cursor).chain( nodeReference, reference, this );
}
else if ( isGroup( reference ) ) // this reference is actually to a group record
{
((RelationshipTraversalCursor) cursor).groups( nodeReference, clearEncoding( reference ), this );
}
else if ( isFilter( reference ) ) // this relationship chain needs to be filtered
{
break;

case FILTER: // this relationship chain needs to be filtered
((RelationshipTraversalCursor) cursor).filtered( nodeReference, clearEncoding( reference ), this, true );
}
else if ( isTxStateFilter( reference ) ) // tx-state changes should be filtered by the head of this chain
{
break;

case FILTER_TX_STATE: // tx-state changes should be filtered by the head of this chain
((RelationshipTraversalCursor) cursor).filtered( nodeReference, clearEncoding( reference ), this, false );
}
else if ( isNoOutgoing( reference ) ) // nothing in store, but proceed to check tx-state changes
{
int relationshipType = (int) clearEncoding( reference );
break;

case GROUP: // this reference is actually to a group record
((RelationshipTraversalCursor) cursor).groups( nodeReference, clearEncoding( reference ), this );
break;

case NO_OUTGOING_OF_TYPE: // nothing in store, but proceed to check tx-state changes
relationshipType = (int) clearEncoding( reference );
((RelationshipTraversalCursor) cursor).filteredTxState( nodeReference, this, relationshipType, OUTGOING );
}
else if ( isNoIncoming( reference ) ) // nothing in store, but proceed to check tx-state changes
{
int relationshipType = (int) clearEncoding( reference );
break;

case NO_INCOMING_OF_TYPE: // nothing in store, but proceed to check tx-state changes
relationshipType = (int) clearEncoding( reference );
((RelationshipTraversalCursor) cursor).filteredTxState( nodeReference, this, relationshipType, INCOMING );
}
else if ( isNoLoop( reference ) ) // nothing in store, but proceed to check tx-state changes
{
int relationshipType = (int) clearEncoding( reference );
break;

case NO_LOOP_OF_TYPE: // nothing in store, but proceed to check tx-state changes
relationshipType = (int) clearEncoding( reference );
((RelationshipTraversalCursor) cursor).filteredTxState( nodeReference, this, relationshipType, LOOP );
}
else // this is a normal relationship reference
{
((RelationshipTraversalCursor) cursor).chain( nodeReference, reference, this );
break;

default:
throw new IllegalStateException( "Unknown encoding " + encoding );
}
}

Expand Down
Expand Up @@ -47,9 +47,9 @@
*/
class References
{
private static final long FLAG_MARKER = 0x8000_0000_0000_0000L;
private static final long FLAG_MASK = 0x7000_0000_0000_0000L;
private static final long FLAGS = 0xF000_0000_0000_0000L;
static final long FLAG_MARKER = 0x8000_0000_0000_0000L;
static final long FLAG_MASK = 0x7000_0000_0000_0000L;
static final long FLAGS = 0xF000_0000_0000_0000L;

/**
* Clear all encoding from a reference.
Expand All @@ -62,149 +62,4 @@ static long clearEncoding( long reference )
assert reference != NO_ID;
return reference & ~FLAGS;
}

static class Relationship
{
/** @see #encodeForFiltering(long) */
private static final long FILTER = 0x1000_0000_0000_0000L;

/** @see #encodeForTxStateFiltering(long) */
private static final long FILTER_TX_STATE = 0x2000_0000_0000_0000L;

/** @see #encodeFromGroup(long) */
private static final long GROUP = 0x3000_0000_0000_0000L;

/** @see #encodeNoOutgoingRels(int) */
private static final long NO_OUTGOING_OF_TYPE = 0x4000_0000_0000_0000L;

/** @see #encodeNoIncomingRels(int) */
private static final long NO_INCOMING_OF_TYPE = 0x5000_0000_0000_0000L;

/** @see #encodeNoLoopRels(int) */
private static final long NO_LOOP_OF_TYPE = 0x6000_0000_0000_0000L;

/**
* Encode a group id as a relationship reference.
*/
static long encodeFromGroup( long groupId )
{
return groupId | GROUP | FLAG_MARKER;
}

/**
* Check whether a relationship reference is an encoded group id.
*/
static boolean isGroup( long relationshipReference )
{
assert relationshipReference != NO_ID;
return (relationshipReference & FLAG_MASK) == GROUP;
}

/**
* Encode that the relationship id needs filtering by it's first element.
*/
static long encodeForFiltering( long relationshipId )
{
return relationshipId | FILTER | FLAG_MARKER;
}

/**
* Check whether a relationship reference is a relationship id marked for filtering.
*/
static boolean isFilter( long relationshipReference )
{
assert relationshipReference != NO_ID;
return (relationshipReference & FLAG_MASK) == FILTER;
}

/**
* Encode that the relationship id needs filtering by it's first element.
*/
static long encodeForTxStateFiltering( long relationshipId )
{
return relationshipId | FILTER_TX_STATE | FLAG_MARKER;
}

/**
* Check whether a relationship reference is a relationship id marked for tx-state filtering.
*/
static boolean isTxStateFilter( long relationshipReference )
{
assert relationshipReference != NO_ID;
return (relationshipReference & FLAG_MASK) == FILTER_TX_STATE;
}

/**
* Encode that no outgoing relationships of the encoded type exist.
*/
static long encodeNoOutgoingRels( int type )
{
return type | NO_OUTGOING_OF_TYPE | FLAG_MARKER;
}

/**
* Check whether this reference encode that no outgoing relationships of the encoded type exist.
*/
static boolean isNoOutgoing( long relationshipReference )
{
assert relationshipReference != NO_ID;
return (relationshipReference & FLAG_MASK) == NO_OUTGOING_OF_TYPE;
}

/**
* Encode that no incoming relationships of the encoded type exist.
*/
static long encodeNoIncomingRels( int type )
{
return type | NO_INCOMING_OF_TYPE | FLAG_MARKER;
}

/**
* Check whether this reference encode that no incoming relationships of the encoded type exist.
*/
static boolean isNoIncoming( long relationshipReference )
{
assert relationshipReference != NO_ID;
return (relationshipReference & FLAG_MASK) == NO_INCOMING_OF_TYPE;
}

/**
* Encode that no loop relationships of the encoded type exist.
*/
static long encodeNoLoopRels( int type )
{
return type | NO_LOOP_OF_TYPE | FLAG_MARKER;
}

/**
* Check whether this reference encode that no loop relationships of the encoded type exist.
*/
static boolean isNoLoop( long relationshipReference )
{
assert relationshipReference != NO_ID;
return (relationshipReference & FLAG_MASK) == NO_LOOP_OF_TYPE;
}
}

static class Group
{
private static final long DIRECT = 0x1000_0000_0000_0000L;

/**
* Encode a relationship id as a group reference.
*/
static long encodeRelationship( long relationshipId )
{
return relationshipId | DIRECT | FLAG_MARKER;
}

/**
* Check whether a group reference is an encoded relationship id.
*/
static boolean isRelationship( long groupReference )
{
assert groupReference != NO_ID;
return (groupReference & FLAG_MASK) == DIRECT;
}
}
}
Expand Up @@ -26,9 +26,11 @@
import org.neo4j.kernel.impl.store.record.RelationshipGroupRecord;
import org.neo4j.kernel.impl.store.record.RelationshipRecord;

import static org.neo4j.kernel.impl.newapi.References.Relationship.encodeNoIncomingRels;
import static org.neo4j.kernel.impl.newapi.References.Relationship.encodeNoLoopRels;
import static org.neo4j.kernel.impl.newapi.References.Relationship.encodeNoOutgoingRels;
import static org.neo4j.kernel.impl.newapi.RelationshipReferenceEncoding.encodeForFiltering;
import static org.neo4j.kernel.impl.newapi.RelationshipReferenceEncoding.encodeForTxStateFiltering;
import static org.neo4j.kernel.impl.newapi.RelationshipReferenceEncoding.encodeNoIncomingRels;
import static org.neo4j.kernel.impl.newapi.RelationshipReferenceEncoding.encodeNoLoopRels;
import static org.neo4j.kernel.impl.newapi.RelationshipReferenceEncoding.encodeNoOutgoingRels;

class RelationshipGroupCursor extends RelationshipGroupRecord implements org.neo4j.internal.kernel.api.RelationshipGroupCursor
{
Expand Down Expand Up @@ -345,14 +347,7 @@ private boolean isBuffered()
private long encodeRelationshipReference( long relationshipId )
{
assert relationshipId != NO_ID;
if ( isBuffered() )
{
return References.Relationship.encodeForFiltering( relationshipId );
}
else
{
return References.Relationship.encodeForTxStateFiltering( relationshipId );
}
return isBuffered() ? encodeForFiltering( relationshipId ) : encodeForTxStateFiltering( relationshipId );
}

static class BufferedGroup
Expand Down

0 comments on commit a3cdf7f

Please sign in to comment.