Skip to content

Commit

Permalink
Use Kernel API for token operations in compiled runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusmelke committed Feb 1, 2018
1 parent 686e7c7 commit 206d332
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ import org.neo4j.cypher.internal.runtime._
import org.neo4j.cypher.internal.v3_4.expressions.SemanticDirection
import org.neo4j.cypher.internal.v3_4.logical.plans.QualifiedName
import org.neo4j.graphdb.{Node, Path, PropertyContainer}
import org.neo4j.internal.kernel.api.{CursorFactory, IndexReference, Read, Write}
import org.neo4j.internal.kernel.api._
import org.neo4j.kernel.api.ReadOperations
import org.neo4j.kernel.api.dbms.DbmsOperations
import org.neo4j.kernel.impl.api.store.RelationshipIterator
import org.neo4j.kernel.impl.core.EmbeddedProxySPI
import org.neo4j.kernel.impl.factory.DatabaseInfo
import org.neo4j.values.AnyValue
import org.neo4j.values.storable.Value
import org.neo4j.values.virtual.{RelationshipValue, ListValue, NodeValue}
import org.neo4j.values.virtual.{ListValue, NodeValue, RelationshipValue}

import scala.collection.Iterator

Expand Down Expand Up @@ -298,5 +298,7 @@ class DelegatingQueryTransactionalContext(val inner: QueryTransactionalContext)

override def dataRead: Read = inner.dataRead

override def tokenRead: TokenRead = inner.tokenRead

override def dataWrite: Write = inner.dataWrite
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ final class TransactionBoundQueryContext(val transactionalContext: Transactional
private def reads() = transactionalContext.dataRead
private val nodeCursor = allocateAndTraceNodeCursor()
private val propertyCursor = allocateAndTracePropertyCursor()
private lazy val nodeValueIndexCursor = allocateAndTraceNodeValueIndexCursor()
private def tokenRead = transactionalContext.kernelTransaction.tokenRead()
private def tokenWrite = transactionalContext.kernelTransaction.tokenWrite()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import org.neo4j.cypher.internal.planner.v3_4.spi.KernelStatisticProvider
import org.neo4j.cypher.internal.runtime.QueryTransactionalContext
import org.neo4j.graphdb.{Lock, PropertyContainer}
import org.neo4j.internal.kernel.api.security.SecurityContext
import org.neo4j.internal.kernel.api.{CursorFactory, Read, Write}
import org.neo4j.internal.kernel.api.{CursorFactory, Read, TokenRead, Write}
import org.neo4j.kernel.GraphDatabaseQueryService
import org.neo4j.kernel.api.KernelTransaction.Revertable
import org.neo4j.kernel.api.dbms.DbmsOperations
Expand Down Expand Up @@ -57,6 +57,8 @@ case class TransactionalContextWrapper(tc: TransactionalContext) extends QueryTr

override def dataRead: Read = tc.kernelTransaction().dataRead()

override def tokenRead: TokenRead = tc.kernelTransaction().tokenRead()

override def dataWrite: Write = tc.kernelTransaction().dataWrite()

override def readOperations: ReadOperations = tc.readOperations()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ import org.neo4j.cypher.internal.planner.v3_4.spi.{IdempotentResult, IndexDescri
import org.neo4j.cypher.internal.v3_4.expressions.SemanticDirection
import org.neo4j.cypher.internal.v3_4.logical.plans.QualifiedName
import org.neo4j.graphdb.{Node, Path, PropertyContainer}
import org.neo4j.internal.kernel.api.{CursorFactory, IndexReference, Read, Write}
import org.neo4j.internal.kernel.api._
import org.neo4j.kernel.api.ReadOperations
import org.neo4j.kernel.api.dbms.DbmsOperations
import org.neo4j.kernel.impl.api.store.RelationshipIterator
import org.neo4j.kernel.impl.core.EmbeddedProxySPI
import org.neo4j.kernel.impl.factory.DatabaseInfo
import org.neo4j.values.AnyValue
import org.neo4j.values.storable.Value
import org.neo4j.values.virtual.{RelationshipValue, ListValue, NodeValue}
import org.neo4j.values.virtual.{ListValue, NodeValue, RelationshipValue}

import scala.collection.Iterator

Expand Down Expand Up @@ -244,6 +244,8 @@ trait QueryTransactionalContext extends CloseableResource {

def dataRead: Read

def tokenRead: TokenRead

def dataWrite: Write

def readOperations: ReadOperations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@ case class Fields(closer: FieldReference,
cursors: FieldReference,
nodeCursor: FieldReference,
propertyCursor: FieldReference,
dataRead: FieldReference)
dataRead: FieldReference,
tokenRead: FieldReference
)
Original file line number Diff line number Diff line change
Expand Up @@ -157,16 +157,16 @@ class GeneratedMethodStructure(val fields: Fields, val generator: CodeBlock, aux

override def lookupLabelId(labelIdVar: String, labelName: String) =
generator.assign(typeRef[Int], labelIdVar,
invoke(readOperations, labelGetForName, constant(labelName)))
invoke(tokenRead, labelGetForName, constant(labelName)))

override def lookupLabelIdE(labelName: String): Expression =
invoke(readOperations, labelGetForName, constant(labelName))
invoke(tokenRead, labelGetForName, constant(labelName))

override def lookupRelationshipTypeId(typeIdVar: String, typeName: String) =
generator.assign(typeRef[Int], typeIdVar, invoke(readOperations, relationshipTypeGetForName, constant(typeName)))
generator.assign(typeRef[Int], typeIdVar, invoke(tokenRead, relationshipTypeGetForName, constant(typeName)))

override def lookupRelationshipTypeIdE(typeName: String) =
invoke(readOperations, relationshipTypeGetForName, constant(typeName))
invoke(tokenRead, relationshipTypeGetForName, constant(typeName))

override def hasNextNode(iterVar: String) =
invoke(generator.load(iterVar), hasNextLong)
Expand Down Expand Up @@ -551,6 +551,9 @@ class GeneratedMethodStructure(val fields: Fields, val generator: CodeBlock, aux
private def dataRead: Expression =
invoke(generator.self(), methodReference(generator.owner(), typeRef[Read], "getOrLoadDataRead"))

private def tokenRead: Expression =
invoke(generator.self(), methodReference(generator.owner(), typeRef[TokenRead], "getOrLoadTokenRead"))

private def cursors: Expression =
invoke(generator.self(), methodReference(generator.owner(), typeRef[CursorFactory], "getOrLoadCursors"))

Expand Down Expand Up @@ -1364,7 +1367,7 @@ class GeneratedMethodStructure(val fields: Fields, val generator: CodeBlock, aux
val variable = locals(typeVar)
val typeOfRel = invoke(generator.load(relCursor(relVar)), method[RelationshipSelectionCursor, Int]("type"))
handleKernelExceptions(generator, fields, _finalizers) { inner =>
val res = invoke(readOperations, relationshipTypeGetName, typeOfRel)
val res = invoke(tokenRead, relationshipTypeGetName, typeOfRel)
inner.assign(variable, res)
generator.load(variable.name())
}
Expand Down Expand Up @@ -1469,7 +1472,7 @@ class GeneratedMethodStructure(val fields: Fields, val generator: CodeBlock, aux
}

override def lookupPropertyKey(propName: String, propIdVar: String) =
generator.assign(typeRef[Int], propIdVar, invoke(readOperations, propertyKeyGetForName, constant(propName)))
generator.assign(typeRef[Int], propIdVar, invoke(tokenRead, propertyKeyGetForName, constant(propName)))

override def newIndexDescriptor(descriptorVar: String, labelVar: String, propKeyVar: String) = {
val getIndexDescriptor = method[IndexDescriptorFactory, IndexDescriptor]("forLabel", typeRef[Int], typeRef[Array[Int]])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import org.neo4j.cypher.internal.util.v3_4.{TaskCloser, symbols}
import org.neo4j.cypher.internal.v3_4.codegen.QueryExecutionTracer
import org.neo4j.cypher.internal.v3_4.executionplan.{GeneratedQuery, GeneratedQueryExecution}
import org.neo4j.cypher.result.QueryResult.QueryResultVisitor
import org.neo4j.internal.kernel.api.{CursorFactory, NodeCursor, PropertyCursor, Read}
import org.neo4j.internal.kernel.api._
import org.neo4j.kernel.api.ReadOperations
import org.neo4j.kernel.impl.core.EmbeddedProxySPI
import org.neo4j.values.virtual.MapValue
Expand Down Expand Up @@ -180,6 +180,7 @@ object GeneratedQueryStructure extends CodeStructure[GeneratedQuery] {
clazz.generate(Templates.constructor(clazz.handle()))
Templates.getOrLoadReadOperations(clazz, fields)
Templates.getOrLoadDataRead(clazz, fields)
Templates.getOrLoadTokenRead(clazz, fields)
Templates.getOrLoadCursors(clazz, fields)
Templates.nodeCursor(clazz, fields)
Templates.propertyCursor(clazz, fields)
Expand Down Expand Up @@ -214,7 +215,9 @@ object GeneratedQueryStructure extends CodeStructure[GeneratedQuery] {
cursors = clazz.field(typeRef[CursorFactory], "cursors"),
nodeCursor = clazz.field(typeRef[NodeCursor], "nodeCursor"),
propertyCursor = clazz.field(typeRef[PropertyCursor], "propertyCursor"),
dataRead = clazz.field(typeRef[Read], "dataRead"))
dataRead = clazz.field(typeRef[Read], "dataRead"),
tokenRead = clazz.field(typeRef[TokenRead], "tokenRead")
)
}

def method[O <: AnyRef, R](name: String, params: TypeReference*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import org.neo4j.cypher.result.QueryResult.{QueryResultVisitor, Record}
import org.neo4j.graphdb.Direction
import org.neo4j.helpers.collection.MapUtil
import org.neo4j.internal.kernel.api.helpers.RelationshipSelectionCursor
import org.neo4j.internal.kernel.api.{CursorFactory, IndexQuery, NodeCursor, Read}
import org.neo4j.internal.kernel.api._
import org.neo4j.kernel.api.ReadOperations
import org.neo4j.kernel.api.schema.index.IndexDescriptor
import org.neo4j.kernel.impl.api.store.RelationshipIterator
Expand Down Expand Up @@ -90,20 +90,18 @@ object Methods {
val mapContains = method[util.Map[String, Object], Boolean]("containsKey", typeRef[Object])
val setContains = method[util.Set[Object], Boolean]("contains", typeRef[Object])
val setAdd = method[util.Set[Object], Boolean]("add", typeRef[Object])
val labelGetForName = method[ReadOperations, Int]("labelGetForName", typeRef[String])
val propertyKeyGetForName = method[ReadOperations, Int]("propertyKeyGetForName", typeRef[String])
val labelGetForName = method[TokenRead, Int]("nodeLabel", typeRef[String])
val propertyKeyGetForName = method[TokenRead, Int]("propertyKey", typeRef[String])
val coerceToPredicate = method[CompiledConversionUtils, Boolean]("coerceToPredicate", typeRef[Object])
val toCollection = method[CompiledConversionUtils, java.util.Collection[Object]]("toCollection", typeRef[Object])
val ternaryEquals = method[CompiledConversionUtils, java.lang.Boolean]("equals", typeRef[Object], typeRef[Object])
val equals = method[Object, Boolean]("equals", typeRef[Object])
val or = method[CompiledConversionUtils, java.lang.Boolean]("or", typeRef[Object], typeRef[Object])
val not = method[CompiledConversionUtils, java.lang.Boolean]("not", typeRef[Object])
val loadParameter = method[CompiledConversionUtils, Object]("loadParameter", typeRef[AnyValue], typeRef[EmbeddedProxySPI])
val relationshipTypeGetForName = method[ReadOperations, Int]("relationshipTypeGetForName", typeRef[String])
val relationshipTypeGetName = method[ReadOperations, String]("relationshipTypeGetName", typeRef[Int])
val relationshipTypeGetForName = method[TokenRead, Int]("relationshipType", typeRef[String])
val relationshipTypeGetName = method[TokenRead, String]("relationshipTypeName", typeRef[Int])
val nodeExists = method[ReadOperations, Boolean]("nodeExists", typeRef[Long])
val nodesGetAll = method[ReadOperations, PrimitiveLongIterator]("nodesGetAll")
val nodeGetProperty = method[ReadOperations, Value]("nodeGetProperty", typeRef[Long], typeRef[Int])
val indexQuery = method[ReadOperations, PrimitiveLongResourceIterator]("indexQuery", typeRef[IndexDescriptor], typeRef[Array[IndexQuery]])
val indexQueryExact = method[IndexQuery, IndexQuery.ExactPredicate]("exact", typeRef[Int], typeRef[Object])
val nodeGetUniqueFromIndexLookup = method[ReadOperations, Long]("nodeGetFromUniqueIndexSeek", typeRef[IndexDescriptor], typeRef[Array[IndexQuery.ExactPredicate]])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ object Templates {
generate.returns(cursors)
}
}

def getOrLoadDataRead(clazz: ClassGenerator, fields: Fields) = {
val methodBuilder: Builder = MethodDeclaration.method(typeRef[Read], "getOrLoadDataRead")
using(clazz.generate(methodBuilder)) { generate =>
Expand All @@ -246,6 +247,21 @@ object Templates {
}
}

def getOrLoadTokenRead(clazz: ClassGenerator, fields: Fields) = {
val methodBuilder: Builder = MethodDeclaration.method(typeRef[TokenRead], "getOrLoadTokenRead")
using(clazz.generate(methodBuilder)) { generate =>
val tokenRead = Expression.get(generate.self(), fields.tokenRead)
using(generate.ifStatement(Expression.isNull(tokenRead))) { block =>
val transactionalContext: MethodReference = method[QueryContext, QueryTransactionalContext]("transactionalContext")
val tokenRead: MethodReference = method[QueryTransactionalContext, TokenRead]("tokenRead")
val queryContext = Expression.get(block.self(), fields.queryContext)
block.put(block.self(), fields.tokenRead,
Expression.invoke(Expression.invoke(queryContext, transactionalContext), tokenRead))
}
generate.returns(tokenRead)
}
}

def setCompletable(classHandle: ClassHandle) = MethodTemplate.method(typeRef[Unit], "setCompletable",
param[Completable]("closeable")).
put(self(classHandle), typeRef[Completable], "closeable", load("closeable", typeRef[Completable])).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import org.neo4j.cypher.internal.v3_4.codegen.QueryExecutionTracer
import org.neo4j.cypher.internal.v3_4.expressions.SemanticDirection
import org.neo4j.internal.kernel.api.helpers.RelationshipSelectionCursor
import org.neo4j.internal.kernel.api.{CursorFactory, NodeCursor, PropertyCursor, Read}
import org.neo4j.internal.kernel.api._
import org.neo4j.kernel.api.ReadOperations
import org.neo4j.kernel.impl.core.EmbeddedProxySPI

Expand Down Expand Up @@ -244,7 +245,8 @@ class GeneratedMethodStructureTest extends CypherFunSuite {
cursors = body.field(typeRef[CursorFactory], "cursors"),
nodeCursor = body.field(typeRef[NodeCursor], "nodeCursor"),
propertyCursor = body.field(typeRef[PropertyCursor], "propertyCursor"),
dataRead = body.field(typeRef[Read], "dataRead")
dataRead = body.field(typeRef[Read], "dataRead"),
tokenRead = body.field(typeRef[TokenRead], "tokenRead")
)
// the "COLUMNS" static field
body.staticField(typeRef[util.List[String]], "COLUMNS", Templates.asList[String](Seq.empty))
Expand All @@ -254,6 +256,7 @@ class GeneratedMethodStructureTest extends CypherFunSuite {
Templates.getOrLoadDataRead(body, fields)
Templates.getOrLoadReadOperations(body, fields)
Templates.getOrLoadCursors(body, fields)
Templates.getOrLoadTokenRead(body, fields)
Templates.nodeCursor(body, fields)
Templates.propertyCursor(body, fields)
body.handle()
Expand Down

0 comments on commit 206d332

Please sign in to comment.