From 0ebb2ee316290be221ff5871f5a4fc3d62dd146a Mon Sep 17 00:00:00 2001 From: Davide Grohmann Date: Thu, 2 Mar 2017 11:42:31 +0100 Subject: [PATCH] Flat all property cursors By having one cursor handling both txState and reading records from disk --- .../api/StateHandlingStatementOperations.java | 71 +++--------- .../api/cursor/TxAbstractPropertyCursor.java | 84 --------------- .../impl/api/cursor/TxAllPropertyCursor.java | 91 ---------------- .../api/cursor/TxSinglePropertyCursor.java | 101 ------------------ .../neo4j/kernel/impl/api/state/TxState.java | 45 -------- .../kernel/impl/api/store/StorageLayer.java | 21 ++-- .../store/StoreAbstractPropertyCursor.java | 48 +++++++-- .../impl/api/store/StorePropertyCursor.java | 33 +++++- .../api/store/StoreSinglePropertyCursor.java | 19 +++- .../kernel/impl/api/store/StoreStatement.java | 10 +- .../TxStateTransactionDataSnapshot.java | 8 +- .../participant/StoreMigrator.java | 2 +- .../storageengine/api/StorageStatement.java | 5 +- .../storageengine/api/StoreReadLayer.java | 12 ++- .../api/txstate/ReadableTransactionState.java | 7 -- .../state/IndexQueryTransactionStateTest.java | 6 +- .../api/state/LabelTransactionStateTest.java | 13 ++- .../StateHandlingStatementOperationsTest.java | 16 +-- .../StateOperationsAutoIndexingTest.java | 15 +-- .../api/store/StorageLayerPropertyTest.java | 2 +- .../api/store/StorePropertyCursorTest.java | 30 +++--- .../TxStateTransactionDataViewTest.java | 21 ++-- .../kernel/impl/store/NeoStoresTest.java | 3 +- .../enterprise/PropertyExistenceEnforcer.java | 7 +- 24 files changed, 192 insertions(+), 478 deletions(-) delete mode 100644 community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxAbstractPropertyCursor.java delete mode 100644 community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxAllPropertyCursor.java delete mode 100644 community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxSinglePropertyCursor.java diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StateHandlingStatementOperations.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StateHandlingStatementOperations.java index a0f0602d4460..65b16ee64501 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StateHandlingStatementOperations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StateHandlingStatementOperations.java @@ -102,8 +102,10 @@ import org.neo4j.storageengine.api.Token; import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.storageengine.api.schema.PopulationProgress; +import org.neo4j.storageengine.api.txstate.NodeState; import org.neo4j.storageengine.api.txstate.ReadableDiffSets; import org.neo4j.storageengine.api.txstate.ReadableTransactionState; +import org.neo4j.storageengine.api.txstate.RelationshipState; import static java.lang.String.format; import static org.neo4j.collection.primitive.PrimitiveIntCollections.filter; @@ -117,7 +119,6 @@ import static org.neo4j.kernel.impl.api.state.IndexTxStateUpdater.LabelChangeType.ADDED_LABEL; import static org.neo4j.kernel.impl.api.state.IndexTxStateUpdater.LabelChangeType.REMOVED_LABEL; import static org.neo4j.kernel.impl.util.Cursors.count; -import static org.neo4j.kernel.impl.util.Cursors.empty; import static org.neo4j.register.Registers.newDoubleLongRegister; import static org.neo4j.storageengine.api.NodeItem.transientNode; import static org.neo4j.storageengine.api.txstate.TxStateVisitor.EMPTY; @@ -218,19 +219,8 @@ public Cursor nodeGetRelationships( KernelStatement statement, @Override public Cursor nodeGetProperties( KernelStatement statement, NodeItem node ) { - Cursor cursor; - if ( statement.hasTxStateWithChanges() && statement.txState().nodeIsAddedInThisTx( node.id() ) ) - { - cursor = empty(); - } - else - { - cursor = storeLayer.nodeGetProperties( statement.getStoreStatement(), node ); - } - - return statement.hasTxStateWithChanges() - ? statement.txState().augmentPropertyCursor( cursor, statement.txState().getNodeState( node.id() ) ) - : cursor; + NodeState state = statement.hasTxStateWithChanges() ? statement.txState().getNodeState( node.id() ) : null; + return storeLayer.nodeGetProperties( statement.getStoreStatement(), node, state ); } @Override @@ -277,40 +267,17 @@ public boolean nodeHasProperty( KernelStatement statement, NodeItem node, int pr private Cursor nodeGetPropertyCursor( KernelStatement statement, NodeItem node, int propertyKeyId ) { - - Cursor cursor; - if ( statement.hasTxStateWithChanges() && statement.txState().nodeIsAddedInThisTx( node.id() ) ) - { - cursor = empty(); - } - else - { - cursor = storeLayer.nodeGetProperty( statement.getStoreStatement(), node, propertyKeyId ); - } - - return statement.hasTxStateWithChanges() - ? statement.txState().augmentSinglePropertyCursor( - cursor, statement.txState().getNodeState( node.id() ), propertyKeyId ) - : cursor; + NodeState state = statement.hasTxStateWithChanges() ? statement.txState().getNodeState( node.id() ) : null; + return storeLayer.nodeGetProperty( statement.getStoreStatement(), node, propertyKeyId, state ); } @Override public Cursor relationshipGetProperties( KernelStatement statement, RelationshipItem relationship ) { - Cursor cursor; - if ( statement.hasTxStateWithChanges() && statement.txState().relationshipIsAddedInThisTx( relationship.id() ) ) - { - cursor = empty(); - } - else - { - cursor = storeLayer.relationshipGetProperties( statement.getStoreStatement(), relationship ); - } - - return statement.hasTxStateWithChanges() - ? statement.txState() - .augmentPropertyCursor( cursor, statement.txState().getRelationshipState( relationship.id() ) ) - : cursor; + RelationshipState state = statement.hasTxStateWithChanges() + ? statement.txState().getRelationshipState( relationship.id() ) + : null; + return storeLayer.relationshipGetProperties( statement.getStoreStatement(), relationship, state ); } @Override @@ -360,20 +327,10 @@ public boolean relationshipHasProperty( KernelStatement statement, RelationshipI private Cursor relationshipGetPropertyCursor( KernelStatement statement, RelationshipItem relationship, int propertyKeyId ) { - Cursor cursor; - if ( statement.hasTxStateWithChanges() && statement.txState().relationshipIsAddedInThisTx( relationship.id() ) ) - { - cursor = empty(); - } - else - { - cursor = storeLayer.relationshipGetProperty( statement.getStoreStatement(), relationship, propertyKeyId ); - } - - return statement.hasTxStateWithChanges() - ? statement.txState().augmentSinglePropertyCursor( cursor, statement.txState() - .getRelationshipState( relationship.id() ), propertyKeyId ) - : cursor; + RelationshipState state = statement.hasTxStateWithChanges() + ? statement.txState().getRelationshipState( relationship.id() ) + : null; + return storeLayer.relationshipGetProperty( statement.getStoreStatement(), relationship, propertyKeyId, state ); } // diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxAbstractPropertyCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxAbstractPropertyCursor.java deleted file mode 100644 index dfd8182845c9..000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxAbstractPropertyCursor.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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.api.cursor; - -import java.util.function.Consumer; - -import org.neo4j.cursor.Cursor; -import org.neo4j.kernel.api.properties.DefinedProperty; -import org.neo4j.storageengine.api.PropertyItem; -import org.neo4j.storageengine.api.txstate.PropertyContainerState; - -/** - * Overlays transaction state on a {@link PropertyItem} cursors. - */ -public abstract class TxAbstractPropertyCursor implements Cursor, PropertyItem -{ - private final Consumer instanceCache; - - protected Cursor cursor; - protected DefinedProperty property; - protected PropertyContainerState state; - - public TxAbstractPropertyCursor( Consumer instanceCache ) - { - this.instanceCache = instanceCache; - } - - public Cursor init( Cursor cursor, PropertyContainerState state ) - { - this.cursor = cursor; - this.state = state; - - return this; - } - - @Override - public PropertyItem get() - { - if ( property == null ) - { - throw new IllegalStateException(); - } - - return this; - } - - @Override - public void close() - { - cursor.close(); - cursor = null; - property = null; - instanceCache.accept( this ); - } - - @Override - public int propertyKeyId() - { - return property.propertyKeyId(); - } - - @Override - public Object value() - { - return property.value(); - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxAllPropertyCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxAllPropertyCursor.java deleted file mode 100644 index 0195063e6ba1..000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxAllPropertyCursor.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.api.cursor; - -import java.util.Iterator; -import java.util.function.Consumer; - -import org.neo4j.kernel.api.properties.DefinedProperty; -import org.neo4j.kernel.api.properties.Property; -import org.neo4j.storageengine.api.PropertyItem; -import org.neo4j.storageengine.api.StorageProperty; - -/** - * Overlays transaction state on a {@link PropertyItem} cursors. - */ -public class TxAllPropertyCursor extends TxAbstractPropertyCursor -{ - private Iterator added; - - public TxAllPropertyCursor( Consumer instanceCache ) - { - super( instanceCache ); - } - - @Override - public boolean next() - { - property = null; - if ( added == null ) - { - while ( cursor.next() ) - { - int propertyKeyId = cursor.get().propertyKeyId(); - - if ( state.isPropertyRemoved( propertyKeyId ) ) - { - continue; - } - - if ( property == null ) - { - this.property = (DefinedProperty) state.getChangedProperty( propertyKeyId ); - } - - if( property == null ) - { - this.property = Property.property( propertyKeyId, cursor.get().value() ); - } - - return property != null; - } - - added = state.addedProperties(); - } - - if ( added != null && added.hasNext() ) - { - property = (DefinedProperty) added.next(); - return true; - } - else - { - property = null; - return false; - } - } - - @Override - public void close() - { - super.close(); - this.added = null; - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxSinglePropertyCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxSinglePropertyCursor.java deleted file mode 100644 index 402c413cde95..000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/cursor/TxSinglePropertyCursor.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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.api.cursor; - -import java.util.function.Consumer; - -import org.neo4j.cursor.Cursor; -import org.neo4j.kernel.api.StatementConstants; -import org.neo4j.kernel.api.properties.DefinedProperty; -import org.neo4j.kernel.api.properties.Property; -import org.neo4j.storageengine.api.PropertyItem; -import org.neo4j.storageengine.api.txstate.PropertyContainerState; - -/** - * Overlays transaction state on a {@link PropertyItem} cursors. - */ -public class TxSinglePropertyCursor extends TxAbstractPropertyCursor -{ - private int propertyKeyId; - - public TxSinglePropertyCursor( Consumer instanceCache ) - { - super( instanceCache ); - } - - public Cursor init( Cursor cursor, - PropertyContainerState state, int propertyKeyId ) - { - super.init( cursor, state ); - this.propertyKeyId = propertyKeyId; - return this; - } - - @Override - public boolean next() - { - property = null; - - if ( propertyKeyId == StatementConstants.NO_SUCH_PROPERTY_KEY ) - { - return false; - } - - try - { - if ( state.isPropertyRemoved( propertyKeyId ) ) - { - return false; - } - - if ( property == null ) - { - property = (DefinedProperty) state.getChangedProperty( propertyKeyId ); - } - - if ( property == null ) - { - property = (DefinedProperty) state.getAddedProperty( propertyKeyId ); - } - - if ( property == null && cursor.next() ) - { - property = Property.property( cursor.get().propertyKeyId(), cursor.get().value() ); - } - - return property != null; - } - finally - { - propertyKeyId = StatementConstants.NO_SUCH_PROPERTY_KEY; - } - } - - @Override - public PropertyItem get() - { - if ( property == null ) - { - throw new IllegalStateException(); - } - - return super.get(); - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/TxState.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/TxState.java index 4a02f0b53f58..04f8af5f558d 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/TxState.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/state/TxState.java @@ -25,13 +25,11 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; -import java.util.function.Consumer; import org.neo4j.collection.primitive.Primitive; import org.neo4j.collection.primitive.PrimitiveIntSet; import org.neo4j.collection.primitive.PrimitiveLongIterator; import org.neo4j.collection.primitive.PrimitiveLongSet; -import org.neo4j.cursor.Cursor; import org.neo4j.helpers.collection.Iterables; import org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException; import org.neo4j.kernel.api.exceptions.schema.CreateConstraintFailureException; @@ -47,14 +45,10 @@ import org.neo4j.kernel.api.txstate.RelationshipChangeVisitorAdapter; import org.neo4j.kernel.api.txstate.TransactionState; import org.neo4j.kernel.impl.api.RelationshipVisitor; -import org.neo4j.kernel.impl.api.cursor.TxAllPropertyCursor; -import org.neo4j.kernel.impl.api.cursor.TxSinglePropertyCursor; import org.neo4j.kernel.impl.api.store.RelationshipIterator; -import org.neo4j.kernel.impl.util.InstanceCache; import org.neo4j.kernel.impl.util.diffsets.DiffSets; import org.neo4j.kernel.impl.util.diffsets.RelationshipDiffSets; import org.neo4j.storageengine.api.Direction; -import org.neo4j.storageengine.api.PropertyItem; import org.neo4j.storageengine.api.StorageProperty; import org.neo4j.storageengine.api.txstate.DiffSetsVisitor; import org.neo4j.storageengine.api.txstate.NodeState; @@ -156,32 +150,9 @@ void setMap( TxState state, Map map ) private Map>> indexUpdates; - private InstanceCache propertyCursor; - private InstanceCache singlePropertyCursor; - private boolean hasChanges; private boolean hasDataChanges; - public TxState() - { - propertyCursor = new InstanceCache() - { - @Override - protected TxAllPropertyCursor create() - { - return new TxAllPropertyCursor( (Consumer) this ); - } - }; - singlePropertyCursor = new InstanceCache() - { - @Override - protected TxSinglePropertyCursor create() - { - return new TxSinglePropertyCursor( (Consumer) this ); - } - }; - } - @Override public void accept( final TxStateVisitor visitor ) throws ConstraintValidationException, CreateConstraintFailureException @@ -683,22 +654,6 @@ public RelationshipState getRelationshipState( long id ) return RELATIONSHIP_STATE.get( this, id ); } - @Override - public Cursor augmentPropertyCursor( Cursor cursor, - PropertyContainerState propertyContainerState ) - { - return propertyContainerState.hasChanges() ? - propertyCursor.get().init( cursor, propertyContainerState ) : cursor; - } - - @Override - public Cursor augmentSinglePropertyCursor( Cursor cursor, - PropertyContainerState propertyContainerState, int propertyKeyId ) - { - return propertyContainerState.hasChanges() ? - singlePropertyCursor.get().init( cursor, propertyContainerState, propertyKeyId ) : cursor; - } - @Override public PrimitiveIntSet augmentLabels( PrimitiveIntSet labels, NodeState nodeState ) { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StorageLayer.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StorageLayer.java index 6f32622ab704..27841b307dc0 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StorageLayer.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StorageLayer.java @@ -78,6 +78,7 @@ import org.neo4j.storageengine.api.Token; import org.neo4j.storageengine.api.schema.PopulationProgress; import org.neo4j.storageengine.api.schema.SchemaRule; +import org.neo4j.storageengine.api.txstate.PropertyContainerState; import org.neo4j.storageengine.api.txstate.ReadableTransactionState; import static org.neo4j.collection.primitive.Primitive.intSet; @@ -418,31 +419,35 @@ public Cursor nodeGetRelationships( StorageStatement statement } @Override - public Cursor nodeGetProperties( StorageStatement statement, NodeItem node ) + public Cursor nodeGetProperties( StorageStatement statement, NodeItem node, + PropertyContainerState state ) { Lock lock = node.lock(); // lock before reading the property id, since we might need to reload the record - return statement.acquirePropertyCursor( node.nextPropertyId(), lock ); + return statement.acquirePropertyCursor( node.nextPropertyId(), lock, state ); } @Override - public Cursor nodeGetProperty( StorageStatement statement, NodeItem node, int propertyKeyId ) + public Cursor nodeGetProperty( StorageStatement statement, NodeItem node, int propertyKeyId, + PropertyContainerState state ) { Lock lock = node.lock(); // lock before reading the property id, since we might need to reload the record - return statement.acquireSinglePropertyCursor( node.nextPropertyId(), propertyKeyId, lock ); + return statement.acquireSinglePropertyCursor( node.nextPropertyId(), propertyKeyId, lock, state ); } @Override - public Cursor relationshipGetProperties( StorageStatement statement, RelationshipItem relationship ) + public Cursor relationshipGetProperties( StorageStatement statement, RelationshipItem relationship, + PropertyContainerState state ) { Lock lock = relationship.lock(); // lock before reading the property id, since we might need to reload the record - return statement.acquirePropertyCursor( relationship.nextPropertyId(), lock ); + return statement.acquirePropertyCursor( relationship.nextPropertyId(), lock, state ); } @Override - public Cursor relationshipGetProperty( StorageStatement statement, RelationshipItem relationship, int propertyKeyId ) + public Cursor relationshipGetProperty( StorageStatement statement, RelationshipItem relationship, + int propertyKeyId, PropertyContainerState state ) { Lock lock = relationship.lock(); // lock before reading the property id, since we might need to reload the record - return statement.acquireSinglePropertyCursor( relationship.nextPropertyId(), propertyKeyId, lock ); + return statement.acquireSinglePropertyCursor( relationship.nextPropertyId(), propertyKeyId, lock, state ); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreAbstractPropertyCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreAbstractPropertyCursor.java index d055724747e8..b401ab4fc0a2 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreAbstractPropertyCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreAbstractPropertyCursor.java @@ -22,12 +22,14 @@ import java.util.function.IntPredicate; import org.neo4j.cursor.Cursor; +import org.neo4j.kernel.api.properties.DefinedProperty; import org.neo4j.kernel.impl.locking.Lock; import org.neo4j.kernel.impl.store.RecordCursor; import org.neo4j.kernel.impl.store.RecordCursors; import org.neo4j.kernel.impl.store.record.PropertyRecord; import org.neo4j.kernel.impl.store.record.Record; import org.neo4j.storageengine.api.PropertyItem; +import org.neo4j.storageengine.api.txstate.PropertyContainerState; import static org.neo4j.kernel.impl.store.record.RecordLoad.FORCE; @@ -37,8 +39,10 @@ public abstract class StoreAbstractPropertyCursor implements Cursor recordCursor; protected boolean fetched; + private DefinedProperty property; private IntPredicate propertyKeyIds; private Lock lock; + protected PropertyContainerState state; StoreAbstractPropertyCursor( RecordCursors cursors ) { @@ -46,10 +50,12 @@ public abstract class StoreAbstractPropertyCursor implements Cursor instanceCache; + private boolean fromDisk; + private Iterator storagePropertyIterator; + public StorePropertyCursor( RecordCursors cursors, Consumer instanceCache ) { super( cursors ); this.instanceCache = instanceCache; } - public StorePropertyCursor init( long firstPropertyId, Lock lock ) + public StorePropertyCursor init( long firstPropertyId, Lock lock, PropertyContainerState state ) { - initialize( ALWAYS_TRUE_INT, firstPropertyId, lock ); + fromDisk = true; + storagePropertyIterator = state == null ? null : state.addedProperties(); + initialize( ALWAYS_TRUE_INT, firstPropertyId, lock, state ); return this; } @Override - protected boolean loop() + protected boolean loadNextFromDisk() + { + return fromDisk; + } + + @Override + protected DefinedProperty nextAdded() { - return true; + fromDisk = false; + if ( storagePropertyIterator != null ) + { + if ( storagePropertyIterator.hasNext() ) + { + return (DefinedProperty) storagePropertyIterator.next(); + } + storagePropertyIterator = null; + } + return null; } @Override protected void doClose() { + fromDisk = false; instanceCache.accept( this ); } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreSinglePropertyCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreSinglePropertyCursor.java index b38705e884f1..19e455f9f7e7 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreSinglePropertyCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreSinglePropertyCursor.java @@ -21,12 +21,15 @@ import java.util.function.Consumer; +import org.neo4j.kernel.api.properties.DefinedProperty; import org.neo4j.kernel.impl.locking.Lock; import org.neo4j.kernel.impl.store.RecordCursors; +import org.neo4j.storageengine.api.txstate.PropertyContainerState; public class StoreSinglePropertyCursor extends StoreAbstractPropertyCursor { private final Consumer instanceCache; + private int propertyKeyId; StoreSinglePropertyCursor( RecordCursors cursors, Consumer instanceCache ) { @@ -34,16 +37,24 @@ public class StoreSinglePropertyCursor extends StoreAbstractPropertyCursor this.instanceCache = instanceCache; } - public StoreSinglePropertyCursor init( int propertyKeyId, long firstPropertyId, Lock lock ) + public StoreSinglePropertyCursor init( int propertyKeyId, long firstPropertyId, Lock lock, + PropertyContainerState state ) { - initialize( key -> key == propertyKeyId, firstPropertyId, lock ); + this.propertyKeyId = propertyKeyId; + initialize( key -> key == propertyKeyId, firstPropertyId, lock, state ); return this; } @Override - protected boolean loop() + protected boolean loadNextFromDisk() { - return !fetched; + return !fetched && (state == null || state.getAddedProperty( propertyKeyId ) == null); + } + + @Override + protected DefinedProperty nextAdded() + { + return !fetched && state != null ? (DefinedProperty) state.getAddedProperty( propertyKeyId ) : null; } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreStatement.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreStatement.java index 7fdbe5d8db98..a7777e4affed 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreStatement.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/store/StoreStatement.java @@ -42,6 +42,7 @@ import org.neo4j.storageengine.api.StorageStatement; import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.storageengine.api.schema.LabelScanReader; +import org.neo4j.storageengine.api.txstate.PropertyContainerState; import org.neo4j.storageengine.api.txstate.ReadableTransactionState; /** @@ -177,15 +178,16 @@ public Cursor relationshipsGetAllCursor( ReadableTransactionSt } @Override - public Cursor acquirePropertyCursor( long propertyId, Lock lock ) + public Cursor acquirePropertyCursor( long propertyId, Lock lock, PropertyContainerState state ) { - return propertyCursorCache.get().init( propertyId, lock ); + return propertyCursorCache.get().init( propertyId, lock, state ); } @Override - public Cursor acquireSinglePropertyCursor( long propertyId, int propertyKeyId, Lock lock ) + public Cursor acquireSinglePropertyCursor( long propertyId, int propertyKeyId, Lock lock, + PropertyContainerState state ) { - return singlePropertyCursorCache.get().init( propertyKeyId, propertyId, lock ); + return singlePropertyCursorCache.get().init( propertyKeyId, propertyId, lock, state ); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/TxStateTransactionDataSnapshot.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/TxStateTransactionDataSnapshot.java index c3df90a7c6a9..0c8b4eaea329 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/TxStateTransactionDataSnapshot.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/coreapi/TxStateTransactionDataSnapshot.java @@ -209,7 +209,7 @@ private void takeSnapshot() { Lock lock = node.get().lock(); try ( Cursor properties = storeStatement - .acquirePropertyCursor( node.get().nextPropertyId(), lock ) ) + .acquirePropertyCursor( node.get().nextPropertyId(), lock, null ) ) { while ( properties.next() ) { @@ -237,7 +237,7 @@ private void takeSnapshot() { Lock lock = relationship.get().lock(); try ( Cursor properties = storeStatement - .acquirePropertyCursor( relationship.get().nextPropertyId(), lock ) ) + .acquirePropertyCursor( relationship.get().nextPropertyId(), lock, null ) ) { while ( properties.next() ) { @@ -370,7 +370,7 @@ private Object committedValue( NodeState nodeState, int property ) Lock lock = node.get().lock(); try ( Cursor properties = storeStatement - .acquireSinglePropertyCursor( node.get().nextPropertyId(), property, lock ) ) + .acquireSinglePropertyCursor( node.get().nextPropertyId(), property, lock, null ) ) { if ( properties.next() ) { @@ -399,7 +399,7 @@ private Object committedValue( RelationshipState relState, int property ) Lock lock = relationship.get().lock(); try ( Cursor properties = storeStatement - .acquireSinglePropertyCursor( relationship.get().nextPropertyId(), property, lock ) ) + .acquireSinglePropertyCursor( relationship.get().nextPropertyId(), property, lock, null ) ) { if ( properties.next() ) { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/participant/StoreMigrator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/participant/StoreMigrator.java index d1cc7da5461b..bcd0ff42fa59 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/participant/StoreMigrator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/participant/StoreMigrator.java @@ -691,7 +691,7 @@ private BiConsumer< final List scratch = new ArrayList<>(); return ( ENTITY entity, RECORD record ) -> { - cursor.init( record.getNextProp(), LockService.NO_LOCK ); + cursor.init( record.getNextProp(), LockService.NO_LOCK, null ); scratch.clear(); while ( cursor.next() ) { diff --git a/community/kernel/src/main/java/org/neo4j/storageengine/api/StorageStatement.java b/community/kernel/src/main/java/org/neo4j/storageengine/api/StorageStatement.java index 584df097138b..d4b436758c58 100644 --- a/community/kernel/src/main/java/org/neo4j/storageengine/api/StorageStatement.java +++ b/community/kernel/src/main/java/org/neo4j/storageengine/api/StorageStatement.java @@ -26,6 +26,7 @@ import org.neo4j.kernel.impl.store.RecordCursors; import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.storageengine.api.schema.LabelScanReader; +import org.neo4j.storageengine.api.txstate.PropertyContainerState; import org.neo4j.storageengine.api.txstate.ReadableTransactionState; /** @@ -115,9 +116,9 @@ Cursor acquireNodeRelationshipCursor( boolean isDense, long no */ Cursor relationshipsGetAllCursor( ReadableTransactionState state ); - Cursor acquirePropertyCursor( long propertyId, Lock shortLivedReadLock ); + Cursor acquirePropertyCursor( long propertyId, Lock shortLivedReadLock, PropertyContainerState state ); - Cursor acquireSinglePropertyCursor( long propertyId, int propertyKeyId, Lock shortLivedReadLock ); + Cursor acquireSinglePropertyCursor( long propertyId, int propertyKeyId, Lock shortLivedReadLock, PropertyContainerState state ); /** * @return {@link LabelScanReader} capable of reading nodes for specific label ids. diff --git a/community/kernel/src/main/java/org/neo4j/storageengine/api/StoreReadLayer.java b/community/kernel/src/main/java/org/neo4j/storageengine/api/StoreReadLayer.java index b27575334669..9f59a2884013 100644 --- a/community/kernel/src/main/java/org/neo4j/storageengine/api/StoreReadLayer.java +++ b/community/kernel/src/main/java/org/neo4j/storageengine/api/StoreReadLayer.java @@ -44,6 +44,7 @@ import org.neo4j.kernel.impl.api.store.RelationshipIterator; import org.neo4j.register.Register.DoubleLongRegister; import org.neo4j.storageengine.api.schema.PopulationProgress; +import org.neo4j.storageengine.api.txstate.PropertyContainerState; import org.neo4j.storageengine.api.txstate.ReadableTransactionState; /** @@ -276,13 +277,16 @@ Cursor nodeGetRelationships( StorageStatement statement, NodeI Cursor nodeGetRelationships( StorageStatement statement, NodeItem nodeItem, Direction direction, int[] relTypes, ReadableTransactionState state ); - Cursor nodeGetProperties( StorageStatement statement, NodeItem node ); + Cursor nodeGetProperties( StorageStatement statement, NodeItem node, PropertyContainerState state ); - Cursor nodeGetProperty( StorageStatement statement, NodeItem node, int propertyKeyId ); + Cursor nodeGetProperty( StorageStatement statement, NodeItem node, int propertyKeyId, + PropertyContainerState state ); - Cursor relationshipGetProperties( StorageStatement statement, RelationshipItem relationship ); + Cursor relationshipGetProperties( StorageStatement statement, RelationshipItem relationship, + PropertyContainerState state ); - Cursor relationshipGetProperty( StorageStatement statement, RelationshipItem relationshipItem, int propertyKeyId ); + Cursor relationshipGetProperty( StorageStatement statement, RelationshipItem relationshipItem, + int propertyKeyId, PropertyContainerState state ); /** * Reserves a node id for future use to store a node. The reason for it being exposed here is that diff --git a/community/kernel/src/main/java/org/neo4j/storageengine/api/txstate/ReadableTransactionState.java b/community/kernel/src/main/java/org/neo4j/storageengine/api/txstate/ReadableTransactionState.java index 5dc9a0713f12..d41b4a561aa0 100644 --- a/community/kernel/src/main/java/org/neo4j/storageengine/api/txstate/ReadableTransactionState.java +++ b/community/kernel/src/main/java/org/neo4j/storageengine/api/txstate/ReadableTransactionState.java @@ -140,13 +140,6 @@ ReadableDiffSets indexUpdatesForRangeSeekByString( IndexDescriptor index, RelationshipState getRelationshipState( long id ); - Cursor augmentPropertyCursor( Cursor cursor, - PropertyContainerState propertyContainerState ); - - Cursor augmentSinglePropertyCursor( Cursor cursor, - PropertyContainerState propertyContainerState, - int propertyKeyId ); - PrimitiveIntSet augmentLabels( PrimitiveIntSet cursor, NodeState nodeState ); /** diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/IndexQueryTransactionStateTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/IndexQueryTransactionStateTest.java index 0b316919a72a..6b90f5e970c2 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/IndexQueryTransactionStateTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/IndexQueryTransactionStateTest.java @@ -46,6 +46,7 @@ import org.neo4j.storageengine.api.NodeItem; import org.neo4j.storageengine.api.StoreReadLayer; import org.neo4j.storageengine.api.schema.IndexReader; +import org.neo4j.storageengine.api.txstate.PropertyContainerState; import org.neo4j.storageengine.api.txstate.ReadableTransactionState; import static java.util.Arrays.asList; @@ -349,9 +350,10 @@ public void shouldExcludeUniqueNodeWithRemovedProperty() throws Exception private void mockStoreProperty() { - when( store.nodeGetProperties( eq( statement ), any( NodeItem.class ) ) ) + when( store.nodeGetProperties( eq( statement ), any( NodeItem.class ), any( PropertyContainerState.class ) ) ) .thenReturn( asPropertyCursor( stringProperty( propertyKeyId, value ) ) ); - when( store.nodeGetProperty( eq( statement ), any( NodeItem.class ), eq( propertyKeyId ) ) ) + when( store.nodeGetProperty( eq( statement ), any( NodeItem.class ), eq( propertyKeyId ), + any( PropertyContainerState.class ) ) ) .thenReturn( asPropertyCursor( stringProperty( propertyKeyId, value ) ) ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/LabelTransactionStateTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/LabelTransactionStateTest.java index db1dd19f8546..2a3d5a74a184 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/LabelTransactionStateTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/LabelTransactionStateTest.java @@ -34,7 +34,6 @@ import org.neo4j.kernel.api.exceptions.EntityNotFoundException; import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory; -import org.neo4j.kernel.api.txstate.TransactionState; import org.neo4j.kernel.impl.api.KernelStatement; import org.neo4j.kernel.impl.api.StateHandlingStatementOperations; import org.neo4j.kernel.impl.api.StatementOperationsTestHelper; @@ -43,6 +42,7 @@ import org.neo4j.kernel.impl.index.LegacyIndexStore; import org.neo4j.storageengine.api.NodeItem; import org.neo4j.storageengine.api.StoreReadLayer; +import org.neo4j.storageengine.api.txstate.PropertyContainerState; import org.neo4j.storageengine.api.txstate.ReadableTransactionState; import static org.junit.Assert.assertEquals; @@ -247,7 +247,8 @@ public void should_return_true_when_adding_new_label() throws Exception { // GIVEN when( storeStatement.acquireSingleNodeCursor( 1337, null ) ).thenReturn( asNodeCursor( 1337 ) ); - when( store.nodeGetProperties( eq( storeStatement ), any( NodeItem.class ) ) ) + when( store + .nodeGetProperties( eq( storeStatement ), any( NodeItem.class ), any( PropertyContainerState.class ) ) ) .thenReturn( asPropertyCursor() ); // WHEN @@ -263,7 +264,8 @@ public void should_return_false_when_adding_existing_label() throws Exception // GIVEN when( storeStatement.acquireSingleNodeCursor( 1337, null ) ) .thenReturn( asNodeCursor( 1337, StubCursors.labels( 12 ) ) ); - when( store.nodeGetProperties( eq( storeStatement ), any( NodeItem.class ) ) ) + when( store + .nodeGetProperties( eq( storeStatement ), any( NodeItem.class ), any( PropertyContainerState.class ) ) ) .thenReturn( asPropertyCursor() ); // WHEN @@ -279,7 +281,8 @@ public void should_return_true_when_removing_existing_label() throws Exception // GIVEN when( storeStatement.acquireSingleNodeCursor( 1337, null ) ) .thenReturn( asNodeCursor( 1337, StubCursors.labels( 12 ) ) ); - when( store.nodeGetProperties( eq( storeStatement ), any( NodeItem.class ) ) ) + when( store + .nodeGetProperties( eq( storeStatement ), any( NodeItem.class ), any( PropertyContainerState.class ) ) ) .thenReturn( asPropertyCursor() ); // WHEN @@ -339,7 +342,7 @@ private void commitLabels( Labels... labels ) throws Exception when( storeStatement .acquireSingleNodeCursor( eq( nodeLabels.nodeId ), any( ReadableTransactionState.class ) ) ) .thenReturn( asNodeCursor( nodeLabels.nodeId, StubCursors.labels( nodeLabels.labelIds ) ) ); - when( store.nodeGetProperties( eq( storeStatement ), any( NodeItem.class ) ) ) + when( store.nodeGetProperties( eq( storeStatement ), any( NodeItem.class ), any(PropertyContainerState.class) ) ) .thenReturn( asPropertyCursor() ); for ( int label : nodeLabels.labelIds ) diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/StateHandlingStatementOperationsTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/StateHandlingStatementOperationsTest.java index 0f2cb726b4a2..67e6d95ced98 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/StateHandlingStatementOperationsTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/StateHandlingStatementOperationsTest.java @@ -102,7 +102,7 @@ public void shouldNeverDelegateWrites() throws Exception when( inner.indexesGetForLabel( 0 ) ).thenReturn( iterator( IndexDescriptorFactory.forLabel( 0, 0 ) ) ); when( storeStatement.acquireSingleNodeCursor( anyLong(), any( ReadableTransactionState.class ) ) ) .thenReturn( asNodeCursor( 0 ) ); - when( inner.nodeGetProperties( eq( storeStatement ), any( NodeItem.class ) ) ). + when( inner.nodeGetProperties( eq( storeStatement ), any( NodeItem.class ), eq( null ) ) ). thenReturn( asPropertyCursor() ); StateHandlingStatementOperations ctx = newTxStateOps( inner ); @@ -428,9 +428,8 @@ public void shouldConsiderTransactionStateDuringIndexBetweenRangeSeekByNumberWit { long nodeId = (long) invocationOnMock.getArguments()[0]; ReadableTransactionState state = (ReadableTransactionState) invocationOnMock.getArguments()[1]; - when( state.augmentSinglePropertyCursor( any( Cursor.class ), any( PropertyContainerState.class ), - eq( propertyKey ) ) ).thenReturn( asPropertyCursor( intProperty( propertyKey, inRange ) ) ); - when( storeReadLayer.nodeGetProperty( eq( storageStatement ), any( NodeItem.class ), eq( propertyKey ) ) ) + when( storeReadLayer + .nodeGetProperty( eq( storageStatement ), any( NodeItem.class ), eq( propertyKey ), eq( null ) ) ) .thenReturn( asPropertyCursor( intProperty( propertyKey, inRange ) ) ); return asNodeCursor( nodeId, nodeId + 20000 ); } ); @@ -516,8 +515,8 @@ public void shouldNotRecordNodeSetPropertyOnSameValue() throws Exception when( autoIndexing.relationships() ).thenReturn( AutoIndexOperations.UNSUPPORTED ); StoreReadLayer storeReadLayer = mock( StoreReadLayer.class ); Cursor propertyItemCursor = propertyCursor( propertyKeyId, value ); - when( storeReadLayer.nodeGetProperty( eq( storeStatement ), any( NodeItem.class ), - eq( propertyKeyId ) ) ).thenReturn( propertyItemCursor ); + when( storeReadLayer.nodeGetProperty( eq( storeStatement ), any( NodeItem.class ), eq( propertyKeyId ), + any( PropertyContainerState.class ) ) ).thenReturn( propertyItemCursor ); StateHandlingStatementOperations operations = newTxStateOps( storeReadLayer, autoIndexing ); // WHEN @@ -551,8 +550,9 @@ public void shouldNotRecordRelationshipSetPropertyOnSameValue() throws Exception when( autoIndexing.relationships() ).thenReturn( autoIndexOps ); StoreReadLayer storeReadLayer = mock( StoreReadLayer.class ); Cursor propertyItemCursor = propertyCursor( propertyKeyId, value ); - when( storeReadLayer.relationshipGetProperty( eq( storeStatement ), any( RelationshipItem.class ), - eq( propertyKeyId ) ) ).thenReturn( propertyItemCursor ); + when( storeReadLayer + .relationshipGetProperty( eq( storeStatement ), any( RelationshipItem.class ), eq( propertyKeyId ), + any( PropertyContainerState.class ) ) ).thenReturn( propertyItemCursor ); StateHandlingStatementOperations operations = newTxStateOps( storeReadLayer, autoIndexing ); // WHEN diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/StateOperationsAutoIndexingTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/StateOperationsAutoIndexingTest.java index a8dd6f3ea0c8..6ad4e6b4e240 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/StateOperationsAutoIndexingTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/state/StateOperationsAutoIndexingTest.java @@ -108,7 +108,8 @@ public void shouldSignalNodePropertyAddedToAutoIndex() throws Exception NodeItem node = mock( NodeItem.class ); when( node.labels() ).thenReturn( PrimitiveIntCollections.emptySet() ); when( storeStmt.acquireSingleNodeCursor( 1337, null ) ).thenReturn( cursor( node ) ); - when( storeLayer.nodeGetProperty( eq( storeStmt ), any( NodeItem.class ), eq( property.propertyKeyId() ) ) ) + when( storeLayer + .nodeGetProperty( eq( storeStmt ), any( NodeItem.class ), eq( property.propertyKeyId() ), eq( null ) ) ) .thenReturn( cursor() ); // When @@ -127,7 +128,8 @@ public void shouldSignalRelationshipPropertyAddedToAutoIndex() throws Exception RelationshipItem relationship = mock( RelationshipItem.class ); when( storeStmt.acquireSingleRelationshipCursor( 1337, null ) ).thenReturn( cursor( relationship ) ); - when( storeLayer.relationshipGetProperty( storeStmt, relationship, propertyKeyId ) ).thenReturn( empty() ); + when( storeLayer.relationshipGetProperty( storeStmt, relationship, propertyKeyId, null ) ) + .thenReturn( empty() ); // When context.relationshipSetProperty( stmt, 1337, property ); @@ -149,7 +151,8 @@ public void shouldSignalNodePropertyChangedToAutoIndex() throws Exception NodeItem node = mock( NodeItem.class ); when( node.labels() ).thenReturn( PrimitiveIntCollections.emptySet() ); when( storeStmt.acquireSingleNodeCursor( 1337, null ) ).thenReturn( cursor( node ) ); - when( storeLayer.nodeGetProperty( eq( storeStmt ), any( NodeItem.class ), eq( property.propertyKeyId() ) ) ) + when( storeLayer + .nodeGetProperty( eq( storeStmt ), any( NodeItem.class ), eq( property.propertyKeyId() ), eq( null ) ) ) .thenReturn( cursor( existingProperty ) ); // When @@ -172,7 +175,7 @@ public void shouldSignalRelationshipPropertyChangedToAutoIndex() throws Exceptio RelationshipItem relationship = mock( RelationshipItem.class ); when( storeStmt.acquireSingleRelationshipCursor( 1337, null ) ).thenReturn( cursor( relationship ) ); - when( storeLayer.relationshipGetProperty( storeStmt, relationship, propertyKeyId ) ) + when( storeLayer.relationshipGetProperty( storeStmt, relationship, propertyKeyId, null ) ) .thenReturn( cursor( existingProperty ) ); // When @@ -192,7 +195,7 @@ public void shouldSignalNodePropertyRemovedToAutoIndex() throws Exception int propertyKeyId = existingProperty.propertyKeyId(); NodeItem node = mock( NodeItem.class ); - when( storeLayer.nodeGetProperty( eq( storeStmt ), any( NodeItem.class ), eq( propertyKeyId ) ) ) + when( storeLayer.nodeGetProperty( eq( storeStmt ), any( NodeItem.class ), eq( propertyKeyId ), eq( null ) ) ) .thenReturn( cursor( existingProperty ) ); when( node.labels() ).thenReturn( PrimitiveIntCollections.emptySet() ); when( storeStmt.acquireSingleNodeCursor( 1337, null ) ).thenReturn( cursor( node ) ); @@ -216,7 +219,7 @@ public void shouldSignalRelationshipPropertyRemovedToAutoIndex() throws Exceptio RelationshipItem relationship = mock( RelationshipItem.class ); when( storeStmt.acquireSingleRelationshipCursor( 1337, null ) ).thenReturn( cursor( relationship ) ); - when( storeLayer.relationshipGetProperty( storeStmt, relationship, propertyKeyId ) ) + when( storeLayer.relationshipGetProperty( storeStmt, relationship, propertyKeyId, null ) ) .thenReturn( cursor( existingProperty ) ); // When diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorageLayerPropertyTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorageLayerPropertyTest.java index 45a23eaab04f..7320dae94447 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorageLayerPropertyTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorageLayerPropertyTest.java @@ -102,7 +102,7 @@ public void should_get_all_node_properties() throws Exception Lock lock = node.get().lock(); try ( Cursor props = statement - .acquireSinglePropertyCursor( node.get().nextPropertyId(), propKey, lock ) ) + .acquireSinglePropertyCursor( node.get().nextPropertyId(), propKey, lock, null ) ) { if ( props.next() ) { diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorePropertyCursorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorePropertyCursorTest.java index bf3425069520..ee84251b1f54 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorePropertyCursorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/store/StorePropertyCursorTest.java @@ -254,7 +254,7 @@ public void shouldReturnTheCursorToTheCacheOnClose() throws Throwable { // given StorePropertyCursor storePropertyCursor = newStorePropertyCursor( propertyStore, cache ); - storePropertyCursor.init( 0, NO_LOCK ); + storePropertyCursor.init( 0, NO_LOCK, null ); // when storePropertyCursor.close(); @@ -333,7 +333,7 @@ public void shouldReturnAProperty() throws Throwable StorePropertyCursor storePropertyCursor = newStorePropertyCursor( propertyStore ); // when - try ( Cursor cursor = storePropertyCursor.init( recordId, NO_LOCK ) ) + try ( Cursor cursor = storePropertyCursor.init( recordId, NO_LOCK, null ) ) { // then assertTrue( cursor.next() ); @@ -396,7 +396,7 @@ public void shouldReturnAPropertyBySkippingOne() throws Throwable StorePropertyCursor storePropertyCursor = newStorePropertyCursor( propertyStore ); // when - try ( Cursor cursor = storePropertyCursor.init( recordId, NO_LOCK ) ) + try ( Cursor cursor = storePropertyCursor.init( recordId, NO_LOCK, null ) ) { // then assertTrue( cursor.next() ); @@ -428,7 +428,7 @@ public void shouldReturnTwoProperties() throws Throwable StorePropertyCursor storePropertyCursor = newStorePropertyCursor( propertyStore ); // when - try ( Cursor cursor = storePropertyCursor.init( recordId, NO_LOCK ) ) + try ( Cursor cursor = storePropertyCursor.init( recordId, NO_LOCK, null ) ) { PropertyItem item; @@ -474,7 +474,7 @@ public void shouldReuseCorrectlyCursor() throws Throwable StorePropertyCursor storePropertyCursor = newStorePropertyCursor( propertyStore ); - try ( Cursor cursor = storePropertyCursor.init( recordId, NO_LOCK ) ) + try ( Cursor cursor = storePropertyCursor.init( recordId, NO_LOCK, null ) ) { assertTrue( cursor.next() ); PropertyItem item = cursor.get(); @@ -484,7 +484,7 @@ public void shouldReuseCorrectlyCursor() throws Throwable } // when using it - try ( Cursor cursor = storePropertyCursor.init( recordId, NO_LOCK ) ) + try ( Cursor cursor = storePropertyCursor.init( recordId, NO_LOCK, null ) ) { // then assertTrue( cursor.next() ); @@ -508,7 +508,7 @@ public void readPropertyChainWithMultipleEntries() try ( StorePropertyCursor cursor = newStorePropertyCursor( propertyStore ) ) { - cursor.init( firstPropertyId, NO_LOCK ); + cursor.init( firstPropertyId, NO_LOCK, null ); List valuesFromCursor = asPropertyValuesList( cursor ); assertEquals( asList( propertyValues ), valuesFromCursor ); @@ -524,7 +524,7 @@ public void callNextAfterReadingPropertyChain() try ( StorePropertyCursor cursor = newStorePropertyCursor( propertyStore ) ) { - cursor.init( firstPropertyId, NO_LOCK ); + cursor.init( firstPropertyId, NO_LOCK, null ); assertTrue( cursor.next() ); assertEquals( "1", cursor.value() ); @@ -550,7 +550,7 @@ public void skipUnusedRecordsInChain() try ( StorePropertyCursor cursor = newStorePropertyCursor( propertyStore ) ) { - cursor.init( firstPropertyId, NO_LOCK ); + cursor.init( firstPropertyId, NO_LOCK, null ); List valuesFromCursor = asPropertyValuesList( cursor ); assertEquals( asList( "1", 3, 5L, '7', "9 and 10" ), valuesFromCursor ); @@ -569,7 +569,7 @@ public void skipUnusedConsecutiveRecordsInChain() try ( StorePropertyCursor cursor = newStorePropertyCursor( propertyStore ) ) { - cursor.init( firstPropertyId, NO_LOCK ); + cursor.init( firstPropertyId, NO_LOCK, null ); List valuesFromCursor = asPropertyValuesList( cursor ); assertEquals( asList( "1", "2", 6L, '7', '8', "9 and 10" ), valuesFromCursor ); @@ -589,7 +589,7 @@ public void skipAllRecordsWhenWholeChainNotInUse() try ( StorePropertyCursor cursor = newStorePropertyCursor( propertyStore ) ) { - cursor.init( firstPropertyId, NO_LOCK ); + cursor.init( firstPropertyId, NO_LOCK, null ); List valuesFromCursor = asPropertyValuesList( cursor ); assertEquals( Collections.emptyList(), valuesFromCursor ); @@ -608,7 +608,7 @@ public void readPropertyChainWithLongStringDynamicRecordsNotInUse() try ( StorePropertyCursor cursor = newStorePropertyCursor( propertyStore ) ) { - cursor.init( chainStartId, NO_LOCK ); + cursor.init( chainStartId, NO_LOCK, null ); List valuesFromCursor = asPropertyValuesList( cursor ); assertEquals( asList( values ), valuesFromCursor ); @@ -674,7 +674,7 @@ public void readPropertyChainWithLongArrayDynamicRecordsNotInUse() try ( StorePropertyCursor cursor = newStorePropertyCursor( propertyStore ) ) { - cursor.init( chainStartId, NO_LOCK ); + cursor.init( chainStartId, NO_LOCK, null ); List valuesFromCursor = asPropertyValuesList( cursor ); for ( int i = 0; i < valuesFromCursor.size(); i++ ) @@ -712,7 +712,7 @@ private void verifyPropertyValue( String expectedValue, long recordId ) { try ( StorePropertyCursor cursor = newStorePropertyCursor( propertyStore ) ) { - cursor.init( recordId, NO_LOCK ); + cursor.init( recordId, NO_LOCK, null ); assertTrue( cursor.next() ); assertEquals( expectedValue, cursor.value() ); assertFalse( cursor.next() ); @@ -723,7 +723,7 @@ private void verifyPropertyValue( byte[] expectedValue, long recordId ) { try ( StorePropertyCursor cursor = newStorePropertyCursor( propertyStore ) ) { - cursor.init( recordId, NO_LOCK ); + cursor.init( recordId, NO_LOCK, null ); assertTrue( cursor.next() ); assertArrayEquals( expectedValue, (byte[]) cursor.value() ); assertFalse( cursor.next() ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/coreapi/TxStateTransactionDataViewTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/coreapi/TxStateTransactionDataViewTest.java index 0bbed6df93d4..606e4017052e 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/coreapi/TxStateTransactionDataViewTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/coreapi/TxStateTransactionDataViewTest.java @@ -104,12 +104,13 @@ public void showsDeletedNodes() throws Exception when( storeStatement.acquireSingleNodeCursor( eq( 2L ), any( ReadableTransactionState.class ) ) ) .thenReturn( asNodeCursor( 2L, 20L, labels( 15 ) ) ); - when( storeStatement.acquirePropertyCursor( eq( 20L ), any( Lock.class ) ) ) + when( storeStatement.acquirePropertyCursor( eq( 20L ), any( Lock.class ), eq( null ) ) ) .thenReturn( asPropertyCursor( stringProperty( 1, "p" ) ) ); when( storeStatement.acquireSingleNodeCursor( eq( 1L ), any( ReadableTransactionState.class ) ) ) .thenReturn( asNodeCursor( 1L, 21L, labels() ) ); - when( storeStatement.acquirePropertyCursor( eq( 21L ), any( Lock.class ) ) ).thenReturn( asPropertyCursor() ); + when( storeStatement.acquirePropertyCursor( eq( 21L ), any( Lock.class ), eq( null ) ) ) + .thenReturn( asPropertyCursor() ); when( ops.propertyKeyGetName( 1 ) ).thenReturn( "key" ); when( ops.labelGetName( 15 ) ).thenReturn( "label" ); @@ -142,11 +143,11 @@ public void showsRemovedRelationships() throws Exception long noPropertyId = -1L; when( storeStatement.acquireSingleRelationshipCursor( 1L , null ) ). thenReturn( asRelationshipCursor( 1L, 1, 1L, 2L, noPropertyId ) ); - when( storeStatement.acquirePropertyCursor( noPropertyId, NO_LOCK ) ).thenReturn( asPropertyCursor() ); + when( storeStatement.acquirePropertyCursor( noPropertyId, NO_LOCK, null ) ).thenReturn( asPropertyCursor() ); long propertyId = 40L; when( storeStatement.acquireSingleRelationshipCursor( 2L, null ) ). thenReturn( asRelationshipCursor( 2L, 1, 1L, 1L, propertyId ) ); - when( storeStatement.acquirePropertyCursor( propertyId, NO_LOCK ) ) + when( storeStatement.acquirePropertyCursor( propertyId, NO_LOCK, null ) ) .thenReturn( asPropertyCursor( Property.stringProperty( 1, "p" ) ) ); when( ops.propertyKeyGetName( 1 ) ).thenReturn( "key" ); @@ -165,7 +166,7 @@ public void correctlySaysNodeIsDeleted() throws Exception Node node = mock( Node.class ); when( node.getId() ).thenReturn( 1L ); when( storeStatement.acquireSingleNodeCursor( 1, null ) ).thenReturn( asNodeCursor( 1, -1 ) ); - when( storeStatement.acquirePropertyCursor( -1, NO_LOCK ) ).thenReturn( asPropertyCursor() ); + when( storeStatement.acquirePropertyCursor( -1, NO_LOCK, null ) ).thenReturn( asPropertyCursor() ); // When & Then assertThat( snapshot().isDeleted( node ), equalTo( true ) ); @@ -182,7 +183,7 @@ public void correctlySaysRelIsDeleted() throws Exception long noPropertyId = -1L; when( storeStatement.acquireSingleRelationshipCursor( 1L, null ) ) .thenReturn( asRelationshipCursor( 1L, 1, 1L, 2L, noPropertyId ) ); - when( storeStatement.acquirePropertyCursor( noPropertyId, NO_LOCK ) ).thenReturn( asPropertyCursor() ); + when( storeStatement.acquirePropertyCursor( noPropertyId, NO_LOCK, null ) ).thenReturn( asPropertyCursor() ); // When & Then assertThat( snapshot().isDeleted( rel ), equalTo( true ) ); @@ -199,7 +200,7 @@ public void shouldListAddedNodePropertiesProperties() throws Exception long propertyId = 20L; when( storeStatement.acquireSingleNodeCursor( eq( 1L ), any( ReadableTransactionState.class ) ) ) .thenReturn( asNodeCursor( 1L, propertyId, labels() ) ); - when( storeStatement.acquireSinglePropertyCursor( propertyId, propertyKeyId, NO_LOCK ) ) + when( storeStatement.acquireSinglePropertyCursor( propertyId, propertyKeyId, NO_LOCK, null ) ) .thenReturn( asPropertyCursor( prevProp ) ); // When @@ -224,7 +225,7 @@ public void shouldListRemovedNodeProperties() throws Exception long propertyId = 20L; when( storeStatement.acquireSingleNodeCursor( eq( 1L ), any( ReadableTransactionState.class ) ) ) .thenReturn( asNodeCursor( 1L, propertyId, labels() ) ); - when( storeStatement.acquireSinglePropertyCursor( propertyId, propertyKeyId, NO_LOCK ) ) + when( storeStatement.acquireSinglePropertyCursor( propertyId, propertyKeyId, NO_LOCK, null ) ) .thenReturn( asPropertyCursor( prevProp ) ); // When @@ -248,7 +249,7 @@ public void shouldListRemovedRelationshipProperties() throws Exception long propertyId = 40L; when( storeStatement.acquireSingleRelationshipCursor( 1, null ) ) .thenReturn( asRelationshipCursor( 1, 0, 0, 0, propertyId ) ); - when( storeStatement.acquireSinglePropertyCursor( propertyId, propertyKeyId, NO_LOCK ) ) + when( storeStatement.acquireSinglePropertyCursor( propertyId, propertyKeyId, NO_LOCK, null ) ) .thenReturn( asPropertyCursor( prevValue ) ); // When @@ -273,7 +274,7 @@ public void shouldListAddedRelationshipProperties() throws Exception long propertyId = 40L; when( storeStatement.acquireSingleRelationshipCursor( 1, null ) ) .thenReturn( asRelationshipCursor( 1, 0, 0, 0, propertyId ) ); - when( storeStatement.acquireSinglePropertyCursor( propertyId, propertyKeyId, NO_LOCK ) ) + when( storeStatement.acquireSinglePropertyCursor( propertyId, propertyKeyId, NO_LOCK, null ) ) .thenReturn( asPropertyCursor( prevProp ) ); // When diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NeoStoresTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NeoStoresTest.java index 238c9c30cf43..30536a1e7d67 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NeoStoresTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NeoStoresTest.java @@ -343,7 +343,8 @@ private DefinedProperty relAddProperty( long relationshipId, int key, Object val private DefinedProperty getProperty( int key, StorageStatement statement, long propertyId ) { - try ( Cursor propertyCursor = statement.acquireSinglePropertyCursor( propertyId, key, NO_LOCK ) ) + try ( Cursor propertyCursor = statement + .acquireSinglePropertyCursor( propertyId, key, NO_LOCK, null ) ) { if ( propertyCursor.next() ) { diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/PropertyExistenceEnforcer.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/PropertyExistenceEnforcer.java index 3f23dea59dba..b1a2b1f09455 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/PropertyExistenceEnforcer.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/PropertyExistenceEnforcer.java @@ -285,15 +285,14 @@ private void validateRelationship( long id ) throws RelationshipPropertyExistenc private Cursor properties( NodeItem node ) { Lock lock = node.lock(); - Cursor cursor = storeStatement().acquirePropertyCursor( node.nextPropertyId(), lock ); - return txState.augmentPropertyCursor( cursor, txState.getNodeState( node.id() ) ); + return storeStatement().acquirePropertyCursor( node.nextPropertyId(), lock, txState.getNodeState( node.id() ) ); } private Cursor properties( RelationshipItem relationship ) { Lock lock = relationship.lock(); - Cursor cursor = storeStatement().acquirePropertyCursor( relationship.nextPropertyId(), lock ); - return txState.augmentPropertyCursor( cursor, txState.getRelationshipState( relationship.id() ) ); + return storeStatement().acquirePropertyCursor( relationship.nextPropertyId(), + lock, txState.getRelationshipState( relationship.id() ) ); } private StorageStatement storeStatement()