From ac17817ec181c2a6cdb146a9338d5e0b5eab878a Mon Sep 17 00:00:00 2001 From: fickludd Date: Mon, 13 Nov 2017 15:24:48 +0100 Subject: [PATCH] remove abstraction leak of stores --- .../kernel/impl/newapi/AllStoreHolder.java | 98 ++------ .../recordstorage/RecordStorageEngine.java | 7 - .../impl/recordstorage/StoreStatement.java | 215 ++++++++++++++++++ .../neo4j/kernel/impl/store/NeoStores.java | 6 +- .../neo4j/kernel/impl/store/StoreHolder.java | 53 ----- .../storageengine/api/StorageEngine.java | 6 - .../storageengine/api/StorageStatement.java | 111 +++++++++ .../kernel/api/KernelTransactionFactory.java | 3 - .../impl/api/KernelTransactionTestBase.java | 3 - .../impl/api/KernelTransactionsTest.java | 2 - 10 files changed, 351 insertions(+), 153 deletions(-) delete mode 100644 community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreHolder.java 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 881bcfe70b213..094740243d99a 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 @@ -20,7 +20,6 @@ package org.neo4j.kernel.impl.newapi; import java.nio.ByteBuffer; -import java.nio.ByteOrder; import java.util.function.Supplier; import org.neo4j.function.Suppliers; @@ -38,14 +37,8 @@ import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory; import org.neo4j.kernel.api.txstate.ExplicitIndexTransactionState; import org.neo4j.kernel.impl.api.store.PropertyUtil; -import org.neo4j.kernel.impl.store.AbstractDynamicStore; -import org.neo4j.kernel.impl.store.NodeStore; -import org.neo4j.kernel.impl.store.PropertyStore; import org.neo4j.kernel.impl.store.RecordCursor; import org.neo4j.kernel.impl.store.RecordStore; -import org.neo4j.kernel.impl.store.RelationshipGroupStore; -import org.neo4j.kernel.impl.store.RelationshipStore; -import org.neo4j.kernel.impl.store.StoreHolder; import org.neo4j.kernel.impl.store.record.AbstractBaseRecord; import org.neo4j.kernel.impl.store.record.DynamicRecord; import org.neo4j.kernel.impl.store.record.NodeRecord; @@ -63,15 +56,14 @@ import org.neo4j.values.storable.TextValue; import org.neo4j.values.storable.Values; -import static org.neo4j.kernel.impl.store.record.AbstractBaseRecord.NO_ID; import static org.neo4j.kernel.impl.store.record.RecordLoad.NORMAL; class AllStoreHolder extends Read implements Token { - private final RelationshipGroupStore groupStore; - private final PropertyStore propertyStore; - private final NodeStore nodeStore; - private final RelationshipStore relationshipStore; + private final StorageStatement.Nodes nodes; + private final StorageStatement.Groups groups; + private final StorageStatement.Properties properties; + private final StorageStatement.Relationships relationships; private final StorageStatement statement; private final StoreReadLayer read; private final Lazy explicitIndexes; @@ -84,11 +76,10 @@ class AllStoreHolder extends Read implements Token this.statement = statement; // use provided statement, to assert no leakage this.explicitIndexes = Suppliers.lazySingleton( explicitIndexes ); - StoreHolder stores = engine.stores(); - this.nodeStore = stores.getNodeStore(); - this.relationshipStore = stores.getRelationshipStore(); - this.groupStore = stores.getRelationshipGroupStore(); - this.propertyStore = stores.getPropertyStore(); + this.nodes = statement.nodes(); + this.relationships = statement.relationships(); + this.groups = statement.groups(); + this.properties = statement.properties(); } @Override @@ -224,43 +215,44 @@ public int propertyKey( String name ) @Override PageCursor nodePage( long reference ) { - return nodeStore.openPageCursorForReading( reference ); +// return read.nodes().openPageCursor( reference ); + return nodes.openPageCursor( reference ); } @Override PageCursor relationshipPage( long reference ) { - return relationshipStore.openPageCursorForReading( reference ); + return relationships.openPageCursor( reference ); } @Override PageCursor groupPage( long reference ) { - return groupStore.openPageCursorForReading( reference ); + return groups.openPageCursor( reference ); } @Override PageCursor propertyPage( long reference ) { - return propertyStore.openPageCursorForReading( reference ); + return properties.openPageCursor( reference ); } @Override PageCursor stringPage( long reference ) { - return propertyStore.getStringStore().openPageCursorForReading( reference ); + return properties.openStringPageCursor( reference ); } @Override PageCursor arrayPage( long reference ) { - return propertyStore.getArrayStore().openPageCursorForReading( reference ); + return properties.openArrayPageCursor( reference ); } @Override RecordCursor labelCursor() { - return newCursor( nodeStore.getDynamicLabelStore() ); + return nodes.newLabelCursor(); } private static RecordCursor newCursor( RecordStore store ) @@ -271,44 +263,43 @@ private static RecordCursor newCursor( RecordS @Override void node( NodeRecord record, long reference, PageCursor pageCursor ) { - nodeStore.getRecordByCursor( reference, record, RecordLoad.CHECK, pageCursor ); + nodes.loadRecordByCursor( reference, record, RecordLoad.CHECK, pageCursor ); } @Override void relationship( RelationshipRecord record, long reference, PageCursor pageCursor ) { - relationshipStore.getRecordByCursor( reference, record, RecordLoad.CHECK, pageCursor ); + relationships.loadRecordByCursor( reference, record, RecordLoad.CHECK, pageCursor ); } @Override void property( PropertyRecord record, long reference, PageCursor pageCursor ) { - propertyStore.getRecordByCursor( reference, record, RecordLoad.NORMAL, pageCursor ); + properties.loadRecordByCursor( reference, record, RecordLoad.NORMAL, pageCursor ); } @Override void group( RelationshipGroupRecord record, long reference, PageCursor page ) { - groupStore.getRecordByCursor( reference, record, RecordLoad.NORMAL, page ); + groups.loadRecordByCursor( reference, record, RecordLoad.NORMAL, page ); } @Override long nodeHighMark() { - return nodeStore.getHighestPossibleIdInUse(); + return nodes.getHighestPossibleIdInUse(); } @Override long relationshipHighMark() { - return relationshipStore.getHighestPossibleIdInUse(); + return relationships.getHighestPossibleIdInUse(); } @Override TextValue string( PropertyCursor cursor, long reference, PageCursor page ) { - ByteBuffer buffer = - cursor.buffer = readDynamic( propertyStore.getStringStore(), reference, cursor.buffer, page ); + ByteBuffer buffer = cursor.buffer = properties.loadString( reference, cursor.buffer, page ); buffer.flip(); return Values.stringValue( UTF8.decode( buffer.array(), 0, buffer.limit() ) ); } @@ -316,49 +307,8 @@ TextValue string( PropertyCursor cursor, long reference, PageCursor page ) @Override ArrayValue array( PropertyCursor cursor, long reference, PageCursor page ) { - ByteBuffer buffer = - cursor.buffer = readDynamic( propertyStore.getArrayStore(), reference, cursor.buffer, page ); + ByteBuffer buffer = cursor.buffer = properties.loadArray( reference, cursor.buffer, page ); buffer.flip(); return PropertyUtil.readArrayFromBuffer( buffer ); } - - private static ByteBuffer readDynamic( - AbstractDynamicStore store, long reference, ByteBuffer buffer, - PageCursor page ) - { - if ( buffer == null ) - { - buffer = ByteBuffer.allocate( 512 ); - } - else - { - buffer.clear(); - } - DynamicRecord record = store.newRecord(); - do - { - store.getRecordByCursor( reference, record, RecordLoad.CHECK, page ); - reference = record.getNextBlock(); - byte[] data = record.getData(); - if ( buffer.remaining() < data.length ) - { - buffer = grow( buffer, data.length ); - } - buffer.put( data, 0, data.length ); - } - while ( reference != NO_ID ); - return buffer; - } - - private static ByteBuffer grow( ByteBuffer buffer, int required ) - { - buffer.flip(); - int capacity = buffer.capacity(); - do - { - capacity *= 2; - } - while ( capacity - buffer.limit() < required ); - return ByteBuffer.allocate( capacity ).order( ByteOrder.LITTLE_ENDIAN ).put( buffer ); - } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/RecordStorageEngine.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/RecordStorageEngine.java index aa7edbc27f396..b7d4e1c035c5e 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/RecordStorageEngine.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/RecordStorageEngine.java @@ -79,7 +79,6 @@ import org.neo4j.kernel.impl.store.RecordStore; import org.neo4j.kernel.impl.store.SchemaStorage; import org.neo4j.kernel.impl.store.StoreFactory; -import org.neo4j.kernel.impl.store.StoreHolder; import org.neo4j.kernel.impl.store.StoreType; import org.neo4j.kernel.impl.store.format.RecordFormat; import org.neo4j.kernel.impl.store.id.IdGeneratorFactory; @@ -399,12 +398,6 @@ public void satisfyDependencies( DependencySatisfier satisfier ) satisfier.satisfyDependency( indexStoreView ); } - @Override - public StoreHolder stores() - { - return neoStores; - } - @Override public void init() throws Throwable { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/StoreStatement.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/StoreStatement.java index 8e57964d28dce..88aaf5ff8cae6 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/StoreStatement.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storageengine/impl/recordstorage/StoreStatement.java @@ -19,10 +19,13 @@ */ package org.neo4j.kernel.impl.storageengine.impl.recordstorage; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.function.IntPredicate; import java.util.function.Supplier; import org.neo4j.cursor.Cursor; +import org.neo4j.io.pagecache.PageCursor; import org.neo4j.kernel.api.AssertOpen; import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; import org.neo4j.kernel.api.schema.index.IndexDescriptor; @@ -36,13 +39,22 @@ import org.neo4j.kernel.impl.api.store.StoreSingleRelationshipCursor; import org.neo4j.kernel.impl.locking.Lock; import org.neo4j.kernel.impl.locking.LockService; +import org.neo4j.kernel.impl.store.AbstractDynamicStore; +import org.neo4j.kernel.impl.store.InvalidRecordException; import org.neo4j.kernel.impl.store.NeoStores; import org.neo4j.kernel.impl.store.NodeStore; +import org.neo4j.kernel.impl.store.RecordCursor; import org.neo4j.kernel.impl.store.RecordCursors; import org.neo4j.kernel.impl.store.RecordStore; import org.neo4j.kernel.impl.store.RelationshipStore; import org.neo4j.kernel.impl.store.StoreType; +import org.neo4j.kernel.impl.store.record.AbstractBaseRecord; +import org.neo4j.kernel.impl.store.record.DynamicRecord; +import org.neo4j.kernel.impl.store.record.NodeRecord; +import org.neo4j.kernel.impl.store.record.PropertyRecord; +import org.neo4j.kernel.impl.store.record.RecordLoad; import org.neo4j.kernel.impl.store.record.RelationshipGroupRecord; +import org.neo4j.kernel.impl.store.record.RelationshipRecord; import org.neo4j.kernel.impl.util.InstanceCache; import org.neo4j.storageengine.api.Direction; import org.neo4j.storageengine.api.NodeItem; @@ -52,6 +64,9 @@ import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.storageengine.api.schema.LabelScanReader; +import static org.neo4j.kernel.impl.store.record.AbstractBaseRecord.NO_ID; +import static org.neo4j.kernel.impl.store.record.RecordLoad.NORMAL; + /** * Statement for store layer. This allows for acquisition of cursors on the store data. *

@@ -82,6 +97,11 @@ public class StoreStatement implements StorageStatement private boolean acquired; private boolean closed; + private final Nodes nodes; + private final Relationships relationships; + private final Groups groups; + private final Properties properties; + public StoreStatement( NeoStores neoStores, Supplier indexReaderFactory, Supplier labelScanReaderSupplier, LockService lockService, RecordStorageCommandCreationContext commandCreationContext ) @@ -147,6 +167,11 @@ protected StorePropertyCursor create() return new StorePropertyCursor( recordCursors, this ); } }; + + nodes = new Nodes(); + relationships = new Relationships(); + groups = new Groups(); + properties = new Properties(); } @Override @@ -279,4 +304,194 @@ public long reserveRelationship() { return commandCreationContext.nextId( StoreType.RELATIONSHIP ); } + + @Override + public Nodes nodes() + { + return nodes; + } + + @Override + public Relationships relationships() + { + return relationships; + } + + @Override + public Groups groups() + { + return groups; + } + + @Override + public Properties properties() + { + return properties; + } + + class Nodes implements StorageStatement.Nodes + { + + @Override + public PageCursor openPageCursor( long reference ) + { + return neoStores.getNodeStore().openPageCursorForReading( reference ); + } + + @Override + public void loadRecordByCursor( long reference, NodeRecord nodeRecord, RecordLoad mode, PageCursor cursor ) + throws InvalidRecordException + { + neoStores.getNodeStore().getRecordByCursor( reference, nodeRecord, mode, cursor ); + } + + @Override + public long getHighestPossibleIdInUse() + { + return neoStores.getNodeStore().getHighestPossibleIdInUse(); + } + + @Override + public RecordCursor newLabelCursor() + { + return newCursor( neoStores.getNodeStore().getDynamicLabelStore() ); + } + } + + class Relationships implements StorageStatement.Relationships + { + + @Override + public PageCursor openPageCursor( long reference ) + { + return neoStores.getRelationshipStore().openPageCursorForReading( reference ); + } + + @Override + public void loadRecordByCursor( long reference, RelationshipRecord relationshipRecord, RecordLoad mode, + PageCursor cursor ) throws InvalidRecordException + { + neoStores.getRelationshipStore().getRecordByCursor( reference, relationshipRecord, mode, cursor ); + } + + @Override + public long getHighestPossibleIdInUse() + { + return neoStores.getRelationshipStore().getHighestPossibleIdInUse(); + } + } + + class Groups implements StorageStatement.Groups + { + + @Override + public PageCursor openPageCursor( long reference ) + { + return neoStores.getRelationshipGroupStore().openPageCursorForReading( reference ); + } + + @Override + public void loadRecordByCursor( long reference, RelationshipGroupRecord relationshipGroupRecord, + RecordLoad mode, PageCursor cursor ) throws InvalidRecordException + { + neoStores.getRelationshipGroupStore().getRecordByCursor( reference, relationshipGroupRecord, mode, cursor ); + } + + @Override + public long getHighestPossibleIdInUse() + { + return neoStores.getRelationshipGroupStore().getHighestPossibleIdInUse(); + } + } + + class Properties implements StorageStatement.Properties + { + + @Override + public PageCursor openPageCursor( long reference ) + { + return neoStores.getPropertyStore().openPageCursorForReading( reference ); + } + + @Override + public void loadRecordByCursor( long reference, PropertyRecord propertyBlocks, RecordLoad mode, + PageCursor cursor ) throws InvalidRecordException + { + neoStores.getPropertyStore().getRecordByCursor( reference, propertyBlocks, mode, cursor ); + } + + @Override + public long getHighestPossibleIdInUse() + { + return neoStores.getPropertyStore().getHighestPossibleIdInUse(); + } + + @Override + public PageCursor openStringPageCursor( long reference ) + { + return neoStores.getPropertyStore().getStringStore().openPageCursorForReading( reference ); + } + + @Override + public PageCursor openArrayPageCursor( long reference ) + { + return neoStores.getPropertyStore().getArrayStore().openPageCursorForReading( reference ); + } + + @Override + public ByteBuffer loadString( long reference, ByteBuffer buffer, PageCursor page ) + { + return readDynamic( neoStores.getPropertyStore().getStringStore(), reference, buffer, page ); + } + + @Override + public ByteBuffer loadArray( long reference, ByteBuffer buffer, PageCursor page ) + { + return readDynamic( neoStores.getPropertyStore().getArrayStore(), reference, buffer, page ); + } + } + + private static ByteBuffer readDynamic( AbstractDynamicStore store, long reference, ByteBuffer buffer, + PageCursor page ) + { + if ( buffer == null ) + { + buffer = ByteBuffer.allocate( 512 ); + } + else + { + buffer.clear(); + } + DynamicRecord record = store.newRecord(); + do + { + store.getRecordByCursor( reference, record, RecordLoad.CHECK, page ); + reference = record.getNextBlock(); + byte[] data = record.getData(); + if ( buffer.remaining() < data.length ) + { + buffer = grow( buffer, data.length ); + } + buffer.put( data, 0, data.length ); + } + while ( reference != NO_ID ); + return buffer; + } + + private static ByteBuffer grow( ByteBuffer buffer, int required ) + { + buffer.flip(); + int capacity = buffer.capacity(); + do + { + capacity *= 2; + } + while ( capacity - buffer.limit() < required ); + return ByteBuffer.allocate( capacity ).order( ByteOrder.LITTLE_ENDIAN ).put( buffer ); + } + + private static RecordCursor newCursor( RecordStore store ) + { + return store.newRecordCursor( store.newRecord() ).acquire( store.getNumberOfReservedLowIds(), NORMAL ); + } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/NeoStores.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/NeoStores.java index 00fc5c8c5f12b..9072c8e7dcb97 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/NeoStores.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/NeoStores.java @@ -68,7 +68,7 @@ * anything but extends the AbstractStore for the "type and version" validation * performed in there. */ -public class NeoStores implements AutoCloseable, StoreHolder +public class NeoStores implements AutoCloseable { private static final String STORE_ALREADY_CLOSED_MESSAGE = "Specified store was already closed."; private static final String STORE_NOT_INITIALIZED_TEMPLATE = "Specified store was not initialized. Please specify" + @@ -312,7 +312,6 @@ public MetaDataStore getMetaDataStore() /** * @return The node store */ - @Override public NodeStore getNodeStore() { return (NodeStore) getStore( StoreType.NODE ); @@ -328,7 +327,6 @@ private DynamicArrayStore getNodeLabelStore() * * @return The relationship store */ - @Override public RelationshipStore getRelationshipStore() { return (RelationshipStore) getStore( StoreType.RELATIONSHIP ); @@ -369,7 +367,6 @@ private DynamicStringStore getLabelTokenNamesStore() * * @return The property store */ - @Override public PropertyStore getPropertyStore() { return (PropertyStore) getStore( StoreType.PROPERTY ); @@ -403,7 +400,6 @@ private DynamicStringStore getPropertyKeyTokenNamesStore() * * @return The relationship group store. */ - @Override public RelationshipGroupStore getRelationshipGroupStore() { return (RelationshipGroupStore) getStore( StoreType.RELATIONSHIP_GROUP ); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreHolder.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreHolder.java deleted file mode 100644 index 8bb2f3a8cf214..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreHolder.java +++ /dev/null @@ -1,53 +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.store; - -/** - * Interface for accessing the current stores: NodeStore, RelationshipStore, - * PropertyStore and RelationshipTypeStore. - */ -public interface StoreHolder -{ - /** - * @return The node store - */ - NodeStore getNodeStore(); - - /** - * The relationship store. - * - * @return The relationship store - */ - RelationshipStore getRelationshipStore(); - - /** - * The relationship group store. - * - * @return The relationship group store - */ - RelationshipGroupStore getRelationshipGroupStore(); - - /** - * Returns the property store. - * - * @return The property store - */ - PropertyStore getPropertyStore(); -} diff --git a/community/kernel/src/main/java/org/neo4j/storageengine/api/StorageEngine.java b/community/kernel/src/main/java/org/neo4j/storageengine/api/StorageEngine.java index 7dadd948e6017..b70373905c469 100644 --- a/community/kernel/src/main/java/org/neo4j/storageengine/api/StorageEngine.java +++ b/community/kernel/src/main/java/org/neo4j/storageengine/api/StorageEngine.java @@ -26,7 +26,6 @@ import org.neo4j.kernel.api.exceptions.TransactionFailureException; import org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException; import org.neo4j.kernel.api.exceptions.schema.CreateConstraintFailureException; -import org.neo4j.kernel.impl.store.StoreHolder; import org.neo4j.kernel.info.DiagnosticsManager; import org.neo4j.storageengine.api.lock.ResourceLocker; import org.neo4j.storageengine.api.txstate.ReadableTransactionState; @@ -119,11 +118,6 @@ void createCommands( */ void forceClose(); - /** - * @return A store holder with access to the open stores. - */ - StoreHolder stores(); - /** * Startup process have reached the conclusion that recovery is required. Make the necessary * preparations to be ready for recovering transactions. 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 fa024ac2269ae..3cef6d326080a 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 @@ -19,14 +19,26 @@ */ package org.neo4j.storageengine.api; +import java.nio.ByteBuffer; import java.util.function.IntPredicate; import org.neo4j.cursor.Cursor; +import org.neo4j.io.pagecache.PageCursor; import org.neo4j.kernel.api.AssertOpen; import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.impl.locking.Lock; +import org.neo4j.kernel.impl.store.InvalidRecordException; +import org.neo4j.kernel.impl.store.RecordCursor; import org.neo4j.kernel.impl.store.RecordCursors; +import org.neo4j.kernel.impl.store.RecordStore; +import org.neo4j.kernel.impl.store.record.AbstractBaseRecord; +import org.neo4j.kernel.impl.store.record.DynamicRecord; +import org.neo4j.kernel.impl.store.record.NodeRecord; +import org.neo4j.kernel.impl.store.record.PropertyRecord; +import org.neo4j.kernel.impl.store.record.RecordLoad; +import org.neo4j.kernel.impl.store.record.RelationshipGroupRecord; +import org.neo4j.kernel.impl.store.record.RelationshipRecord; import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.storageengine.api.schema.LabelScanReader; @@ -175,4 +187,103 @@ Cursor acquireSinglePropertyCursor( long propertyId, int propertyK * @return a reserved relationship id for future use. */ long reserveRelationship(); + + Nodes nodes(); + + Relationships relationships(); + + Groups groups(); + + Properties properties(); + + interface RecordReads + { + /** + * Open a new PageCursor for reading nodes. + *

+ * DANGER: make sure to always close this cursor. + * + * @param reference the initial node reference to access. + * @return the opened PageCursor + */ + PageCursor openPageCursor( long reference ); + + /** + * Load a node {@code record} with the node corresponding to the given node {@code reference}. + *

+ * The provided page cursor will be used to get the record, and in doing this it will be redirected to the + * correct page if needed. + * + * @param reference the record reference, understood to be the absolute reference to the store. + * @param record the record to fill. + * @param mode loading behaviour, read more in {@link RecordStore#getRecord(long, AbstractBaseRecord, RecordLoad)}. + * @param cursor the PageCursor to use for record loading. + * @throws InvalidRecordException if record not in use and the {@code mode} allows for throwing. + */ + void loadRecordByCursor( long reference, RECORD record, RecordLoad mode, PageCursor cursor ) + throws InvalidRecordException; + + long getHighestPossibleIdInUse(); + } + + interface Nodes extends RecordReads + { + /** + * @return a new Record cursor for accessing DynamicRecords containing labels. + */ + RecordCursor newLabelCursor(); + } + + interface Relationships extends RecordReads + { + } + + interface Groups extends RecordReads + { + } + + interface Properties extends RecordReads + { + /** + * Open a new PageCursor for reading strings. + *

+ * DANGER: make sure to always close this cursor. + * + * @param reference the initial string reference to access. + * @return the opened PageCursor + */ + PageCursor openStringPageCursor( long reference ); + + /** + * Open a new PageCursor for reading arrays. + *

+ * DANGER: make sure to always close this cursor. + * + * @param reference the initial array reference to access. + * @return the opened PageCursor + */ + PageCursor openArrayPageCursor( long reference ); + + /** + * Loads a string into the given buffer. If that is too small we recreate the buffer. The buffer is returned + * in write mode, and needs to be flipped before reading. + * + * @param reference the initial string reference to load + * @param buffer the buffer to load into + * @param page the page cursor to be used + * @return the ByteBuffer of the string + */ + ByteBuffer loadString( long reference, ByteBuffer buffer, PageCursor page ); + + /** + * Loads a array into the given buffer. If that is too small we recreate the buffer. The buffer is returned + * in write mode, and needs to be flipped before reading. + * + * @param reference the initial array reference to load + * @param buffer the buffer to load into + * @param page the page cursor to be used + * @return the ByteBuffer of the array + */ + ByteBuffer loadArray( long reference, ByteBuffer buffer, PageCursor page ); + } } 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 350dc533e7a03..316997b4126b9 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 @@ -37,7 +37,6 @@ import org.neo4j.kernel.impl.locking.SimpleStatementLocks; import org.neo4j.kernel.impl.locking.StatementLocks; import org.neo4j.kernel.impl.proc.Procedures; -import org.neo4j.kernel.impl.store.StoreHolder; import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory; import org.neo4j.kernel.impl.transaction.TransactionMonitor; import org.neo4j.resources.CpuClock; @@ -81,12 +80,10 @@ static Instances kernelTransactionWithInternals( SecurityContext securityContext when( headerInformationFactory.create() ).thenReturn( headerInformation ); StorageEngine storageEngine = mock( StorageEngine.class ); - StoreHolder storeHolder = mock( StoreHolder.class ); StoreReadLayer storeReadLayer = mock( StoreReadLayer.class ); StorageStatement storageStatement = mock( StorageStatement.class ); when( storeReadLayer.newStatement() ).thenReturn( storageStatement ); when( storageEngine.storeReadLayer() ).thenReturn( storeReadLayer ); - when( storageEngine.stores() ).thenReturn( storeHolder ); KernelTransactionImplementation transaction = new KernelTransactionImplementation( mock( StatementOperationParts.class ), 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 dc81701deb5f9..f23c72bee2679 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 @@ -41,7 +41,6 @@ import org.neo4j.kernel.impl.storageengine.impl.recordstorage.StoreStatement; import org.neo4j.kernel.impl.store.MetaDataStore; import org.neo4j.kernel.impl.store.NeoStores; -import org.neo4j.kernel.impl.store.StoreHolder; import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory; import org.neo4j.kernel.impl.transaction.TransactionMonitor; import org.neo4j.kernel.impl.transaction.TransactionRepresentation; @@ -73,7 +72,6 @@ public class KernelTransactionTestBase { protected final StorageEngine storageEngine = mock( StorageEngine.class ); - protected final StoreHolder storeHolder = mock( StoreHolder.class ); protected final NeoStores neoStores = mock( NeoStores.class ); protected final MetaDataStore metaDataStore = mock( MetaDataStore.class ); protected final StoreReadLayer readLayer = mock( StoreReadLayer.class ); @@ -99,7 +97,6 @@ public void before() throws Exception when( readLayer.newStatement() ).thenReturn( mock( StoreStatement.class ) ); when( neoStores.getMetaDataStore() ).thenReturn( metaDataStore ); when( storageEngine.storeReadLayer() ).thenReturn( readLayer ); - when( storageEngine.stores() ).thenReturn( storeHolder ); doAnswer( invocation -> ((Collection) invocation.getArgument(0) ).add( new Command .RelationshipCountsCommand( 1, 2,3, 4L ) ) ) .when( storageEngine ).createCommands( 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 badfc2d40941f..b26d2807a6ec2 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 @@ -49,7 +49,6 @@ import org.neo4j.kernel.impl.locking.SimpleStatementLocksFactory; import org.neo4j.kernel.impl.locking.StatementLocksFactory; import org.neo4j.kernel.impl.proc.Procedures; -import org.neo4j.kernel.impl.store.StoreHolder; import org.neo4j.kernel.impl.store.TransactionId; import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory; import org.neo4j.kernel.impl.transaction.TransactionMonitor; @@ -532,7 +531,6 @@ private static KernelTransactions newKernelTransactions( boolean testKernelTrans when( readLayer.newStatement() ).thenReturn( firstStoreStatements, otherStorageStatements ); StorageEngine storageEngine = mock( StorageEngine.class ); - when( storageEngine.stores() ).thenReturn( mock( StoreHolder.class ) ); when( storageEngine.storeReadLayer() ).thenReturn( readLayer ); doAnswer( invocation -> {