Skip to content

Commit

Permalink
Use new API for property reads
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusmelke committed Dec 4, 2017
1 parent 5f0cd67 commit feabca4
Showing 1 changed file with 147 additions and 79 deletions.
226 changes: 147 additions & 79 deletions community/kernel/src/main/java/org/neo4j/kernel/impl/core/NodeProxy.java
Expand Up @@ -28,7 +28,6 @@
import java.util.Objects;

import org.neo4j.collection.primitive.PrimitiveIntIterator;
import org.neo4j.cursor.Cursor;
import org.neo4j.graphdb.ConstraintViolationException;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
Expand All @@ -39,24 +38,25 @@
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.ResourceIterable;
import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.internal.kernel.api.CursorFactory;
import org.neo4j.internal.kernel.api.NodeCursor;
import org.neo4j.internal.kernel.api.PropertyCursor;
import org.neo4j.internal.kernel.api.Token;
import org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException;
import org.neo4j.internal.kernel.api.exceptions.InvalidTransactionTypeKernelException;
import org.neo4j.internal.kernel.api.exceptions.PropertyKeyIdNotFoundKernelException;
import org.neo4j.internal.kernel.api.exceptions.explicitindex.AutoIndexingKernelException;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.ReadOperations;
import org.neo4j.kernel.api.Statement;
import org.neo4j.kernel.api.StatementTokenNameLookup;
import org.neo4j.kernel.api.exceptions.LabelNotFoundKernelException;
import org.neo4j.kernel.api.exceptions.PropertyKeyIdNotFoundKernelException;
import org.neo4j.kernel.api.exceptions.PropertyNotFoundException;
import org.neo4j.kernel.api.exceptions.RelationshipTypeIdNotFoundKernelException;
import org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException;
import org.neo4j.kernel.api.exceptions.schema.IllegalTokenNameException;
import org.neo4j.kernel.api.exceptions.schema.TooManyLabelsException;
import org.neo4j.kernel.impl.api.operations.KeyReadOperations;
import org.neo4j.storageengine.api.EntityType;
import org.neo4j.storageengine.api.NodeItem;
import org.neo4j.storageengine.api.PropertyItem;
import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.Values;

Expand Down Expand Up @@ -345,40 +345,62 @@ public Object getProperty( String key, Object defaultValue )
{
throw new IllegalArgumentException( "(null) property key is not allowed" );
}

try ( Statement statement = actions.statement() )
{
int propertyKeyId = statement.readOperations().propertyKeyGetForName( key );
Value value = statement.readOperations().nodeGetProperty( nodeId, propertyKeyId );
return value == Values.NO_VALUE ? defaultValue : value.asObjectCopy();
}
catch ( EntityNotFoundException e )
KernelTransaction transaction = actions.kernelTransaction();
CursorFactory cursors = transaction.cursors();
try ( NodeCursor nodes = cursors.allocateNodeCursor();
PropertyCursor properties = cursors.allocatePropertyCursor()
)
{
throw new NotFoundException( e );
int propertyKey = transaction.token().propertyKey( key );
if ( propertyKey == KeyReadOperations.NO_SUCH_PROPERTY_KEY )
{
throw new NotFoundException( format( "No such property, '%s'.", key ) );
}
transaction.dataRead().singleNode( nodeId, nodes );
if ( !nodes.next() )
{
throw new NotFoundException( new EntityNotFoundException( EntityType.NODE, nodeId ) );
}
nodes.properties( properties );
while ( properties.next() )
{
if ( propertyKey == properties.propertyKey() )
{
Value value = properties.propertyValue();
return value == Values.NO_VALUE ? defaultValue : value.asObjectCopy();
}
}
return defaultValue;
}
}

@Override
public Iterable<String> getPropertyKeys()
{
try ( Statement statement = actions.statement() )
KernelTransaction transaction = actions.kernelTransaction();
CursorFactory cursors = transaction.cursors();
List<String> keys = new ArrayList<>();
try ( NodeCursor nodes = cursors.allocateNodeCursor();
PropertyCursor properties = cursors.allocatePropertyCursor()
)
{
List<String> keys = new ArrayList<>();
PrimitiveIntIterator properties = statement.readOperations().nodeGetPropertyKeys( getId() );
while ( properties.hasNext() )
transaction.dataRead().singleNode( nodeId, nodes );
Token token = transaction.token();
if ( !nodes.next() )
{
keys.add( statement.readOperations().propertyKeyGetName( properties.next() ) );
throw new NotFoundException( new EntityNotFoundException( EntityType.NODE, nodeId ) );
}
nodes.properties( properties );
while ( properties.next() )
{
keys.add( token.propertyKeyGetName( properties.propertyKey() ));
}
return keys;
}
catch ( EntityNotFoundException e )
{
throw new NotFoundException( "Node not found", e );
}
catch ( PropertyKeyIdNotFoundKernelException e )
{
throw new IllegalStateException( "Property key retrieved through kernel API should exist.", e );
}
return keys;
}

@Override
Expand All @@ -391,53 +413,79 @@ public Map<String,Object> getProperties( String... keys )
return Collections.emptyMap();
}

try ( Statement statement = actions.statement() )
KernelTransaction transaction = actions.kernelTransaction();
CursorFactory cursors = transaction.cursors();
int itemsToReturn = keys.length;
Map<String,Object> properties = new HashMap<>( itemsToReturn );
Token token = transaction.token();

//Find ids, note we are betting on that the number of keys
//is small enough not to use a set here.
int[] propertyIds = new int[itemsToReturn];
for ( int i = 0; i < itemsToReturn; i++ )
{
propertyIds[i] = token.propertyKey( keys[i] );
}
try ( NodeCursor nodes = cursors.allocateNodeCursor();
PropertyCursor propertyCursor = cursors.allocatePropertyCursor() )
{
try ( Cursor<NodeItem> node = statement.readOperations().nodeCursorById( nodeId ) )
transaction.dataRead().singleNode( nodeId, nodes );
if ( !nodes.next() )
{
try ( Cursor<PropertyItem> propertyCursor = statement.readOperations().nodeGetProperties( node.get() ) )
{
return PropertyContainerProxyHelper.getProperties( statement, propertyCursor, keys );
}
throw new NotFoundException( new EntityNotFoundException( EntityType.NODE, nodeId ) );
}
catch ( EntityNotFoundException e )
nodes.properties( propertyCursor );
while ( propertyCursor.next() )
{
throw new NotFoundException( "Node not found", e );
//Do a linear check if this is a property we are interested in.
for ( int propertyId : propertyIds )
{
int currentKey = propertyCursor.propertyKey();
if ( propertyId == currentKey )
{
properties.put( token.propertyKeyGetName( currentKey ),
propertyCursor.propertyValue().asObjectCopy() );
}
}

}
}
catch ( PropertyKeyIdNotFoundKernelException e )
{
throw new IllegalStateException( "Property key retrieved through kernel API should exist.", e );
}

return properties;
}

@Override
public Map<String,Object> getAllProperties()
{
try ( Statement statement = actions.statement() )
KernelTransaction transaction = actions.kernelTransaction();
CursorFactory cursors = transaction.cursors();
Map<String,Object> properties = new HashMap<>();

try ( NodeCursor nodes = cursors.allocateNodeCursor();
PropertyCursor propertyCursor = cursors.allocatePropertyCursor() )
{
try ( Cursor<NodeItem> node = statement.readOperations().nodeCursorById( nodeId ) )
Token token = transaction.token();
transaction.dataRead().singleNode( nodeId, nodes );
if ( !nodes.next() )
{
try ( Cursor<PropertyItem> propertyCursor = statement.readOperations().nodeGetProperties( node.get() ) )
{
Map<String,Object> properties = new HashMap<>();

// Get all properties
while ( propertyCursor.next() )
{
String name = statement.readOperations().propertyKeyGetName(
propertyCursor.get().propertyKeyId() );
properties.put( name, propertyCursor.get().value().asObjectCopy() );
}

return properties;
}
throw new NotFoundException( new EntityNotFoundException( EntityType.NODE, nodeId ) );
}
catch ( EntityNotFoundException e )
nodes.properties( propertyCursor );
while ( propertyCursor.next() )
{
throw new NotFoundException( "Node not found", e );
properties.put( token.propertyKeyGetName( propertyCursor.propertyKey() ),
propertyCursor.propertyValue().asObjectCopy() );
}
}
catch ( PropertyKeyIdNotFoundKernelException e )
{
throw new IllegalStateException( "Property key retrieved through kernel API should exist.", e );
}
return properties;
}

@Override
Expand All @@ -447,32 +495,36 @@ public Object getProperty( String key ) throws NotFoundException
{
throw new IllegalArgumentException( "(null) property key is not allowed" );
}

try ( Statement statement = actions.statement() )
KernelTransaction transaction = actions.kernelTransaction();
CursorFactory cursors = transaction.cursors();
try ( NodeCursor nodes = cursors.allocateNodeCursor();
PropertyCursor properties = cursors.allocatePropertyCursor()
)
{
try
int propertyKey = transaction.token().propertyKey( key );
if ( propertyKey == KeyReadOperations.NO_SUCH_PROPERTY_KEY )
{
int propertyKeyId = statement.readOperations().propertyKeyGetForName( key );
if ( propertyKeyId == KeyReadOperations.NO_SUCH_PROPERTY_KEY )
{
throw new NotFoundException( format( "No such property, '%s'.", key ) );
}

Value value = statement.readOperations().nodeGetProperty( nodeId, propertyKeyId );

if ( value == Values.NO_VALUE )
{
throw new PropertyNotFoundException( propertyKeyId, EntityType.NODE, nodeId );
}

return value.asObjectCopy();

throw new NotFoundException( format( "No such property, '%s'.", key ) );
}
catch ( EntityNotFoundException | PropertyNotFoundException e )
transaction.dataRead().singleNode( nodeId, nodes );
if ( !nodes.next() )
{
throw new NotFoundException(
e.getUserMessage( new StatementTokenNameLookup( statement.readOperations() ) ), e );
throw new NotFoundException( new EntityNotFoundException( EntityType.NODE, nodeId ) );
}
nodes.properties( properties );
while ( properties.next() )
{
if ( propertyKey == properties.propertyKey() )
{
Value value = properties.propertyValue();
if ( value == Values.NO_VALUE )
{
throw new NotFoundException( format( "No such property, '%s'.", key ) );
}
return value.asObjectCopy();
}
}
throw new NotFoundException( format( "No such property, '%s'.", key ) );
}
}

Expand All @@ -483,15 +535,31 @@ public boolean hasProperty( String key )
{
return false;
}

try ( Statement statement = actions.statement() )
{
int propertyKeyId = statement.readOperations().propertyKeyGetForName( key );
return statement.readOperations().nodeHasProperty( nodeId, propertyKeyId );
}
catch ( EntityNotFoundException e )
KernelTransaction transaction = actions.kernelTransaction();
CursorFactory cursors = transaction.cursors();
try ( NodeCursor nodes = cursors.allocateNodeCursor();
PropertyCursor properties = cursors.allocatePropertyCursor()
)
{
throw new NotFoundException( e );
int propertyKey = transaction.token().propertyKey( key );
if ( propertyKey == KeyReadOperations.NO_SUCH_PROPERTY_KEY )
{
throw new NotFoundException( format( "No such property, '%s'.", key ) );
}
transaction.dataRead().singleNode( nodeId, nodes );
if ( !nodes.next() )
{
throw new NotFoundException( new EntityNotFoundException( EntityType.NODE, nodeId ) );
}
nodes.properties( properties );
while ( properties.next() )
{
if ( propertyKey == properties.propertyKey() )
{
return true;
}
}
return false;
}
}

Expand Down

0 comments on commit feabca4

Please sign in to comment.