diff --git a/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/Write.java b/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/Write.java index 8c75c8609ce2e..5a8fff2340bce 100644 --- a/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/Write.java +++ b/community/kernel-api/src/main/java/org/neo4j/internal/kernel/api/Write.java @@ -35,8 +35,9 @@ public interface Write /** * Delete a node. * @param node the internal id of the node to delete + * @return returns true if it deleted a node or false if no node was found for this id */ - void nodeDelete( long node ); + boolean nodeDelete( long node ); /** * Create a relationship between two nodes. diff --git a/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/NodeWriteTestBase.java b/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/NodeWriteTestBase.java index f6e5123828a54..f963dd4bed157 100644 --- a/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/NodeWriteTestBase.java +++ b/community/kernel-api/src/test/java/org/neo4j/internal/kernel/api/NodeWriteTestBase.java @@ -27,6 +27,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; import static org.neo4j.graphdb.Label.label; @@ -69,6 +70,53 @@ public void shouldRollbackOnFailure() throws Exception } } + @Test + public void shouldRemoveNode() throws Exception + { + long node; + try ( org.neo4j.graphdb.Transaction tx = graphDb.beginTx() ) + { + node = graphDb.createNode().getId(); + tx.success(); + } + + try ( Transaction tx = session.beginTransaction() ) + { + tx.dataWrite().nodeDelete( node ); + tx.success(); + } + try ( org.neo4j.graphdb.Transaction tx = graphDb.beginTx() ) + { + try + { + graphDb.getNodeById( node ); + fail( "Did not remove node" ); + } + catch ( NotFoundException e ) + { + // expected + } + } + } + + @Test + public void shouldNotRemoveNodeThatDoesNotExist() throws Exception + { + long node = 0; + + try ( Transaction tx = session.beginTransaction() ) + { + assertFalse( tx.dataWrite().nodeDelete( node ) ); + tx.failure(); + } + try ( Transaction tx = session.beginTransaction() ) + { + assertFalse( tx.dataWrite().nodeDelete( node ) ); + tx.success(); + } + // should not crash + } + @Test public void shouldAddLabelNode() throws Exception { @@ -85,9 +133,7 @@ public void shouldAddLabelNode() throws Exception try ( org.neo4j.graphdb.Transaction ctx = graphDb.beginTx() ) { - assertThat( - graphDb.getNodeById( node ).getLabels(), - equalTo( Iterables.iterable( label( labelName ) ) ) ); + assertThat( graphDb.getNodeById( node ).getLabels(), equalTo( Iterables.iterable( label( labelName ) ) ) ); } } @@ -113,9 +159,9 @@ public void shouldRemoveLabel() throws Exception try ( org.neo4j.graphdb.Transaction ctx = graphDb.beginTx() ) { - assertThat( - graphDb.getNodeById( nodeId ).getLabels(), - equalTo( Iterables.empty() ) ); + assertThat( graphDb.getNodeById( nodeId ).getLabels(), equalTo( Iterables.empty() ) ); } } + + } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java index 69f3d65e2c1c5..37de035de0b5e 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java @@ -83,6 +83,7 @@ import org.neo4j.kernel.impl.locking.ReentrantLockService; import org.neo4j.kernel.impl.locking.StatementLocksFactory; import org.neo4j.kernel.impl.logging.LogService; +import org.neo4j.kernel.impl.newapi.Cursors; import org.neo4j.kernel.impl.proc.Procedures; import org.neo4j.kernel.impl.storageengine.impl.recordstorage.RecordStorageEngine; import org.neo4j.kernel.impl.storageengine.impl.recordstorage.id.IdController; @@ -688,7 +689,7 @@ private NeoStoreKernelModule buildKernel( LogFiles logFiles, TransactionAppender constraintIndexCreator, statementOperationParts, schemaWriteGuard, transactionHeaderInformationFactory, transactionCommitProcess, indexConfigStore, explicitIndexProviderLookup, hooks, transactionMonitor, availabilityGuard, tracers, storageEngine, procedures, transactionIdStore, clock, - cpuClock, heapAllocation, accessCapability ) ); + cpuClock, heapAllocation, accessCapability, new Cursors() ) ); buildTransactionMonitor( kernelTransactions, clock, config ); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementation.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementation.java index c074c677c8b51..bc72be61f30da 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementation.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementation.java @@ -63,6 +63,7 @@ import org.neo4j.kernel.impl.locking.LockTracer; import org.neo4j.kernel.impl.locking.Locks; import org.neo4j.kernel.impl.locking.StatementLocks; +import org.neo4j.kernel.impl.newapi.Cursors; import org.neo4j.kernel.impl.newapi.Operations; import org.neo4j.kernel.impl.proc.Procedures; import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory; @@ -164,7 +165,7 @@ public KernelTransactionImplementation( StatementOperationParts statementOperati TransactionMonitor transactionMonitor, Supplier explicitIndexTxStateSupplier, Pool pool, Clock clock, CpuClock cpuClock, HeapAllocation heapAllocation, TransactionTracer transactionTracer, LockTracer lockTracer, PageCursorTracerSupplier cursorTracerSupplier, - StorageEngine storageEngine, AccessCapability accessCapability ) + StorageEngine storageEngine, AccessCapability accessCapability, Cursors cursors ) { this.statementOperations = statementOperations; this.schemaWriteGuard = schemaWriteGuard; @@ -185,7 +186,7 @@ public KernelTransactionImplementation( StatementOperationParts statementOperati procedures, accessCapability, lockTracer, statementOperations ); this.statistics = new Statistics( this, cpuClock, heapAllocation ); this.userMetaData = new HashMap<>(); - this.operations = new Operations( storageEngine, storageStatement, this, explicitIndexTxStateSupplier ); + this.operations = new Operations( storageEngine, storageStatement, this, explicitIndexTxStateSupplier, cursors ); } /** @@ -684,7 +685,7 @@ public Read dataRead() @Override public Write dataWrite() { - throw new UnsupportedOperationException( "not implemented" ); + return operations; } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactions.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactions.java index 627cc42a116b0..f635cb80ba111 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactions.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactions.java @@ -42,6 +42,7 @@ import org.neo4j.kernel.impl.index.IndexConfigStore; import org.neo4j.kernel.impl.locking.StatementLocks; import org.neo4j.kernel.impl.locking.StatementLocksFactory; +import org.neo4j.kernel.impl.newapi.Cursors; import org.neo4j.kernel.impl.proc.Procedures; import org.neo4j.kernel.impl.store.TransactionId; import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory; @@ -88,6 +89,7 @@ public class KernelTransactions extends LifecycleAdapter implements Supplier explicitIndexTxStateSupplier() @@ -332,7 +335,7 @@ public KernelTransactionImplementation newInstance() constraintIndexCreator, procedures, transactionHeaderInformationFactory, transactionCommitProcess, transactionMonitor, explicitIndexTxStateSupplier, localTxPool, clock, cpuClock, heapAllocation, tracers.transactionTracer, tracers.lockTracer, - tracers.pageCursorTracerSupplier, storageEngine, accessCapability ); + tracers.pageCursorTracerSupplier, storageEngine, accessCapability, cursors ); this.transactions.add( tx ); return tx; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/explicitindex/InternalAutoIndexOperations.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/explicitindex/InternalAutoIndexOperations.java index b54ecbb074469..01f9b1b69e334 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/explicitindex/InternalAutoIndexOperations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/explicitindex/InternalAutoIndexOperations.java @@ -312,4 +312,4 @@ private void ensureIndexExists( DataWriteOperations ops ) throws ExplicitIndexNo indexCreated = true; } } -} +} \ No newline at end of file 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 32a03ceca4c20..cd995ad62eb93 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 @@ -70,8 +70,10 @@ class AllStoreHolder extends Read implements Token AllStoreHolder( StorageEngine engine, StorageStatement statement, - Supplier explicitIndexes ) + Supplier explicitIndexes, + Cursors cursors ) { + super( cursors ); this.read = engine.storeReadLayer(); this.statement = statement; // use provided statement, to assert no leakage this.explicitIndexes = Suppliers.lazySingleton( explicitIndexes ); @@ -238,11 +240,6 @@ RecordCursor labelCursor() return nodes.newLabelCursor(); } - private static RecordCursor newCursor( RecordStore store ) - { - return store.newRecordCursor( store.newRecord() ).acquire( store.getNumberOfReservedLowIds(), NORMAL ); - } - @Override void node( NodeRecord record, long reference, PageCursor pageCursor ) { @@ -294,4 +291,9 @@ ArrayValue array( PropertyCursor cursor, long reference, PageCursor page ) buffer.flip(); return PropertyUtil.readArrayFromBuffer( buffer ); } + + public boolean nodeExists( long id ) + { + return read.nodeExists( id ); + } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Cursors.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Cursors.java index 5cf5b370a75b4..ed0b724ec8b05 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Cursors.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Cursors.java @@ -19,66 +19,59 @@ */ package org.neo4j.kernel.impl.newapi; -class Cursors implements org.neo4j.internal.kernel.api.CursorFactory +public class Cursors implements org.neo4j.internal.kernel.api.CursorFactory { - private final Read read; - - Cursors( Read read ) - { - this.read = read; - } - @Override public NodeCursor allocateNodeCursor() { - return new NodeCursor( read ); + return new NodeCursor( ); } @Override public RelationshipScanCursor allocateRelationshipScanCursor() { - return new RelationshipScanCursor( read ); + return new RelationshipScanCursor( ); } @Override public RelationshipTraversalCursor allocateRelationshipTraversalCursor() { - return new RelationshipTraversalCursor( read ); + return new RelationshipTraversalCursor( allocateRelationshipGroupCursor() ); } @Override public PropertyCursor allocatePropertyCursor() { - return new PropertyCursor( read ); + return new PropertyCursor( ); } @Override public RelationshipGroupCursor allocateRelationshipGroupCursor() { - return new RelationshipGroupCursor( read ); + return new RelationshipGroupCursor( ); } @Override public NodeValueIndexCursor allocateNodeValueIndexCursor() { - return new NodeValueIndexCursor( read ); + return new NodeValueIndexCursor( ); } @Override public NodeLabelIndexCursor allocateNodeLabelIndexCursor() { - return new NodeLabelIndexCursor( read ); + return new NodeLabelIndexCursor( ); } @Override public NodeExplicitIndexCursor allocateNodeManualIndexCursor() { - return new NodeExplicitIndexCursor( read ); + return new NodeExplicitIndexCursor( ); } @Override public RelationshipExplicitIndexCursor allocateRelationshipManualIndexCursor() { - return new RelationshipExplicitIndexCursor( read ); + return new RelationshipExplicitIndexCursor( ); } } 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 25bb71f1bb2e1..fbae315064903 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 @@ -26,17 +26,17 @@ class KernelToken implements Token { - private final StoreReadLayer read; + private final StoreReadLayer store; KernelToken( StorageEngine engine ) { - read = engine.storeReadLayer(); + store = engine.storeReadLayer(); } @Override public int labelGetOrCreateForName( String labelName ) throws KernelException { - throw new UnsupportedOperationException( "not implemented" ); + return store.labelGetOrCreateForName( labelName ); } @Override @@ -72,18 +72,18 @@ public void relationshipTypeCreateForName( String relationshipTypeName, int id ) @Override public int nodeLabel( String name ) { - return read.labelGetForName( name ); + return store.labelGetForName( name ); } @Override public int relationshipType( String name ) { - return read.relationshipTypeGetForName( name ); + return store.relationshipTypeGetForName( name ); } @Override public int propertyKey( String name ) { - return read.propertyKeyGetForName( name ); + return store.propertyKeyGetForName( name ); } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NewKernel.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NewKernel.java index eb4873d7337cc..e4086feb568b6 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NewKernel.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NewKernel.java @@ -51,6 +51,11 @@ public NewKernel( StorageEngine engine, Supplier this.explicitIndexes = explicitIndexes; this.kernel = kernel; this.isRunning = false; + this.cursors = new Cursors( ); + // This extra statement will be remove once we start adding tx-state. That is because + // by then we cannot use a global Read in the CursorFactory, but need to use transaction + // specific Read instances which are given to the Cursors on initialization. + this.read = new AllStoreHolder( engine, engine.storeReadLayer().newStatement(), explicitIndexes, cursors ); } @Override @@ -69,14 +74,9 @@ public KernelSession beginSession( SecurityContext securityContext ) public void start() { - // This extra statement will be remove once we start adding tx-state. That is because - // by then we cannot use a global Read in the CursorFactory, but need to use transaction - // specific Read instances which are given to the Cursors on initialization. statement = engine.storeReadLayer().newStatement(); - this.read = new AllStoreHolder( engine, statement, explicitIndexes ); - this.cursors = new Cursors( read ); + this.cursors = new Cursors(); isRunning = true; - } public void stop() diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeCursor.java index af93ef00abbea..e0be455a9748f 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeCursor.java @@ -34,20 +34,18 @@ class NodeCursor extends NodeRecord implements org.neo4j.internal.kernel.api.NodeCursor { - private final Read read; - private final RecordCursor labelCursor; + private Read read; + private RecordCursor labelCursor; private PageCursor pageCursor; private long next; private long highMark; - NodeCursor( Read read ) + NodeCursor() { super( NO_ID ); - this.read = read; - this.labelCursor = read.labelCursor(); } - void scan() + void scan( Read read ) { if ( getId() != NO_ID ) { @@ -59,9 +57,11 @@ void scan() } this.next = 0; this.highMark = read.nodeHighMark(); + this.read = read; + this.labelCursor = read.labelCursor(); } - void single( long reference ) + void single( long reference, Read read ) { if ( getId() != NO_ID ) { @@ -73,6 +73,8 @@ void single( long reference ) } this.next = reference; this.highMark = NO_ID; + this.read = read; + this.labelCursor = read.labelCursor(); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeExplicitIndexCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeExplicitIndexCursor.java index d2e0e47c12b13..764b46a744cc7 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeExplicitIndexCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeExplicitIndexCursor.java @@ -28,16 +28,11 @@ class NodeExplicitIndexCursor extends IndexCursor implements org.neo4j.internal.kernel.api.NodeExplicitIndexCursor, ExplicitClient { - private final Read read; + private Read read; private int expectedSize; private long node; private float score; - NodeExplicitIndexCursor( Read read ) - { - this.read = read; - } - @Override public void initialize( IndexProgressor progressor, int expectedSize ) { @@ -53,6 +48,11 @@ public boolean acceptEntity( long reference, float score ) return true; } + public void setRead( Read read ) + { + this.read = read; + } + @Override public int expectedTotalNumberOfResults() { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeLabelIndexCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeLabelIndexCursor.java index f5273b5f20980..07a5ff384a7eb 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeLabelIndexCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeLabelIndexCursor.java @@ -29,15 +29,10 @@ class NodeLabelIndexCursor extends IndexCursor implements org.neo4j.internal.kernel.api.NodeLabelIndexCursor, NodeLabelClient { - private final Read read; + private Read read; private long node; private LabelSet labels; - NodeLabelIndexCursor( Read read ) - { - this.read = read; - } - @Override public void initialize( IndexProgressor progressor, boolean providesLabels ) { @@ -52,6 +47,11 @@ public boolean acceptNode( long reference, LabelSet labels ) return true; } + public void setRead( Read read ) + { + this.read = read; + } + @Override public void node( NodeCursor cursor ) { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeValueClientFilter.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeValueClientFilter.java index c472d74c14bf3..aa2e416d97741 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeValueClientFilter.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeValueClientFilter.java @@ -71,17 +71,19 @@ class NodeValueClientFilter implements NodeValueClient, IndexProgressor private final NodeCursor node; private final PropertyCursor property; private final IndexQuery[] filters; + private final Read read; private int[] keys; private IndexProgressor progressor; NodeValueClientFilter( NodeValueClient target, - NodeCursor node, PropertyCursor property, IndexQuery... filters ) + NodeCursor node, PropertyCursor property, Read read, IndexQuery... filters ) { this.target = target; this.node = node; this.property = property; this.filters = filters; + this.read = read; Arrays.sort( filters, ASCENDING_BY_KEY ); } @@ -102,7 +104,7 @@ public boolean acceptNode( long reference, Value[] values ) } else { - node.single( reference ); + node.single( reference, read ); if ( node.next() ) { node.properties( property ); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeValueIndexCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeValueIndexCursor.java index 58131110e5365..2f0513de14da2 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeValueIndexCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/NodeValueIndexCursor.java @@ -29,16 +29,11 @@ class NodeValueIndexCursor extends IndexCursor implements org.neo4j.internal.kernel.api.NodeValueIndexCursor, NodeValueClient { - private final Read read; + private Read read; private long node; private int[] keys; private Value[] values; - NodeValueIndexCursor( Read read ) - { - this.read = read; - } - @Override public void initialize( IndexProgressor progressor, int[] propertyIds ) { @@ -54,6 +49,11 @@ public boolean acceptNode( long reference, Value[] values ) return true; } + public void setRead( Read read ) + { + this.read = read; + } + @Override public void node( NodeCursor cursor ) { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java index c2648e40bddc8..7e8c526016b0b 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Operations.java @@ -41,6 +41,7 @@ import org.neo4j.internal.kernel.api.RelationshipTraversalCursor; import org.neo4j.internal.kernel.api.Scan; import org.neo4j.internal.kernel.api.SchemaRead; +import org.neo4j.internal.kernel.api.Write; import org.neo4j.internal.kernel.api.exceptions.KernelException; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.api.txstate.ExplicitIndexTransactionState; @@ -52,19 +53,22 @@ /** * Collects all Kernel API operations and guards them from being used outside of transaction. */ -public class Operations implements Read, ExplicitIndexRead, SchemaRead +public class Operations implements Read, ExplicitIndexRead, SchemaRead, Write { private final KernelTransactionImplementation ktx; private final AllStoreHolder allStoreHolder; + private final StorageStatement statement; public Operations( StorageEngine engine, StorageStatement statement, KernelTransactionImplementation ktx, - Supplier explicitIndexes ) + Supplier explicitIndexes, + Cursors cursors ) { - allStoreHolder = new AllStoreHolder( engine, statement, explicitIndexes ); + allStoreHolder = new AllStoreHolder( engine, statement, explicitIndexes, cursors ); this.ktx = ktx; + this.statement = statement; } // READ @@ -304,4 +308,115 @@ private void assertOpen() throw new TransactionTerminatedException( terminationReason.get() ); } } + + // WRITE + + @Override + public long nodeCreate() + { + assertOpen(); + long nodeId = statement.reserveNode(); + ktx.txState().nodeDoCreate( nodeId ); + return nodeId; + } + + @Override + public boolean nodeDelete( long node ) + { + assertOpen(); + + if ( ktx.hasTxStateWithChanges() ) + { + if ( ktx.txState().nodeIsAddedInThisTx( node ) ) + { + ktx.txState().nodeDoDelete( node ); + return true; + } + if ( ktx.txState().nodeIsDeletedInThisTx( node ) ) + { + // already deleted + return false; + } + } + + if ( allStoreHolder.nodeExists( node ) ) + { + ktx.txState().nodeDoDelete( node ); + return true; + } + + // tried to delete node that does not exist + return false; + } + + @Override + public long relationshipCreate( long sourceNode, int relationshipLabel, long targetNode ) + { + assertOpen(); + throw new UnsupportedOperationException(); + } + + @Override + public void relationshipDelete( long relationship ) + { + assertOpen(); + throw new UnsupportedOperationException(); + } + + @Override + public void nodeAddLabel( long node, int nodeLabel ) + { + assertOpen(); + ktx.txState().nodeDoAddLabel( nodeLabel, node ); + } + + @Override + public void nodeRemoveLabel( long node, int nodeLabel ) + { + assertOpen(); + + ktx.txState().nodeDoRemoveLabel( nodeLabel, node ); + } + + @Override + public Value nodeSetProperty( long node, int propertyKey, Value value ) + { + assertOpen(); + throw new UnsupportedOperationException(); + } + + @Override + public Value nodeRemoveProperty( long node, int propertyKey ) + { + assertOpen(); + throw new UnsupportedOperationException(); + } + + @Override + public Value relationshipSetProperty( long relationship, int propertyKey, Value value ) + { + assertOpen(); + throw new UnsupportedOperationException(); + } + + @Override + public Value relationshipRemoveProperty( long node, int propertyKey ) + { + assertOpen(); + throw new UnsupportedOperationException(); + } + + @Override + public Value graphSetProperty( int propertyKey, Value value ) + { + assertOpen(); + throw new UnsupportedOperationException(); + } + + @Override + public Value graphRemoveProperty( int propertyKey ) + { + assertOpen(); + throw new UnsupportedOperationException(); + } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/PropertyCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/PropertyCursor.java index b02701ea2562e..5c1203cb7f992 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/PropertyCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/PropertyCursor.java @@ -46,7 +46,7 @@ public class PropertyCursor extends PropertyRecord implements org.neo4j.internal.kernel.api.PropertyCursor { private static final int MAX_BYTES_IN_SHORT_STRING_OR_SHORT_ARRAY = 32; - private final Read read; + private Read read; private long next; private int block; ByteBuffer buffer; @@ -54,13 +54,12 @@ public class PropertyCursor extends PropertyRecord implements org.neo4j.internal private PageCursor stringPage; private PageCursor arrayPage; - public PropertyCursor( Read read ) + public PropertyCursor() { super( NO_ID ); - this.read = read; } - void init( long reference ) + void init( long reference, Read read ) { if ( getId() != NO_ID ) { @@ -72,6 +71,7 @@ void init( long reference ) { page = read.propertyPage( reference ); } + this.read = read; } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Read.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Read.java index aced9350d01fc..75716ad4fab1f 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Read.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/Read.java @@ -57,6 +57,13 @@ abstract class Read implements org.neo4j.internal.kernel.api.ExplicitIndexRead, org.neo4j.internal.kernel.api.SchemaRead { + final Cursors cursors; + + Read( Cursors cursors ) + { + this.cursors = cursors; + } + @Override public final void nodeIndexSeek( org.neo4j.internal.kernel.api.IndexReference index, @@ -64,6 +71,7 @@ public final void nodeIndexSeek( IndexOrder indexOrder, IndexQuery... query ) throws KernelException { + ((NodeValueIndexCursor) cursor).setRead( this ); IndexProgressor.NodeValueClient target = (NodeValueIndexCursor) cursor; IndexReader reader = indexReader( index ); if ( !reader.hasFullNumberPrecision( query ) ) @@ -97,7 +105,7 @@ public final void nodeIndexSeek( if ( j > 0 ) { filters = Arrays.copyOf( filters, j ); - target = new NodeValueClientFilter( target, new NodeCursor( this ), new PropertyCursor( this ), filters ); + target = new NodeValueClientFilter( target, cursors.allocateNodeCursor(), cursors.allocatePropertyCursor(), this, filters ); } } reader.query( target, indexOrder, query ); @@ -111,24 +119,28 @@ public final void nodeIndexScan( { // for a scan, we simply query for existence of the first property, which covers all entries in an index int firstProperty = index.properties()[0]; + ((NodeValueIndexCursor) cursor).setRead( this ); indexReader( index ).query( (NodeValueIndexCursor) cursor, indexOrder, IndexQuery.exists( firstProperty ) ); } @Override public final void nodeLabelScan( int label, org.neo4j.internal.kernel.api.NodeLabelIndexCursor cursor ) { + ((NodeLabelIndexCursor) cursor).setRead( this ); labelScan( (NodeLabelIndexCursor) cursor, labelScanReader().nodesWithLabel( label ) ); } @Override public void nodeLabelUnionScan( org.neo4j.internal.kernel.api.NodeLabelIndexCursor cursor, int... labels ) { + ((NodeLabelIndexCursor) cursor).setRead( this ); labelScan( (NodeLabelIndexCursor) cursor, labelScanReader().nodesWithAnyOfLabels( labels ) ); } @Override public void nodeLabelIntersectionScan( org.neo4j.internal.kernel.api.NodeLabelIndexCursor cursor, int... labels ) { + ((NodeLabelIndexCursor) cursor).setRead( this ); labelScan( (NodeLabelIndexCursor) cursor, labelScanReader().nodesWithAllLabels( labels ) ); } @@ -146,7 +158,7 @@ public final Scan nodeLabelS @Override public final void allNodesScan( org.neo4j.internal.kernel.api.NodeCursor cursor ) { - ((NodeCursor) cursor).scan(); + ((NodeCursor) cursor).scan(this); } @Override @@ -158,19 +170,19 @@ public final Scan allNodesScan() @Override public final void singleNode( long reference, org.neo4j.internal.kernel.api.NodeCursor cursor ) { - ((NodeCursor) cursor).single( reference ); + ((NodeCursor) cursor).single( reference, this ); } @Override public final void singleRelationship( long reference, org.neo4j.internal.kernel.api.RelationshipScanCursor cursor ) { - ((RelationshipScanCursor) cursor).single( reference ); + ((RelationshipScanCursor) cursor).single( reference, this ); } @Override public final void allRelationshipsScan( org.neo4j.internal.kernel.api.RelationshipScanCursor cursor ) { - ((RelationshipScanCursor) cursor).scan( -1/*include all labels*/ ); + ((RelationshipScanCursor) cursor).scan( -1/*include all labels*/, this ); } @Override @@ -182,7 +194,7 @@ public final Scan allRelat @Override public final void relationshipLabelScan( int label, org.neo4j.internal.kernel.api.RelationshipScanCursor cursor ) { - ((RelationshipScanCursor) cursor).scan( label ); + ((RelationshipScanCursor) cursor).scan( label, this ); } @Override @@ -201,11 +213,11 @@ public final void relationshipGroups( } else if ( hasDirectFlag( reference ) ) // the relationships for this node are not grouped { - ((RelationshipGroupCursor) cursor).buffer( nodeReference, clearFlags( reference ) ); + ((RelationshipGroupCursor) cursor).buffer( nodeReference, clearFlags( reference ), this ); } else // this is a normal group reference. { - ((RelationshipGroupCursor) cursor).direct( nodeReference, reference ); + ((RelationshipGroupCursor) cursor).direct( nodeReference, reference, this ); } } @@ -246,34 +258,34 @@ public final void relationships( } else if ( hasGroupFlag( reference ) ) // this reference is actually to a group record { - ((RelationshipTraversalCursor) cursor).groups( nodeReference, clearFlags( reference ) ); + ((RelationshipTraversalCursor) cursor).groups( nodeReference, clearFlags( reference ), this ); } else if ( hasFilterFlag( reference ) ) // this relationship chain need to be filtered { - ((RelationshipTraversalCursor) cursor).filtered( nodeReference, clearFlags( reference ) ); + ((RelationshipTraversalCursor) cursor).filtered( nodeReference, clearFlags( reference ), this ); } else // this is a normal relationship reference { - ((RelationshipTraversalCursor) cursor).chain( nodeReference, reference ); + ((RelationshipTraversalCursor) cursor).chain( nodeReference, reference, this ); } } @Override public final void nodeProperties( long reference, org.neo4j.internal.kernel.api.PropertyCursor cursor ) { - ((PropertyCursor) cursor).init( reference ); + ((PropertyCursor) cursor).init( reference, this ); } @Override public final void relationshipProperties( long reference, org.neo4j.internal.kernel.api.PropertyCursor cursor ) { - ((PropertyCursor) cursor).init( reference ); + ((PropertyCursor) cursor).init( reference, this ); } @Override public final void graphProperties( org.neo4j.internal.kernel.api.PropertyCursor cursor ) { - ((PropertyCursor) cursor).init( graphPropertiesReference() ); + ((PropertyCursor) cursor).init( graphPropertiesReference(), this ); } abstract long graphPropertiesReference(); @@ -282,6 +294,7 @@ public final void graphProperties( org.neo4j.internal.kernel.api.PropertyCursor public final void nodeExplicitIndexLookup( NodeExplicitIndexCursor cursor, String index, String key, Value value ) throws KernelException { + ((org.neo4j.kernel.impl.newapi.NodeExplicitIndexCursor) cursor).setRead( this ); explicitIndex( (org.neo4j.kernel.impl.newapi.NodeExplicitIndexCursor) cursor, explicitNodeIndex( index ).get( key, value.asObject() ) ); } @@ -289,6 +302,7 @@ public final void nodeExplicitIndexLookup( public final void nodeExplicitIndexQuery( NodeExplicitIndexCursor cursor, String index, Object query ) throws KernelException { + ((org.neo4j.kernel.impl.newapi.NodeExplicitIndexCursor) cursor).setRead( this ); explicitIndex( (org.neo4j.kernel.impl.newapi.NodeExplicitIndexCursor) cursor, explicitNodeIndex( index ).query( query instanceof Value ? ((Value) query).asObject() : query ) ); } @@ -297,6 +311,7 @@ public final void nodeExplicitIndexQuery( public final void nodeExplicitIndexQuery( NodeExplicitIndexCursor cursor, String index, String key, Object query ) throws KernelException { + ((org.neo4j.kernel.impl.newapi.NodeExplicitIndexCursor) cursor).setRead( this ); explicitIndex( (org.neo4j.kernel.impl.newapi.NodeExplicitIndexCursor) cursor, explicitNodeIndex( index ).query( key, query instanceof Value ? ((Value) query).asObject() : query ) ); } @@ -310,6 +325,7 @@ public void relationshipExplicitIndexGet( long source, long target ) throws KernelException { + ((org.neo4j.kernel.impl.newapi.RelationshipExplicitIndexCursor) cursor).setRead( this ); explicitIndex( (org.neo4j.kernel.impl.newapi.RelationshipExplicitIndexCursor) cursor, explicitRelationshipIndex( index ).get( key, value.asObject(), source, target ) ); @@ -323,6 +339,7 @@ public void relationshipExplicitIndexQuery( long source, long target ) throws KernelException { + ((org.neo4j.kernel.impl.newapi.RelationshipExplicitIndexCursor) cursor).setRead( this ); explicitIndex( (org.neo4j.kernel.impl.newapi.RelationshipExplicitIndexCursor) cursor, explicitRelationshipIndex( index ) @@ -338,6 +355,7 @@ public void relationshipExplicitIndexQuery( long source, long target ) throws KernelException { + ((org.neo4j.kernel.impl.newapi.RelationshipExplicitIndexCursor) cursor).setRead( this ); explicitIndex( (org.neo4j.kernel.impl.newapi.RelationshipExplicitIndexCursor) cursor, explicitRelationshipIndex( index ).query( diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipCursor.java index 6146af0d988cb..f2b8cda84e0e7 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipCursor.java @@ -24,12 +24,11 @@ abstract class RelationshipCursor extends RelationshipRecord implements RelationshipDataAccessor { - final Read read; + Read read; - RelationshipCursor( Read read ) + RelationshipCursor() { super( NO_ID ); - this.read = read; } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipExplicitIndexCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipExplicitIndexCursor.java index 5986ddd4f3b0d..77d76a46f8783 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipExplicitIndexCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipExplicitIndexCursor.java @@ -29,16 +29,11 @@ class RelationshipExplicitIndexCursor extends IndexCursor implements org.neo4j.internal.kernel.api.RelationshipExplicitIndexCursor, ExplicitClient { - private final Read read; + private Read read; private int expectedSize; private long relationship; private float score; - RelationshipExplicitIndexCursor( Read read ) - { - this.read = read; - } - @Override public void initialize( IndexProgressor progressor, int expectedSize ) { @@ -54,6 +49,11 @@ public boolean acceptEntity( long reference, float score ) return true; } + public void setRead( Read read ) + { + this.read = read; + } + @Override public int expectedTotalNumberOfResults() { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipGroupCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipGroupCursor.java index 98ce7d34cfd4c..483df60ed7d1c 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipGroupCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipGroupCursor.java @@ -31,19 +31,18 @@ class RelationshipGroupCursor extends RelationshipGroupRecord implements org.neo4j.internal.kernel.api.RelationshipGroupCursor { - private final Read read; + private Read read; private final RelationshipRecord edge = new RelationshipRecord( NO_ID ); private Group current; private PageCursor page; private PageCursor edgePage; - RelationshipGroupCursor( Read read ) + RelationshipGroupCursor( ) { - super( -1 ); - this.read = read; + super( NO_ID ); } - void buffer( long nodeReference, long relationshipReference ) + void buffer( long nodeReference, long relationshipReference, Read read ) { setOwningNode( nodeReference ); setId( NO_ID ); @@ -86,10 +85,11 @@ else if ( edge.getSecondNode() == nodeReference ) // incoming } } this.current = new Group( edge, current ); // we need a dummy before the first to denote the initial pos + this.read = read; } } - void direct( long nodeReference, long reference ) + void direct( long nodeReference, long reference, Read read ) { setOwningNode( nodeReference ); current = null; @@ -99,6 +99,7 @@ void direct( long nodeReference, long reference ) { page = read.groupPage( reference ); } + this.read = read; } @Override @@ -218,7 +219,7 @@ public void outgoing( org.neo4j.internal.kernel.api.RelationshipTraversalCursor { if ( current != null && cursor instanceof RelationshipTraversalCursor ) { - ((RelationshipTraversalCursor) cursor).buffered( getOwningNode(), current.outgoing ); + ((RelationshipTraversalCursor) cursor).buffered( getOwningNode(), current.outgoing, read ); } else { @@ -231,7 +232,7 @@ public void incoming( org.neo4j.internal.kernel.api.RelationshipTraversalCursor { if ( current != null && cursor instanceof RelationshipTraversalCursor ) { - ((RelationshipTraversalCursor) cursor).buffered( getOwningNode(), current.incoming ); + ((RelationshipTraversalCursor) cursor).buffered( getOwningNode(), current.incoming, read ); } else { @@ -244,7 +245,7 @@ public void loops( org.neo4j.internal.kernel.api.RelationshipTraversalCursor cur { if ( current != null && cursor instanceof RelationshipTraversalCursor ) { - ((RelationshipTraversalCursor) cursor).buffered( getOwningNode(), current.loops ); + ((RelationshipTraversalCursor) cursor).buffered( getOwningNode(), current.loops, read ); } else { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipScanCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipScanCursor.java index af2af2d2c36fd..80627c805aea5 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipScanCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipScanCursor.java @@ -28,12 +28,7 @@ class RelationshipScanCursor extends RelationshipCursor implements org.neo4j.int private long highMark; private PageCursor pageCursor; - RelationshipScanCursor( Read read ) - { - super( read ); - } - - void scan( int label ) + void scan( int label, Read read ) { if ( getId() != NO_ID ) { @@ -46,9 +41,10 @@ void scan( int label ) next = 0; this.label = label; highMark = read.relationshipHighMark(); + this.read = read; } - void single( long reference ) + void single( long reference, Read read ) { if ( getId() != NO_ID ) { @@ -61,6 +57,7 @@ void single( long reference ) next = reference; label = -1; highMark = NO_ID; + this.read = read; } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipTraversalCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipTraversalCursor.java index 1bc35f4fecf33..30412abc81411 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipTraversalCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/newapi/RelationshipTraversalCursor.java @@ -90,29 +90,29 @@ boolean check( long source, long target, long origin ) private FilterState filterState; private int filterType = NO_ID; - RelationshipTraversalCursor( Read read ) + RelationshipTraversalCursor( RelationshipGroupCursor group ) { - super( read ); - this.group = new RelationshipGroupCursor( read ); + this.group = group; } /* * Cursor being called as a group, use the buffered records in Record * instead. */ - void buffered( long nodeReference, Record record ) + void buffered( long nodeReference, Record record, Read read ) { this.originNodeReference = nodeReference; this.buffer = Record.initialize( record ); this.groupState = GroupState.NONE; this.filterState = FilterState.NONE; this.filterType = NO_ID; + this.read = read; } /* * Normal traversal. */ - void chain( long nodeReference, long reference ) + void chain( long nodeReference, long reference, Read read ) { if ( pageCursor == null ) { @@ -124,12 +124,13 @@ void chain( long nodeReference, long reference ) filterType = NO_ID; originNodeReference = nodeReference; next = reference; + this.read = read; } /* * Reference to a group record */ - void groups( long nodeReference, long groupReference ) + void groups( long nodeReference, long groupReference, Read read ) { setId( NO_ID ); next = NO_ID; @@ -138,9 +139,10 @@ void groups( long nodeReference, long groupReference ) filterType = NO_ID; originNodeReference = nodeReference; read.relationshipGroups( nodeReference, groupReference, group ); + this.read = read; } - void filtered( long nodeReference, long reference ) + void filtered( long nodeReference, long reference, Read read ) { if ( pageCursor == null ) { @@ -151,6 +153,7 @@ void filtered( long nodeReference, long reference ) filterState = FilterState.NOT_INITIALIZED; originNodeReference = nodeReference; next = reference; + this.read = read; } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/TransactionStats.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/TransactionStats.java index a62c9959f3331..287af8d9ea946 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/TransactionStats.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/TransactionStats.java @@ -53,7 +53,6 @@ public void transactionFinished( boolean committed, boolean write ) else { incrementCounter( rolledBackReadTransactionCount, rolledBackWriteTransactionCount, write ); - } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/api/KernelTransactionFactory.java b/community/kernel/src/test/java/org/neo4j/kernel/api/KernelTransactionFactory.java index 316997b4126b9..a53bb29a5a658 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/api/KernelTransactionFactory.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/api/KernelTransactionFactory.java @@ -36,6 +36,7 @@ import org.neo4j.kernel.impl.locking.NoOpClient; import org.neo4j.kernel.impl.locking.SimpleStatementLocks; import org.neo4j.kernel.impl.locking.StatementLocks; +import org.neo4j.kernel.impl.newapi.Cursors; import org.neo4j.kernel.impl.proc.Procedures; import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory; import org.neo4j.kernel.impl.transaction.TransactionMonitor; @@ -96,7 +97,7 @@ static Instances kernelTransactionWithInternals( SecurityContext securityContext Clocks.systemClock(), CpuClock.NOT_AVAILABLE, HeapAllocation.NOT_AVAILABLE, NULL, LockTracer.NONE, PageCursorTracerSupplier.NULL, - storageEngine, new CanWrite() ); + storageEngine, new CanWrite(), new Cursors() ); StatementLocks statementLocks = new SimpleStatementLocks( new NoOpClient() ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionTerminationTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionTerminationTest.java index 1221476efcf41..55d00634aff47 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionTerminationTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionTerminationTest.java @@ -40,6 +40,7 @@ import org.neo4j.kernel.impl.locking.LockTracer; import org.neo4j.kernel.impl.locking.NoOpClient; import org.neo4j.kernel.impl.locking.SimpleStatementLocks; +import org.neo4j.kernel.impl.newapi.Cursors; import org.neo4j.kernel.impl.proc.Procedures; import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory; import org.neo4j.kernel.impl.transaction.TransactionMonitor; @@ -340,7 +341,7 @@ private static class TestKernelTransaction extends KernelTransactionImplementati mock( Pool.class ), Clocks.fakeClock(), CpuClock.NOT_AVAILABLE, HeapAllocation.NOT_AVAILABLE, TransactionTracer.NULL, LockTracer.NONE, PageCursorTracerSupplier.NULL, - mock( StorageEngine.class, RETURNS_MOCKS ), new CanWrite() ); + mock( StorageEngine.class, RETURNS_MOCKS ), new CanWrite(), mock(Cursors.class) ); this.monitor = monitor; } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionTestBase.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionTestBase.java index f23c72bee2679..15cbd180c04b9 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionTestBase.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionTestBase.java @@ -38,6 +38,7 @@ import org.neo4j.kernel.impl.locking.NoOpClient; import org.neo4j.kernel.impl.locking.SimpleStatementLocks; import org.neo4j.kernel.impl.locking.StatementLocks; +import org.neo4j.kernel.impl.newapi.Cursors; import org.neo4j.kernel.impl.storageengine.impl.recordstorage.StoreStatement; import org.neo4j.kernel.impl.store.MetaDataStore; import org.neo4j.kernel.impl.store.NeoStores; @@ -148,7 +149,7 @@ public KernelTransactionImplementation newNotInitializedTransaction() hooks, null, null, headerInformationFactory, commitProcess, transactionMonitor, explicitIndexStateSupplier, txPool, clock, CpuClock.NOT_AVAILABLE, HeapAllocation.NOT_AVAILABLE, TransactionTracer.NULL, LockTracer.NONE, - PageCursorTracerSupplier.NULL, storageEngine, new CanWrite() ); + PageCursorTracerSupplier.NULL, storageEngine, new CanWrite(), new Cursors() ); } public class CapturingCommitProcess implements TransactionCommitProcess diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionsTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionsTest.java index b26d2807a6ec2..42429f075438e 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionsTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/KernelTransactionsTest.java @@ -48,6 +48,7 @@ import org.neo4j.kernel.impl.locking.Locks; import org.neo4j.kernel.impl.locking.SimpleStatementLocksFactory; import org.neo4j.kernel.impl.locking.StatementLocksFactory; +import org.neo4j.kernel.impl.newapi.Cursors; import org.neo4j.kernel.impl.proc.Procedures; import org.neo4j.kernel.impl.store.TransactionId; import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory; @@ -586,7 +587,7 @@ private static KernelTransactions createTransactions( StorageEngine storageEngin commitProcess, null, null, new TransactionHooks(), mock( TransactionMonitor.class ), availabilityGuard, tracers, storageEngine, new Procedures(), transactionIdStore, clock, CpuClock.NOT_AVAILABLE, - HeapAllocation.NOT_AVAILABLE, new CanWrite() ); + HeapAllocation.NOT_AVAILABLE, new CanWrite(), new Cursors() ); } private static TestKernelTransactions createTestTransactions( StorageEngine storageEngine, @@ -598,7 +599,7 @@ private static TestKernelTransactions createTestTransactions( StorageEngine stor null, DEFAULT, commitProcess, null, null, new TransactionHooks(), mock( TransactionMonitor.class ), availabilityGuard, tracers, storageEngine, new Procedures(), transactionIdStore, clock, - new CanWrite() ); + new CanWrite(), new Cursors() ); } private static TransactionCommitProcess newRememberingCommitProcess( final TransactionRepresentation[] slot ) @@ -647,12 +648,12 @@ private static class TestKernelTransactions extends KernelTransactions ExplicitIndexProviderLookup explicitIndexProviderLookup, TransactionHooks hooks, TransactionMonitor transactionMonitor, AvailabilityGuard availabilityGuard, Tracers tracers, StorageEngine storageEngine, Procedures procedures, TransactionIdStore transactionIdStore, SystemNanoClock clock, - AccessCapability accessCapability ) + AccessCapability accessCapability, Cursors cursors ) { super( statementLocksFactory, constraintIndexCreator, statementOperations, schemaWriteGuard, txHeaderFactory, transactionCommitProcess, indexConfigStore, explicitIndexProviderLookup, hooks, transactionMonitor, availabilityGuard, tracers, storageEngine, procedures, transactionIdStore, - clock, CpuClock.NOT_AVAILABLE, HeapAllocation.NOT_AVAILABLE, accessCapability ); + clock, CpuClock.NOT_AVAILABLE, HeapAllocation.NOT_AVAILABLE, accessCapability, cursors ); } @Override diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/IndexCursorFilterTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/IndexCursorFilterTest.java index 2a5fff784e910..eafb501ccbe5d 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/IndexCursorFilterTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/IndexCursorFilterTest.java @@ -41,7 +41,7 @@ public class IndexCursorFilterTest implements IndexProgressor, NodeValueClient { @Rule - public final MockStore store = new MockStore(); + public final MockStore store = new MockStore( new Cursors() ); private final List events = new ArrayList<>(); @Test @@ -128,7 +128,7 @@ public void shouldNotAcceptNodeWithoutMatchingProperty() throws Exception private NodeValueClientFilter initializeFilter( int[] keys, IndexQuery... filters ) { NodeValueClientFilter filter = new NodeValueClientFilter( - this, new NodeCursor( store ), new PropertyCursor( store ), filters ); + this, new NodeCursor(), new PropertyCursor(), null, filters ); //TODO: change null to actual Read filter.initialize( this, keys ); return filter; } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/MockStore.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/MockStore.java index c4e22b340e2ee..ba83abd1fe68a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/MockStore.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/MockStore.java @@ -62,6 +62,11 @@ public DynamicRecord nextRecord() } }; + MockStore( Cursors cursors ) + { + super( cursors ); + } + @Override long graphPropertiesReference() { diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/NodeWriteTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/NodeWriteTest.java new file mode 100644 index 0000000000000..40935a2ef69cc --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/NodeWriteTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2002-2017 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.newapi; + +import org.neo4j.internal.kernel.api.NodeWriteTestBase; + +public class NodeWriteTest extends NodeWriteTestBase +{ + @Override + public WriteTestSupport newTestSupport() + { + return new WriteTestSupport(); + } +} diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/WriteTestSupport.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/WriteTestSupport.java new file mode 100644 index 0000000000000..317de2a0c4089 --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/newapi/WriteTestSupport.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2002-2017 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.newapi; + +import java.io.File; +import java.io.IOException; + +import org.neo4j.graphdb.DependencyResolver; +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.Relationship; +import org.neo4j.graphdb.Transaction; +import org.neo4j.internal.kernel.api.Kernel; +import org.neo4j.internal.kernel.api.KernelAPIWriteTestSupport; +import org.neo4j.kernel.internal.GraphDatabaseAPI; +import org.neo4j.test.TestGraphDatabaseFactory; + +class WriteTestSupport implements KernelAPIWriteTestSupport +{ + private GraphDatabaseService db; + + @Override + public void setup( File storeDir ) throws IOException + { + db = new TestGraphDatabaseFactory().newImpermanentDatabaseBuilder( storeDir ).newGraphDatabase(); + } + + @Override + public void clearGraph() + { + try ( Transaction tx = db.beginTx() ) + { + + for ( Relationship relationship : db.getAllRelationships() ) + { + relationship.delete(); + } + + for ( Node node : db.getAllNodes() ) + { + node.delete(); + } + + tx.success(); + } + } + + @Override + public Kernel kernelToTest() + { + DependencyResolver resolver = ((GraphDatabaseAPI) this.db).getDependencyResolver(); + return resolver.resolveDependency( Kernel.class ); + } + + @Override + public GraphDatabaseService graphBackdoor() + { + return db; + } + + @Override + public void tearDown() + { + db.shutdown(); + db = null; + } +}