From 1602ae4ae95e433cb6588b738c8bbe3b1f19f121 Mon Sep 17 00:00:00 2001 From: Pontus Melke Date: Thu, 22 Mar 2018 14:25:17 +0100 Subject: [PATCH] Port tests to use Kernel API --- .../full/FullCheckIntegrationTest.java | 57 +-- .../neo4j/internal/kernel/api/SchemaRead.java | 16 + .../neo4j/internal/kernel/api/TokenRead.java | 30 ++ .../builtinprocs/BuiltInProcedures.java | 47 ++- .../kernel/builtinprocs/IndexProcedures.java | 39 +- .../store/DefaultCapableIndexReference.java | 2 +- .../impl/coreapi/PlaceboTransaction.java | 12 +- .../impl/coreapi/PropertyContainerLocker.java | 97 ++--- .../impl/coreapi/TopLevelTransaction.java | 10 +- .../impl/factory/GraphDatabaseFacade.java | 2 +- .../kernel/impl/newapi/AllStoreHolder.java | 31 ++ .../neo4j/kernel/impl/newapi/KernelToken.java | 21 ++ .../neo4j/graphdb/IndexingAcceptanceTest.java | 189 ++++++++++ .../neo4j/graphdb/LabelsAcceptanceTest.java | 31 +- .../NativeLabelScanStoreStartupIT.java | 10 +- .../neo4j/kernel/TestPlaceboTransaction.java | 19 +- .../neo4j/kernel/api/CompositeIndexingIT.java | 199 ++++++----- .../api/TransactionStatementSequenceTest.java | 36 +- .../api/TransactionStatementSharingTest.java | 152 -------- .../builtinprocs/BuiltInProceduresTest.java | 51 ++- .../kernel/counts/RelationshipCountsTest.java | 22 +- .../api/KernelSchemaStateFlushingTest.java | 36 +- .../KernelTransactionSecurityContextTest.java | 18 +- .../kernel/impl/api/index/IndexCRUDIT.java | 28 +- .../api/index/IndexPopulationJobTest.java | 4 +- .../impl/api/index/IndexRecoveryIT.java | 22 +- .../impl/api/index/IndexStatisticsIT.java | 20 +- .../impl/api/index/IndexStatisticsTest.java | 89 ++--- .../impl/api/index/SchemaIndexTestHelper.java | 8 +- .../impl/api/integrationtest/KernelIT.java | 332 ++++++++---------- .../integrationtest/ProceduresKernelIT.java | 12 +- .../impl/api/store/StorageLayerTest.java | 21 +- .../kernel/impl/core/ManyPropertyKeysIT.java | 9 +- .../neo4j/kernel/impl/newapi/MockStore.java | 22 ++ .../test/java/counts/RebuildCountsTest.java | 7 +- ...Start3_2DbOn3_3AndCreateFusionIndexIT.java | 54 +-- .../index/IndexSamplingIntegrationTest.java | 27 +- .../neo4j/locking/QueryExecutionLocksIT.java | 7 +- .../schema/IndexPopulationFlipRaceIT.java | 24 +- ...ltiIndexPopulationConcurrentUpdatesIT.java | 17 +- .../test/java/org/neo4j/kernel/LabelIT.java | 6 +- .../java/org/neo4j/kernel/ha/HaCountsIT.java | 20 +- .../neo4j/storeupgrade/StoreUpgradeIT.java | 27 +- 43 files changed, 1003 insertions(+), 880 deletions(-) delete mode 100644 community/kernel/src/test/java/org/neo4j/kernel/api/TransactionStatementSharingTest.java diff --git a/community/consistency-check/src/test/java/org/neo4j/consistency/checking/full/FullCheckIntegrationTest.java b/community/consistency-check/src/test/java/org/neo4j/consistency/checking/full/FullCheckIntegrationTest.java index f4d73123c30e2..5f3753886e2ab 100644 --- a/community/consistency-check/src/test/java/org/neo4j/consistency/checking/full/FullCheckIntegrationTest.java +++ b/community/consistency-check/src/test/java/org/neo4j/consistency/checking/full/FullCheckIntegrationTest.java @@ -59,17 +59,19 @@ import org.neo4j.helpers.collection.Iterators; import org.neo4j.helpers.collection.Pair; import org.neo4j.helpers.progress.ProgressMonitorFactory; +import org.neo4j.internal.kernel.api.TokenRead; +import org.neo4j.internal.kernel.api.TokenWrite; +import org.neo4j.internal.kernel.api.exceptions.KernelException; import org.neo4j.io.pagecache.IOLimiter; -import org.neo4j.kernel.api.ReadOperations; -import org.neo4j.kernel.api.TokenWriteOperations; +import org.neo4j.kernel.api.KernelTransaction; +import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.direct.DirectStoreAccess; -import org.neo4j.internal.kernel.api.exceptions.KernelException; import org.neo4j.kernel.api.exceptions.TransactionFailureException; import org.neo4j.kernel.api.index.IndexAccessor; import org.neo4j.kernel.api.index.IndexEntryUpdate; import org.neo4j.kernel.api.index.IndexPopulator; -import org.neo4j.kernel.api.index.IndexUpdater; import org.neo4j.kernel.api.index.IndexProvider; +import org.neo4j.kernel.api.index.IndexUpdater; import org.neo4j.kernel.api.labelscan.LabelScanStore; import org.neo4j.kernel.api.labelscan.LabelScanWriter; import org.neo4j.kernel.api.labelscan.NodeLabelUpdate; @@ -78,7 +80,6 @@ import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.annotations.Documented; -import org.neo4j.kernel.impl.api.KernelStatement; import org.neo4j.kernel.impl.api.index.IndexUpdateMode; import org.neo4j.kernel.impl.api.index.NodeUpdates; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; @@ -220,16 +221,15 @@ protected void generateInitialData( GraphDatabaseService db ) try ( org.neo4j.graphdb.Transaction tx = db.beginTx() ) { db.schema().indexFor( label( "label3" ) ).on( PROP1 ).create(); - - try ( KernelStatement statement = statementOn( db ) ) + KernelTransaction ktx = transactionOn( db ); + try ( Statement ignore = ktx.acquireStatement() ) { // the Core API for composite index creation is not quite merged yet - TokenWriteOperations tokenWriteOperations = statement.tokenWriteOperations(); - key1 = tokenWriteOperations.propertyKeyGetOrCreateForName( PROP1 ); - key2 = tokenWriteOperations.propertyKeyGetOrCreateForName( PROP2 ); - label3 = statement.readOperations().labelGetForName( "label3" ); - statement.schemaWriteOperations() - .indexCreate( SchemaDescriptorFactory.forLabel( label3, key1, key2 ) ); + TokenWrite tokenWrite = ktx.tokenWrite(); + key1 = tokenWrite.propertyKeyGetOrCreateForName( PROP1 ); + key2 = tokenWrite.propertyKeyGetOrCreateForName( PROP2 ); + label3 = ktx.tokenRead().nodeLabel( "label3" ); + ktx.schemaWrite().indexCreate( SchemaDescriptorFactory.forLabel( label3, key1, key2 ) ); } db.schema().constraintFor( label( "label4" ) ).assertPropertyIsUnique( PROP1 ).create(); @@ -259,20 +259,21 @@ protected void generateInitialData( GraphDatabaseService db ) set( db.createNode( label( "label4" ) ), property( PROP1, VALUE1 ) ); tx.success(); - try ( KernelStatement statement = statementOn( db ) ) + KernelTransaction ktx = transactionOn( db ); + try ( Statement ignore = ktx.acquireStatement() ) { - ReadOperations readOperations = statement.readOperations(); - TokenWriteOperations tokenWriteOperations = statement.tokenWriteOperations(); - label1 = readOperations.labelGetForName( "label1" ); - label2 = readOperations.labelGetForName( "label2" ); - label3 = readOperations.labelGetForName( "label3" ); - label4 = readOperations.labelGetForName( "label4" ); - draconian = tokenWriteOperations.labelGetOrCreateForName( "draconian" ); - key1 = readOperations.propertyKeyGetForName( PROP1 ); - mandatory = tokenWriteOperations.propertyKeyGetOrCreateForName( "mandatory" ); - C = readOperations.relationshipTypeGetForName( "C" ); - T = readOperations.relationshipTypeGetForName( "T" ); - M = tokenWriteOperations.relationshipTypeGetOrCreateForName( "M" ); + TokenRead tokenRead = ktx.tokenRead(); + TokenWrite tokenWrite = ktx.tokenWrite(); + label1 = tokenRead.nodeLabel( "label1" ); + label2 = tokenRead.nodeLabel( "label2" ); + label3 = tokenRead.nodeLabel( "label3" ); + label4 = tokenRead.nodeLabel( "label4" ); + draconian = tokenWrite.labelGetOrCreateForName( "draconian" ); + key1 = tokenRead.propertyKey( PROP1 ); + mandatory = tokenWrite.propertyKeyGetOrCreateForName( "mandatory" ); + C = tokenRead.relationshipType( "C" ); + T = tokenRead.relationshipType( "T" ); + M = tokenWrite.relationshipTypeGetOrCreateForName( "M" ); } } catch ( KernelException e ) @@ -2321,11 +2322,11 @@ private void writeToSchemaStore( SchemaStore schemaStore, SchemaRule rule ) } } - private static KernelStatement statementOn( GraphDatabaseService db ) + private static KernelTransaction transactionOn( GraphDatabaseService db ) { DependencyResolver resolver = ((GraphDatabaseAPI) db).getDependencyResolver(); ThreadToStatementContextBridge bridge = resolver.resolveDependency( ThreadToStatementContextBridge.class ); - return (KernelStatement) bridge.get(); + return bridge.getKernelTransactionBoundToThisThread( true ); } private static class Reference diff --git a/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaRead.java b/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaRead.java index b5e6114e9bb06..efa4aaf8131e6 100644 --- a/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaRead.java +++ b/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/SchemaRead.java @@ -22,11 +22,14 @@ import java.util.Iterator; import java.util.function.Function; +import org.neo4j.internal.kernel.api.exceptions.KernelException; import org.neo4j.internal.kernel.api.exceptions.schema.SchemaKernelException; import org.neo4j.internal.kernel.api.schema.SchemaDescriptor; import org.neo4j.internal.kernel.api.schema.constraints.ConstraintDescriptor; import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; +import org.neo4j.register.Register; import org.neo4j.storageengine.api.schema.PopulationProgress; +import org.neo4j.values.storable.Value; /** * Surface for getting schema information, such as fetching specific indexes or constraints. @@ -107,6 +110,19 @@ PopulationProgress indexGetPopulationProgress( IndexReference index ) throws */ long indexSize( IndexReference index ) throws IndexNotFoundKernelException; + /** + * @param index The index of interest + * @param nodeId node id to match. + * @param value the property value + * @return number of index entries for the given {@code nodeId} and {@code value}. + */ + long nodesCountIndexed( IndexReference index, long nodeId, Value value ) throws KernelException; + + Register.DoubleLongRegister indexUpdatesAndSize( IndexReference index, Register.DoubleLongRegister target ) + throws IndexNotFoundKernelException; + + Register.DoubleLongRegister indexSample( IndexReference index, Register.DoubleLongRegister target ) + throws IndexNotFoundKernelException; /** * Finds all constraints for the given schema * diff --git a/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/TokenRead.java b/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/TokenRead.java index ad9ff84d17774..f30efd4535bcb 100644 --- a/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/TokenRead.java +++ b/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/TokenRead.java @@ -82,9 +82,39 @@ public interface TokenRead */ String propertyKeyName( int propertyKeyId ) throws PropertyKeyIdNotFoundKernelException; + /** + * Returns all all label tokens + * @return an iterator over all label tokens in the database + */ Iterator labelsGetAllTokens(); + /** + * Returns all all property tokens + * @return an iterator over all property tokens in the database + */ Iterator propertyKeyGetAllTokens(); + /** + * Returns all all relationship type tokens + * @return an iterator over all relationship type tokens in the database + */ Iterator relationshipTypesGetAllTokens(); + + /** + * Returns the number of labels in the database + * @return the number of labels in the database + */ + int labelCount( ); + + /** + * Returns the number of properties in the database + * @return the number of properties in the database + */ + int propertyKeyCount( ); + + /** + * Returns the number of relationship types in the database + * @return the number of relationship types in the database + */ + int relationshipTypeCount( ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java index fe4cee5bcbc34..92f0145efc32f 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/BuiltInProcedures.java @@ -42,20 +42,22 @@ import org.neo4j.graphdb.index.RelationshipIndex; import org.neo4j.helpers.collection.MapUtil; import org.neo4j.helpers.collection.PrefetchingResourceIterator; +import org.neo4j.internal.kernel.api.CapableIndexReference; +import org.neo4j.internal.kernel.api.IndexReference; import org.neo4j.internal.kernel.api.NodeExplicitIndexCursor; import org.neo4j.internal.kernel.api.RelationshipExplicitIndexCursor; import org.neo4j.internal.kernel.api.SchemaRead; import org.neo4j.internal.kernel.api.TokenNameLookup; +import org.neo4j.internal.kernel.api.TokenRead; import org.neo4j.internal.kernel.api.exceptions.KernelException; +import org.neo4j.internal.kernel.api.exceptions.LabelNotFoundKernelException; import org.neo4j.internal.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.ReadOperations; import org.neo4j.kernel.api.SilentTokenNameLookup; import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; -import org.neo4j.kernel.api.index.IndexProvider; -import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; +import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; import org.neo4j.kernel.impl.api.TokenAccess; import org.neo4j.kernel.impl.api.index.IndexingService; import org.neo4j.kernel.internal.GraphDatabaseAPI; @@ -66,7 +68,6 @@ import org.neo4j.values.storable.Values; import static org.neo4j.helpers.collection.Iterators.asList; -import static org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor.Type.UNIQUE; import static org.neo4j.procedure.Mode.READ; import static org.neo4j.procedure.Mode.WRITE; @@ -112,21 +113,22 @@ public Stream listRelationshipTypes() @Procedure( name = "db.indexes", mode = READ ) public Stream listIndexes() throws ProcedureException { - try ( Statement statement = tx.acquireStatement() ) + try ( Statement ignore = tx.acquireStatement() ) { - ReadOperations operations = statement.readOperations(); - TokenNameLookup tokens = new SilentTokenNameLookup( tx.tokenRead() ); + TokenRead tokenRead = tx.tokenRead(); + TokenNameLookup tokens = new SilentTokenNameLookup( tokenRead ); - List indexes = asList( operations.indexesGetAll() ); + SchemaRead schemaRead = tx.schemaRead(); + List indexes = asList( schemaRead.indexesGetAll() ); indexes.sort( Comparator.comparing( a -> a.userDescription( tokens ) ) ); ArrayList result = new ArrayList<>(); - for ( SchemaIndexDescriptor index : indexes ) + for ( IndexReference index : indexes ) { try { String type; - if ( index.type() == UNIQUE ) + if ( index.isUnique() ) { type = IndexType.NODE_UNIQUE_PROPERTY.typeName(); } @@ -135,18 +137,25 @@ public Stream listIndexes() throws ProcedureException type = IndexType.NODE_LABEL_PROPERTY.typeName(); } - String label = index.schema().keyName( tokens ); + String label = tokenRead.nodeLabelName( index.label() ); List propertyNames = propertyNames( tokens, index ); - result.add( new IndexResult( "INDEX ON " + index.schema().userDescription( tokens ), label, + result.add( new IndexResult( "INDEX ON " + + SchemaDescriptorFactory.forLabel( index.label(), index.properties() ) + .userDescription( tokens ), label, propertyNames, - operations.indexGetState( index ).toString(), type, - indexProviderDescriptorMap( operations.indexGetProviderDescriptor( index ) ) ) ); + schemaRead.indexGetState( index ).toString(), type, + indexProviderDescriptorMap( schemaRead.index( index.label(), index.properties() ) ) ) ); } catch ( IndexNotFoundKernelException e ) { throw new ProcedureException( Status.Schema.IndexNotFound, e, "No index on ", index.userDescription( tokens ) ); } + catch ( LabelNotFoundKernelException e ) + { + throw new ProcedureException( Status.General.InvalidArguments, e, + "Label not found " ); + } } return result.stream(); } @@ -584,16 +593,16 @@ public Stream relationshipManualIndexRemove( @Name( "indexName" ) return Stream.of( new BooleanResult( Boolean.TRUE ) ); } - private Map indexProviderDescriptorMap( IndexProvider.Descriptor providerDescriptor ) + private Map indexProviderDescriptorMap( CapableIndexReference indexReference ) { return MapUtil.stringMap( - "key", providerDescriptor.getKey(), - "version", providerDescriptor.getVersion() ); + "key", indexReference.providerKey(), + "version", indexReference.providerVersion() ); } - private List propertyNames( TokenNameLookup tokens, SchemaIndexDescriptor index ) + private List propertyNames( TokenNameLookup tokens, IndexReference index ) { - int[] propertyIds = index.schema().getPropertyIds(); + int[] propertyIds = index.properties(); List propertyNames = new ArrayList<>( propertyIds.length ); for ( int propertyId : propertyIds ) { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/IndexProcedures.java b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/IndexProcedures.java index ecc0b77c8df7d..d5d467f884b09 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/IndexProcedures.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/builtinprocs/IndexProcedures.java @@ -23,30 +23,29 @@ import java.util.concurrent.TimeoutException; import org.neo4j.function.Predicates; +import org.neo4j.internal.kernel.api.CapableIndexReference; +import org.neo4j.internal.kernel.api.IndexReference; import org.neo4j.internal.kernel.api.InternalIndexState; import org.neo4j.internal.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.ReadOperations; import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; -import org.neo4j.kernel.api.exceptions.schema.SchemaRuleNotFoundException; import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; -import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.impl.api.index.IndexingService; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingMode; import org.neo4j.kernel.impl.api.operations.KeyReadOperations; public class IndexProcedures implements AutoCloseable { + private final KernelTransaction ktx; private final Statement statement; - private final ReadOperations operations; private final IndexingService indexingService; public IndexProcedures( KernelTransaction tx, IndexingService indexingService ) { + this.ktx = tx; statement = tx.acquireStatement(); - operations = statement.readOperations(); this.indexingService = indexingService; } @@ -86,7 +85,7 @@ private IndexSpecifier parse( String specification ) private int getLabelId( String labelName ) throws ProcedureException { - int labelId = operations.labelGetForName( labelName ); + int labelId = ktx.tokenRead().nodeLabel( labelName ); if ( labelId == KeyReadOperations.NO_SUCH_LABEL ) { throw new ProcedureException( Status.Schema.LabelAccessFailed, "No such label %s", labelName ); @@ -100,7 +99,7 @@ private int[] getPropertyIds( String[] propertyKeyNames ) throws ProcedureExcept for ( int i = 0; i < propertyKeyIds.length; i++ ) { - int propertyKeyId = operations.propertyKeyGetForName( propertyKeyNames[i] ); + int propertyKeyId = ktx.tokenRead().propertyKey( propertyKeyNames[i] ); if ( propertyKeyId == KeyReadOperations.NO_SUCH_PROPERTY_KEY ) { throw new ProcedureException( Status.Schema.PropertyKeyAccessFailed, "No such property key %s", @@ -111,21 +110,19 @@ private int[] getPropertyIds( String[] propertyKeyNames ) throws ProcedureExcept return propertyKeyIds; } - private SchemaIndexDescriptor getIndex( int labelId, int[] propertyKeyIds, IndexSpecifier index ) throws + private CapableIndexReference getIndex( int labelId, int[] propertyKeyIds, IndexSpecifier index ) throws ProcedureException { - try - { - return operations - .indexGetForSchema( SchemaDescriptorFactory.forLabel( labelId, propertyKeyIds ) ); - } - catch ( SchemaRuleNotFoundException e ) + CapableIndexReference indexReference = ktx.schemaRead().index( labelId, propertyKeyIds ); + + if ( indexReference == CapableIndexReference.NO_INDEX ) { - throw new ProcedureException( Status.Schema.IndexNotFound, e, "No index on %s", index ); + throw new ProcedureException( Status.Schema.IndexNotFound, "No index on %s", index ); } + return indexReference; } - private void waitUntilOnline( SchemaIndexDescriptor index, IndexSpecifier indexDescription, + private void waitUntilOnline( IndexReference index, IndexSpecifier indexDescription, long timeout, TimeUnit timeoutUnits ) throws ProcedureException { @@ -140,7 +137,7 @@ private void waitUntilOnline( SchemaIndexDescriptor index, IndexSpecifier indexD } } - private boolean isOnline( IndexSpecifier indexDescription, SchemaIndexDescriptor index ) throws ProcedureException + private boolean isOnline( IndexSpecifier indexDescription, IndexReference index ) throws ProcedureException { InternalIndexState state = getState( indexDescription, index ); switch ( state ) @@ -157,12 +154,12 @@ private boolean isOnline( IndexSpecifier indexDescription, SchemaIndexDescriptor } } - private InternalIndexState getState( IndexSpecifier indexDescription, SchemaIndexDescriptor index ) + private InternalIndexState getState( IndexSpecifier indexDescription, IndexReference index ) throws ProcedureException { try { - return operations.indexGetState( index ); + return ktx.schemaRead().indexGetState( index ); } catch ( IndexNotFoundKernelException e ) { @@ -170,9 +167,9 @@ private InternalIndexState getState( IndexSpecifier indexDescription, SchemaInde } } - private void triggerSampling( SchemaIndexDescriptor index ) throws IndexNotFoundKernelException + private void triggerSampling( IndexReference index ) throws IndexNotFoundKernelException { - indexingService.triggerIndexSampling( index.schema(), IndexSamplingMode.TRIGGER_REBUILD_ALL ); + indexingService.triggerIndexSampling( SchemaDescriptorFactory.forLabel( index.label(), index.properties() ), IndexSamplingMode.TRIGGER_REBUILD_ALL ); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/DefaultCapableIndexReference.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/DefaultCapableIndexReference.java index 72a686d0b6f65..bb670c9247036 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/DefaultCapableIndexReference.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/DefaultCapableIndexReference.java @@ -128,7 +128,7 @@ public static CapableIndexReference fromDescriptor( SchemaIndexDescriptor descri { boolean unique = descriptor.type() == SchemaIndexDescriptor.Type.UNIQUE; final SchemaDescriptor schema = descriptor.schema(); - return new DefaultCapableIndexReference( unique, IndexCapability.NO_CAPABILITY, null, + return new DefaultCapableIndexReference( unique, IndexCapability.NO_CAPABILITY, IndexProvider.UNDECIDED, schema.keyId(), schema.getPropertyIds() ); } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/PlaceboTransaction.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/PlaceboTransaction.java index 0bdf52da6b966..d45a9c17bd157 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/PlaceboTransaction.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/PlaceboTransaction.java @@ -20,25 +20,21 @@ package org.neo4j.kernel.impl.coreapi; import java.util.Optional; -import java.util.function.Supplier; import org.neo4j.graphdb.Lock; import org.neo4j.graphdb.PropertyContainer; +import org.neo4j.internal.kernel.api.security.SecurityContext; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.exceptions.Status; -import org.neo4j.internal.kernel.api.security.SecurityContext; public class PlaceboTransaction implements InternalTransaction { private static final PropertyContainerLocker locker = new PropertyContainerLocker(); - private final Supplier stmt; private final KernelTransaction currentTransaction; private boolean success; - public PlaceboTransaction( KernelTransaction currentTransaction, Supplier stmt ) + public PlaceboTransaction( KernelTransaction currentTransaction ) { - this.stmt = stmt; this.currentTransaction = currentTransaction; } @@ -72,13 +68,13 @@ public void close() @Override public Lock acquireWriteLock( PropertyContainer entity ) { - return locker.exclusiveLock( stmt, entity ); + return locker.exclusiveLock( currentTransaction, entity ); } @Override public Lock acquireReadLock( PropertyContainer entity ) { - return locker.sharedLock( stmt, entity ); + return locker.sharedLock( currentTransaction, entity ); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/PropertyContainerLocker.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/PropertyContainerLocker.java index 8581982c618da..919d0be7d0265 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/PropertyContainerLocker.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/PropertyContainerLocker.java @@ -19,52 +19,34 @@ */ package org.neo4j.kernel.impl.coreapi; -import java.util.function.Supplier; - import org.neo4j.graphdb.Lock; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.PropertyContainer; import org.neo4j.graphdb.Relationship; +import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.impl.locking.ResourceTypes; -import org.neo4j.storageengine.api.lock.ResourceType; /** * Manages user-facing locks. */ public class PropertyContainerLocker { - public Lock exclusiveLock( Supplier stmtSupplier, PropertyContainer container ) + public Lock exclusiveLock( KernelTransaction ktx, PropertyContainer container ) { - try ( Statement statement = stmtSupplier.get() ) + try ( Statement ignore = ktx.acquireStatement() ) { if ( container instanceof Node ) { long id = ((Node) container).getId(); - ResourceTypes resourceType = ResourceTypes.NODE; - statement.readOperations().acquireExclusive( resourceType, id ); - return new CoreAPILock( stmtSupplier, resourceType, id ) - { - @Override - void release( Statement statement, ResourceType type, long resourceId ) - { - statement.readOperations().releaseExclusive( type, resourceId ); - } - }; + ktx.locks().acquireExclusiveNodeLock( id ); + return new CoreAPILock( () -> ktx.locks().releaseExclusiveNodeLock( id ) ); } else if ( container instanceof Relationship ) { long id = ((Relationship) container).getId(); - ResourceTypes resourceType = ResourceTypes.RELATIONSHIP; - statement.readOperations().acquireExclusive( resourceType, id ); - return new CoreAPILock( stmtSupplier, resourceType, id ) - { - @Override - void release( Statement statement, ResourceType type, long resourceId ) - { - statement.readOperations().releaseExclusive( type, resourceId ); - } - }; + ktx.locks().acquireExclusiveRelationshipLock( id ); + return new CoreAPILock( () -> ktx.locks().releaseExclusiveRelationshipLock( id ) ); } else { @@ -80,22 +62,16 @@ public Lock exclusiveLock( Statement statement, PropertyContainer container ) { if ( container instanceof Node ) { - statement.readOperations().acquireExclusive( ResourceTypes.NODE, ((Node) container).getId() ); - return () -> - { - long id = ((Node) container).getId(); - statement.readOperations().releaseExclusive( ResourceTypes.NODE, id ); - }; + long id = ((Node) container).getId(); + statement.readOperations().acquireExclusive( ResourceTypes.NODE, id ); + return () -> statement.readOperations().releaseExclusive( ResourceTypes.NODE, id ); } else if ( container instanceof Relationship ) { + long id = ((Relationship) container).getId(); statement.readOperations() - .acquireExclusive( ResourceTypes.RELATIONSHIP, ((Relationship) container).getId() ); - return () -> - { - long id = ((Relationship) container).getId(); - statement.readOperations().releaseExclusive( ResourceTypes.RELATIONSHIP, id ); - }; + .acquireExclusive( ResourceTypes.RELATIONSHIP, id ); + return () -> statement.readOperations().releaseExclusive( ResourceTypes.RELATIONSHIP, id ); } else { @@ -103,37 +79,21 @@ else if ( container instanceof Relationship ) } } - public Lock sharedLock( Supplier stmtProvider, PropertyContainer container ) + public Lock sharedLock( KernelTransaction ktx, PropertyContainer container ) { - try ( Statement statement = stmtProvider.get() ) + try ( Statement ignore = ktx.acquireStatement() ) { if ( container instanceof Node ) { long id = ((Node) container).getId(); - ResourceTypes resourceType = ResourceTypes.NODE; - statement.readOperations().acquireShared( resourceType, id ); - return new CoreAPILock( stmtProvider, resourceType, id ) - { - @Override - void release( Statement statement, ResourceType type, long resourceId ) - { - statement.readOperations().releaseShared( type, resourceId ); - } - }; + ktx.locks().acquireSharedNodeLock( id ); + return new CoreAPILock( () -> ktx.locks().releaseSharedNodeLock( id ) ); } else if ( container instanceof Relationship ) { long id = ((Relationship) container).getId(); - ResourceTypes resourceType = ResourceTypes.RELATIONSHIP; - statement.readOperations().acquireShared( resourceType, id ); - return new CoreAPILock( stmtProvider, resourceType, id ) - { - @Override - void release( Statement statement, ResourceType type, long resourceId ) - { - statement.readOperations().releaseShared( type, resourceId ); - } - }; + ktx.locks().acquireSharedRelationshipLock( id ); + return new CoreAPILock( () -> ktx.locks().releaseSharedRelationshipLock( id ) ); } else { @@ -142,18 +102,14 @@ void release( Statement statement, ResourceType type, long resourceId ) } } - private abstract static class CoreAPILock implements Lock + private static class CoreAPILock implements Lock { - private final Supplier stmtProvider; - private final ResourceType type; - private final long resourceId; private boolean released; + private final Runnable release; - CoreAPILock( Supplier stmtProvider, ResourceType type, long resourceId ) + CoreAPILock( Runnable release ) { - this.stmtProvider = stmtProvider; - this.type = type; - this.resourceId = resourceId; + this.release = release; } @Override @@ -164,13 +120,8 @@ public void release() throw new IllegalStateException( "Already released" ); } released = true; - try ( Statement statement = stmtProvider.get() ) - { - release( statement, type, resourceId ); - } + release.run(); } - - abstract void release( Statement statement, ResourceType type, long resourceId ); } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/TopLevelTransaction.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/TopLevelTransaction.java index 7808172313809..c5f081a67095f 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/TopLevelTransaction.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/TopLevelTransaction.java @@ -29,25 +29,23 @@ import org.neo4j.graphdb.TransactionTerminatedException; import org.neo4j.graphdb.TransientFailureException; import org.neo4j.graphdb.TransientTransactionFailureException; +import org.neo4j.internal.kernel.api.exceptions.KernelException; +import org.neo4j.internal.kernel.api.security.SecurityContext; import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.exceptions.ConstraintViolationTransactionFailureException; -import org.neo4j.internal.kernel.api.exceptions.KernelException; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.api.exceptions.Status.Classification; import org.neo4j.kernel.api.exceptions.Status.Code; -import org.neo4j.internal.kernel.api.security.SecurityContext; public class TopLevelTransaction implements InternalTransaction { private static final PropertyContainerLocker locker = new PropertyContainerLocker(); private boolean successCalled; - private final Supplier stmt; private final KernelTransaction transaction; public TopLevelTransaction( KernelTransaction transaction, Supplier stmt ) { - this.stmt = stmt; this.transaction = transaction; } @@ -117,13 +115,13 @@ private String closeFailureMessage() @Override public Lock acquireWriteLock( PropertyContainer entity ) { - return locker.exclusiveLock( stmt, entity ); + return locker.exclusiveLock( transaction, entity ); } @Override public Lock acquireReadLock( PropertyContainer entity ) { - return locker.sharedLock(stmt, entity); + return locker.sharedLock(transaction, entity); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/GraphDatabaseFacade.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/GraphDatabaseFacade.java index 2ab654a7f13d5..1277ac827b443 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/GraphDatabaseFacade.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/GraphDatabaseFacade.java @@ -694,7 +694,7 @@ private InternalTransaction beginTransactionInternal( KernelTransaction.Type typ if ( statementContext.hasTransaction() ) { // FIXME: perhaps we should check that the new type and access mode are compatible with the current tx - return new PlaceboTransaction( statementContext.getKernelTransactionBoundToThisThread( true ), statementContext ); + return new PlaceboTransaction( statementContext.getKernelTransactionBoundToThisThread( true ) ); } return new TopLevelTransaction( spi.beginTransaction( type, loginContext, timeoutMillis ), statementContext ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/AllStoreHolder.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/AllStoreHolder.java index b6b00fd503517..4dc9eeeddf99a 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/AllStoreHolder.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/AllStoreHolder.java @@ -32,6 +32,7 @@ import org.neo4j.internal.kernel.api.CapableIndexReference; import org.neo4j.internal.kernel.api.IndexReference; import org.neo4j.internal.kernel.api.InternalIndexState; +import org.neo4j.internal.kernel.api.exceptions.KernelException; import org.neo4j.internal.kernel.api.exceptions.ProcedureException; import org.neo4j.internal.kernel.api.exceptions.explicitindex.ExplicitIndexNotFoundKernelException; import org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException; @@ -80,6 +81,7 @@ import org.neo4j.kernel.impl.store.record.RecordLoad; import org.neo4j.kernel.impl.store.record.RelationshipGroupRecord; import org.neo4j.kernel.impl.store.record.RelationshipRecord; +import org.neo4j.register.Register; import org.neo4j.storageengine.api.StorageEngine; import org.neo4j.storageengine.api.StorageStatement; import org.neo4j.storageengine.api.StoreReadLayer; @@ -92,6 +94,7 @@ import org.neo4j.values.ValueMapper; import org.neo4j.values.storable.ArrayValue; import org.neo4j.values.storable.TextValue; +import org.neo4j.values.storable.Value; import org.neo4j.values.storable.Values; import static java.lang.String.format; @@ -452,6 +455,34 @@ public long indexSize( IndexReference index ) throws IndexNotFoundKernelExceptio return storeReadLayer.indexSize( SchemaDescriptorFactory.forLabel( index.label(), index.properties() ) ); } + @Override + public long nodesCountIndexed( IndexReference index, long nodeId, Value value ) throws KernelException + { + ktx.assertOpen(); + IndexReader reader = statement.getIndexReader( DefaultIndexReference.toDescriptor( index ) ); + return reader.countIndexedNodes( nodeId, value ); + } + + @Override + public Register.DoubleLongRegister indexUpdatesAndSize( IndexReference index, Register.DoubleLongRegister target ) + throws IndexNotFoundKernelException + { + ktx.assertOpen(); + return storeReadLayer.indexUpdatesAndSize( + SchemaDescriptorFactory.forLabel( index.label(), index.properties() ), target ); + + } + + @Override + public Register.DoubleLongRegister indexSample( IndexReference index, Register.DoubleLongRegister target ) + throws IndexNotFoundKernelException + { + ktx.assertOpen(); + ktx.assertOpen(); + return storeReadLayer.indexUpdatesAndSize( + SchemaDescriptorFactory.forLabel( index.label(), index.properties() ), target ); + } + CapableIndexReference indexGetCapability( SchemaIndexDescriptor schemaIndexDescriptor ) { try diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/KernelToken.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/KernelToken.java index d1cdff2eff529..f1f6f2bba55d8 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/KernelToken.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/KernelToken.java @@ -172,6 +172,27 @@ public Iterator relationshipTypesGetAllTokens() return Iterators.map( token -> new NamedToken( token.name(), token.id() ), store.relationshipTypeGetAllTokens()); } + @Override + public int labelCount() + { + ktx.assertOpen(); + return store.labelCount(); + } + + @Override + public int propertyKeyCount() + { + ktx.assertOpen(); + return store.propertyKeyCount(); + } + + @Override + public int relationshipTypeCount() + { + ktx.assertOpen(); + return store.relationshipTypeCount(); + } + private String checkValidTokenName( String name ) throws IllegalTokenNameException { if ( name == null || name.isEmpty() ) diff --git a/community/kernel/src/test/java/org/neo4j/graphdb/IndexingAcceptanceTest.java b/community/kernel/src/test/java/org/neo4j/graphdb/IndexingAcceptanceTest.java index e8603d5e691d2..1cf4effb050f2 100644 --- a/community/kernel/src/test/java/org/neo4j/graphdb/IndexingAcceptanceTest.java +++ b/community/kernel/src/test/java/org/neo4j/graphdb/IndexingAcceptanceTest.java @@ -27,8 +27,20 @@ import java.util.Map; +import org.neo4j.collection.primitive.Primitive; +import org.neo4j.collection.primitive.PrimitiveLongIterator; +import org.neo4j.collection.primitive.PrimitiveLongSet; +import org.neo4j.graphdb.schema.IndexDefinition; import org.neo4j.graphdb.spatial.Point; import org.neo4j.helpers.collection.Iterators; +import org.neo4j.internal.kernel.api.CapableIndexReference; +import org.neo4j.internal.kernel.api.IndexOrder; +import org.neo4j.internal.kernel.api.NodeValueIndexCursor; +import org.neo4j.internal.kernel.api.exceptions.KernelException; +import org.neo4j.kernel.api.KernelTransaction; +import org.neo4j.kernel.api.exceptions.schema.SchemaRuleNotFoundException; +import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; +import org.neo4j.kernel.internal.GraphDatabaseAPI; import org.neo4j.test.mockito.matcher.Neo4jMatchers; import org.neo4j.test.rule.ImpermanentDatabaseRule; import org.neo4j.values.storable.CoordinateReferenceSystem; @@ -47,6 +59,8 @@ import static org.neo4j.helpers.collection.Iterators.asSet; import static org.neo4j.helpers.collection.Iterators.count; import static org.neo4j.helpers.collection.MapUtil.map; +import static org.neo4j.internal.kernel.api.IndexQuery.stringPrefix; +import static org.neo4j.kernel.impl.coreapi.schema.PropertyNameUtils.getPropertyIds; import static org.neo4j.test.mockito.matcher.Neo4jMatchers.containsOnly; import static org.neo4j.test.mockito.matcher.Neo4jMatchers.findNodesByLabelAndProperty; import static org.neo4j.test.mockito.matcher.Neo4jMatchers.hasProperty; @@ -494,6 +508,181 @@ public void shouldAddIndexedPropertyToNodeWithDynamicLabels() } } + @Test + public void shouldSupportIndexSeekByPrefix() throws KernelException + { + // GIVEN + GraphDatabaseService db = dbRule.getGraphDatabaseAPI(); + IndexDefinition index = Neo4jMatchers.createIndex( db, LABEL1, "name" ); + createNodes( db, LABEL1, "name", "Mattias", "Mats", "Carla" ); + PrimitiveLongSet expected = createNodes( db, LABEL1, "name", "Karl", "Karlsson" ); + + // WHEN + PrimitiveLongSet found = Primitive.longSet(); + try ( Transaction tx = db.beginTx() ) + { + KernelTransaction ktx = getKernelTransaction( (GraphDatabaseAPI) db ); + CapableIndexReference reference = indexReference( ktx, index ); + int propertyKeyId = reference.properties()[0]; + try ( NodeValueIndexCursor cursor = ktx.cursors().allocateNodeValueIndexCursor()) + { + ktx.dataRead().nodeIndexSeek( reference, cursor, IndexOrder.NONE, stringPrefix( propertyKeyId, "Karl" ) ); + while ( cursor.next() ) + { + found.add( cursor.nodeReference() ); + } + } + } + + // THEN + assertThat( found, equalTo( expected ) ); + } + + @Test + public void shouldIncludeNodesCreatedInSameTxInIndexSeekByPrefix() throws KernelException + { + // GIVEN + GraphDatabaseService db = dbRule.getGraphDatabaseAPI(); + IndexDefinition index = Neo4jMatchers.createIndex( db, LABEL1, "name" ); + createNodes( db, LABEL1, "name", "Mattias", "Mats" ); + PrimitiveLongSet expected = createNodes( db, LABEL1, "name", "Carl", "Carlsson" ); + // WHEN + PrimitiveLongSet found = Primitive.longSet(); + try ( Transaction tx = db.beginTx() ) + { + expected.add( createNode( db, map( "name", "Carlchen" ), LABEL1 ).getId() ); + createNode( db, map( "name", "Karla" ), LABEL1 ); + KernelTransaction ktx = getKernelTransaction( (GraphDatabaseAPI) db ); + + CapableIndexReference reference = indexReference( ktx, index ); + int propertyKeyId = reference.properties()[0]; + try ( NodeValueIndexCursor cursor = ktx.cursors().allocateNodeValueIndexCursor()) + { + ktx.dataRead().nodeIndexSeek( reference, cursor, IndexOrder.NONE, stringPrefix( propertyKeyId, "Carl" ) ); + while ( cursor.next() ) + { + found.add( cursor.nodeReference() ); + } + } + } + // THEN + assertThat( found, equalTo( expected ) ); + } + + @Test + public void shouldNotIncludeNodesDeletedInSameTxInIndexSeekByPrefix() + throws KernelException + { + // GIVEN + GraphDatabaseService db = dbRule.getGraphDatabaseAPI(); + IndexDefinition index = Neo4jMatchers.createIndex( db, LABEL1, "name" ); + createNodes( db, LABEL1, "name", "Mattias" ); + PrimitiveLongSet toDelete = createNodes( db, LABEL1, "name", "Karlsson", "Mats" ); + PrimitiveLongSet expected = createNodes( db, LABEL1, "name", "Karl" ); + // WHEN + PrimitiveLongSet found = Primitive.longSet(); + try ( Transaction tx = db.beginTx() ) + { + PrimitiveLongIterator deleting = toDelete.iterator(); + while ( deleting.hasNext() ) + { + long id = deleting.next(); + db.getNodeById( id ).delete(); + expected.remove( id ); + } + KernelTransaction ktx = getKernelTransaction( (GraphDatabaseAPI) db ); + + CapableIndexReference reference = indexReference( ktx, index ); + int propertyKeyId = reference.properties()[0]; + try ( NodeValueIndexCursor cursor = ktx.cursors().allocateNodeValueIndexCursor() ) + { + ktx.dataRead() + .nodeIndexSeek( reference, cursor, IndexOrder.NONE, stringPrefix( propertyKeyId, "Karl" ) ); + while ( cursor.next() ) + { + found.add( cursor.nodeReference() ); + } + } + } + // THEN + assertThat( found, equalTo( expected ) ); + } + + @Test + public void shouldConsiderNodesChangedInSameTxInIndexPrefixSearch() + throws KernelException + { + // GIVEN + GraphDatabaseService db = dbRule.getGraphDatabaseAPI(); + IndexDefinition index = Neo4jMatchers.createIndex( db, LABEL1, "name" ); + createNodes( db, LABEL1, "name", "Mattias" ); + PrimitiveLongSet toChangeToMatch = createNodes( db, LABEL1, "name", "Mats" ); + PrimitiveLongSet toChangeToNotMatch = createNodes( db, LABEL1, "name", "Karlsson" ); + PrimitiveLongSet expected = createNodes( db, LABEL1, "name", "Karl" ); + String prefix = "Karl"; + // WHEN + PrimitiveLongSet found = Primitive.longSet(); + try ( Transaction tx = db.beginTx() ) + { + PrimitiveLongIterator toMatching = toChangeToMatch.iterator(); + while ( toMatching.hasNext() ) + { + long id = toMatching.next(); + db.getNodeById( id ).setProperty( "name", prefix + "X" + id ); + expected.add( id ); + } + PrimitiveLongIterator toNotMatching = toChangeToNotMatch.iterator(); + while ( toNotMatching.hasNext() ) + { + long id = toNotMatching.next(); + db.getNodeById( id ).setProperty( "name", "X" + id ); + expected.remove( id ); + } + KernelTransaction ktx = getKernelTransaction( (GraphDatabaseAPI) db ); + CapableIndexReference descriptor = indexReference( ktx, index ); + int propertyKeyId = descriptor.properties()[0]; + try ( NodeValueIndexCursor cursor = ktx.cursors().allocateNodeValueIndexCursor()) + { + ktx.dataRead().nodeIndexSeek( descriptor, cursor, IndexOrder.NONE, stringPrefix( propertyKeyId, prefix ) ); + while ( cursor.next() ) + { + found.add( cursor.nodeReference() ); + } + } + } + // THEN + assertThat( found, equalTo( expected ) ); + } + + private PrimitiveLongSet createNodes( GraphDatabaseService db, Label label, String propertyKey, String... propertyValues ) + { + PrimitiveLongSet expected = Primitive.longSet(); + try ( Transaction tx = db.beginTx() ) + { + for ( String value : propertyValues ) + { + expected.add( createNode( db, map( propertyKey, value ), label ).getId() ); + } + tx.success(); + } + return expected; + } + + private CapableIndexReference indexReference( KernelTransaction transaction, IndexDefinition index ) + throws SchemaRuleNotFoundException + { + int labelId = transaction.tokenRead().nodeLabel( index.getLabel().name() ); + int[] propertyKeyIds = getPropertyIds( transaction.tokenRead(), index.getPropertyKeys() ); + + return transaction.schemaRead().index( labelId, propertyKeyIds ); + } + + private KernelTransaction getKernelTransaction( GraphDatabaseAPI db ) + { + return db.getDependencyResolver() + .resolveDependency( ThreadToStatementContextBridge.class ).getKernelTransactionBoundToThisThread( true ); + } + private void assertCanCreateAndFind( GraphDatabaseService db, Label label, String propertyKey, Object value ) { Node created = createNode( db, map( propertyKey, value ), label ); diff --git a/community/kernel/src/test/java/org/neo4j/graphdb/LabelsAcceptanceTest.java b/community/kernel/src/test/java/org/neo4j/graphdb/LabelsAcceptanceTest.java index bd0cf02f188f1..eadb1a58639d0 100644 --- a/community/kernel/src/test/java/org/neo4j/graphdb/LabelsAcceptanceTest.java +++ b/community/kernel/src/test/java/org/neo4j/graphdb/LabelsAcceptanceTest.java @@ -34,12 +34,14 @@ import java.util.stream.Stream; import javax.annotation.Nonnull; -import org.neo4j.cursor.Cursor; import org.neo4j.graphdb.factory.GraphDatabaseBuilder; import org.neo4j.helpers.collection.Iterables; +import org.neo4j.internal.kernel.api.LabelSet; +import org.neo4j.internal.kernel.api.NodeCursor; +import org.neo4j.internal.kernel.api.PropertyCursor; import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.kernel.GraphDatabaseDependencies; -import org.neo4j.kernel.api.Statement; +import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.impl.factory.CommunityEditionModule; @@ -56,8 +58,6 @@ import org.neo4j.kernel.impl.store.id.configuration.IdTypeConfiguration; import org.neo4j.kernel.impl.store.id.configuration.IdTypeConfigurationProvider; import org.neo4j.kernel.internal.GraphDatabaseAPI; -import org.neo4j.storageengine.api.NodeItem; -import org.neo4j.storageengine.api.PropertyItem; import org.neo4j.test.ImpermanentGraphDatabase; import org.neo4j.test.TestGraphDatabaseFactory; import org.neo4j.test.TestGraphDatabaseFactoryState; @@ -73,7 +73,6 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.neo4j.collection.primitive.PrimitiveIntCollections.consume; import static org.neo4j.graphdb.Label.label; import static org.neo4j.helpers.collection.Iterables.asList; import static org.neo4j.helpers.collection.Iterables.map; @@ -593,18 +592,22 @@ public void shouldAllowManyLabelsAndPropertyCursor() throws Exception { DependencyResolver resolver = db.getDependencyResolver(); ThreadToStatementContextBridge bridge = resolver.resolveDependency( ThreadToStatementContextBridge.class ); - try ( Statement statement = bridge.getTopLevelTransactionBoundToThisThread( true ).acquireStatement() ) + KernelTransaction ktx = bridge.getKernelTransactionBoundToThisThread( true ); + try ( NodeCursor nodes = ktx.cursors().allocateNodeCursor(); + PropertyCursor propertyCursor = ktx.cursors().allocatePropertyCursor() ) { - try ( Cursor nodeCursor = statement.readOperations().nodeCursorById( node.getId() ) ) + while ( nodes.next() ) { - try ( Cursor properties = statement.readOperations() - .nodeGetProperties( nodeCursor.get() ) ) + nodes.properties( propertyCursor ); + while ( propertyCursor.next() ) { - while ( properties.next() ) - { - seenProperties.add( properties.get().propertyKeyId() ); - consume( nodeCursor.get().labels().iterator(), seenLabels::add ); - } + seenProperties.add( propertyCursor.propertyKey() ); + } + + LabelSet labels = nodes.labels(); + for ( int i = 0; i < labels.numberOfLabels(); i++ ) + { + seenLabels.add( labels.label( i ) ); } } } diff --git a/community/kernel/src/test/java/org/neo4j/graphdb/NativeLabelScanStoreStartupIT.java b/community/kernel/src/test/java/org/neo4j/graphdb/NativeLabelScanStoreStartupIT.java index 097d36160b786..19117a91f7f98 100644 --- a/community/kernel/src/test/java/org/neo4j/graphdb/NativeLabelScanStoreStartupIT.java +++ b/community/kernel/src/test/java/org/neo4j/graphdb/NativeLabelScanStoreStartupIT.java @@ -27,7 +27,7 @@ import org.neo4j.collection.primitive.PrimitiveLongCollections; import org.neo4j.io.pagecache.IOLimiter; -import org.neo4j.kernel.api.Statement; +import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.impl.labelscan.LabelScanStoreTest; import org.neo4j.kernel.api.labelscan.LabelScanStore; import org.neo4j.kernel.api.labelscan.LabelScanWriter; @@ -107,12 +107,10 @@ private Node createTestNode() try ( Transaction transaction = dbRule.beginTx() ) { node = dbRule.createNode( LABEL); - try ( Statement statement = dbRule.getDependencyResolver() + KernelTransaction ktx = dbRule.getDependencyResolver() .resolveDependency( ThreadToStatementContextBridge.class ) - .getKernelTransactionBoundToThisThread( true ).acquireStatement() ) - { - labelId = statement.readOperations().labelGetForName( LABEL.name() ); - } + .getKernelTransactionBoundToThisThread( true ); + labelId = ktx.tokenRead().nodeLabel( LABEL.name() ); transaction.success(); } return node; diff --git a/community/kernel/src/test/java/org/neo4j/kernel/TestPlaceboTransaction.java b/community/kernel/src/test/java/org/neo4j/kernel/TestPlaceboTransaction.java index 26517989732bd..7acc03924b6f9 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/TestPlaceboTransaction.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/TestPlaceboTransaction.java @@ -26,13 +26,12 @@ import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Transaction; +import org.neo4j.internal.kernel.api.Locks; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.ReadOperations; import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.impl.coreapi.PlaceboTransaction; -import org.neo4j.kernel.impl.locking.ResourceTypes; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -49,7 +48,7 @@ public class TestPlaceboTransaction private Transaction placeboTx; private Node resource; private KernelTransaction kernelTransaction; - private ReadOperations readOps; + private Locks locks; @Before public void before() @@ -57,11 +56,9 @@ public void before() ThreadToStatementContextBridge bridge = mock( ThreadToStatementContextBridge.class ); when( bridge.get() ).thenReturn( mock( Statement.class ) ); kernelTransaction = spy( KernelTransaction.class ); - Statement statement = mock( Statement.class ); - readOps = mock( ReadOperations.class ); - when( statement.readOperations() ).thenReturn( readOps ); - when( bridge.get() ).thenReturn( statement ); - placeboTx = new PlaceboTransaction( kernelTransaction, bridge ); + locks = mock( Locks.class ); + when(kernelTransaction.locks()).thenReturn( locks ); + placeboTx = new PlaceboTransaction( kernelTransaction ); resource = mock( Node.class ); when( resource.getId() ).thenReturn( 1L ); } @@ -118,7 +115,7 @@ public void canAcquireReadLock() placeboTx.acquireReadLock( resource ); // then - verify( readOps ).acquireShared( ResourceTypes.NODE, resource.getId() ); + verify( locks ).acquireSharedNodeLock( resource.getId() ); } @Test @@ -128,7 +125,7 @@ public void canAcquireWriteLock() placeboTx.acquireWriteLock( resource ); // then - verify( readOps ).acquireExclusive( ResourceTypes.NODE, resource.getId() ); + verify( locks ).acquireExclusiveNodeLock( resource.getId() ); } @Test @@ -138,7 +135,7 @@ public void shouldReturnTerminationReason() when( kernelTransaction.getReasonIfTerminated() ).thenReturn( Optional.empty() ) .thenReturn( Optional.of( Status.Transaction.Interrupted ) ); - PlaceboTransaction tx = new PlaceboTransaction( kernelTransaction, new ThreadToStatementContextBridge() ); + PlaceboTransaction tx = new PlaceboTransaction( kernelTransaction ); Optional terminationReason1 = tx.terminationReason(); Optional terminationReason2 = tx.terminationReason(); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/api/CompositeIndexingIT.java b/community/kernel/src/test/java/org/neo4j/kernel/api/CompositeIndexingIT.java index 5800f9701164e..702c9038a85e5 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/api/CompositeIndexingIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/api/CompositeIndexingIT.java @@ -30,22 +30,18 @@ import org.junit.runners.Parameterized; import java.util.Arrays; +import java.util.HashSet; import java.util.Set; -import org.neo4j.collection.primitive.PrimitiveLongCollections; -import org.neo4j.collection.primitive.PrimitiveLongIterator; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Transaction; import org.neo4j.helpers.collection.Iterators; +import org.neo4j.internal.kernel.api.IndexOrder; import org.neo4j.internal.kernel.api.IndexQuery; import org.neo4j.internal.kernel.api.InternalIndexState; -import org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException; -import org.neo4j.internal.kernel.api.exceptions.InvalidTransactionTypeKernelException; -import org.neo4j.internal.kernel.api.exceptions.explicitindex.AutoIndexingKernelException; -import org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException; -import org.neo4j.internal.kernel.api.schema.LabelSchemaDescriptor; -import org.neo4j.kernel.api.exceptions.index.IndexNotApplicableKernelException; -import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; +import org.neo4j.internal.kernel.api.NodeValueIndexCursor; +import org.neo4j.internal.kernel.api.Write; +import org.neo4j.internal.kernel.api.exceptions.KernelException; import org.neo4j.kernel.api.schema.constaints.ConstraintDescriptorFactory; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptorFactory; @@ -59,7 +55,9 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor.Type.UNIQUE; +import static org.neo4j.kernel.impl.api.store.DefaultCapableIndexReference.fromDescriptor; @RunWith( Parameterized.class ) public class CompositeIndexingIT @@ -84,25 +82,23 @@ public void setup() throws Exception graphDatabaseAPI = dbRule.getGraphDatabaseAPI(); try ( Transaction tx = graphDatabaseAPI.beginTx() ) { - try ( Statement statement = statement() ) + KernelTransaction ktx = ktx(); + if ( index.type() == UNIQUE ) { - if ( index.type() == UNIQUE ) - { - statement.schemaWriteOperations().uniquePropertyConstraintCreate( - (LabelSchemaDescriptor) index.schema() ); - } - else - { - statement.schemaWriteOperations().indexCreate( index.schema() ); - } + ktx.schemaWrite().uniquePropertyConstraintCreate( index.schema() ); + } + else + { + ktx.schemaWrite().indexCreate( index.schema() ); } tx.success(); } - try ( Transaction ignore = graphDatabaseAPI.beginTx(); - Statement statement = statement() ) + try ( Transaction ignore = graphDatabaseAPI.beginTx() ) { - while ( statement.readOperations().indexGetState( index ) != InternalIndexState.ONLINE ) + KernelTransaction ktx = ktx(); + while ( ktx.schemaRead().indexGetState( fromDescriptor( index ) ) != + InternalIndexState.ONLINE ) { Thread.sleep( 10 ); } // Will break loop on test timeout @@ -112,17 +108,17 @@ public void setup() throws Exception @After public void clean() throws Exception { - try ( Transaction tx = graphDatabaseAPI.beginTx(); - Statement statement = statement() ) + try ( Transaction tx = graphDatabaseAPI.beginTx() ) { + KernelTransaction ktx = ktx(); if ( index.type() == UNIQUE ) { - statement.schemaWriteOperations().constraintDrop( + ktx.schemaWrite().constraintDrop( ConstraintDescriptorFactory.uniqueForSchema( index.schema() ) ); } else { - statement.schemaWriteOperations().indexDrop( index ); + ktx.schemaWrite().indexDrop( fromDescriptor( index ) ); } tx.success(); } @@ -158,38 +154,44 @@ public CompositeIndexingIT( SchemaIndexDescriptor nodeDescriptor ) @Test public void shouldSeeNodeAddedByPropertyToIndexInTranslation() throws Exception { - try ( Transaction ignore = graphDatabaseAPI.beginTx(); - Statement statement = statement() ) + try ( Transaction ignore = graphDatabaseAPI.beginTx() ) { - DataWriteOperations writeOperations = statement.dataWriteOperations(); - long nodeID = writeOperations.nodeCreate(); - writeOperations.nodeAddLabel( nodeID, LABEL_ID ); + KernelTransaction ktx = ktx(); + Write write = ktx.dataWrite(); + long nodeID = write.nodeCreate(); + write.nodeAddLabel( nodeID, LABEL_ID ); for ( int propID : index.schema().getPropertyIds() ) { - writeOperations.nodeSetProperty( nodeID, propID, Values.intValue( propID ) ); + write.nodeSetProperty( nodeID, propID, Values.intValue( propID ) ); + } + try ( NodeValueIndexCursor cursor = seek( ktx ) ) + { + assertTrue( cursor.next() ); + assertThat( cursor.nodeReference(), equalTo( nodeID ) ); + assertFalse( cursor.next() ); } - PrimitiveLongIterator resultIterator = seek( statement ); - assertThat( resultIterator.next(), equalTo( nodeID ) ); - assertFalse( resultIterator.hasNext() ); } } @Test public void shouldSeeNodeAddedToByLabelIndexInTransaction() throws Exception { - try ( Transaction ignore = graphDatabaseAPI.beginTx(); - Statement statement = statement() ) + try ( Transaction ignore = graphDatabaseAPI.beginTx() ) { - DataWriteOperations writeOperations = statement.dataWriteOperations(); - long nodeID = writeOperations.nodeCreate(); + KernelTransaction ktx = ktx(); + Write write = ktx.dataWrite(); + long nodeID = write.nodeCreate(); for ( int propID : index.schema().getPropertyIds() ) { - writeOperations.nodeSetProperty( nodeID, propID, Values.intValue( propID ) ); + write.nodeSetProperty( nodeID, propID, Values.intValue( propID ) ); + } + write.nodeAddLabel( nodeID, LABEL_ID ); + try ( NodeValueIndexCursor cursor = seek( ktx ) ) + { + assertTrue( cursor.next() ); + assertThat( cursor.nodeReference(), equalTo( nodeID ) ); + assertFalse( cursor.next() ); } - writeOperations.nodeAddLabel( nodeID, LABEL_ID ); - PrimitiveLongIterator resultIterator = seek( statement ); - assertThat( resultIterator.next(), equalTo( nodeID ) ); - assertFalse( resultIterator.hasNext() ); } } @@ -197,11 +199,14 @@ public void shouldSeeNodeAddedToByLabelIndexInTransaction() throws Exception public void shouldNotSeeNodeThatWasDeletedInTransaction() throws Exception { long nodeID = createNode(); - try ( Transaction ignore = graphDatabaseAPI.beginTx(); - Statement statement = statement() ) + try ( Transaction ignore = graphDatabaseAPI.beginTx() ) { - statement.dataWriteOperations().nodeDelete( nodeID ); - assertFalse( seek( statement ).hasNext() ); + KernelTransaction ktx = ktx(); + ktx.dataWrite().nodeDelete( nodeID ); + try ( NodeValueIndexCursor cursor = seek( ktx ) ) + { + assertFalse( cursor.next() ); + } } } @@ -209,11 +214,14 @@ public void shouldNotSeeNodeThatWasDeletedInTransaction() throws Exception public void shouldNotSeeNodeThatHasItsLabelRemovedInTransaction() throws Exception { long nodeID = createNode(); - try ( Transaction ignore = graphDatabaseAPI.beginTx(); - Statement statement = statement() ) + try ( Transaction ignore = graphDatabaseAPI.beginTx() ) { - statement.dataWriteOperations().nodeRemoveLabel( nodeID, LABEL_ID ); - assertFalse( seek( statement ).hasNext() ); + KernelTransaction ktx = ktx(); + ktx.dataWrite().nodeRemoveLabel( nodeID, LABEL_ID ); + try ( NodeValueIndexCursor cursor = seek( ktx ) ) + { + assertFalse( cursor.next() ); + } } } @@ -221,11 +229,14 @@ public void shouldNotSeeNodeThatHasItsLabelRemovedInTransaction() throws Excepti public void shouldNotSeeNodeThatHasAPropertyRemovedInTransaction() throws Exception { long nodeID = createNode(); - try ( Transaction ignore = graphDatabaseAPI.beginTx(); - Statement statement = statement() ) + try ( Transaction ignore = graphDatabaseAPI.beginTx() ) { - statement.dataWriteOperations().nodeRemoveProperty( nodeID, index.schema().getPropertyIds()[0] ); - assertFalse( seek( statement ).hasNext() ); + KernelTransaction ktx = ktx(); + ktx.dataWrite().nodeRemoveProperty( nodeID, index.schema().getPropertyIds()[0] ); + try ( NodeValueIndexCursor cursor = seek( ktx ) ) + { + assertFalse( cursor.next() ); + } } } @@ -234,14 +245,20 @@ public void shouldSeeAllNodesAddedInTransaction() throws Exception { if ( index.type() != UNIQUE ) // this test does not make any sense for UNIQUE indexes { - try ( Transaction ignore = graphDatabaseAPI.beginTx(); - Statement statement = statement() ) + try ( Transaction ignore = graphDatabaseAPI.beginTx() ) { long nodeID1 = createNode(); long nodeID2 = createNode(); long nodeID3 = createNode(); - PrimitiveLongIterator resultIterator = seek( statement ); - Set result = PrimitiveLongCollections.toSet( resultIterator ); + KernelTransaction ktx = ktx(); + Set result = new HashSet<>( ); + try ( NodeValueIndexCursor cursor = seek( ktx ) ) + { + while ( cursor.next() ) + { + result.add( cursor.nodeReference() ); + } + } assertThat( result, containsInAnyOrder( nodeID1, nodeID2, nodeID3 ) ); } } @@ -255,11 +272,17 @@ public void shouldSeeAllNodesAddedBeforeTransaction() throws Exception long nodeID1 = createNode(); long nodeID2 = createNode(); long nodeID3 = createNode(); - try ( Transaction ignore = graphDatabaseAPI.beginTx(); - Statement statement = statement() ) + try ( Transaction ignore = graphDatabaseAPI.beginTx() ) { - PrimitiveLongIterator resultIterator = seek( statement ); - Set result = PrimitiveLongCollections.toSet( resultIterator ); + KernelTransaction ktx = ktx(); + Set result = new HashSet<>( ); + try ( NodeValueIndexCursor cursor = seek( ktx ) ) + { + while ( cursor.next() ) + { + result.add( cursor.nodeReference() ); + } + } assertThat( result, containsInAnyOrder( nodeID1, nodeID2, nodeID3 ) ); } } @@ -269,48 +292,54 @@ public void shouldSeeAllNodesAddedBeforeTransaction() throws Exception public void shouldNotSeeNodesLackingOneProperty() throws Exception { long nodeID1 = createNode(); - try ( Transaction ignore = graphDatabaseAPI.beginTx(); - Statement statement = statement() ) + try ( Transaction ignore = graphDatabaseAPI.beginTx() ) { - DataWriteOperations writeOperations = statement.dataWriteOperations(); - long irrelevantNodeID = writeOperations.nodeCreate(); - writeOperations.nodeAddLabel( irrelevantNodeID, LABEL_ID ); + KernelTransaction ktx = ktx(); + Write write = ktx.dataWrite(); + long irrelevantNodeID = write.nodeCreate(); + write.nodeAddLabel( irrelevantNodeID, LABEL_ID ); int[] propertyIds = index.schema().getPropertyIds(); for ( int i = 0; i < propertyIds.length - 1; i++ ) { int propID = propertyIds[i]; - writeOperations.nodeSetProperty( irrelevantNodeID, propID, Values.intValue( propID ) ); + write.nodeSetProperty( irrelevantNodeID, propID, Values.intValue( propID ) ); + } + Set result = new HashSet<>( ); + try ( NodeValueIndexCursor cursor = seek( ktx ) ) + { + while ( cursor.next() ) + { + result.add( cursor.nodeReference() ); + } } - PrimitiveLongIterator resultIterator = seek( statement ); - Set result = PrimitiveLongCollections.toSet( resultIterator ); assertThat( result, contains( nodeID1 ) ); } } private long createNode() - throws InvalidTransactionTypeKernelException, EntityNotFoundException, ConstraintValidationException, - AutoIndexingKernelException + throws KernelException { long nodeID; - try ( Transaction tx = graphDatabaseAPI.beginTx() ; - Statement statement = statement() ) + try ( Transaction tx = graphDatabaseAPI.beginTx() ) { - DataWriteOperations writeOperations = statement.dataWriteOperations(); - nodeID = writeOperations.nodeCreate(); - writeOperations.nodeAddLabel( nodeID, LABEL_ID ); + KernelTransaction ktx = ktx(); + Write write = ktx.dataWrite(); + nodeID = write.nodeCreate(); + write.nodeAddLabel( nodeID, LABEL_ID ); for ( int propID : index.schema().getPropertyIds() ) { - writeOperations.nodeSetProperty( nodeID, propID, Values.intValue( propID ) ); + write.nodeSetProperty( nodeID, propID, Values.intValue( propID ) ); } tx.success(); } return nodeID; } - private PrimitiveLongIterator seek( Statement statement ) throws IndexNotFoundKernelException, - IndexNotApplicableKernelException + private NodeValueIndexCursor seek( KernelTransaction transaction ) throws KernelException { - return statement.readOperations().indexQuery( index, exactQuery() ); + NodeValueIndexCursor cursor = transaction.cursors().allocateNodeValueIndexCursor(); + transaction.dataRead().nodeIndexSeek( fromDescriptor( index ), cursor, IndexOrder.NONE, exactQuery() ); + return cursor; } private IndexQuery[] exactQuery() @@ -325,10 +354,6 @@ private IndexQuery[] exactQuery() return query; } - private Statement statement() - { - return graphDatabaseAPI.getDependencyResolver().resolveDependency( ThreadToStatementContextBridge.class ).get(); - } private KernelTransaction ktx() { diff --git a/community/kernel/src/test/java/org/neo4j/kernel/api/TransactionStatementSequenceTest.java b/community/kernel/src/test/java/org/neo4j/kernel/api/TransactionStatementSequenceTest.java index 90e710bb5f04a..02d055486b06f 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/api/TransactionStatementSequenceTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/api/TransactionStatementSequenceTest.java @@ -36,10 +36,10 @@ public void shouldAllowReadStatementAfterReadStatement() { // given KernelTransaction tx = kernelTransaction( AnonymousContext.read() ); - tx.acquireStatement().readOperations(); + tx.dataRead(); // when / then - tx.acquireStatement().readOperations(); + tx.dataRead(); } @Test @@ -47,10 +47,10 @@ public void shouldAllowDataStatementAfterReadStatement() throws Exception { // given KernelTransaction tx = kernelTransaction( AnonymousContext.write() ); - tx.acquireStatement().readOperations(); + tx.dataRead(); // when / then - tx.acquireStatement().dataWriteOperations(); + tx.dataWrite(); } @Test @@ -58,10 +58,10 @@ public void shouldAllowSchemaStatementAfterReadStatement() throws Exception { // given KernelTransaction tx = kernelTransaction( AUTH_DISABLED ); - tx.acquireStatement().readOperations(); + tx.dataRead(); // when / then - tx.acquireStatement().schemaWriteOperations(); + tx.schemaWrite(); } @Test @@ -69,12 +69,12 @@ public void shouldRejectSchemaStatementAfterDataStatement() throws Exception { // given KernelTransaction tx = kernelTransaction( AUTH_DISABLED ); - tx.acquireStatement().dataWriteOperations(); + tx.dataWrite(); // when try { - tx.acquireStatement().schemaWriteOperations(); + tx.schemaWrite(); fail( "expected exception" ); } @@ -91,12 +91,12 @@ public void shouldRejectDataStatementAfterSchemaStatement() throws Exception { // given KernelTransaction tx = kernelTransaction( AUTH_DISABLED ); - tx.acquireStatement().schemaWriteOperations(); + tx.schemaWrite(); // when try { - tx.acquireStatement().dataWriteOperations(); + tx.dataWrite(); fail( "expected exception" ); } @@ -113,10 +113,10 @@ public void shouldAllowDataStatementAfterDataStatement() throws Exception { // given KernelTransaction tx = kernelTransaction( AnonymousContext.write() ); - tx.acquireStatement().dataWriteOperations(); + tx.dataWrite(); // when / then - tx.acquireStatement().dataWriteOperations(); + tx.dataWrite(); } @Test @@ -124,10 +124,10 @@ public void shouldAllowSchemaStatementAfterSchemaStatement() throws Exception { // given KernelTransaction tx = kernelTransaction( AUTH_DISABLED ); - tx.acquireStatement().schemaWriteOperations(); + tx.schemaWrite(); // when / then - tx.acquireStatement().schemaWriteOperations(); + tx.schemaWrite(); } @Test @@ -135,10 +135,10 @@ public void shouldAllowReadStatementAfterDataStatement() throws Exception { // given KernelTransaction tx = kernelTransaction( AnonymousContext.write() ); - tx.acquireStatement().dataWriteOperations(); + tx.dataWrite(); // when / then - tx.acquireStatement().readOperations(); + tx.dataRead(); } @Test @@ -146,9 +146,9 @@ public void shouldAllowReadStatementAfterSchemaStatement() throws Exception { // given KernelTransaction tx = kernelTransaction( AUTH_DISABLED ); - tx.acquireStatement().schemaWriteOperations(); + tx.schemaWrite(); // when / then - tx.acquireStatement().readOperations(); + tx.dataRead(); } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/api/TransactionStatementSharingTest.java b/community/kernel/src/test/java/org/neo4j/kernel/api/TransactionStatementSharingTest.java deleted file mode 100644 index 42f8515832f87..0000000000000 --- a/community/kernel/src/test/java/org/neo4j/kernel/api/TransactionStatementSharingTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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 . - */ -package org.neo4j.kernel.api; - -import org.junit.Test; - -import org.neo4j.kernel.api.security.AnonymousContext; - -import static org.junit.Assert.assertSame; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.verify; -import static org.neo4j.kernel.api.KernelTransactionFactory.kernelTransaction; -import static org.neo4j.internal.kernel.api.security.LoginContext.AUTH_DISABLED; - -public class TransactionStatementSharingTest -{ - @Test - public void shouldShareStatementStateForConcurrentReadStatementAndReadStatement() - { - // given - KernelTransaction tx = kernelTransaction( AnonymousContext.read() ); - ReadOperations stmt1 = tx.acquireStatement().readOperations(); - - // when - ReadOperations stmt2 = tx.acquireStatement().readOperations(); - - // then - assertSame( stmt1, stmt2 ); - } - - @Test - public void shouldShareStatementStateForConcurrentReadStatementAndDataStatement() throws Exception - { - // given - KernelTransaction tx = kernelTransaction( AnonymousContext.write() ); - ReadOperations stmt1 = tx.acquireStatement().readOperations(); - - // when - DataWriteOperations stmt2 = tx.acquireStatement().dataWriteOperations(); - - // then - assertSame( stmt1, stmt2 ); - } - - @Test - public void shouldShareStatementStateForConcurrentReadStatementAndSchemaStatement() throws Exception - { - // given - KernelTransaction tx = kernelTransaction( AUTH_DISABLED ); - ReadOperations stmt1 = tx.acquireStatement().readOperations(); - - // when - SchemaWriteOperations stmt2 = tx.acquireStatement().schemaWriteOperations(); - - // then - assertSame( stmt1, stmt2 ); - } - - @Test - public void shouldShareStatementStateForConcurrentDataStatementAndReadStatement() throws Exception - { - // given - KernelTransaction tx = kernelTransaction( AnonymousContext.write() ); - DataWriteOperations stmt1 = tx.acquireStatement().dataWriteOperations(); - - // when - ReadOperations stmt2 = tx.acquireStatement().readOperations(); - - // then - assertSame( stmt1, stmt2 ); - } - - @Test - public void shouldShareStatementStateForConcurrentDataStatementAndDataStatement() throws Exception - { - // given - KernelTransaction tx = kernelTransaction( AnonymousContext.write() ); - DataWriteOperations stmt1 = tx.acquireStatement().dataWriteOperations(); - - // when - DataWriteOperations stmt2 = tx.acquireStatement().dataWriteOperations(); - - // then - assertSame( stmt1, stmt2 ); - } - - @Test - public void shouldShareStatementStateForConcurrentSchemaStatementAndReadStatement() throws Exception - { - // given - KernelTransaction tx = kernelTransaction( AUTH_DISABLED ); - SchemaWriteOperations stmt1 = tx.acquireStatement().schemaWriteOperations(); - - // when - ReadOperations stmt2 = tx.acquireStatement().readOperations(); - - // then - assertSame( stmt1, stmt2 ); - } - - @Test - public void shouldShareStatementStateForConcurrentSchemaStatementAndSchemaStatement() throws Exception - { - // given - KernelTransaction tx = kernelTransaction( AUTH_DISABLED ); - SchemaWriteOperations stmt1 = tx.acquireStatement().schemaWriteOperations(); - - // when - SchemaWriteOperations stmt2 = tx.acquireStatement().schemaWriteOperations(); - - // then - assertSame( stmt1, stmt2 ); - } - - @Test - public void shouldNotShareStateForSequentialReadStatementAndReadStatement() - { - // given - KernelTransactionFactory.Instances instances = - KernelTransactionFactory.kernelTransactionWithInternals( AnonymousContext.read() ); - KernelTransaction tx = instances.transaction; - Statement statement = tx.acquireStatement(); - ReadOperations ops1 = statement.readOperations(); - verify( instances.storageStatement ).acquire(); - statement.close(); - - // when - verify( instances.storageStatement ).release(); - reset( instances.storageStatement ); - ReadOperations ops2 = tx.acquireStatement().readOperations(); - - // then - verify( instances.storageStatement ).acquire(); - } -} diff --git a/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInProceduresTest.java b/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInProceduresTest.java index af50b1bdf46a3..e60d9e8bae60e 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInProceduresTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/builtinprocs/BuiltInProceduresTest.java @@ -22,6 +22,7 @@ import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import java.util.HashMap; @@ -37,6 +38,8 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.helpers.collection.Iterators; import org.neo4j.helpers.collection.MapUtil; +import org.neo4j.internal.kernel.api.CapableIndexReference; +import org.neo4j.internal.kernel.api.IndexReference; import org.neo4j.internal.kernel.api.InternalIndexState; import org.neo4j.internal.kernel.api.NamedToken; import org.neo4j.internal.kernel.api.Read; @@ -46,7 +49,6 @@ import org.neo4j.internal.kernel.api.procs.ProcedureSignature; import org.neo4j.internal.kernel.api.security.SecurityContext; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.ReadOperations; import org.neo4j.kernel.api.ResourceTracker; import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.StubResourceManager; @@ -55,9 +57,9 @@ import org.neo4j.kernel.api.proc.Key; import org.neo4j.kernel.api.schema.constaints.ConstraintDescriptor; import org.neo4j.kernel.api.schema.constaints.ConstraintDescriptorFactory; -import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; -import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptorFactory; import org.neo4j.kernel.impl.api.index.inmemory.InMemoryIndexProviderFactory; +import org.neo4j.kernel.impl.api.store.DefaultCapableIndexReference; +import org.neo4j.kernel.impl.api.store.DefaultIndexReference; import org.neo4j.kernel.impl.factory.Edition; import org.neo4j.kernel.impl.proc.Procedures; import org.neo4j.kernel.internal.GraphDatabaseAPI; @@ -83,15 +85,14 @@ public class BuiltInProceduresTest { - private final List indexes = new LinkedList<>(); - private final List uniqueIndexes = new LinkedList<>(); + private final List indexes = new LinkedList<>(); + private final List uniqueIndexes = new LinkedList<>(); private final List constraints = new LinkedList<>(); private final Map labels = new HashMap<>(); private final Map propKeys = new HashMap<>(); private final Map relTypes = new HashMap<>(); private final Read read = mock( Read.class ); - private final ReadOperations readOperations = mock( ReadOperations.class ); private final TokenRead tokens = mock( TokenRead.class ); private final SchemaRead schemaRead = mock( SchemaRead.class ); private final Statement statement = mock( Statement.class ); @@ -413,7 +414,7 @@ private void givenIndex( String label, String propKey ) int labelId = token( label, labels ); int propId = token( propKey, propKeys ); - SchemaIndexDescriptor index = SchemaIndexDescriptorFactory.forLabel( labelId, propId ); + IndexReference index = DefaultIndexReference.general( labelId, propId ); indexes.add( index ); } @@ -422,7 +423,7 @@ private void givenUniqueConstraint( String label, String propKey ) int labelId = token( label, labels ); int propId = token( propKey, propKeys ); - SchemaIndexDescriptor index = SchemaIndexDescriptorFactory.uniqueForLabel( labelId, propId ); + IndexReference index = DefaultIndexReference.unique( labelId, propId ); uniqueIndexes.add( index ); constraints.add( ConstraintDescriptorFactory.uniqueForLabel( labelId, propId ) ); } @@ -493,15 +494,39 @@ public void setup() throws Exception when( tx.tokenRead() ).thenReturn( tokens ); when( tx.dataRead() ).thenReturn( read ); when( tx.schemaRead() ).thenReturn( schemaRead ); - when( statement.readOperations() ).thenReturn( readOperations ); when( tokens.propertyKeyGetAllTokens() ).thenAnswer( asTokens( propKeys ) ); when( tokens.labelsGetAllTokens() ).thenAnswer( asTokens( labels ) ); when( tokens.relationshipTypesGetAllTokens() ).thenAnswer( asTokens( relTypes ) ); - when( readOperations.indexesGetAll() ).thenAnswer( + when( schemaRead.indexesGetAll() ).thenAnswer( i -> Iterators.concat( indexes.iterator(), uniqueIndexes.iterator() ) ); + when( schemaRead.index( anyInt(), anyInt() )).thenAnswer( new Answer() + { + @Override + public CapableIndexReference answer( InvocationOnMock invocationOnMock ) throws Throwable + { + int label = invocationOnMock.getArgument( 0 ); + int prop = invocationOnMock.getArgument( 1 ); + for ( IndexReference index : indexes ) + { + if ( index.label() == label && prop == index.properties()[0] ) + { + return new DefaultCapableIndexReference( index.isUnique(), null, + InMemoryIndexProviderFactory.PROVIDER_DESCRIPTOR, label, prop ); + } + } + for ( IndexReference index : uniqueIndexes ) + { + if ( index.label() == label && prop == index.properties()[0] ) + { + return new DefaultCapableIndexReference( index.isUnique(), null, + InMemoryIndexProviderFactory.PROVIDER_DESCRIPTOR, label, prop ); + } + } + throw new AssertionError( ); + } + } ); when( schemaRead.constraintsGetAll() ).thenAnswer( i -> constraints.iterator() ); - when( readOperations.proceduresGetAll() ).thenReturn( procs.getAllProcedures() ); when( tokens.propertyKeyName( anyInt() ) ) .thenAnswer( invocation -> propKeys.get( invocation.getArgument( 0 ) ) ); @@ -517,9 +542,7 @@ public void setup() throws Exception when( schemaRead.constraintsGetForLabel( anyInt() ) ).thenReturn( emptyIterator() ); when( read.countsForNode( anyInt() ) ).thenReturn( 1L ); when( read.countsForRelationship( anyInt(), anyInt(), anyInt() ) ).thenReturn( 1L ); - when( readOperations.indexGetState( any( SchemaIndexDescriptor.class ) ) ).thenReturn( InternalIndexState.ONLINE ); - when( readOperations.indexGetProviderDescriptor( any( SchemaIndexDescriptor.class ) ) ) - .thenReturn( InMemoryIndexProviderFactory.PROVIDER_DESCRIPTOR ); + when( schemaRead.indexGetState( any( IndexReference.class ) ) ).thenReturn( InternalIndexState.ONLINE ); } private Answer> asTokens( Map tokens ) diff --git a/community/kernel/src/test/java/org/neo4j/kernel/counts/RelationshipCountsTest.java b/community/kernel/src/test/java/org/neo4j/kernel/counts/RelationshipCountsTest.java index 8a13467ac7a5c..b5d31060a69da 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/counts/RelationshipCountsTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/counts/RelationshipCountsTest.java @@ -32,6 +32,8 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.Transaction; +import org.neo4j.internal.kernel.api.TokenRead; +import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.ReadOperations; import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.impl.api.operations.KeyReadOperations; @@ -52,13 +54,14 @@ public class RelationshipCountsTest public final DatabaseRule db = new ImpermanentDatabaseRule(); @Rule public final ThreadingRule threading = new ThreadingRule(); - private Supplier statementSupplier; + private Supplier ktxSupplier; @Before public void exposeGuts() { - statementSupplier = db.getGraphDatabaseAPI().getDependencyResolver() - .resolveDependency( ThreadToStatementContextBridge.class ); + ktxSupplier = () -> db.getGraphDatabaseAPI().getDependencyResolver() + .resolveDependency( ThreadToStatementContextBridge.class ) + .getKernelTransactionBoundToThisThread( true ); } @Test @@ -395,9 +398,10 @@ private long numberOfRelationshipsMatching( Label lhs, RelationshipType type, La */ private long countsForRelationship( Label start, RelationshipType type, Label end ) { - try ( Statement statement = statementSupplier.get() ) + KernelTransaction ktx = ktxSupplier.get(); + try ( Statement ignore = ktx.acquireStatement() ) { - ReadOperations read = statement.readOperations(); + TokenRead tokenRead = ktx.tokenRead(); int startId; int typeId; int endId; @@ -408,7 +412,7 @@ private long countsForRelationship( Label start, RelationshipType type, Label en } else { - if ( KeyReadOperations.NO_SUCH_LABEL == (startId = read.labelGetForName( start.name() )) ) + if ( KeyReadOperations.NO_SUCH_LABEL == (startId = tokenRead.nodeLabel( start.name() )) ) { return 0; } @@ -420,7 +424,7 @@ private long countsForRelationship( Label start, RelationshipType type, Label en } else { - if ( KeyReadOperations.NO_SUCH_LABEL == (typeId = read.relationshipTypeGetForName( type.name() )) ) + if ( KeyReadOperations.NO_SUCH_LABEL == (typeId = tokenRead.relationshipType( type.name() )) ) { return 0; } @@ -432,12 +436,12 @@ private long countsForRelationship( Label start, RelationshipType type, Label en } else { - if ( KeyReadOperations.NO_SUCH_LABEL == (endId = read.labelGetForName( end.name() )) ) + if ( KeyReadOperations.NO_SUCH_LABEL == (endId = tokenRead.nodeLabel( end.name() )) ) { return 0; } } - return read.countsForRelationship( startId, typeId, endId ); + return ktx.dataRead().countsForRelationship( startId, typeId, endId ); } } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelSchemaStateFlushingTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelSchemaStateFlushingTest.java index 17126f802cf18..71897b719c13a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelSchemaStateFlushingTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelSchemaStateFlushingTest.java @@ -26,6 +26,7 @@ import java.util.concurrent.locks.LockSupport; +import org.neo4j.internal.kernel.api.IndexReference; import org.neo4j.internal.kernel.api.exceptions.KernelException; import org.neo4j.internal.kernel.api.schema.constraints.ConstraintDescriptor; import org.neo4j.kernel.api.InwardKernel; @@ -34,7 +35,6 @@ import org.neo4j.kernel.api.exceptions.TransactionFailureException; import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; -import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.impl.api.index.SchemaIndexTestHelper; import org.neo4j.kernel.internal.GraphDatabaseAPI; import org.neo4j.test.rule.ImpermanentDatabaseRule; @@ -85,13 +85,13 @@ public void shouldInvalidateSchemaStateOnCreateIndex() throws Exception @Test public void shouldInvalidateSchemaStateOnDropIndex() throws Exception { - SchemaIndexDescriptor descriptor = createIndex(); + IndexReference ref = createIndex(); - awaitIndexOnline( descriptor, "test" ); + awaitIndexOnline( ref, "test" ); commitToSchemaState( "test", "before" ); - dropIndex( descriptor ); + dropIndex( ref ); // when String after = commitToSchemaState( "test", "after" ); @@ -155,35 +155,35 @@ private void dropConstraint( ConstraintDescriptor descriptor ) throws KernelExce } } - private SchemaIndexDescriptor createIndex() throws KernelException + private IndexReference createIndex() throws KernelException { try ( KernelTransaction transaction = kernel.newTransaction( KernelTransaction.Type.implicit, AUTH_DISABLED ); - Statement statement = transaction.acquireStatement() ) + Statement ignore = transaction.acquireStatement() ) { - SchemaIndexDescriptor descriptor = statement.schemaWriteOperations().indexCreate( + IndexReference reference = transaction.schemaWrite().indexCreate( SchemaDescriptorFactory.forLabel( 1, 1 ) ); transaction.success(); - return descriptor; + return reference; } } - private void dropIndex( SchemaIndexDescriptor descriptor ) throws KernelException + private void dropIndex( IndexReference reference ) throws KernelException { try ( KernelTransaction transaction = kernel.newTransaction( KernelTransaction.Type.implicit, AUTH_DISABLED ); - Statement statement = transaction.acquireStatement() ) + Statement ignore = transaction.acquireStatement() ) { - statement.schemaWriteOperations().indexDrop( descriptor ); + transaction.schemaWrite().indexDrop( reference ); transaction.success(); } } - private void awaitIndexOnline( SchemaIndexDescriptor descriptor, String keyForProbing ) + private void awaitIndexOnline( IndexReference descriptor, String keyForProbing ) throws IndexNotFoundKernelException, TransactionFailureException { try ( KernelTransaction transaction = kernel.newTransaction( KernelTransaction.Type.implicit, AUTH_DISABLED ); - Statement statement = transaction.acquireStatement() ) + Statement ignore = transaction.acquireStatement() ) { - SchemaIndexTestHelper.awaitIndexOnline( statement.readOperations(), descriptor ); + SchemaIndexTestHelper.awaitIndexOnline( transaction.schemaRead(), descriptor ); transaction.success(); } awaitSchemaStateCleared( keyForProbing ); @@ -192,9 +192,9 @@ private void awaitIndexOnline( SchemaIndexDescriptor descriptor, String keyForPr private void awaitSchemaStateCleared( String keyForProbing ) throws TransactionFailureException { try ( KernelTransaction transaction = kernel.newTransaction( KernelTransaction.Type.implicit, AUTH_DISABLED ); - Statement statement = transaction.acquireStatement() ) + Statement ignore = transaction.acquireStatement() ) { - while ( statement.readOperations().schemaStateGetOrCreate( keyForProbing, ignored -> null ) != null ) + while ( transaction.schemaRead().schemaStateGetOrCreate( keyForProbing, ignored -> null ) != null ) { LockSupport.parkNanos( MILLISECONDS.toNanos( 10 ) ); } @@ -214,9 +214,9 @@ private String commitToSchemaState( String key, String value ) throws Transactio private String getOrCreateFromState( KernelTransaction tx, String key, final String value ) { - try ( Statement statement = tx.acquireStatement() ) + try ( Statement ignore = tx.acquireStatement() ) { - return statement.readOperations().schemaStateGetOrCreate( key, from -> value ); + return tx.schemaRead().schemaStateGetOrCreate( key, from -> value ); } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionSecurityContextTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionSecurityContextTest.java index 95d5cf0eac6a0..76c2b24d96f12 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionSecurityContextTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionSecurityContextTest.java @@ -25,10 +25,8 @@ import org.neo4j.graphdb.security.AuthorizationViolationException; import org.neo4j.internal.kernel.api.Read; +import org.neo4j.internal.kernel.api.SchemaWrite; import org.neo4j.internal.kernel.api.Write; -import org.neo4j.kernel.api.DataWriteOperations; -import org.neo4j.kernel.api.ReadOperations; -import org.neo4j.kernel.api.SchemaWriteOperations; import org.neo4j.kernel.api.security.AnonymousContext; import static org.junit.Assert.assertNotNull; @@ -88,7 +86,7 @@ public void shouldNotAllowSchemaWritesInNoneMode() throws Throwable exception.expect( AuthorizationViolationException.class ); // When - tx.acquireStatement().schemaWriteOperations(); + tx.schemaWrite(); } @Test @@ -98,7 +96,7 @@ public void shouldAllowReadsInReadMode() KernelTransactionImplementation tx = newTransaction( AnonymousContext.read() ); // When - ReadOperations reads = tx.acquireStatement().readOperations(); + Read reads = tx.dataRead(); // Then assertNotNull( reads ); @@ -127,7 +125,7 @@ public void shouldNotAllowSchemaWriteAccessInReadMode() throws Throwable exception.expect( AuthorizationViolationException.class ); // When - tx.acquireStatement().schemaWriteOperations(); + tx.schemaWrite(); } @Test @@ -179,7 +177,7 @@ public void shouldNotAllowSchemaWriteAccessInWriteOnlyMode() throws Throwable exception.expect( AuthorizationViolationException.class ); // When - tx.acquireStatement().schemaWriteOperations(); + tx.schemaWrite(); } @Test @@ -218,7 +216,7 @@ public void shouldNotAllowSchemaWriteAccessInWriteMode() throws Throwable exception.expect( AuthorizationViolationException.class ); // When - tx.acquireStatement().schemaWriteOperations(); + tx.schemaWrite(); } @Test @@ -241,7 +239,7 @@ public void shouldAllowWritesInFullMode() throws Throwable KernelTransactionImplementation tx = newTransaction( AUTH_DISABLED ); // When - DataWriteOperations writes = tx.acquireStatement().dataWriteOperations(); + Write writes = tx.dataWrite(); // Then assertNotNull( writes ); @@ -254,7 +252,7 @@ public void shouldAllowSchemaWriteAccessInFullMode() throws Throwable KernelTransactionImplementation tx = newTransaction( AUTH_DISABLED ); // When - SchemaWriteOperations writes = tx.acquireStatement().schemaWriteOperations(); + SchemaWrite writes = tx.schemaWrite(); // Then assertNotNull( writes ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexCRUDIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexCRUDIT.java index db71b4cf6a3a8..ceac59c81fda6 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexCRUDIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexCRUDIT.java @@ -35,17 +35,17 @@ import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Transaction; +import org.neo4j.internal.kernel.api.TokenRead; import org.neo4j.internal.kernel.api.schema.LabelSchemaDescriptor; import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.io.pagecache.PageCache; -import org.neo4j.kernel.api.ReadOperations; -import org.neo4j.kernel.api.Statement; +import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.index.IndexAccessor; import org.neo4j.kernel.api.index.IndexEntryUpdate; import org.neo4j.kernel.api.index.IndexPopulator; +import org.neo4j.kernel.api.index.IndexProvider; import org.neo4j.kernel.api.index.IndexUpdater; import org.neo4j.kernel.api.index.PropertyAccessor; -import org.neo4j.kernel.api.index.IndexProvider; import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.extension.KernelExtensionFactory; @@ -87,12 +87,13 @@ public void addingANodeWithPropertyShouldGetIndexed() throws Exception Node node = createNode( map( indexProperty, value1, otherProperty, otherValue ), myLabel ); // Then, for now, this should trigger two NodePropertyUpdates - try ( Transaction tx = db.beginTx(); - Statement statement = ctxSupplier.get() ) + try ( Transaction tx = db.beginTx() ) { - ReadOperations readOperations = statement.readOperations(); - int propertyKey1 = readOperations.propertyKeyGetForName( indexProperty ); - int label = readOperations.labelGetForName( myLabel.name() ); + KernelTransaction ktx = + ctxSupplier.getKernelTransactionBoundToThisThread( true ); + TokenRead tokenRead = ktx.tokenRead(); + int propertyKey1 = tokenRead.propertyKey( indexProperty ); + int label = tokenRead.nodeLabel( myLabel.name() ); LabelSchemaDescriptor descriptor = SchemaDescriptorFactory.forLabel( label, propertyKey1 ); assertThat( writer.updatesCommitted, equalTo( asSet( IndexEntryUpdate.add( node.getId(), descriptor, Values.of( value1 ) ) ) ) ); @@ -128,12 +129,13 @@ public void addingALabelToPreExistingNodeShouldGetIndexed() throws Exception } // THEN - try ( Transaction tx = db.beginTx(); - Statement statement = ctxSupplier.get() ) + try ( Transaction tx = db.beginTx() ) { - ReadOperations readOperations = statement.readOperations(); - int propertyKey1 = readOperations.propertyKeyGetForName( indexProperty ); - int label = readOperations.labelGetForName( myLabel.name() ); + KernelTransaction ktx = + ctxSupplier.getKernelTransactionBoundToThisThread( true ); + TokenRead tokenRead = ktx.tokenRead(); + int propertyKey1 = tokenRead.propertyKey( indexProperty ); + int label = tokenRead.nodeLabel( myLabel.name() ); LabelSchemaDescriptor descriptor = SchemaDescriptorFactory.forLabel( label, propertyKey1 ); assertThat( writer.updatesCommitted, equalTo( asSet( IndexEntryUpdate.add( node.getId(), descriptor, Values.of( value ) ) ) ) ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexPopulationJobTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexPopulationJobTest.java index a0ae6be8d7b6e..0f45217e3bc94 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexPopulationJobTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexPopulationJobTest.java @@ -655,9 +655,9 @@ private long createNode( Map properties, Label... labels ) private int getPropertyKeyForName( String name ) throws TransactionFailureException { try ( KernelTransaction tx = kernel.newTransaction( KernelTransaction.Type.implicit, AnonymousContext.read() ); - Statement statement = tx.acquireStatement() ) + Statement ignore = tx.acquireStatement() ) { - int result = statement.readOperations().propertyKeyGetForName( name ); + int result = tx.tokenRead().propertyKey( name ); tx.success(); return result; } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexRecoveryIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexRecoveryIT.java index 9e1385c464beb..0a73898a3b3f4 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexRecoveryIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexRecoveryIT.java @@ -41,7 +41,7 @@ import org.neo4j.internal.kernel.api.schema.LabelSchemaDescriptor; import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.io.pagecache.PageCache; -import org.neo4j.kernel.api.Statement; +import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.index.IndexAccessor; import org.neo4j.kernel.api.index.IndexEntryUpdate; import org.neo4j.kernel.api.index.IndexPopulator; @@ -335,17 +335,17 @@ private Set> createSomeBananas( Label label ) { ThreadToStatementContextBridge ctxSupplier = db.getDependencyResolver().resolveDependency( ThreadToStatementContextBridge.class ); - try ( Statement statement = ctxSupplier.get() ) + KernelTransaction ktx = + ctxSupplier.getKernelTransactionBoundToThisThread( true ); + + int labelId = ktx.tokenRead().nodeLabel( label.name() ); + int propertyKeyId = ktx.tokenRead().propertyKey( key ); + LabelSchemaDescriptor schemaDescriptor = SchemaDescriptorFactory.forLabel( labelId, propertyKeyId ); + for ( int number : new int[]{4, 10} ) { - int labelId = statement.readOperations().labelGetForName( label.name() ); - int propertyKeyId = statement.readOperations().propertyKeyGetForName( key ); - LabelSchemaDescriptor schemaDescriptor = SchemaDescriptorFactory.forLabel( labelId, propertyKeyId ); - for ( int number : new int[] {4, 10} ) - { - Node node = db.createNode( label ); - node.setProperty( key, number ); - updates.add( IndexEntryUpdate.add( node.getId(), schemaDescriptor, Values.of( number ) ) ); - } + Node node = db.createNode( label ); + node.setProperty( key, number ); + updates.add( IndexEntryUpdate.add( node.getId(), schemaDescriptor, Values.of( number ) ) ); } tx.success(); return updates; diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexStatisticsIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexStatisticsIT.java index 94fee0acb2d7c..9167ef3719d2c 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexStatisticsIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexStatisticsIT.java @@ -33,7 +33,7 @@ import org.neo4j.graphdb.mockfs.EphemeralFileSystemAbstraction; import org.neo4j.graphdb.mockfs.UncloseableDelegatingFileSystemAbstraction; import org.neo4j.graphdb.schema.IndexDefinition; -import org.neo4j.kernel.api.Statement; +import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptorFactory; import org.neo4j.kernel.impl.api.CountsAccessor; @@ -139,27 +139,25 @@ private void assertLogExistsForRecoveryOn( String labelAndProperty ) private int labelId( Label alien ) { - try ( Transaction ignore = db.beginTx(); - Statement statement = statement() ) + try ( Transaction ignore = db.beginTx() ) { - return statement.readOperations().labelGetForName( alien.name() ); + return ktx().tokenRead().nodeLabel( alien.name() ); } } private int pkId( String propertyName ) { - try ( Transaction ignore = db.beginTx(); - Statement statement = statement() ) + try ( Transaction ignore = db.beginTx() ) { - return statement.readOperations().propertyKeyGetForName( propertyName ); + return ktx().tokenRead().propertyKey( propertyName ); } } - private Statement statement() + private KernelTransaction ktx() { - return ( (GraphDatabaseAPI) db ).getDependencyResolver() - .resolveDependency( ThreadToStatementContextBridge.class ) - .get(); + return ((GraphDatabaseAPI) db).getDependencyResolver() + .resolveDependency( ThreadToStatementContextBridge.class ) + .getKernelTransactionBoundToThisThread( true ); } private void createAliens() diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexStatisticsTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexStatisticsTest.java index addd3d767eeb5..35cb73664631b 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexStatisticsTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexStatisticsTest.java @@ -46,13 +46,15 @@ import org.neo4j.graphdb.NotFoundException; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.factory.GraphDatabaseSettings; +import org.neo4j.internal.kernel.api.IndexReference; import org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException; import org.neo4j.internal.kernel.api.exceptions.KernelException; import org.neo4j.internal.kernel.api.schema.LabelSchemaDescriptor; +import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; -import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; +import org.neo4j.kernel.impl.api.store.DefaultIndexReference; import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.impl.storageengine.impl.recordstorage.RecordStorageEngine; import org.neo4j.kernel.impl.store.NeoStores; @@ -71,6 +73,7 @@ import static org.junit.Assert.fail; import static org.junit.runners.Parameterized.Parameter; import static org.junit.runners.Parameterized.Parameters; +import static org.neo4j.kernel.api.schema.SchemaDescriptorFactory.forLabel; /** * This test validates that we count the correct amount of index updates. @@ -149,7 +152,7 @@ public void shouldProvideIndexStatisticsForDataCreatedWhenPopulationBeforeTheInd createSomePersons(); // when - SchemaIndexDescriptor index = createIndex( "Person", "name" ); + IndexReference index = createIndex( "Person", "name" ); awaitIndexesOnline(); // then @@ -162,7 +165,7 @@ public void shouldProvideIndexStatisticsForDataCreatedWhenPopulationBeforeTheInd public void shouldNotSeeDataCreatedAfterPopulation() throws KernelException { // given - SchemaIndexDescriptor index = createIndex( "Person", "name" ); + IndexReference index = createIndex( "Person", "name" ); awaitIndexesOnline(); // when @@ -180,7 +183,7 @@ public void shouldProvideIndexStatisticsForDataSeenDuringPopulationAndIgnoreData { // given createSomePersons(); - SchemaIndexDescriptor index = createIndex( "Person", "name" ); + IndexReference index = createIndex( "Person", "name" ); awaitIndexesOnline(); // when @@ -197,11 +200,11 @@ public void shouldRemoveIndexStatisticsAfterIndexIsDeleted() throws KernelExcept { // given createSomePersons(); - SchemaIndexDescriptor index = createIndex( "Person", "name" ); + IndexReference index = createIndex( "Person", "name" ); awaitIndexesOnline(); SchemaStorage storage = new SchemaStorage( neoStores().getSchemaStore() ); - long indexId = storage.indexGetForSchema( index ).getId(); + long indexId = storage.indexGetForSchema( DefaultIndexReference.toDescriptor( index ) ).getId(); // when dropIndex( index ); @@ -230,7 +233,7 @@ public void shouldProvideIndexSelectivityWhenThereAreManyDuplicates() throws Exc int created = repeatCreateNamedPeopleFor( NAMES.length * CREATION_MULTIPLIER ).length; // when - SchemaIndexDescriptor index = createIndex( "Person", "name" ); + IndexReference index = createIndex( "Person", "name" ); awaitIndexesOnline(); // then @@ -247,7 +250,7 @@ public void shouldProvideIndexStatisticsWhenIndexIsBuiltViaPopulationAndConcurre int initialNodes = repeatCreateNamedPeopleFor( NAMES.length * CREATION_MULTIPLIER ).length; // when populating while creating - SchemaIndexDescriptor index = createIndex( "Person", "name" ); + IndexReference index = createIndex( "Person", "name" ); final UpdatesTracker updatesTracker = executeCreations( index, CREATION_MULTIPLIER ); awaitIndexesOnline(); @@ -267,7 +270,7 @@ public void shouldProvideIndexStatisticsWhenIndexIsBuiltViaPopulationAndConcurre int initialNodes = nodes.length; // when populating while creating - SchemaIndexDescriptor index = createIndex( "Person", "name" ); + IndexReference index = createIndex( "Person", "name" ); UpdatesTracker updatesTracker = executeCreationsAndDeletions( nodes, index, CREATION_MULTIPLIER ); awaitIndexesOnline(); @@ -289,7 +292,7 @@ public void shouldProvideIndexStatisticsWhenIndexIsBuiltViaPopulationAndConcurre int initialNodes = nodes.length; // when populating while creating - SchemaIndexDescriptor index = createIndex( "Person", "name" ); + IndexReference index = createIndex( "Person", "name" ); UpdatesTracker updatesTracker = executeCreationsAndUpdates( nodes, index, CREATION_MULTIPLIER ); awaitIndexesOnline(); @@ -310,7 +313,7 @@ public void shouldProvideIndexStatisticsWhenIndexIsBuiltViaPopulationAndConcurre int initialNodes = nodes.length; // when populating while creating - SchemaIndexDescriptor index = createIndex( "Person", "name" ); + IndexReference index = createIndex( "Person", "name" ); UpdatesTracker updatesTracker = executeCreationsDeletionsAndUpdates( nodes, index, CREATION_MULTIPLIER ); awaitIndexesOnline(); @@ -333,7 +336,7 @@ public void shouldWorkWhileHavingHeavyConcurrentUpdates() throws Exception ExecutorService executorService = Executors.newFixedThreadPool( threads ); // when populating while creating - final SchemaIndexDescriptor index = createIndex( "Person", "name" ); + final IndexReference index = createIndex( "Person", "name" ); final Collection> jobs = new ArrayList<>( threads ); for ( int i = 0; i < threads; i++ ) @@ -468,48 +471,47 @@ private long[] repeatCreateNamedPeopleFor( int totalNumberOfPeople ) throws Exce return nodes; } - private void dropIndex( SchemaIndexDescriptor index ) throws KernelException + private void dropIndex( IndexReference index ) throws KernelException { try ( Transaction tx = db.beginTx() ) { - try ( Statement statement = bridge.get() ) + KernelTransaction ktx = bridge.getKernelTransactionBoundToThisThread( true ); + try ( Statement ignore = ktx.acquireStatement() ) { - statement.schemaWriteOperations().indexDrop( index ); + ktx.schemaWrite().indexDrop( index ); } tx.success(); } } - private long indexSize( SchemaIndexDescriptor descriptor ) throws KernelException + private long indexSize( IndexReference reference ) throws KernelException { return ((GraphDatabaseAPI) db).getDependencyResolver() .resolveDependency( IndexingService.class ) - .indexUpdatesAndSize( descriptor.schema() ).readSecond(); + .indexUpdatesAndSize( forLabel( reference.label(), reference.properties() ) ).readSecond(); } - private long indexUpdates( SchemaIndexDescriptor descriptor ) throws KernelException + private long indexUpdates( IndexReference reference ) throws KernelException { return ((GraphDatabaseAPI) db).getDependencyResolver() .resolveDependency( IndexingService.class ) - .indexUpdatesAndSize( descriptor.schema() ).readFirst(); + .indexUpdatesAndSize( forLabel( reference.label(), reference.properties() ) ).readFirst(); } - private double indexSelectivity( SchemaIndexDescriptor descriptor ) throws KernelException + private double indexSelectivity( IndexReference reference ) throws KernelException { try ( Transaction tx = db.beginTx() ) { - double selectivity = getSelectivity( descriptor ); + double selectivity = getSelectivity( reference ); tx.success(); return selectivity; } } - private double getSelectivity( SchemaIndexDescriptor descriptor ) throws IndexNotFoundKernelException + private double getSelectivity( IndexReference reference ) throws IndexNotFoundKernelException { - try ( Statement statement = bridge.get() ) - { - return statement.readOperations().indexUniqueValuesSelectivity( descriptor ); - } + + return bridge.getKernelTransactionBoundToThisThread( true ).schemaRead().indexUniqueValuesSelectivity( reference ); } private CountsTracker getTracker() @@ -544,17 +546,18 @@ private long createNode( Statement statement, String labelName, String propertyK return nodeId; } - private SchemaIndexDescriptor createIndex( String labelName, String propertyKeyName ) throws KernelException + private IndexReference createIndex( String labelName, String propertyKeyName ) throws KernelException { try ( Transaction tx = db.beginTx() ) { - SchemaIndexDescriptor index; - try ( Statement statement = bridge.get() ) + IndexReference index; + KernelTransaction ktx = bridge.getKernelTransactionBoundToThisThread( true ); + try ( Statement ignore = ktx.acquireStatement() ) { - int labelId = statement.tokenWriteOperations().labelGetOrCreateForName( labelName ); - int propertyKeyId = statement.tokenWriteOperations().propertyKeyGetOrCreateForName( propertyKeyName ); - LabelSchemaDescriptor descriptor = SchemaDescriptorFactory.forLabel( labelId, propertyKeyId ); - index = statement.schemaWriteOperations().indexCreate( descriptor ); + int labelId = ktx.tokenWrite().labelGetOrCreateForName( labelName ); + int propertyKeyId = ktx.tokenWrite().propertyKeyGetOrCreateForName( propertyKeyName ); + LabelSchemaDescriptor descriptor = forLabel( labelId, propertyKeyId ); + index = ktx.schemaWrite().indexCreate( descriptor ); } tx.success(); return index; @@ -575,34 +578,34 @@ private void awaitIndexesOnline() } } - private UpdatesTracker executeCreations( SchemaIndexDescriptor index, int numberOfCreations ) throws KernelException + private UpdatesTracker executeCreations( IndexReference index, int numberOfCreations ) throws KernelException { return internalExecuteCreationsDeletionsAndUpdates( null, index, numberOfCreations, false, false ); } private UpdatesTracker executeCreationsAndDeletions( long[] nodes, - SchemaIndexDescriptor index, + IndexReference index, int numberOfCreations ) throws KernelException { return internalExecuteCreationsDeletionsAndUpdates( nodes, index, numberOfCreations, true, false ); } private UpdatesTracker executeCreationsAndUpdates( long[] nodes, - SchemaIndexDescriptor index, + IndexReference index, int numberOfCreations ) throws KernelException { return internalExecuteCreationsDeletionsAndUpdates( nodes, index, numberOfCreations, false, true ); } private UpdatesTracker executeCreationsDeletionsAndUpdates( long[] nodes, - SchemaIndexDescriptor index, + IndexReference index, int numberOfCreations ) throws KernelException { return internalExecuteCreationsDeletionsAndUpdates( nodes, index, numberOfCreations, true, true ); } private UpdatesTracker internalExecuteCreationsDeletionsAndUpdates( long[] nodes, - SchemaIndexDescriptor index, + IndexReference index, int numberOfCreations, boolean allowDeletions, boolean allowUpdates ) throws KernelException @@ -656,7 +659,7 @@ private UpdatesTracker internalExecuteCreationsDeletionsAndUpdates( long[] nodes return updatesTracker; } - private void notifyIfPopulationCompleted( SchemaIndexDescriptor index, UpdatesTracker updatesTracker ) + private void notifyIfPopulationCompleted( IndexReference index, UpdatesTracker updatesTracker ) { if ( isCompletedPopulation( index, updatesTracker ) ) { @@ -664,7 +667,7 @@ private void notifyIfPopulationCompleted( SchemaIndexDescriptor index, UpdatesTr } } - private boolean isCompletedPopulation( SchemaIndexDescriptor index, UpdatesTracker updatesTracker ) + private boolean isCompletedPopulation( IndexReference index, UpdatesTracker updatesTracker ) { return !updatesTracker.isPopulationCompleted() && indexOnlineMonitor.isIndexOnline( index ); @@ -721,15 +724,15 @@ private static void assertCorrectIndexSelectivity( double expected, double actua private static class IndexOnlineMonitor extends IndexingService.MonitorAdapter { - private final Set onlineIndexes = Collections.newSetFromMap( new ConcurrentHashMap<>() ); + private final Set onlineIndexes = Collections.newSetFromMap( new ConcurrentHashMap<>() ); @Override public void populationCompleteOn( SchemaIndexDescriptor descriptor ) { - onlineIndexes.add( descriptor ); + onlineIndexes.add( DefaultIndexReference.fromDescriptor( descriptor ) ); } - public boolean isIndexOnline( SchemaIndexDescriptor descriptor ) + public boolean isIndexOnline( IndexReference descriptor ) { return onlineIndexes.contains( descriptor ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/SchemaIndexTestHelper.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/SchemaIndexTestHelper.java index 1f9cbd0c863cd..6a5b822d97ace 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/SchemaIndexTestHelper.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/SchemaIndexTestHelper.java @@ -25,11 +25,11 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; +import org.neo4j.internal.kernel.api.IndexReference; import org.neo4j.internal.kernel.api.InternalIndexState; -import org.neo4j.kernel.api.ReadOperations; +import org.neo4j.internal.kernel.api.SchemaRead; import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; import org.neo4j.kernel.api.index.IndexProvider; -import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.extension.KernelExtensionFactory; import org.neo4j.kernel.impl.spi.KernelContext; @@ -109,13 +109,13 @@ public static boolean awaitLatch( CountDownLatch latch ) } } - public static void awaitIndexOnline( ReadOperations readOperations, SchemaIndexDescriptor index ) + public static void awaitIndexOnline( SchemaRead schemaRead, IndexReference index ) throws IndexNotFoundKernelException { long start = System.currentTimeMillis(); while ( true ) { - if ( readOperations.indexGetState( index ) == InternalIndexState.ONLINE ) + if ( schemaRead.indexGetState( index ) == InternalIndexState.ONLINE ) { break; } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/KernelIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/KernelIT.java index 9e6328208d90f..484cb710eb4bb 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/KernelIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/KernelIT.java @@ -23,35 +23,30 @@ import org.junit.Test; import java.util.Collections; +import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import org.neo4j.collection.primitive.PrimitiveIntCollections; -import org.neo4j.collection.primitive.PrimitiveIntSet; -import org.neo4j.collection.primitive.PrimitiveLongCollections; -import org.neo4j.collection.primitive.PrimitiveLongIterator; -import org.neo4j.cursor.Cursor; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.TransactionFailureException; import org.neo4j.internal.kernel.api.IndexReference; +import org.neo4j.internal.kernel.api.LabelSet; +import org.neo4j.internal.kernel.api.NodeCursor; +import org.neo4j.internal.kernel.api.NodeLabelIndexCursor; import org.neo4j.internal.kernel.api.SchemaWrite; import org.neo4j.internal.kernel.api.TokenWrite; -import org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException; import org.neo4j.internal.kernel.api.exceptions.InvalidTransactionTypeKernelException; import org.neo4j.internal.kernel.api.exceptions.schema.SchemaKernelException; import org.neo4j.internal.kernel.api.schema.LabelSchemaDescriptor; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.impl.transaction.log.TransactionIdStore; import org.neo4j.kernel.internal.GraphDatabaseAPI; -import org.neo4j.storageengine.api.NodeItem; -import static java.util.Collections.emptySet; import static java.util.concurrent.TimeUnit.SECONDS; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -59,7 +54,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static org.neo4j.graphdb.Label.label; import static org.neo4j.internal.kernel.api.security.LoginContext.AUTH_DISABLED; import static org.neo4j.kernel.api.schema.SchemaDescriptorFactory.forLabel; @@ -74,18 +68,18 @@ public void mixingBeansApiWithKernelAPI() throws Exception // 1: Start your transactions through the Beans API Transaction transaction = db.beginTx(); - // 2: Get a hold of a KernelAPI statement context for the *current* transaction this way: - Statement statement = statementContextSupplier.get(); + // 2: Get a hold of a KernelAPI transaction this way: + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); // 3: Now you can interact through both the statement context and the kernel API to manipulate the // same transaction. Node node = db.createNode(); - int labelId = statement.tokenWriteOperations().labelGetOrCreateForName( "labello" ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId ); + int labelId = ktx.tokenWrite().labelGetOrCreateForName( "labello" ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId ); // 4: Close the StatementContext - statement.close(); + ktx.close(); // 5: Commit through the beans API transaction.success(); @@ -97,13 +91,12 @@ public void mixingBeansApiWithKernelAPIForNestedTransaction() throws Exception { // GIVEN Transaction outerTx = db.beginTx(); - Statement statement = statementContextSupplier.get(); + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); // WHEN Node node = db.createNode(); - int labelId = statement.tokenWriteOperations().labelGetOrCreateForName( "labello" ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId ); - statement.close(); + int labelId = ktx.tokenWrite().labelGetOrCreateForName( "labello" ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId ); outerTx.close(); } @@ -115,26 +108,23 @@ public void changesInTransactionContextShouldBeRolledBackWhenTxIsRolledBack() th int labelId; try ( Transaction tx = db.beginTx() ) { - Statement statement = statementContextSupplier.get(); + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); // WHEN node = db.createNode(); - labelId = statement.tokenWriteOperations().labelGetOrCreateForName( "labello" ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId ); - statement.close(); + labelId = ktx.tokenWrite().labelGetOrCreateForName( "labello" ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId ); } // THEN try ( Transaction tx = db.beginTx() ) { - try ( Statement statement = statementContextSupplier.get() ) + KernelTransaction ktx = + statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + try ( NodeCursor cursor = ktx.cursors().allocateNodeCursor() ) { - statement.readOperations().nodeHasLabel( node.getId(), labelId ); - fail( "should have thrown exception" ); - } - catch ( EntityNotFoundException e ) - { - // Yay! + ktx.dataRead().singleNode( node.getId(), cursor ); + assertFalse( cursor.next() ); } } } @@ -148,11 +138,10 @@ public void shouldNotBeAbleToCommitIfFailedTransactionContext() throws Exception TransactionFailureException expectedException = null; try ( Transaction transaction = db.beginTx() ) { - Statement statement = statementContextSupplier.get(); + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); node = db.createNode(); - labelId = statement.tokenWriteOperations().labelGetOrCreateForName( "labello" ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId ); - statement.close(); + labelId = ktx.tokenWrite().labelGetOrCreateForName( "labello" ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId ); transaction.failure(); transaction.success(); } @@ -166,17 +155,13 @@ public void shouldNotBeAbleToCommitIfFailedTransactionContext() throws Exception } // THEN - try ( Transaction tx = db.beginTx(); - Statement statement = statementContextSupplier.get() ) + try ( Transaction ignore = db.beginTx() ) { - try - { - statement.readOperations().nodeHasLabel( node.getId(), labelId ); - fail( "should have thrown exception" ); - } - catch ( EntityNotFoundException e ) + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + try ( NodeCursor cursor = ktx.cursors().allocateNodeCursor() ) { - // Yay! + ktx.dataRead().singleNode( node.getId(), cursor ); + assertFalse( cursor.next() ); } } } @@ -189,25 +174,28 @@ public void transactionStateShouldRemovePreviouslyAddedLabel() throws Exception int labelId1; int labelId2; Node node = db.createNode(); - try ( Statement statement = statementContextSupplier.get() ) - { - // WHEN - labelId1 = statement.tokenWriteOperations().labelGetOrCreateForName( "labello1" ); - labelId2 = statement.tokenWriteOperations().labelGetOrCreateForName( "labello2" ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId1 ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId2 ); - statement.dataWriteOperations().nodeRemoveLabel( node.getId(), labelId2 ); - } + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + // WHEN + labelId1 = ktx.tokenWrite().labelGetOrCreateForName( "labello1" ); + labelId2 = ktx.tokenWrite().labelGetOrCreateForName( "labello2" ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId1 ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId2 ); + ktx.dataWrite().nodeRemoveLabel( node.getId(), labelId2 ); tx.success(); tx.close(); // THEN tx = db.beginTx(); - try ( Statement statement = statementContextSupplier.get() ) + ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + try ( NodeCursor cursor = ktx.cursors().allocateNodeCursor() ) { - assertEquals( PrimitiveIntCollections.asSet( new int[]{labelId1} ), - PrimitiveIntCollections.asSet( statement.readOperations().nodeGetLabels( node.getId() ) ) ); + ktx.dataRead().singleNode( node.getId(), cursor ); + assertTrue( cursor.next() ); + LabelSet labels = cursor.labels(); + assertThat( labels.numberOfLabels(), equalTo( 1 ) ); + assertThat( labels.label( 0 ), equalTo( labelId1 ) ); } + tx.close(); } @@ -215,22 +203,28 @@ public void transactionStateShouldRemovePreviouslyAddedLabel() throws Exception public void transactionStateShouldReflectRemovingAddedLabelImmediately() throws Exception { Transaction tx = db.beginTx(); - Statement statement = statementContextSupplier.get(); + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); // WHEN Node node = db.createNode(); - int labelId1 = statement.tokenWriteOperations().labelGetOrCreateForName( "labello1" ); - int labelId2 = statement.tokenWriteOperations().labelGetOrCreateForName( "labello2" ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId1 ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId2 ); - statement.dataWriteOperations().nodeRemoveLabel( node.getId(), labelId2 ); + int labelId1 = ktx.tokenWrite().labelGetOrCreateForName( "labello1" ); + int labelId2 = ktx.tokenWrite().labelGetOrCreateForName( "labello2" ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId1 ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId2 ); + ktx.dataWrite().nodeRemoveLabel( node.getId(), labelId2 ); // THEN - assertFalse( statement.readOperations().nodeHasLabel( node.getId(), labelId2 ) ); - assertEquals( PrimitiveIntCollections.asSet( new int[]{labelId1} ), - PrimitiveIntCollections.asSet( statement.readOperations().nodeGetLabels( node.getId() ) ) ); + try ( NodeCursor cursor = ktx.cursors().allocateNodeCursor() ) + { + ktx.dataRead().singleNode( node.getId(), cursor ); + assertTrue( cursor.next() ); + LabelSet labels = cursor.labels(); + assertThat( labels.numberOfLabels(), equalTo( 1 ) ); + assertFalse( labels.contains( labelId2 ) ); + assertTrue( labels.contains( labelId1 ) ); + } - statement.close(); + ktx.close(); tx.success(); tx.close(); } @@ -241,28 +235,34 @@ public void transactionStateShouldReflectRemovingLabelImmediately() throws Excep // GIVEN Transaction tx = db.beginTx(); - Statement statement = statementContextSupplier.get(); + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); Node node = db.createNode(); - int labelId1 = statement.tokenWriteOperations().labelGetOrCreateForName( "labello1" ); - int labelId2 = statement.tokenWriteOperations().labelGetOrCreateForName( "labello2" ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId1 ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId2 ); - statement.close(); + int labelId1 = ktx.tokenWrite().labelGetOrCreateForName( "labello1" ); + int labelId2 = ktx.tokenWrite().labelGetOrCreateForName( "labello2" ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId1 ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId2 ); tx.success(); tx.close(); tx = db.beginTx(); - statement = statementContextSupplier.get(); + ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); // WHEN - statement.dataWriteOperations().nodeRemoveLabel( node.getId(), labelId2 ); + ktx.dataWrite().nodeRemoveLabel( node.getId(), labelId2 ); // THEN - PrimitiveIntSet labels = PrimitiveIntCollections.asSet( - statement.readOperations().nodeGetLabels( node.getId() ) ); - assertFalse( statement.readOperations().nodeHasLabel( node.getId(), labelId2 ) ); - assertEquals( PrimitiveIntCollections.asSet( new int[]{labelId1} ), labels ); - statement.close(); + // THEN + try ( NodeCursor cursor = ktx.cursors().allocateNodeCursor() ) + { + ktx.dataRead().singleNode( node.getId(), cursor ); + assertTrue( cursor.next() ); + LabelSet labels = cursor.labels(); + assertThat( labels.numberOfLabels(), equalTo( 1 ) ); + assertFalse( labels.contains( labelId2 ) ); + assertTrue( labels.contains( labelId1 ) ); + } + + ktx.close(); tx.success(); tx.close(); } @@ -272,33 +272,32 @@ public void labelShouldBeRemovedAfterCommit() throws Exception { // GIVEN Transaction tx = db.beginTx(); - Statement statement = statementContextSupplier.get(); + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); Node node = db.createNode(); - int labelId1 = statement.tokenWriteOperations().labelGetOrCreateForName( "labello1" ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId1 ); - statement.close(); + int labelId1 = ktx.tokenWrite().labelGetOrCreateForName( "labello1" ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId1 ); tx.success(); tx.close(); // WHEN tx = db.beginTx(); - statement = statementContextSupplier.get(); - statement.dataWriteOperations().nodeRemoveLabel( node.getId(), labelId1 ); - statement.close(); + ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + ktx.dataWrite().nodeRemoveLabel( node.getId(), labelId1 ); tx.success(); tx.close(); // THEN tx = db.beginTx(); - statement = statementContextSupplier.get(); - Set labels = PrimitiveIntCollections.toSet( - statement.readOperations().nodeGetLabels( node.getId() ) ); + ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + try ( NodeCursor cursor = ktx.cursors().allocateNodeCursor() ) + { + ktx.dataRead().singleNode( node.getId(), cursor ); + assertTrue( cursor.next() ); + assertThat( cursor.labels().numberOfLabels(), equalTo( 0 ) ); + } - statement.close(); tx.success(); tx.close(); - - assertThat( labels, equalTo( Collections.emptySet() ) ); } @Test @@ -308,21 +307,16 @@ public void addingNewLabelToNodeShouldRespondTrue() throws Exception Transaction tx = db.beginTx(); Node node = db.createNode(); int labelId; - try ( Statement statement = statementContextSupplier.get() ) - { - labelId = statement.tokenWriteOperations().labelGetOrCreateForName( "mylabel" ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId ); - } + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + labelId = ktx.tokenWrite().labelGetOrCreateForName( "mylabel" ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId ); tx.success(); tx.close(); // WHEN tx = db.beginTx(); - boolean added; - try ( Statement statement = statementContextSupplier.get() ) - { - added = statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId ); - } + ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + boolean added = ktx.dataWrite().nodeAddLabel( node.getId(), labelId ); tx.close(); // THEN @@ -336,20 +330,18 @@ public void addingExistingLabelToNodeShouldRespondFalse() throws Exception Transaction tx = db.beginTx(); Node node = db.createNode(); int labelId; - try ( Statement statement = statementContextSupplier.get() ) - { - labelId = statement.tokenWriteOperations().labelGetOrCreateForName( "mylabel" ); - } + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + labelId = ktx.tokenWrite().labelGetOrCreateForName( "mylabel" ); + tx.success(); tx.close(); // WHEN tx = db.beginTx(); - boolean added; - try ( Statement statement = statementContextSupplier.get() ) - { - added = statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId ); - } + ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + + boolean added = ktx.dataWrite().nodeAddLabel( node.getId(), labelId ); + tx.close(); // THEN @@ -362,22 +354,18 @@ public void removingExistingLabelFromNodeShouldRespondTrue() throws Exception // GIVEN Transaction tx = db.beginTx(); Node node = db.createNode(); - int labelId; - try ( Statement statement = statementContextSupplier.get() ) - { - labelId = statement.tokenWriteOperations().labelGetOrCreateForName( "mylabel" ); - statement.dataWriteOperations().nodeAddLabel( node.getId(), labelId ); - } + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + + int labelId = ktx.tokenWrite().labelGetOrCreateForName( "mylabel" ); + ktx.dataWrite().nodeAddLabel( node.getId(), labelId ); + tx.success(); tx.close(); // WHEN tx = db.beginTx(); - boolean removed; - try ( Statement statement = statementContextSupplier.get() ) - { - removed = statement.dataWriteOperations().nodeRemoveLabel( node.getId(), labelId ); - } + ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + boolean removed = ktx.dataWrite().nodeRemoveLabel( node.getId(), labelId ); // THEN assertTrue( "Should have been removed now", removed ); @@ -391,20 +379,15 @@ public void removingNonExistentLabelFromNodeShouldRespondFalse() throws Exceptio Transaction tx = db.beginTx(); Node node = db.createNode(); int labelId; - try ( Statement statement = statementContextSupplier.get() ) - { - labelId = statement.tokenWriteOperations().labelGetOrCreateForName( "mylabel" ); - } + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + labelId = ktx.tokenWrite().labelGetOrCreateForName( "mylabel" ); tx.success(); tx.close(); // WHEN tx = db.beginTx(); - boolean removed; - try ( Statement statement = statementContextSupplier.get() ) - { - removed = statement.dataWriteOperations().nodeRemoveLabel( node.getId(), labelId ); - } + ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + boolean removed = ktx.dataWrite().nodeRemoveLabel( node.getId(), labelId ); // THEN assertFalse( "Shouldn't have been removed now", removed ); @@ -422,41 +405,28 @@ public void deletingNodeWithLabelsShouldHaveThoseLabelRemovalsReflectedInTransac tx.close(); tx = db.beginTx(); - Statement statement = statementContextSupplier.get(); + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); // WHEN - statement.dataWriteOperations().nodeDelete( node.getId() ); + ktx.dataWrite().nodeDelete( node.getId() ); // Then - int labelId = statement.readOperations().labelGetForName( label.name() ); - try - { - statement.readOperations().nodeGetLabels( node.getId() ); - fail(); - } - catch ( EntityNotFoundException e ) + int labelId = ktx.tokenRead().nodeLabel( label.name() ); + try ( NodeCursor nodeCursor = ktx.cursors().allocateNodeCursor() ) { - // Ok + ktx.dataRead().singleNode( node.getId(), nodeCursor ); + assertFalse( nodeCursor.next() ); } - try + try ( NodeLabelIndexCursor nodeCursor = ktx.cursors().allocateNodeLabelIndexCursor() ) { - statement.readOperations().nodeHasLabel( node.getId(), labelId ); - fail(); + ktx.dataRead().nodeLabelScan( labelId, nodeCursor ); + assertFalse( nodeCursor.next() ); } - catch ( EntityNotFoundException e ) - { - // Ok - } - - Set nodes = PrimitiveLongCollections.toSet( statement.readOperations().nodesGetForLabel( labelId ) ); - - statement.close(); + ktx.close(); tx.success(); tx.close(); - - assertEquals( emptySet(), nodes ); } @Test @@ -477,12 +447,17 @@ public void deletingNodeWithLabelsShouldHaveRemovalReflectedInLabelScans() // WHEN tx = db.beginTx(); - Set nodeSet; - try ( Statement statement = statementContextSupplier.get() ) + Set nodeSet = new HashSet<>(); + KernelTransaction ktx = + statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + try ( NodeLabelIndexCursor nodes = ktx.cursors().allocateNodeLabelIndexCursor() ) { - int labelId = statement.readOperations().labelGetForName( label.name() ); - PrimitiveLongIterator nodes = statement.readOperations().nodesGetForLabel( labelId ); - nodeSet = PrimitiveLongCollections.toSet( nodes ); + int labelId = ktx.tokenRead().nodeLabel( label.name() ); + ktx.dataRead().nodeLabelScan( labelId, nodes ); + while ( nodes.next() ) + { + nodeSet.add( nodes.nodeReference() ); + } } tx.success(); tx.close(); @@ -533,7 +508,7 @@ public void schemaStateShouldBeEvictedOnIndexDropped() throws Exception // THEN schema state should be immediately updated (this works because the schema cache is updated during // transaction apply, while the schema lock is held). - assertFalse( schemaStateContains("my key") ); + assertFalse( schemaStateContains( "my key" ) ); } @Test @@ -542,10 +517,7 @@ public void txReturnsCorrectIdWhenCommitted() throws Exception executeDummyTxs( db, 42 ); KernelTransaction tx = kernel.newTransaction( KernelTransaction.Type.implicit, AUTH_DISABLED ); - try ( Statement statement = tx.acquireStatement() ) - { - statement.dataWriteOperations().nodeCreate(); - } + tx.dataWrite().nodeCreate(); tx.success(); long previousCommittedTxId = lastCommittedTxId( db ); @@ -560,10 +532,7 @@ public void txReturnsCorrectIdWhenRolledBack() throws Exception executeDummyTxs( db, 42 ); KernelTransaction tx = kernel.newTransaction( KernelTransaction.Type.implicit, AUTH_DISABLED ); - try ( Statement statement = tx.acquireStatement() ) - { - statement.dataWriteOperations().nodeCreate(); - } + tx.dataWrite().nodeCreate(); tx.failure(); assertEquals( KernelTransaction.ROLLBACK, tx.closeTransaction() ); @@ -576,10 +545,7 @@ public void txReturnsCorrectIdWhenMarkedForTermination() throws Exception executeDummyTxs( db, 42 ); KernelTransaction tx = kernel.newTransaction( KernelTransaction.Type.implicit, AUTH_DISABLED ); - try ( Statement statement = tx.acquireStatement() ) - { - statement.dataWriteOperations().nodeCreate(); - } + tx.dataWrite().nodeCreate(); tx.markForTermination( Status.Transaction.Terminated ); assertEquals( KernelTransaction.ROLLBACK, tx.closeTransaction() ); @@ -592,10 +558,7 @@ public void txReturnsCorrectIdWhenFailedlAndMarkedForTermination() throws Except executeDummyTxs( db, 42 ); KernelTransaction tx = kernel.newTransaction( KernelTransaction.Type.implicit, AUTH_DISABLED ); - try ( Statement statement = tx.acquireStatement() ) - { - statement.dataWriteOperations().nodeCreate(); - } + tx.dataWrite().nodeCreate(); tx.failure(); tx.markForTermination( Status.Transaction.Terminated ); @@ -609,9 +572,9 @@ public void txReturnsCorrectIdWhenReadOnly() throws Exception executeDummyTxs( db, 42 ); KernelTransaction tx = kernel.newTransaction( KernelTransaction.Type.implicit, AUTH_DISABLED ); - try ( Statement statement = tx.acquireStatement(); - Cursor cursor = statement.readOperations().nodeCursorById( 1 ) ) + try ( NodeCursor cursor = tx.cursors().allocateNodeCursor() ) { + tx.dataRead().singleNode( 1L, cursor ); } tx.success(); @@ -643,16 +606,17 @@ private IndexReference createIndex( KernelTransaction transaction ) TokenWrite tokenWrite = transaction.tokenWrite(); SchemaWrite schemaWrite = transaction.schemaWrite(); LabelSchemaDescriptor schemaDescriptor = forLabel( tokenWrite.labelGetOrCreateForName( "hello" ), - tokenWrite.propertyKeyGetOrCreateForName( "hepp" ) ); + tokenWrite.propertyKeyGetOrCreateForName( "hepp" ) ); return schemaWrite.indexCreate( schemaDescriptor ); } private String getOrCreateSchemaState( String key, final String maybeSetThisState ) { - try ( Transaction tx = db.beginTx(); - Statement statement = statementContextSupplier.get() ) + try ( Transaction tx = db.beginTx() ) { - String state = statement.readOperations().schemaStateGetOrCreate( key, s -> maybeSetThisState ); + KernelTransaction ktx = + statementContextSupplier.getKernelTransactionBoundToThisThread( true ); + String state = ktx.schemaRead().schemaStateGetOrCreate( key, s -> maybeSetThisState ); tx.success(); return state; } @@ -660,11 +624,11 @@ private String getOrCreateSchemaState( String key, final String maybeSetThisStat private boolean schemaStateContains( String key ) { - try ( Transaction tx = db.beginTx(); - Statement statement = statementContextSupplier.get() ) + try ( Transaction tx = db.beginTx() ) { + KernelTransaction ktx = statementContextSupplier.getKernelTransactionBoundToThisThread( true ); final AtomicBoolean result = new AtomicBoolean( true ); - statement.readOperations().schemaStateGetOrCreate( key, s -> + ktx.schemaRead().schemaStateGetOrCreate( key, s -> { result.set( false ); return null; diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/ProceduresKernelIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/ProceduresKernelIT.java index 18f2eaf243fc7..d8bd19bc57e8a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/ProceduresKernelIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/integrationtest/ProceduresKernelIT.java @@ -31,7 +31,6 @@ import org.neo4j.internal.kernel.api.procs.ProcedureSignature; import org.neo4j.internal.kernel.api.procs.QualifiedName; import org.neo4j.kernel.api.ResourceTracker; -import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.exceptions.TransactionFailureException; import org.neo4j.kernel.api.proc.CallableProcedure; import org.neo4j.kernel.api.proc.Context; @@ -136,18 +135,17 @@ public void shouldCallReadOnlyProcedure() throws Throwable } @Test - public void registeredProcedureShouldGetReadOperations() throws Throwable + public void registeredProcedureShouldGetRead() throws Throwable { // Given kernel.registerProcedure( new CallableProcedure.BasicProcedure( signature ) { @Override - public RawIterator apply( Context ctx, Object[] input, ResourceTracker resourceTracker ) throws ProcedureException + public RawIterator apply( Context ctx, Object[] input, + ResourceTracker resourceTracker ) throws ProcedureException { - try ( Statement statement = ctx.get( Context.KERNEL_TRANSACTION ).acquireStatement() ) - { - return RawIterator.of( new Object[]{statement.readOperations()} ); - } + return RawIterator.of( + new Object[]{ctx.get( Context.KERNEL_TRANSACTION ).dataRead()} ); } } ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorageLayerTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorageLayerTest.java index febfc46b390b1..ab085e1cb898b 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorageLayerTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorageLayerTest.java @@ -31,7 +31,7 @@ import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.Transaction; import org.neo4j.io.pagecache.tracing.cursor.context.EmptyVersionContextSupplier; -import org.neo4j.kernel.api.Statement; +import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.impl.api.ClockContext; import org.neo4j.kernel.impl.api.KernelStatement; import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; @@ -99,34 +99,31 @@ protected static Node createLabeledNode( GraphDatabaseService db, Map constraintsGetForSchema( SchemaDescriptor descriptor ) { diff --git a/community/neo4j/src/test/java/counts/RebuildCountsTest.java b/community/neo4j/src/test/java/counts/RebuildCountsTest.java index 9322b18e10d96..98428b79a853c 100644 --- a/community/neo4j/src/test/java/counts/RebuildCountsTest.java +++ b/community/neo4j/src/test/java/counts/RebuildCountsTest.java @@ -34,7 +34,6 @@ import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.mockfs.UncloseableDelegatingFileSystemAbstraction; import org.neo4j.io.fs.FileSystemAbstraction; -import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.impl.api.index.inmemory.InMemoryIndexProvider; import org.neo4j.kernel.impl.api.index.inmemory.InMemoryIndexProviderFactory; import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; @@ -142,10 +141,10 @@ private int labelId( Label alien ) { ThreadToStatementContextBridge contextBridge = ((GraphDatabaseAPI) db).getDependencyResolver() .resolveDependency( ThreadToStatementContextBridge.class ); - try ( Transaction tx = db.beginTx(); - Statement statement = contextBridge.get() ) + try ( Transaction tx = db.beginTx() ) { - return statement.readOperations().labelGetForName( alien.name() ); + return contextBridge.getKernelTransactionBoundToThisThread( true ) + .tokenRead().nodeLabel( alien.name() ); } } diff --git a/community/neo4j/src/test/java/migration/Start3_2DbOn3_3AndCreateFusionIndexIT.java b/community/neo4j/src/test/java/migration/Start3_2DbOn3_3AndCreateFusionIndexIT.java index 2322fe6a28570..28ed67bc4bb1f 100644 --- a/community/neo4j/src/test/java/migration/Start3_2DbOn3_3AndCreateFusionIndexIT.java +++ b/community/neo4j/src/test/java/migration/Start3_2DbOn3_3AndCreateFusionIndexIT.java @@ -34,14 +34,14 @@ import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.factory.GraphDatabaseFactory; import org.neo4j.graphdb.schema.IndexDefinition; +import org.neo4j.internal.kernel.api.CapableIndexReference; import org.neo4j.internal.kernel.api.IndexQuery; +import org.neo4j.internal.kernel.api.TokenRead; import org.neo4j.io.fs.FileUtils; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.ReadOperations; import org.neo4j.kernel.api.Statement; -import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; -import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.impl.api.KernelStatement; +import org.neo4j.kernel.impl.api.store.DefaultIndexReference; import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.internal.GraphDatabaseAPI; import org.neo4j.storageengine.api.StorageStatement; @@ -157,32 +157,36 @@ private void verifyIndexes( GraphDatabaseAPI db, Label label ) throws Exception private int countIndexedNodes( GraphDatabaseAPI db, Label label, String... keys ) throws Exception { - try ( Transaction tx = db.beginTx(); - KernelTransaction ktx = db.getDependencyResolver() - .resolveDependency( ThreadToStatementContextBridge.class ).getKernelTransactionBoundToThisThread( true ); - Statement statement = ktx.acquireStatement() ) + try ( Transaction tx = db.beginTx() ) { - ReadOperations read = statement.readOperations(); - int labelId = read.labelGetForName( label.name() ); - int[] propertyKeyIds = new int[keys.length]; - for ( int i = 0; i < keys.length; i++ ) - { - propertyKeyIds[i] = read.propertyKeyGetForName( keys[i] ); - } + KernelTransaction ktx = db.getDependencyResolver() + .resolveDependency( ThreadToStatementContextBridge.class ) + .getKernelTransactionBoundToThisThread( true ); - SchemaIndexDescriptor index = read.indexGetForSchema( SchemaDescriptorFactory.forLabel( labelId, propertyKeyIds ) ); - int count; - StorageStatement storeStatement = ((KernelStatement)statement).getStoreStatement(); - IndexReader reader = storeStatement.getIndexReader( index ); - IndexQuery[] predicates = new IndexQuery[propertyKeyIds.length]; - for ( int i = 0; i < propertyKeyIds.length; i++ ) + try ( Statement statement = ktx.acquireStatement() ) { - predicates[i] = IndexQuery.exists( propertyKeyIds[i] ); - } - count = count( reader.query( predicates ) ); + TokenRead tokenRead = ktx.tokenRead(); + int labelId = tokenRead.nodeLabel( label.name() ); + int[] propertyKeyIds = new int[keys.length]; + for ( int i = 0; i < keys.length; i++ ) + { + propertyKeyIds[i] = tokenRead.propertyKey( keys[i] ); + } - tx.success(); - return count; + CapableIndexReference index = ktx.schemaRead().index( labelId, propertyKeyIds ); + int count; + StorageStatement storeStatement = ((KernelStatement) statement).getStoreStatement(); + IndexReader reader = storeStatement.getIndexReader( DefaultIndexReference.toDescriptor( index ) ); + IndexQuery[] predicates = new IndexQuery[propertyKeyIds.length]; + for ( int i = 0; i < propertyKeyIds.length; i++ ) + { + predicates[i] = IndexQuery.exists( propertyKeyIds[i] ); + } + count = count( reader.query( predicates ) ); + + tx.success(); + return count; + } } } diff --git a/community/neo4j/src/test/java/org/neo4j/index/IndexSamplingIntegrationTest.java b/community/neo4j/src/test/java/org/neo4j/index/IndexSamplingIntegrationTest.java index 60f5e46802023..96db9b79958dd 100644 --- a/community/neo4j/src/test/java/org/neo4j/index/IndexSamplingIntegrationTest.java +++ b/community/neo4j/src/test/java/org/neo4j/index/IndexSamplingIntegrationTest.java @@ -31,8 +31,9 @@ import org.neo4j.graphdb.ResourceIterator; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.schema.IndexDefinition; +import org.neo4j.internal.kernel.api.TokenRead; import org.neo4j.io.fs.FileUtils; -import org.neo4j.kernel.api.ReadOperations; +import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; @@ -198,17 +199,21 @@ private long indexId( GraphDatabaseAPI api ) throws IndexNotFoundKernelException { ThreadToStatementContextBridge contextBridge = api.getDependencyResolver().resolveDependency( ThreadToStatementContextBridge.class ); - try ( Transaction tx = api.beginTx(); - Statement statement = contextBridge.get() ) + try ( Transaction tx = api.beginTx()) { - IndexingService indexingService = - api.getDependencyResolver().resolveDependency( IndexingService.class ); - ReadOperations readOperations = statement.readOperations(); - int labelId = readOperations.labelGetForName( label.name() ); - int propertyKeyId = readOperations.propertyKeyGetForName( property ); - long indexId = indexingService.getIndexId( SchemaDescriptorFactory.forLabel( labelId, propertyKeyId ) ); - tx.success(); - return indexId; + KernelTransaction ktx = + contextBridge.getKernelTransactionBoundToThisThread( true ); + try (Statement ignore = ktx.acquireStatement() ) + { + IndexingService indexingService = + api.getDependencyResolver().resolveDependency( IndexingService.class ); + TokenRead tokenRead = ktx.tokenRead(); + int labelId = tokenRead.nodeLabel( label.name() ); + int propertyKeyId = tokenRead.propertyKey( property ); + long indexId = indexingService.getIndexId( SchemaDescriptorFactory.forLabel( labelId, propertyKeyId ) ); + tx.success(); + return indexId; + } } } diff --git a/community/neo4j/src/test/java/org/neo4j/locking/QueryExecutionLocksIT.java b/community/neo4j/src/test/java/org/neo4j/locking/QueryExecutionLocksIT.java index c95653adf9c84..47156f12804c4 100644 --- a/community/neo4j/src/test/java/org/neo4j/locking/QueryExecutionLocksIT.java +++ b/community/neo4j/src/test/java/org/neo4j/locking/QueryExecutionLocksIT.java @@ -1167,10 +1167,9 @@ void lockAcquired( boolean exclusive, ResourceType resourceType, long... ids ) { ThreadToStatementContextBridge bridge = databaseRule.resolveDependency( ThreadToStatementContextBridge.class ); - try ( Statement statement = bridge.get() ) - { - statement.readOperations().schemaStateFlush(); - } + KernelTransaction ktx = + bridge.getKernelTransactionBoundToThisThread( true ); + ktx.schemaRead().schemaStateFlush(); } executed = true; } diff --git a/community/neo4j/src/test/java/schema/IndexPopulationFlipRaceIT.java b/community/neo4j/src/test/java/schema/IndexPopulationFlipRaceIT.java index 4d3e74e21dcf2..c969167610db4 100644 --- a/community/neo4j/src/test/java/schema/IndexPopulationFlipRaceIT.java +++ b/community/neo4j/src/test/java/schema/IndexPopulationFlipRaceIT.java @@ -26,12 +26,11 @@ import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Transaction; import org.neo4j.helpers.collection.Pair; +import org.neo4j.internal.kernel.api.IndexReference; import org.neo4j.kernel.api.InwardKernel; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.Statement; -import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; -import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptorFactory; import org.neo4j.kernel.api.security.AnonymousContext; +import org.neo4j.kernel.impl.api.store.DefaultIndexReference; import org.neo4j.test.rule.DatabaseRule; import org.neo4j.test.rule.EmbeddedDatabaseRule; import org.neo4j.test.rule.RandomRule; @@ -138,23 +137,22 @@ private void verifyThatThereAreExactlyOneIndexEntryPerNodeInTheIndexes( int i, P throws Exception { InwardKernel kernelAPI = db.getDependencyResolver().resolveDependency( InwardKernel.class ); - try ( KernelTransaction tx = kernelAPI.newTransaction( KernelTransaction.Type.implicit, AnonymousContext.read() ); - Statement statement = tx.acquireStatement() ) + try ( KernelTransaction tx = kernelAPI.newTransaction( KernelTransaction.Type.implicit, AnonymousContext.read() )) { - int labelAId = statement.readOperations().labelGetForName( labelA( i ).name() ); - int keyAId = statement.readOperations().propertyKeyGetForName( keyA( i ) ); - int labelBId = statement.readOperations().labelGetForName( labelB( i ).name() ); - int keyBId = statement.readOperations().propertyKeyGetForName( keyB( i ) ); - SchemaIndexDescriptor indexA = SchemaIndexDescriptorFactory.forLabel( labelAId, keyAId ); - SchemaIndexDescriptor indexB = SchemaIndexDescriptorFactory.forLabel( labelBId, keyBId ); + int labelAId = tx.tokenRead().nodeLabel( labelA( i ).name() ); + int keyAId = tx.tokenRead().propertyKey( keyA( i ) ); + int labelBId = tx.tokenRead().nodeLabel( labelB( i ).name() ); + int keyBId = tx.tokenRead().propertyKey( keyB( i ) ); + IndexReference indexA = DefaultIndexReference.general( labelAId, keyAId ); + IndexReference indexB = DefaultIndexReference.general( labelBId, keyBId ); for ( int j = 0; j < NODES_PER_INDEX; j++ ) { long nodeAId = data.first()[j]; - assertEquals( 1, statement.readOperations().nodesCountIndexed( + assertEquals( 1, tx.schemaRead().nodesCountIndexed( indexA, nodeAId, Values.of( nodeAId ) ) ); long nodeBId = data.other()[j]; - assertEquals( 1, statement.readOperations().nodesCountIndexed( + assertEquals( 1, tx.schemaRead().nodesCountIndexed( indexB, nodeBId, Values.of( nodeBId ) ) ); } } diff --git a/community/neo4j/src/test/java/schema/MultiIndexPopulationConcurrentUpdatesIT.java b/community/neo4j/src/test/java/schema/MultiIndexPopulationConcurrentUpdatesIT.java index 3b7ca0f0ca54f..87e8bb1512d5e 100644 --- a/community/neo4j/src/test/java/schema/MultiIndexPopulationConcurrentUpdatesIT.java +++ b/community/neo4j/src/test/java/schema/MultiIndexPopulationConcurrentUpdatesIT.java @@ -44,10 +44,10 @@ import org.neo4j.helpers.collection.Visitor; import org.neo4j.internal.kernel.api.InternalIndexState; import org.neo4j.internal.kernel.api.TokenNameLookup; +import org.neo4j.internal.kernel.api.TokenRead; import org.neo4j.internal.kernel.api.schema.LabelSchemaDescriptor; import org.neo4j.internal.kernel.api.schema.SchemaDescriptor; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.ReadOperations; import org.neo4j.kernel.api.SilentTokenNameLookup; import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.exceptions.index.IndexActivationFailedKernelException; @@ -398,12 +398,14 @@ private Map getLabelIdsByName( String... names ) { ThreadToStatementContextBridge transactionStatementContextBridge = getTransactionStatementContextBridge(); Map labelNameIdMap = new HashMap<>(); - try ( Statement statement = transactionStatementContextBridge.get() ) + KernelTransaction ktx = + transactionStatementContextBridge.getKernelTransactionBoundToThisThread( true ); + try ( Statement ignore = ktx.acquireStatement() ) { - ReadOperations readOperations = statement.readOperations(); + TokenRead tokenRead = ktx.tokenRead(); for ( String name : names ) { - labelNameIdMap.put( name, readOperations.labelGetForName( name ) ); + labelNameIdMap.put( name, tokenRead.nodeLabel( name ) ); } } return labelNameIdMap; @@ -412,10 +414,11 @@ private Map getLabelIdsByName( String... names ) private int getPropertyIdByName( String name ) { ThreadToStatementContextBridge transactionStatementContextBridge = getTransactionStatementContextBridge(); - try ( Statement statement = transactionStatementContextBridge.get() ) + KernelTransaction ktx = + transactionStatementContextBridge.getKernelTransactionBoundToThisThread( true ); + try ( Statement ignore = ktx.acquireStatement() ) { - ReadOperations readOperations = statement.readOperations(); - return readOperations.propertyKeyGetForName( name ); + return ktx.tokenRead().propertyKey( name ); } } diff --git a/enterprise/ha/src/test/java/org/neo4j/kernel/LabelIT.java b/enterprise/ha/src/test/java/org/neo4j/kernel/LabelIT.java index 22bc3995855e4..55b87acd70a75 100644 --- a/enterprise/ha/src/test/java/org/neo4j/kernel/LabelIT.java +++ b/enterprise/ha/src/test/java/org/neo4j/kernel/LabelIT.java @@ -26,7 +26,6 @@ import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Transaction; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.exceptions.TransactionFailureException; import org.neo4j.kernel.ha.HighlyAvailableGraphDatabase; import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; @@ -74,10 +73,7 @@ private static long getLabelId( HighlyAvailableGraphDatabase db, Label label ) try ( Transaction ignore = db.beginTx() ) { ThreadToStatementContextBridge bridge = threadToStatementContextBridgeFrom( db ); - try ( Statement statement = bridge.get() ) - { - return statement.readOperations().labelGetForName( label.name() ); - } + return bridge.getKernelTransactionBoundToThisThread( true ).tokenRead().nodeLabel( label.name() ); } } diff --git a/enterprise/ha/src/test/java/org/neo4j/kernel/ha/HaCountsIT.java b/enterprise/ha/src/test/java/org/neo4j/kernel/ha/HaCountsIT.java index a809d45fc5464..f659b7324e2f2 100644 --- a/enterprise/ha/src/test/java/org/neo4j/kernel/ha/HaCountsIT.java +++ b/enterprise/ha/src/test/java/org/neo4j/kernel/ha/HaCountsIT.java @@ -28,12 +28,14 @@ import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.schema.IndexDefinition; +import org.neo4j.internal.kernel.api.IndexReference; import org.neo4j.internal.kernel.api.exceptions.KernelException; import org.neo4j.kernel.api.KernelTransaction; import org.neo4j.kernel.api.Statement; import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.impl.api.index.IndexingService; +import org.neo4j.kernel.impl.api.store.DefaultIndexReference; import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.impl.ha.ClusterManager.ManagedCluster; import org.neo4j.kernel.impl.storageengine.impl.recordstorage.RecordStorageEngine; @@ -178,15 +180,15 @@ private void createANode( HighlyAvailableGraphDatabase db, Label label, String v private SchemaIndexDescriptor createAnIndex( HighlyAvailableGraphDatabase db, Label label, String propertyName ) throws KernelException { - try ( Transaction tx = db.beginTx(); - Statement statement = statement( db ) ) + try ( Transaction tx = db.beginTx()) { - int labelId = statement.tokenWriteOperations().labelGetOrCreateForName( label.name() ); - int propertyKeyId = statement.tokenWriteOperations().propertyKeyGetOrCreateForName( propertyName ); - SchemaIndexDescriptor index = statement.schemaWriteOperations() + KernelTransaction ktx = kernelTransaction( db ); + int labelId = ktx.tokenWrite().labelGetOrCreateForName( label.name() ); + int propertyKeyId = ktx.tokenWrite().propertyKeyGetOrCreateForName( propertyName ); + IndexReference index = ktx.schemaWrite() .indexCreate( SchemaDescriptorFactory.forLabel( labelId, propertyKeyId ) ); tx.success(); - return index; + return DefaultIndexReference.toDescriptor( index ); } } @@ -252,10 +254,10 @@ private long awaitOnline( HighlyAvailableGraphDatabase db, SchemaIndexDescriptor long end = start + 60_000; while ( System.currentTimeMillis() < end ) { - try ( Transaction tx = db.beginTx(); - Statement statement = statement( db ) ) + try ( Transaction tx = db.beginTx() ) { - switch ( statement.readOperations().indexGetState( index ) ) + KernelTransaction transaction = kernelTransaction( db ); + switch ( transaction.schemaRead().indexGetState( DefaultIndexReference.fromDescriptor( index ) ) ) { case ONLINE: return indexingService( db ).getIndexId( index.schema() ); diff --git a/integrationtests/src/test/java/org/neo4j/storeupgrade/StoreUpgradeIT.java b/integrationtests/src/test/java/org/neo4j/storeupgrade/StoreUpgradeIT.java index 4ab3fc0b408b9..f7d1363adff2f 100644 --- a/integrationtests/src/test/java/org/neo4j/storeupgrade/StoreUpgradeIT.java +++ b/integrationtests/src/test/java/org/neo4j/storeupgrade/StoreUpgradeIT.java @@ -48,13 +48,13 @@ import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.helpers.Exceptions; import org.neo4j.helpers.collection.Iterables; +import org.neo4j.internal.kernel.api.IndexReference; +import org.neo4j.internal.kernel.api.SchemaRead; import org.neo4j.internal.kernel.api.exceptions.KernelException; import org.neo4j.io.fs.FileUtils; import org.neo4j.kernel.api.InwardKernel; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.kernel.api.ReadOperations; import org.neo4j.kernel.api.Statement; -import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.api.security.AnonymousContext; import org.neo4j.kernel.configuration.BoltConnector; import org.neo4j.kernel.configuration.Config; @@ -423,30 +423,31 @@ private static void checkIndexCounts( Store store, GraphDatabaseAPI db ) throws { InwardKernel kernel = db.getDependencyResolver().resolveDependency( InwardKernel.class ); try ( KernelTransaction tx = kernel.newTransaction( KernelTransaction.Type.implicit, AnonymousContext.read() ); - Statement statement = tx.acquireStatement() ) + Statement ignore = tx.acquireStatement() ) { - Iterator indexes = SchemaIndexDescriptor.sortByType( getAllIndexes( statement ) ); + SchemaRead schemaRead = tx.schemaRead(); + Iterator indexes = IndexReference.sortByType( getAllIndexes( schemaRead ) ); DoubleLongRegister register = Registers.newDoubleLongRegister(); for ( int i = 0; indexes.hasNext(); i++ ) { - SchemaIndexDescriptor descriptor = indexes.next(); + IndexReference reference = indexes.next(); // wait index to be online since sometimes we need to rebuild the indexes on migration - awaitOnline( statement.readOperations(), descriptor ); + awaitOnline( schemaRead, reference ); assertDoubleLongEquals( store.indexCounts[i][0], store.indexCounts[i][1], - statement.readOperations().indexUpdatesAndSize( descriptor, register ) ); + schemaRead.indexUpdatesAndSize( reference, register ) ); assertDoubleLongEquals( store.indexCounts[i][2], store.indexCounts[i][3], - statement.readOperations().indexSample( descriptor, register ) ); - double selectivity = statement.readOperations().indexUniqueValuesSelectivity( descriptor ); + schemaRead.indexSample( reference, register ) ); + double selectivity =schemaRead.indexUniqueValuesSelectivity( reference ); assertEquals( store.indexSelectivity[i], selectivity, 0.0000001d ); } } } - private static Iterator getAllIndexes( Statement statement ) + private static Iterator getAllIndexes( SchemaRead schemaRead ) { - return statement.readOperations().indexesGetAll(); + return schemaRead.indexesGetAll(); } private static void checkLabelCounts( GraphDatabaseAPI db ) @@ -549,14 +550,14 @@ private static long[] counts( long upgrade, long size, long unique, long sampleS return new long[]{upgrade, size, unique, sampleSize}; } - private static SchemaIndexDescriptor awaitOnline( ReadOperations readOperations, SchemaIndexDescriptor index ) + private static IndexReference awaitOnline( SchemaRead schemRead, IndexReference index ) throws KernelException { long start = System.currentTimeMillis(); long end = start + 20_000; while ( System.currentTimeMillis() < end ) { - switch ( readOperations.indexGetState( index ) ) + switch ( schemRead.indexGetState( index ) ) { case ONLINE: return index;