From 767639178d29ef90c55aced7e637dd157f6a7f60 Mon Sep 17 00:00:00 2001 From: Mikhaylo Demianenko Date: Thu, 29 Oct 2015 14:06:54 +0100 Subject: [PATCH] Creation and initialisation of stores only during NeoStores construction, remove laziness. Previously it was possible to construct stores only when they were requested 'in a lazy way' independently from main NeoStores container lifecycle. That brings a confusion when container are started/stopped on HA setup, since it was possible to construct stores on closed datasource. To avoid confusion and simplify component lifecycle, but still keep possibility to open only requested stores now we can enumerate stores that should be opened, in case if we don't need all, and they will be constructed during container creation. In case if we will request store on already closed container, or will request not requested store - exception will be thrown. --- .../consistency/ConsistencyCheckService.java | 2 +- .../consistency/ConsistencyCheckService.java | 2 +- .../checking/GraphStoreFixture.java | 3 +- .../org/neo4j/kernel/NeoStoreDataSource.java | 3 +- .../neo4j/kernel/impl/store/DumpStore.java | 55 +- .../kernel/impl/store/DumpStoreChain.java | 10 +- .../neo4j/kernel/impl/store/NeoStores.java | 154 +- .../neo4j/kernel/impl/store/StoreAccess.java | 2 +- .../neo4j/kernel/impl/store/StoreFactory.java | 49 +- .../impl/store/counts/DumpCountsStore.java | 2 +- .../storemigration/SchemaIndexMigrator.java | 3 +- .../impl/storemigration/StoreMigrator.java | 5 +- .../PropertyDeduplicator.java | 5 +- .../impl/util/rawstorereader/RsdrMain.java | 2 +- .../unsafe/batchinsert/BatchInserterImpl.java | 3 +- .../batchimport/store/BatchingNeoStores.java | 5 +- ...nsactionRepresentationCommitProcessIT.java | 4 +- ...ropertyPhysicalToLogicalConverterTest.java | 4 +- .../api/store/StorePropertyCursorTest.java | 3 +- .../kernel/impl/core/ManyPropertyKeysIT.java | 3 +- .../impl/store/FreeIdsAfterRecoveryTest.java | 7 +- ...dGeneratorRebuildFailureEmulationTest.java | 2 +- .../{NeoStoreTest.java => NeoStoresTest.java} | 1681 +++++++++-------- .../kernel/impl/store/NodeStoreTest.java | 3 +- .../store/RecordStoreConsistentReadTest.java | 4 +- .../store/RelationshipGroupStoreTest.java | 9 +- .../kernel/impl/store/SchemaStoreTest.java | 3 +- .../kernel/impl/store/StoreFactoryTest.java | 9 +- .../kernel/impl/store/TestArrayStore.java | 3 +- .../kernel/impl/store/TestDynamicStore.java | 3 +- .../impl/store/TestGraphProperties.java | 2 +- .../store/TestGrowingFileMemoryMapping.java | 4 +- .../impl/store/TestIdGeneratorRebuilding.java | 3 +- .../impl/store/counts/CountsComputerTest.java | 2 +- .../SchemaIndexMigratorTest.java | 59 +- .../storemigration/StoreMigratorTest.java | 6 +- .../state/ApplyRecoveredTransactionsTest.java | 3 +- .../state/NeoStoreTransactionTest.java | 6 +- .../transaction/state/NodeCommandTest.java | 4 +- .../state/NodeLabelsFieldTest.java | 4 +- .../state/TransactionRecordStateTest.java | 4 +- .../unsafe/batchinsert/BatchInsertTest.java | 2 +- .../batchimport/PropertyEncoderStepTest.java | 4 +- .../test/java/upgrade/StoreUpgraderTest.java | 2 +- .../neo4j/com/storecopy/ResponsePackerIT.java | 3 +- .../ccheck/ConsistencyPerformanceCheck.java | 3 +- .../ha/transaction/OnDiskLastTxIdGetter.java | 19 +- .../kernel/ha/OnDiskLastTxIdGetterTest.java | 2 +- .../java/upgrade/StoreMigratorFrom19IT.java | 6 +- .../java/upgrade/StoreMigratorFrom20IT.java | 3 +- 50 files changed, 1148 insertions(+), 1036 deletions(-) rename community/kernel/src/test/java/org/neo4j/kernel/impl/store/{NeoStoreTest.java => NeoStoresTest.java} (95%) diff --git a/community/consistency-check-legacy/src/main/java/org/neo4j/legacy/consistency/ConsistencyCheckService.java b/community/consistency-check-legacy/src/main/java/org/neo4j/legacy/consistency/ConsistencyCheckService.java index 989e7f33131e..0007d5aa76ff 100644 --- a/community/consistency-check-legacy/src/main/java/org/neo4j/legacy/consistency/ConsistencyCheckService.java +++ b/community/consistency-check-legacy/src/main/java/org/neo4j/legacy/consistency/ConsistencyCheckService.java @@ -134,7 +134,7 @@ public PrintWriter get() } } ) ); - try ( NeoStores neoStores = factory.openNeoStoresEagerly() ) + try ( NeoStores neoStores = factory.openAllNeoStores() ) { StoreAccess store = new StoreAccess( neoStores ).initialize(); LabelScanStore labelScanStore = null; diff --git a/community/consistency-check/src/main/java/org/neo4j/consistency/ConsistencyCheckService.java b/community/consistency-check/src/main/java/org/neo4j/consistency/ConsistencyCheckService.java index 544e3bf64ec5..490f7e8be6dd 100644 --- a/community/consistency-check/src/main/java/org/neo4j/consistency/ConsistencyCheckService.java +++ b/community/consistency-check/src/main/java/org/neo4j/consistency/ConsistencyCheckService.java @@ -139,7 +139,7 @@ public PrintWriter get() } } ) ); - try ( NeoStores neoStores = factory.openNeoStoresEagerly() ) + try ( NeoStores neoStores = factory.openAllNeoStores() ) { LabelScanStore labelScanStore = null; try diff --git a/community/consistency-check/src/test/java/org/neo4j/consistency/checking/GraphStoreFixture.java b/community/consistency-check/src/test/java/org/neo4j/consistency/checking/GraphStoreFixture.java index 1521281f6695..2a613f820474 100644 --- a/community/consistency-check/src/test/java/org/neo4j/consistency/checking/GraphStoreFixture.java +++ b/community/consistency-check/src/test/java/org/neo4j/consistency/checking/GraphStoreFixture.java @@ -105,8 +105,7 @@ public DirectStoreAccess directStoreAccess() { DefaultFileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction(); PageCache pageCache = getPageCache( fileSystem ); - neoStore = new StoreFactory( fileSystem, directory, pageCache, NullLogProvider.getInstance() ) - .openNeoStoresEagerly(); + neoStore = new StoreFactory( fileSystem, directory, pageCache, NullLogProvider.getInstance() ).openAllNeoStores(); StoreAccess nativeStores; if ( keepStatistics ) { 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 aa2b223e14b7..12632afe536e 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java @@ -184,7 +184,6 @@ import static org.neo4j.helpers.Settings.setting; import static org.neo4j.helpers.collection.Iterables.toList; import static org.neo4j.kernel.impl.locking.LockService.NO_LOCK_SERVICE; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; import static org.neo4j.kernel.impl.transaction.log.pruning.LogPruneStrategyFactory.fromConfigValue; public class NeoStoreDataSource implements NeoStoresSupplier, Lifecycle, IndexProviders @@ -659,7 +658,7 @@ public void start() throws IOException } } ); - final NeoStores neoStores = storeFactory.openNeoStores( SF_CREATE ); + final NeoStores neoStores = storeFactory.openAllNeoStores( true ); return new NeoStoreModule() { @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/DumpStore.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/DumpStore.java index 551b6836aa28..5ad1b05a876a 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/DumpStore.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/DumpStore.java @@ -44,6 +44,7 @@ public class DumpStore> { + public static void main( String... args ) throws Exception { if ( args == null || args.length == 0 ) @@ -102,40 +103,43 @@ else if ( !file.isDirectory() && file.getName().indexOf( ':' ) != -1 ) throw new IllegalArgumentException( "No such file: " + arg ); } } - try ( NeoStores neoStores = createStoreFactory.apply( file ).openNeoStoresEagerly() ) + NeoStores.StoreType storeType = STORE_FILENAME_TYPE_MAPPER.apply( file.getName() ); + try ( NeoStores neoStores = createStoreFactory.apply( file ).openNeoStores( storeType ) ) { - switch ( file.getName() ) + switch ( storeType ) { - case "neostore.nodestore.db": + case NODE: dumpNodeStore( neoStores, ids ); break; - case "neostore.relationshipstore.db": + case RELATIONSHIP: dumpRelationshipStore( neoStores, ids ); break; - case "neostore.propertystore.db": + case PROPERTY: dumpPropertyStore( neoStores, ids ); break; - case "neostore.schemastore.db": + case SCHEMA: dumpSchemaStore( neoStores, ids ); break; - case "neostore.propertystore.db.index": + case PROPERTY_KEY_TOKEN: dumpPropertyKeys( neoStores, ids ); break; - case "neostore.labeltokenstore.db": + case LABEL_TOKEN: dumpLabels( neoStores, ids ); break; - case "neostore.relationshiptypestore.db": + case RELATIONSHIP_TYPE_TOKEN: dumpRelationshipTypes( neoStores, ids ); break; - case "neostore.relationshipgroupstore.db": + case RELATIONSHIP_GROUP: dumpRelationshipGroups( neoStores, ids ); break; default: - throw new IllegalArgumentException( "Unknown store file: " + arg ); + throw new IllegalArgumentException( "Unsupported store type: " + storeType ); } } } + + private static LogProvider logProvider() { return Boolean.getBoolean( "logger" ) ? FormattedLogProvider.toOutputStream( System.out ) : NullLogProvider.getInstance(); @@ -346,4 +350,33 @@ protected Object transform( RECORD record ) throws Exception { return record.inUse() ? record : null; } + + static Function STORE_FILENAME_TYPE_MAPPER = new Function() + { + @Override + public NeoStores.StoreType apply( String filename ) + { + switch ( filename ) + { + case "neostore.nodestore.db": + return NeoStores.StoreType.NODE; + case "neostore.relationshipstore.db": + return NeoStores.StoreType.RELATIONSHIP; + case "neostore.propertystore.db": + return NeoStores.StoreType.PROPERTY; + case "neostore.schemastore.db": + return NeoStores.StoreType.SCHEMA; + case "neostore.propertystore.db.index": + return NeoStores.StoreType.PROPERTY_KEY_TOKEN; + case "neostore.labeltokenstore.db": + return NeoStores.StoreType.LABEL_TOKEN; + case "neostore.relationshiptypestore.db": + return NeoStores.StoreType.RELATIONSHIP_TYPE_TOKEN; + case "neostore.relationshipgroupstore.db": + return NeoStores.StoreType.RELATIONSHIP_GROUP; + default: + throw new IllegalArgumentException( "Unknown store file: " + filename ); + } + } + }; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/DumpStoreChain.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/DumpStoreChain.java index ee6e860371d8..824073fe1342 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/DumpStoreChain.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/DumpStoreChain.java @@ -39,6 +39,7 @@ import org.neo4j.logging.NullLogProvider; import static org.neo4j.kernel.impl.pagecache.StandalonePageCacheFactory.createPageCache; +import static org.neo4j.kernel.impl.store.DumpStore.STORE_FILENAME_TYPE_MAPPER; public abstract class DumpStoreChain { @@ -106,7 +107,7 @@ void dump( File storeDir ) throws IOException Config config = new Config(); StoreFactory storeFactory = new StoreFactory( storeDir, config, idGeneratorFactory, pageCache, fs, logProvider() ); - try ( NeoStores neoStores = storeFactory.openNeoStoresEagerly() ) + try ( NeoStores neoStores = storeFactory.openNeoStores( getStoreTypes() ) ) { RecordStore store = store( neoStores ); for ( long next = first; next != -1; ) @@ -119,6 +120,13 @@ void dump( File storeDir ) throws IOException } } + private NeoStores.StoreType[] getStoreTypes() + { + return new NeoStores.StoreType[]{STORE_FILENAME_TYPE_MAPPER.apply( NODESTORE ), + STORE_FILENAME_TYPE_MAPPER.apply( PROPSTORE ), + STORE_FILENAME_TYPE_MAPPER.apply( RELSTORE )}; + } + abstract long next( RECORD record ); abstract RecordStore store( NeoStores neoStores ); 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 926ac143960a..455b276fce90 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 @@ -23,9 +23,9 @@ import java.io.IOException; import java.util.Iterator; -import org.neo4j.function.Function; import org.neo4j.function.Predicate; import org.neo4j.graphdb.factory.GraphDatabaseSettings; +import org.neo4j.helpers.ArrayUtil; import org.neo4j.helpers.collection.FilteringIterator; import org.neo4j.helpers.collection.IteratorWrapper; import org.neo4j.helpers.collection.Visitor; @@ -54,6 +54,12 @@ */ 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" + + " %s as one of the stores types that should be open" + + " to be able to use it."; + public static boolean isStorePresent( PageCache pageCache, File storeDir ) { File metaDataStore = new File( storeDir, MetaDataStore.DEFAULT_NAME ); @@ -67,7 +73,7 @@ public static boolean isStorePresent( PageCache pageCache, File storeDir ) } } - private enum StoreType + public enum StoreType { NODE_LABEL { @@ -88,7 +94,7 @@ public CommonAbstractStore open( NeoStores me ) { File fileName = me.getStoreFileName( StoreFactory.NODE_STORE_NAME ); return me.initialize( new NodeStore( fileName, me.config, me.idGeneratorFactory, me.pageCache, - me.logProvider, me.getNodeLabelStore() ) ); + me.logProvider, (DynamicArrayStore) me.getOrCreateStore( NODE_LABEL ) ) ); } }, PROPERTY_KEY_TOKEN_NAME @@ -108,7 +114,8 @@ public CommonAbstractStore open( NeoStores me ) { File fileName = me.getStoreFileName( StoreFactory.PROPERTY_KEY_TOKEN_STORE_NAME ); return me.initialize( new PropertyKeyTokenStore( fileName, me.config, me.idGeneratorFactory, - me.pageCache, me.logProvider, me.getPropertyKeyTokenNamesStore() ) ); + me.pageCache, me.logProvider, + (DynamicStringStore) me.getOrCreateStore( PROPERTY_KEY_TOKEN_NAME ) ) ); } }, PROPERTY_STRING @@ -141,7 +148,10 @@ public CommonAbstractStore open( NeoStores me ) File fileName = me.getStoreFileName( StoreFactory.PROPERTY_STORE_NAME ); return me.initialize( new PropertyStore( fileName, me.config, me.idGeneratorFactory, me.pageCache, me.logProvider, - me.getStringPropertyStore(), me.getPropertyKeyTokenStore(), me.getArrayPropertyStore() ) ); + (DynamicStringStore) me.getOrCreateStore( PROPERTY_STRING ), + (PropertyKeyTokenStore) me.getOrCreateStore( PROPERTY_KEY_TOKEN ), + (DynamicArrayStore) me.getOrCreateStore( PROPERTY_ARRAY ) + ) ); } }, RELATIONSHIP @@ -174,7 +184,8 @@ public CommonAbstractStore open( NeoStores me ) { File fileName = me.getStoreFileName( StoreFactory.RELATIONSHIP_TYPE_TOKEN_STORE_NAME ); return me.initialize( new RelationshipTypeTokenStore( fileName, me.config, me.idGeneratorFactory, - me.pageCache, me.logProvider, me.getRelationshipTypeTokenNamesStore() ) ); + me.pageCache, me.logProvider, (DynamicStringStore) me.getOrCreateStore( + RELATIONSHIP_TYPE_TOKEN_NAME ) ) ); } }, LABEL_TOKEN_NAME @@ -194,7 +205,7 @@ public CommonAbstractStore open( NeoStores me ) { File fileName = me.getStoreFileName( StoreFactory.LABEL_TOKEN_STORE_NAME ); return me.initialize( new LabelTokenStore( fileName, me.config, me.idGeneratorFactory, me.pageCache, - me.logProvider, me.getLabelTokenNamesStore() ) ); + me.logProvider, (DynamicStringStore) me.getOrCreateStore( LABEL_TOKEN_NAME ) ) ); } }, SCHEMA @@ -242,7 +253,7 @@ public void initialize( CountsAccessor.Updater updater ) @Override public long initialVersion() { - return me.getMetaDataStore().getLastCommittedTransactionId(); + return ((MetaDataStore) me.getOrCreateStore( META_DATA )).getLastCommittedTransactionId(); } } ); @@ -288,12 +299,12 @@ public CommonAbstractStore open( NeoStores me ) private final boolean recordStore; - private StoreType() + StoreType() { this( true ); } - private StoreType( boolean recordStore ) + StoreType( boolean recordStore ) { this.recordStore = recordStore; } @@ -324,12 +335,10 @@ public boolean test( StoreType type ) private final boolean createIfNotExist; private final File storeDir; private final File neoStoreFileName; + private final StoreType[] initializedStores; private final FileSystemAbstraction fileSystemAbstraction; // All stores, as Object due to CountsTracker being different that all other stores. private final Object[] stores; - // The way a store is retrieved. As a function since if eagerly initialized then no synchronization - // is required for getting/initializing - private final Function storeGetter; NeoStores( File neoStoreFileName, @@ -339,7 +348,7 @@ public boolean test( StoreType type ) final LogProvider logProvider, FileSystemAbstraction fileSystemAbstraction, boolean createIfNotExist, - boolean eagerlyInitializedStores ) + StoreType... storeTypes ) { this.neoStoreFileName = neoStoreFileName; this.config = config; @@ -350,38 +359,12 @@ public boolean test( StoreType type ) this.createIfNotExist = createIfNotExist; this.storeDir = neoStoreFileName.getParentFile(); - final Object[] stores = new Object[STORE_TYPES.length]; - if ( eagerlyInitializedStores ) - { - // Ensure they're all instantiated and initialized - // So that we can just return from the array without fuzz - this.storeGetter = new Function() - { - @Override - public Object apply( StoreType type ) - { - return stores[type.ordinal()]; - } - }; - for ( StoreType type : STORE_TYPES ) - { - getInitializedStore( type, stores ); - } - } - else + stores = new Object[StoreType.values().length]; + for ( StoreType type : storeTypes ) { - // Do synchronization on every call since the stores are opened lazily. - this.storeGetter = new Function() - { - @Override - public Object apply( StoreType type ) - { - return getInitializedStore( type, stores ); - } - }; + getOrCreateStore( type ); } - - this.stores = stores; + initializedStores = storeTypes; } public File getStoreDir() @@ -433,14 +416,12 @@ public void flush() } } - private synchronized Object getInitializedStore( StoreType type, Object[] stores ) + private Object openStore( StoreType type ) { - int i = type.ordinal(); - if ( stores[i] == null ) - { - stores[i] = type.open( this ); - } - return stores[i]; + int storeIndex = type.ordinal(); + Object store = type.open( this ); + stores[storeIndex] = store; + return store; } T initialize( T store ) @@ -449,12 +430,51 @@ T initialize( T store ) return store; } + /** + * Returns specified store by type from already opened store array. If store is not opened exception will be + * thrown. + * + * @see #getOrCreateStore + * @param storeType store type to retrieve + * @return store of requested type + * @throws IllegalStateException if opened store not found + */ + private Object getStore(StoreType storeType) + { + Object store = stores[storeType.ordinal()]; + if ( store == null ) + { + String message = ArrayUtil.contains( initializedStores, storeType ) ? STORE_ALREADY_CLOSED_MESSAGE : + String.format( STORE_NOT_INITIALIZED_TEMPLATE, storeType.name() ); + throw new IllegalStateException( message ); + } + return store; + } + + /** + * Returns specified store by type from already opened store array. Will open a new store if can't find any. + * Should be used only during construction of stores. + * + * @see #getStore + * @param storeType store type to get or create + * @return store of requested type + */ + private Object getOrCreateStore( StoreType storeType ) + { + Object store = stores[storeType.ordinal()]; + if ( store == null ) + { + store = openStore( storeType ); + } + return store; + } + /** * @return the NeoStore. */ public MetaDataStore getMetaDataStore() { - return (MetaDataStore) storeGetter.apply( StoreType.META_DATA ); + return (MetaDataStore) getStore( StoreType.META_DATA ); } /** @@ -462,12 +482,12 @@ public MetaDataStore getMetaDataStore() */ public NodeStore getNodeStore() { - return (NodeStore) storeGetter.apply( StoreType.NODE ); + return (NodeStore) getStore( StoreType.NODE ); } private DynamicArrayStore getNodeLabelStore() { - return (DynamicArrayStore) storeGetter.apply( StoreType.NODE_LABEL ); + return (DynamicArrayStore) getStore( StoreType.NODE_LABEL ); } /** @@ -477,7 +497,7 @@ private DynamicArrayStore getNodeLabelStore() */ public RelationshipStore getRelationshipStore() { - return (RelationshipStore) storeGetter.apply( StoreType.RELATIONSHIP ); + return (RelationshipStore) getStore( StoreType.RELATIONSHIP ); } /** @@ -487,12 +507,12 @@ public RelationshipStore getRelationshipStore() */ public RelationshipTypeTokenStore getRelationshipTypeTokenStore() { - return (RelationshipTypeTokenStore) storeGetter.apply( StoreType.RELATIONSHIP_TYPE_TOKEN ); + return (RelationshipTypeTokenStore) getStore( StoreType.RELATIONSHIP_TYPE_TOKEN ); } private DynamicStringStore getRelationshipTypeTokenNamesStore() { - return (DynamicStringStore) storeGetter.apply( StoreType.RELATIONSHIP_TYPE_TOKEN_NAME ); + return (DynamicStringStore) getStore( StoreType.RELATIONSHIP_TYPE_TOKEN_NAME ); } /** @@ -502,12 +522,12 @@ private DynamicStringStore getRelationshipTypeTokenNamesStore() */ public LabelTokenStore getLabelTokenStore() { - return (LabelTokenStore) storeGetter.apply( StoreType.LABEL_TOKEN ); + return (LabelTokenStore) getStore( StoreType.LABEL_TOKEN ); } private DynamicStringStore getLabelTokenNamesStore() { - return (DynamicStringStore) storeGetter.apply( StoreType.LABEL_TOKEN_NAME ); + return (DynamicStringStore) getStore( StoreType.LABEL_TOKEN_NAME ); } /** @@ -517,17 +537,17 @@ private DynamicStringStore getLabelTokenNamesStore() */ public PropertyStore getPropertyStore() { - return (PropertyStore) storeGetter.apply( StoreType.PROPERTY ); + return (PropertyStore) getStore( StoreType.PROPERTY ); } private DynamicStringStore getStringPropertyStore() { - return (DynamicStringStore) storeGetter.apply( StoreType.PROPERTY_STRING ); + return (DynamicStringStore) getStore( StoreType.PROPERTY_STRING ); } private DynamicArrayStore getArrayPropertyStore() { - return (DynamicArrayStore) storeGetter.apply( StoreType.PROPERTY_ARRAY ); + return (DynamicArrayStore) getStore( StoreType.PROPERTY_ARRAY ); } /** @@ -535,12 +555,12 @@ private DynamicArrayStore getArrayPropertyStore() */ public PropertyKeyTokenStore getPropertyKeyTokenStore() { - return (PropertyKeyTokenStore) storeGetter.apply( StoreType.PROPERTY_KEY_TOKEN ); + return (PropertyKeyTokenStore) getStore( StoreType.PROPERTY_KEY_TOKEN ); } private DynamicStringStore getPropertyKeyTokenNamesStore() { - return (DynamicStringStore) storeGetter.apply( StoreType.PROPERTY_KEY_TOKEN_NAME ); + return (DynamicStringStore) getStore( StoreType.PROPERTY_KEY_TOKEN_NAME ); } /** @@ -548,7 +568,7 @@ private DynamicStringStore getPropertyKeyTokenNamesStore() */ public RelationshipGroupStore getRelationshipGroupStore() { - return (RelationshipGroupStore) storeGetter.apply( StoreType.RELATIONSHIP_GROUP ); + return (RelationshipGroupStore) getStore( StoreType.RELATIONSHIP_GROUP ); } /** @@ -556,12 +576,12 @@ public RelationshipGroupStore getRelationshipGroupStore() */ public SchemaStore getSchemaStore() { - return (SchemaStore) storeGetter.apply( StoreType.SCHEMA ); + return (SchemaStore) getStore( StoreType.SCHEMA ); } public CountsTracker getCounts() { - return (CountsTracker) storeGetter.apply( StoreType.COUNTS ); + return (CountsTracker) getStore( StoreType.COUNTS ); } private CountsTracker createWritableCountsTracker( File fileName ) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreAccess.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreAccess.java index b0c3eb6fff2b..1ca661c9e7fa 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreAccess.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreAccess.java @@ -97,7 +97,7 @@ public StoreAccess( FileSystemAbstraction fileSystem, PageCache pageCache, File private StoreAccess( FileSystemAbstraction fileSystem, PageCache pageCache, File storeDir, Config config ) { this( new StoreFactory( storeDir, config, new DefaultIdGeneratorFactory( fileSystem ), pageCache, - fileSystem, NullLogProvider.getInstance() ).openNeoStoresEagerly() ); + fileSystem, NullLogProvider.getInstance() ).openAllNeoStores() ); this.closeable = true; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreFactory.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreFactory.java index 5b96587b3e7d..f8b1d89b99ce 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreFactory.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/StoreFactory.java @@ -59,10 +59,6 @@ public class StoreFactory public static final String RELATIONSHIP_GROUP_STORE_NAME = ".relationshipgroupstore.db"; public static final String COUNTS_STORE = ".counts.db"; - private static final byte SF_DEFAULT = 0; - public static final byte SF_CREATE = 1; - public static final byte SF_LAZY = 1 << 1; - private Config config; @SuppressWarnings( "deprecation" ) private IdGeneratorFactory idGeneratorFactory; @@ -123,16 +119,47 @@ public void setPageCache( PageCache pageCache ) this.pageCache = pageCache; } - public NeoStores openNeoStoresEagerly() + /** + * Open {@link NeoStores} with all possible stores. If some store does not exist it will not be created. + * @return container with all opened stores + */ + public NeoStores openAllNeoStores() + { + return openNeoStores( false, NeoStores.StoreType.values() ); + } + + /** + * Open {@link NeoStores} with all possible stores with a possibility to create store if it not exist. + * @param createStoreIfNotExists - should store be created if it's not exist + * @return container with all opened stores + */ + public NeoStores openAllNeoStores( boolean createStoreIfNotExists ) + { + return openNeoStores( createStoreIfNotExists, NeoStores.StoreType.values() ); + } + + /** + * Open {@link NeoStores} for requested and store types. If requested store depend from non request store, + * it will be automatically opened as well. + * If some store does not exist it will not be created. + * @param storeTypes - types of stores to be opened. + * @return container with opened stores + */ + public NeoStores openNeoStores( NeoStores.StoreType... storeTypes ) { - return openNeoStores( SF_DEFAULT ); + return openNeoStores( false, storeTypes ); } - public NeoStores openNeoStores( int flags ) + /** + * Open {@link NeoStores} for requested and store types. If requested store depend from non request store, + * it will be automatically opened as well. + * @param createStoreIfNotExists - should store be created if it's not exist + * @param storeTypes - types of stores to be opened. + * @return container with opened stores + */ + public NeoStores openNeoStores( boolean createStoreIfNotExists, NeoStores.StoreType... storeTypes ) { - boolean createIfNotExists = (flags & SF_CREATE) != 0; - boolean eagerlyInitializeStores = (flags & SF_LAZY) == 0; - if ( createIfNotExists ) + if ( createStoreIfNotExists ) { try { @@ -145,7 +172,7 @@ public NeoStores openNeoStores( int flags ) } } return new NeoStores( neoStoreFileName, config, idGeneratorFactory, pageCache, logProvider, - fileSystemAbstraction, createIfNotExists, eagerlyInitializeStores ); + fileSystemAbstraction, createStoreIfNotExists, storeTypes ); } public abstract static class Configuration diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/counts/DumpCountsStore.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/counts/DumpCountsStore.java index f0c2d764e2f2..a6d8e7aadcfc 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/store/counts/DumpCountsStore.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/store/counts/DumpCountsStore.java @@ -66,7 +66,7 @@ public static void dumpCountsStore( FileSystemAbstraction fs, File path, PrintSt { StoreFactory factory = new StoreFactory( fs, path, pages, NullLogProvider.getInstance() ); - NeoStores neoStores = factory.openNeoStoresEagerly(); + NeoStores neoStores = factory.openAllNeoStores(); neoStores.getCounts().accept( new DumpCountsStore( out, neoStores ) ); } else diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigrator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigrator.java index 8c5dd5cf9cc4..87e339acf1c2 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigrator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigrator.java @@ -46,7 +46,6 @@ import org.neo4j.logging.NullLogProvider; import static org.neo4j.kernel.api.index.SchemaIndexProvider.getRootDirectory; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_LAZY; import static org.neo4j.kernel.impl.store.record.SchemaRule.Kind.UNIQUENESS_CONSTRAINT; public class SchemaIndexMigrator implements StoreMigrationParticipant @@ -92,7 +91,7 @@ private void deleteIndexesContainingArrayValues( File storeDir, IndexSamplingConfig samplingConfig = new IndexSamplingConfig( new Config() ); List indexesToBeDeleted = new ArrayList<>(); storeFactory.setStoreDir( storeDir ); - try ( NeoStores neoStores = storeFactory.openNeoStores( SF_LAZY ) ) + try ( NeoStores neoStores = storeFactory.openNeoStores( NeoStores.StoreType.SCHEMA ) ) { SchemaStore schema = neoStores.getSchemaStore(); Iterator rules = schema.loadAllSchemaRules(); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrator.java index ff8ab33b1ece..d9d759aa7ecc 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreMigrator.java @@ -100,7 +100,6 @@ import static org.neo4j.helpers.collection.IteratorUtil.loop; import static org.neo4j.kernel.impl.store.CommonAbstractStore.ALL_STORES_VERSION; import static org.neo4j.kernel.impl.store.MetaDataStore.DEFAULT_NAME; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; import static org.neo4j.kernel.impl.storemigration.FileOperation.COPY; import static org.neo4j.kernel.impl.storemigration.FileOperation.DELETE; import static org.neo4j.kernel.impl.storemigration.FileOperation.MOVE; @@ -318,7 +317,7 @@ private void rebuildCountsFromScratch( File storeDir, long lastTxId, PageCache p final StoreFactory storeFactory = new StoreFactory( fileSystem, storeDir, pageCache, NullLogProvider.getInstance() ); - try ( NeoStores neoStores = storeFactory.openNeoStoresEagerly() ) + try ( NeoStores neoStores = storeFactory.openAllNeoStores() ) { NodeStore nodeStore = neoStores.getNodeStore(); RelationshipStore relationshipStore = neoStores.getRelationshipStore(); @@ -498,7 +497,7 @@ private void migratePropertyKeys( Legacy19Store legacyStore, PageCache pageCache { // The legacy property key token store contains duplicates, copy over and deduplicate // property key token store and go through property store with the new token ids. StoreFactory storeFactory = storeFactory( pageCache, migrationDir ); - try ( NeoStores neoStores = storeFactory.openNeoStores( SF_CREATE ) ) + try ( NeoStores neoStores = storeFactory.openAllNeoStores( true ) ) { PropertyStore propertyStore = neoStores.getPropertyStore(); // dedup and write new property key token store (incl. names) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v21/propertydeduplication/PropertyDeduplicator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v21/propertydeduplication/PropertyDeduplicator.java index 0c7daab003f0..1c665c7e5dd2 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v21/propertydeduplication/PropertyDeduplicator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/legacystore/v21/propertydeduplication/PropertyDeduplicator.java @@ -42,8 +42,6 @@ import org.neo4j.kernel.impl.store.record.Record; import org.neo4j.logging.NullLogProvider; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_LAZY; - public class PropertyDeduplicator { private final FileSystemAbstraction fileSystem; @@ -69,7 +67,8 @@ public void deduplicateProperties() throws IOException { final StoreFactory storeFactory = new StoreFactory( fileSystem, workingDir, pageCache, NullLogProvider.getInstance() ); - try ( NeoStores neoStores = storeFactory.openNeoStores( SF_LAZY ) ) + try ( NeoStores neoStores = storeFactory.openNeoStores( NeoStores.StoreType.PROPERTY, NeoStores.StoreType + .NODE, NeoStores.StoreType.SCHEMA) ) { PropertyStore propertyStore = neoStores.getPropertyStore(); NodeStore nodeStore = neoStores.getNodeStore(); diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/util/rawstorereader/RsdrMain.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/util/rawstorereader/RsdrMain.java index 17461b25ed25..598150e3b118 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/util/rawstorereader/RsdrMain.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/util/rawstorereader/RsdrMain.java @@ -84,7 +84,7 @@ public static void main( String[] args ) throws IOException try ( PageCache pageCache = createPageCache( files, config ) ) { StoreFactory factory = openStore( new File( storedir, MetaDataStore.DEFAULT_NAME ), config, pageCache ); - NeoStores neoStores = factory.openNeoStoresEagerly(); + NeoStores neoStores = factory.openAllNeoStores(); interact( neoStores ); } } diff --git a/community/kernel/src/main/java/org/neo4j/unsafe/batchinsert/BatchInserterImpl.java b/community/kernel/src/main/java/org/neo4j/unsafe/batchinsert/BatchInserterImpl.java index eb1db8c4380a..6ccb7ed4f83e 100644 --- a/community/kernel/src/main/java/org/neo4j/unsafe/batchinsert/BatchInserterImpl.java +++ b/community/kernel/src/main/java/org/neo4j/unsafe/batchinsert/BatchInserterImpl.java @@ -153,7 +153,6 @@ import static org.neo4j.helpers.collection.IteratorUtil.first; import static org.neo4j.kernel.impl.store.NodeLabelsField.parseLabelsField; import static org.neo4j.kernel.impl.store.PropertyStore.encodeString; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; import static org.neo4j.kernel.impl.util.IoPrimitiveUtils.safeCastLongToInt; /** @@ -276,7 +275,7 @@ public Label apply( long from ) } msgLog.info( Thread.currentThread() + " Starting BatchInserter(" + this + ")" ); life.start(); - neoStores = sf.openNeoStores( SF_CREATE ); + neoStores = sf.openAllNeoStores( true ); neoStores.verifyStoreOk(); nodeStore = neoStores.getNodeStore(); diff --git a/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/store/BatchingNeoStores.java b/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/store/BatchingNeoStores.java index e14086e33283..1c7ddb446341 100644 --- a/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/store/BatchingNeoStores.java +++ b/community/kernel/src/main/java/org/neo4j/unsafe/impl/batchimport/store/BatchingNeoStores.java @@ -63,7 +63,6 @@ import static org.neo4j.graphdb.factory.GraphDatabaseSettings.dense_node_threshold; import static org.neo4j.graphdb.factory.GraphDatabaseSettings.pagecache_memory; import static org.neo4j.helpers.collection.MapUtil.stringMap; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; /** * Creator and accessor of {@link NeoStores} with some logic to provide very batch friendly services to the @@ -182,7 +181,7 @@ public static void createStore( FileSystemAbstraction fileSystem, String storeDi { StoreFactory storeFactory = new StoreFactory( fileSystem, new File( storeDir ), pageCache, NullLogProvider.getInstance() ); - try ( NeoStores neoStores = storeFactory.openNeoStores( SF_CREATE ) ) + try ( NeoStores neoStores = storeFactory.openAllNeoStores( true ) ) { neoStores.getMetaDataStore(); neoStores.getLabelTokenStore(); @@ -200,7 +199,7 @@ private NeoStores newNeoStores( PageCache pageCache ) BatchingIdGeneratorFactory idGeneratorFactory = new BatchingIdGeneratorFactory( fileSystem ); StoreFactory storeFactory = new StoreFactory( storeDir, neo4jConfig, idGeneratorFactory, pageCache, fileSystem, logProvider ); - return storeFactory.openNeoStores( SF_CREATE ); + return storeFactory.openAllNeoStores( true ); } public IoTracer getIoTracer() diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/TransactionRepresentationCommitProcessIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/TransactionRepresentationCommitProcessIT.java index 617642906904..a231bf399a12 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/TransactionRepresentationCommitProcessIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/TransactionRepresentationCommitProcessIT.java @@ -99,7 +99,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.neo4j.helpers.collection.MapUtil.stringMap; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; + public class TransactionRepresentationCommitProcessIT { @@ -142,7 +142,7 @@ public void setUp() PageCache pageCache = pageCacheRule.getPageCache( fileSystem ); storeDir = testDirectory.graphDbDir(); StoreFactory storeFactory = new StoreFactory( fileSystem, storeDir, pageCache, NullLogProvider.getInstance() ); - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); } @After diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/PropertyPhysicalToLogicalConverterTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/PropertyPhysicalToLogicalConverterTest.java index 0cb1c42a234b..850a5ffecf46 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/PropertyPhysicalToLogicalConverterTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/PropertyPhysicalToLogicalConverterTest.java @@ -49,7 +49,7 @@ import static org.neo4j.helpers.collection.Iterables.toList; import static org.neo4j.helpers.collection.IteratorUtil.count; import static org.neo4j.helpers.collection.IteratorUtil.single; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; + public class PropertyPhysicalToLogicalConverterTest { @@ -222,7 +222,7 @@ public void before() throws Exception fs.get().mkdirs( storeDir ); StoreFactory storeFactory = new StoreFactory( storeDir, new Config(), new DefaultIdGeneratorFactory( fs.get() ), pageCacheRule.getPageCache( fs.get() ), fs.get(), NullLogProvider.getInstance() ); - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); store = neoStores.getPropertyStore(); converter = new PropertyPhysicalToLogicalConverter( store ); } 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 dd98604f8ee1..e7754f743a7c 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 @@ -67,7 +67,6 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; import static org.neo4j.kernel.impl.locking.LockService.NO_LOCK; @@ -311,7 +310,7 @@ public void setup() throws IOException } fs.mkdirs( storeDir ); StoreFactory storeFactory = new StoreFactory( fs, storeDir, pageCache, log ); - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); propertyStore = neoStores.getPropertyStore(); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/core/ManyPropertyKeysIT.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/core/ManyPropertyKeysIT.java index eeb2fce7411c..18855646f416 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/core/ManyPropertyKeysIT.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/core/ManyPropertyKeysIT.java @@ -49,7 +49,6 @@ import static org.junit.Assert.assertEquals; import static org.neo4j.helpers.collection.IteratorUtil.first; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; /** * Tests for handling many property keys (even after restart of database) @@ -123,7 +122,7 @@ private GraphDatabaseAPI databaseWithManyPropertyKeys( int propertyKeyCount ) th DefaultFileSystemAbstraction fs = new DefaultFileSystemAbstraction(); PageCache pageCache = pageCacheRule.getPageCache( fs ); StoreFactory storeFactory = new StoreFactory( fs, storeDir, pageCache, NullLogProvider.getInstance() ); - NeoStores neoStores = storeFactory.openNeoStores( SF_CREATE ); + NeoStores neoStores = storeFactory.openAllNeoStores( true ); PropertyKeyTokenStore store = neoStores.getPropertyKeyTokenStore(); for ( int i = 0; i < propertyKeyCount; i++ ) { diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/FreeIdsAfterRecoveryTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/FreeIdsAfterRecoveryTest.java index bf05eabdfa84..4f07b5933fbb 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/FreeIdsAfterRecoveryTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/FreeIdsAfterRecoveryTest.java @@ -39,8 +39,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_LAZY; + import static org.neo4j.kernel.impl.store.id.IdGeneratorImpl.HEADER_SIZE; import static org.neo4j.kernel.impl.store.id.IdGeneratorImpl.markAsSticky; @@ -59,7 +58,7 @@ public void shouldCompletelyRebuildIdGeneratorsAfterCrash() throws Exception StoreFactory storeFactory = new StoreFactory( fs, directory.directory(), pageCacheRule.getPageCache( fs ), NullLogProvider.getInstance() ); long highId; - try ( NeoStores stores = storeFactory.openNeoStores( SF_LAZY | SF_CREATE ) ) + try ( NeoStores stores = storeFactory.openAllNeoStores( true ) ) { // a node store with a "high" node NodeStore nodeStore = stores.getNodeStore(); @@ -83,7 +82,7 @@ public void shouldCompletelyRebuildIdGeneratorsAfterCrash() throws Exception } // WHEN - try ( NeoStores stores = storeFactory.openNeoStores( SF_LAZY | SF_CREATE ) ) + try ( NeoStores stores = storeFactory.openAllNeoStores( true ) ) { NodeStore nodeStore = stores.getNodeStore(); assertFalse( nodeStore.getStoreOk() ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/IdGeneratorRebuildFailureEmulationTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/IdGeneratorRebuildFailureEmulationTest.java index b38e402ad1a0..ac7b53ff167f 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/IdGeneratorRebuildFailureEmulationTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/IdGeneratorRebuildFailureEmulationTest.java @@ -84,7 +84,7 @@ private void performTest() throws Exception NeoStores neoStores = null; try { - neoStores = factory.openNeoStoresEagerly(); + neoStores = factory.openAllNeoStores(); // emulate a failure during rebuild: emulateFailureOnRebuildOf( neoStores ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NeoStoreTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NeoStoresTest.java similarity index 95% rename from community/kernel/src/test/java/org/neo4j/kernel/impl/store/NeoStoreTest.java rename to community/kernel/src/test/java/org/neo4j/kernel/impl/store/NeoStoresTest.java index 89d625901d3f..f11b66a3306a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NeoStoreTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NeoStoresTest.java @@ -82,12 +82,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.neo4j.helpers.collection.MapUtil.stringMap; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; -public class NeoStoreTest + +public class NeoStoresTest { @Rule public PageCacheRule pageCacheRule = new PageCacheRule(); @@ -105,6 +106,11 @@ public class NeoStoreTest private PropertyStore pStore; private RelationshipTypeTokenStore rtStore; private NeoStoreDataSource ds; + private KernelTransaction tx; + private TransactionRecordState transaction; + private StoreReadLayer storeLayer; + private PropertyLoader propertyLoader; + @Before public void setUpNeoStores() throws Exception @@ -114,110 +120,40 @@ public void setUpNeoStores() throws Exception pageCache = pageCacheRule.getPageCache( fs.get() ); StoreFactory sf = new StoreFactory( storeDir, config, new DefaultIdGeneratorFactory( fs.get() ), pageCache, fs.get(), NullLogProvider.getInstance() ); - sf.openNeoStores( SF_CREATE ).close(); - } - - private static class MyPropertyKeyToken extends Token - { - private static Map stringToIndex = new HashMap<>(); - private static Map intToIndex = new HashMap<>(); - - protected MyPropertyKeyToken( String key, int keyId ) - { - super( key, keyId ); - } - - public static Iterable index( String key ) - { - if ( stringToIndex.containsKey( key ) ) - { - return Collections.singletonList( stringToIndex.get( key ) ); - } - return Collections.emptyList(); - } - - public static Token getIndexFor( int index ) - { - return intToIndex.get( index ); - } - - public static void add( MyPropertyKeyToken index ) - { - stringToIndex.put( index.name(), index ); - intToIndex.put( index.id(), index ); - } - } - - private Token createDummyIndex( int id, String key ) - { - MyPropertyKeyToken index = new MyPropertyKeyToken( key, id ); - MyPropertyKeyToken.add( index ); - return index; + sf.openAllNeoStores( true ).close(); } - private void initializeStores( File storeDir, Map additionalConfig ) throws IOException + @Test + public void impossibleToGetStoreFromClosedNeoStoresContainer() { - ds = dsRule.getDataSource( storeDir, fs.get(), pageCache, additionalConfig ); - ds.init(); - ds.start(); + Config config = new Config( new HashMap(), GraphDatabaseSettings.class ); + StoreFactory sf = new StoreFactory( storeDir, config, new DefaultIdGeneratorFactory( fs.get() ), pageCache, + fs.get(), NullLogProvider.getInstance() ); + NeoStores neoStores = sf.openAllNeoStores( true ); - NeoStores neoStores = ds.get(); - pStore = neoStores.getPropertyStore(); - rtStore = neoStores.getRelationshipTypeTokenStore(); - storeLayer = ds.getStoreLayer(); - propertyLoader = new PropertyLoader( neoStores ); - } + assertNotNull( neoStores.getMetaDataStore() ); - private KernelTransaction tx; - private TransactionRecordState transaction; - private StoreReadLayer storeLayer; - private PropertyLoader propertyLoader; + neoStores.close(); - private void startTx() throws TransactionFailureException - { - tx = ds.getKernel().newTransaction(); - transaction = ((KernelTransactionImplementation) tx).getTransactionRecordState(); + exception.expect( IllegalStateException.class ); + exception.expectMessage( "Specified store was already closed."); + neoStores.getMetaDataStore(); } - private void commitTx() throws TransactionFailureException + @Test + public void impossibleToGetNotRequestedStore() { - tx.success(); - tx.close(); - } + Config config = new Config( new HashMap(), GraphDatabaseSettings.class ); + StoreFactory sf = new StoreFactory( storeDir, config, new DefaultIdGeneratorFactory( fs.get() ), pageCache, + fs.get(), NullLogProvider.getInstance() ); + NeoStores neoStores = sf.openNeoStores( true, NeoStores.StoreType.NODE_LABEL ); - private int index( String key ) - { - Iterator itr = MyPropertyKeyToken.index( key ).iterator(); - if ( !itr.hasNext() ) - { - int id = (int) nextId( PropertyKeyTokenRecord.class ); - createDummyIndex( id, key ); - transaction.createPropertyKeyToken( key, id ); - return id; - } - return itr.next().id(); - } - private long nextId( Class clazz ) - { - NeoStores neoStores = ds.get(); - if ( clazz.equals( PropertyKeyTokenRecord.class ) ) - { - return neoStores.getPropertyKeyTokenStore().nextId(); - } - if ( clazz.equals( RelationshipType.class ) ) - { - return neoStores.getRelationshipTypeTokenStore().nextId(); - } - if ( clazz.equals( Node.class ) ) - { - return neoStores.getNodeStore().nextId(); - } - if ( clazz.equals( Relationship.class ) ) - { - return neoStores.getRelationshipStore().nextId(); - } - throw new IllegalArgumentException( clazz.getName() ); + exception.expect( IllegalStateException.class ); + exception.expectMessage( + "Specified store was not initialized. Please specify " + NeoStores.StoreType.META_DATA.name() + + " as one of the stores types that should be open to be able to use it." ); + neoStores.getMetaDataStore(); } @Test @@ -325,456 +261,498 @@ public void testCreateStore() throws Exception ds.stop(); } - private void validateNodeRel1( final long node, DefinedProperty prop1, - DefinedProperty prop2, DefinedProperty prop3, long rel1, long rel2, - final int relType1, final int relType2 ) throws IOException, EntityNotFoundException + + + @Test + public void testRels1() throws Exception { - assertTrue( nodeExists( node ) ); - ArrayMap> props = new ArrayMap<>(); - PropertyReceiver receiver = newPropertyReceiver( props ); - propertyLoader.nodeLoadProperties( node, receiver ); - int count = 0; - for ( int keyId : props.keySet() ) + initializeStores( storeDir, stringMap() ); + startTx(); + int relType1 = (int) nextId( RelationshipType.class ); + String typeName = "relationshiptype1"; + transaction.createRelationshipTypeToken( typeName, relType1 ); + long nodeIds[] = new long[3]; + for ( int i = 0; i < 3; i++ ) { - long id = props.get( keyId ).other(); - PropertyRecord record = pStore.getRecord( id ); - PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); - DefinedProperty data = block.newPropertyData( pStore ); - if ( data.propertyKeyId() == prop1.propertyKeyId() ) - { - assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( "string1", data.value() ); - transaction.nodeChangeProperty( node, prop1.propertyKeyId(), "-string1" ); - } - else if ( data.propertyKeyId() == prop2.propertyKeyId() ) - { - assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( 1, data.value() ); - transaction.nodeChangeProperty( node, prop2.propertyKeyId(), new Integer( -1 ) ); - } - else if ( data.propertyKeyId() == prop3.propertyKeyId() ) - { - assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( true, data.value() ); - transaction.nodeChangeProperty( node, prop3.propertyKeyId(), false ); - } - else - { - throw new IOException(); - } - count++; + nodeIds[i] = nextId( Node.class ); + transaction.nodeCreate( nodeIds[i] ); + transaction.nodeAddProperty( nodeIds[i], + index( "nisse" ), new Integer( 10 - i ) ); } - assertEquals( 3, count ); - count = 0; - - try ( Cursor nodeCursor = ((KernelStatement) tx.acquireStatement()).getStoreStatement() - .acquireSingleNodeCursor( - node ) ) + for ( int i = 0; i < 2; i++ ) { - nodeCursor.next(); - - try ( Cursor relationships = nodeCursor.get().relationships( Direction.BOTH ) ) + transaction.relCreate( nextId( Relationship.class ), + relType1, nodeIds[i], nodeIds[i + 1] ); + } + commitTx(); + startTx(); + for ( int i = 0; i < 3; i += 2 ) + { + try ( Cursor nodeCursor = ((KernelStatement) tx.acquireStatement()).getStoreStatement() + .acquireSingleNodeCursor( + nodeIds[i] ) ) { - while ( relationships.next() ) + nodeCursor.next(); + PrimitiveLongIterator relationships = nodeCursor.get().getRelationships( Direction.BOTH ); + while ( relationships.hasNext() ) { - long rel = relationships.get().id(); - if ( rel == rel1 ) - { - assertEquals( node, relationships.get().startNode() ); - assertEquals( relType1, relationships.get().type() ); - } - else if ( rel == rel2 ) - { - assertEquals( node, relationships.get().endNode() ); - assertEquals( relType2, relationships.get().type() ); - } - else - { - throw new IOException(); - } - count++; - + transaction.relDelete( relationships.next() ); } } + + transaction.nodeDelete( nodeIds[i] ); } - assertEquals( 2, count ); + commitTx(); + ds.stop(); } - private PropertyReceiver newPropertyReceiver( final ArrayMap> props ) + @Test + @Ignore + public void testRels2() throws Exception { - return new PropertyReceiver() + initializeStores( storeDir, stringMap() ); + startTx(); + int relType1 = (int) nextId( RelationshipType.class ); + String typeName = "relationshiptype1"; + transaction.createRelationshipTypeToken( typeName, relType1 ); + long nodeIds[] = new long[3]; + for ( int i = 0; i < 3; i++ ) { - @Override - public void receive( DefinedProperty property, long propertyRecordId ) + nodeIds[i] = nextId( Node.class ); + transaction.nodeCreate( nodeIds[i] ); + transaction.nodeAddProperty( nodeIds[i], + index( "nisse" ), new Integer( 10 - i ) ); + } + for ( int i = 0; i < 2; i++ ) + { + transaction.relCreate( nextId( Relationship.class ), + relType1, nodeIds[i], nodeIds[i + 1] ); + } + transaction.relCreate( nextId( Relationship.class ), + relType1, nodeIds[0], nodeIds[2] ); + commitTx(); + startTx(); + for ( int i = 0; i < 3; i++ ) + { + try ( Cursor nodeCursor = ((KernelStatement) tx.acquireStatement()).getStoreStatement() + .acquireSingleNodeCursor( + nodeIds[i] ) ) { - props.put( property.propertyKeyId(), Pair.of( property, propertyRecordId ) ); + nodeCursor.next(); + PrimitiveLongIterator relationships = nodeCursor.get().getRelationships( Direction.BOTH ); + while ( relationships.hasNext() ) + { + transaction.relDelete( relationships.next() ); + } } - }; + + transaction.nodeDelete( nodeIds[i] ); + } + commitTx(); + ds.stop(); } - private void validateNodeRel2( final long node, DefinedProperty prop1, - DefinedProperty prop2, DefinedProperty prop3, - long rel1, long rel2, final int relType1, final int relType2 ) - throws IOException, EntityNotFoundException, RuntimeException + @Test + public void testRels3() throws Exception { - assertTrue( nodeExists( node ) ); - ArrayMap> props = new ArrayMap<>(); - propertyLoader.nodeLoadProperties( node, newPropertyReceiver( props ) ); - int count = 0; - for ( int keyId : props.keySet() ) + // test linked list stuff during relationship delete + initializeStores( storeDir, stringMap() ); + startTx(); + int relType1 = (int) nextId( RelationshipType.class ); + transaction.createRelationshipTypeToken( "relationshiptype1", relType1 ); + long nodeIds[] = new long[8]; + for ( int i = 0; i < nodeIds.length; i++ ) { - long id = props.get( keyId ).other(); - PropertyRecord record = pStore.getRecord( id ); - PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); - DefinedProperty data = block.newPropertyData( pStore ); - if ( data.propertyKeyId() == prop1.propertyKeyId() ) - { - assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( "string2", data.value() ); - transaction.nodeChangeProperty( node, prop1.propertyKeyId(), "-string2" ); - } - else if ( data.propertyKeyId() == prop2.propertyKeyId() ) - { - assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( 2, data.value() ); - transaction.nodeChangeProperty( node, prop2.propertyKeyId(), new Integer( -2 ) ); - } - else if ( data.propertyKeyId() == prop3.propertyKeyId() ) - { - assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( false, data.value() ); - transaction.nodeChangeProperty( node, prop3.propertyKeyId(), true ); - } - else - { - throw new IOException(); - } - count++; + nodeIds[i] = nextId( Node.class ); + transaction.nodeCreate( nodeIds[i] ); } - assertEquals( 3, count ); - count = 0; - - try ( Cursor nodeCursor = ((KernelStatement) tx.acquireStatement()).getStoreStatement() - .acquireSingleNodeCursor( - node ) ) + for ( int i = 0; i < nodeIds.length / 2; i++ ) { - nodeCursor.next(); + transaction.relCreate( nextId( Relationship.class ), + relType1, nodeIds[i], nodeIds[i * 2] ); + } + long rel5 = nextId( Relationship.class ); + transaction.relCreate( rel5, relType1, nodeIds[0], nodeIds[5] ); + long rel2 = nextId( Relationship.class ); + transaction.relCreate( rel2, relType1, nodeIds[1], nodeIds[2] ); + long rel3 = nextId( Relationship.class ); + transaction.relCreate( rel3, relType1, nodeIds[1], nodeIds[3] ); + long rel6 = nextId( Relationship.class ); + transaction.relCreate( rel6, relType1, nodeIds[1], nodeIds[6] ); + long rel1 = nextId( Relationship.class ); + transaction.relCreate( rel1, relType1, nodeIds[0], nodeIds[1] ); + long rel4 = nextId( Relationship.class ); + transaction.relCreate( rel4, relType1, nodeIds[0], nodeIds[4] ); + long rel7 = nextId( Relationship.class ); + transaction.relCreate( rel7, relType1, nodeIds[0], nodeIds[7] ); + commitTx(); + startTx(); + transaction.relDelete( rel7 ); + transaction.relDelete( rel4 ); + transaction.relDelete( rel1 ); + transaction.relDelete( rel6 ); + transaction.relDelete( rel3 ); + transaction.relDelete( rel2 ); + transaction.relDelete( rel5 ); + commitTx(); + ds.stop(); + } - try ( Cursor relationships = nodeCursor.get().relationships( Direction.BOTH ) ) - { - while ( relationships.next() ) - { - long rel = relationships.get().id(); - if ( rel == rel1 ) - { - assertEquals( node, relationships.get().endNode() ); - assertEquals( relType1, relationships.get().type() ); - } - else if ( rel == rel2 ) - { - assertEquals( node, relationships.get().startNode() ); - assertEquals( relType2, relationships.get().type() ); - } - else - { - throw new IOException(); - } - count++; + @Test + public void testProps1() throws Exception + { + initializeStores( storeDir, stringMap() ); + startTx(); + long nodeId = nextId( Node.class ); + transaction.nodeCreate( nodeId ); + pStore.nextId(); + DefinedProperty prop = transaction.nodeAddProperty( + nodeId, index( "nisse" ), + new Integer( 10 ) ); + commitTx(); + ds.stop(); + initializeStores( storeDir, stringMap() ); + startTx(); + transaction.nodeChangeProperty( nodeId, prop.propertyKeyId(), new Integer( 5 ) ); + transaction.nodeRemoveProperty( nodeId, prop.propertyKeyId() ); + transaction.nodeDelete( nodeId ); + commitTx(); + ds.stop(); + } - } - } - } - assertEquals( 2, count ); + @Test + public void testSetBlockSize() throws Exception + { + File storeDir = dir.directory( "small_store" ); + initializeStores( storeDir, stringMap( "string_block_size", "62", "array_block_size", "302" ) ); + assertEquals( 62 + AbstractDynamicStore.BLOCK_HEADER_SIZE, + pStore.getStringBlockSize() ); + assertEquals( 302 + AbstractDynamicStore.BLOCK_HEADER_SIZE, + pStore.getArrayBlockSize() ); + ds.stop(); } - private boolean nodeExists( long nodeId ) + @Test + public void setVersion() throws Exception { - try ( StoreStatement statement = storeLayer.acquireStatement() ) - { - try ( Cursor node = statement.acquireSingleNodeCursor( nodeId ) ) - { - return node.next(); - } - } + FileSystemAbstraction fileSystem = fs.get(); + File storeDir = new File( "target/test-data/set-version" ).getAbsoluteFile(); + new TestGraphDatabaseFactory().setFileSystem( fileSystem ).newImpermanentDatabase( storeDir ).shutdown(); + assertEquals( 0, MetaDataStore.setRecord( pageCache, new File( storeDir, + MetaDataStore.DEFAULT_NAME ).getAbsoluteFile(), Position.LOG_VERSION, 10 ) ); + assertEquals( 10, MetaDataStore.setRecord( pageCache, new File( storeDir, + MetaDataStore.DEFAULT_NAME ).getAbsoluteFile(), Position.LOG_VERSION, 12 ) ); + + Config config = new Config( new HashMap(), GraphDatabaseSettings.class ); + StoreFactory sf = new StoreFactory( storeDir, config, new DefaultIdGeneratorFactory( fileSystem ), pageCache, + fileSystem, NullLogProvider.getInstance() ); + + NeoStores neoStores = sf.openAllNeoStores(); + assertEquals( 12, neoStores.getMetaDataStore().getCurrentLogVersion() ); + neoStores.close(); } - private void validateRel1( long rel, DefinedProperty prop1, - DefinedProperty prop2, DefinedProperty prop3, long firstNode, long secondNode, - int relType ) throws IOException + @Test + public void shouldNotReadNonRecordDataAsRecord() throws Exception { - ArrayMap> props = new ArrayMap<>(); - propertyLoader.relLoadProperties( rel, newPropertyReceiver( props ) ); - int count = 0; - for ( int keyId : props.keySet() ) + FileSystemAbstraction fileSystem = fs.get(); + File neoStoreDir = new File( "/tmp/graph.db/neostore" ).getAbsoluteFile(); + StoreFactory factory = new StoreFactory( fileSystem, neoStoreDir, pageCache, NullLogProvider.getInstance() ); + + try ( NeoStores neoStores = factory.openAllNeoStores( true ) ) { - long id = props.get( keyId ).other(); - PropertyRecord record = pStore.getRecord( id ); - PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); - DefinedProperty data = block.newPropertyData( pStore ); - if ( data.propertyKeyId() == prop1.propertyKeyId() ) - { - assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( "string1", data.value() ); - transaction.relChangeProperty( rel, prop1.propertyKeyId(), "-string1" ); - } - else if ( data.propertyKeyId() == prop2.propertyKeyId() ) - { - assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( 1, data.value() ); - transaction.relChangeProperty( rel, prop2.propertyKeyId(), new Integer( -1 ) ); - } - else if ( data.propertyKeyId() == prop3.propertyKeyId() ) - { - assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( true, data.value() ); - transaction.relChangeProperty( rel, prop3.propertyKeyId(), false ); - } - else - { - throw new IOException(); - } - count++; + MetaDataStore metaDataStore = neoStores.getMetaDataStore(); + metaDataStore.setCreationTime( 3 ); + metaDataStore.setRandomNumber( 4 ); + metaDataStore.setCurrentLogVersion( 5 ); + metaDataStore.setLastCommittedAndClosedTransactionId( 6, 0, 0, 0 ); + metaDataStore.setStoreVersion( 7 ); + metaDataStore.setGraphNextProp( 8 ); + metaDataStore.setLatestConstraintIntroducingTx( 9 ); } - assertEquals( 3, count ); - assertRelationshipData( rel, firstNode, secondNode, relType ); - } - private void assertRelationshipData( long rel, final long firstNode, final long secondNode, - final int relType ) - { - try + File file = new File( neoStoreDir, MetaDataStore.DEFAULT_NAME ); + try ( StoreChannel channel = fileSystem.open( file, "rw" ) ) { - storeLayer.relationshipVisit( rel, new RelationshipVisitor() - { - @Override - public void visit( long relId, int type, long startNode, long endNode ) - { - assertEquals( firstNode, startNode ); - assertEquals( secondNode, endNode ); - assertEquals( relType, type ); - } - } ); + channel.position( 0 ); + channel.write( ByteBuffer.wrap( UTF8.encode( "This is some data that is not a record." ) ) ); } - catch ( EntityNotFoundException e ) + + try ( NeoStores neoStores = factory.openAllNeoStores() ) { - throw new RuntimeException( e ); + MetaDataStore metaDataStore = neoStores.getMetaDataStore(); + assertEquals( MetaDataStore.FIELD_NOT_PRESENT, metaDataStore.getCreationTime() ); + assertEquals( MetaDataStore.FIELD_NOT_PRESENT, metaDataStore.getRandomNumber() ); + assertEquals( MetaDataStore.FIELD_NOT_PRESENT, metaDataStore.getCurrentLogVersion() ); + assertEquals( MetaDataStore.FIELD_NOT_PRESENT, metaDataStore.getLastCommittedTransactionId() ); + assertEquals( MetaDataStore.FIELD_NOT_PRESENT, metaDataStore.getStoreVersion() ); + assertEquals( 8, metaDataStore.getGraphNextProp() ); + assertEquals( 9, metaDataStore.getLatestConstraintIntroducingTx() ); } } - private void validateRel2( long rel, DefinedProperty prop1, - DefinedProperty prop2, DefinedProperty prop3, - long firstNode, long secondNode, int relType ) throws IOException + @Test + public void testSetLatestConstraintTx() throws Exception { - ArrayMap> props = new ArrayMap<>(); - propertyLoader.relLoadProperties( rel, newPropertyReceiver( props ) ); - int count = 0; - for ( int keyId : props.keySet() ) - { - long id = props.get( keyId ).other(); - PropertyRecord record = pStore.getRecord( id ); - PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); - DefinedProperty data = block.newPropertyData( pStore ); - if ( data.propertyKeyId() == prop1.propertyKeyId() ) - { - assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( "string2", data.value() ); - transaction.relChangeProperty( rel, prop1.propertyKeyId(), "-string2" ); - } - else if ( data.propertyKeyId() == prop2.propertyKeyId() ) - { - assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( 2, data.value() ); - transaction.relChangeProperty( rel, prop2.propertyKeyId(), new Integer( -2 ) ); - } - else if ( data.propertyKeyId() == prop3.propertyKeyId() ) - { - assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( false, data.value() ); - transaction.relChangeProperty( rel, prop3.propertyKeyId(), true ); - } - else - { - throw new IOException(); - } - count++; - } - assertEquals( 3, count ); - assertRelationshipData( rel, firstNode, secondNode, relType ); + // given + Config config = new Config( new HashMap(), GraphDatabaseSettings.class ); + StoreFactory sf = new StoreFactory( dir.directory(), config, new DefaultIdGeneratorFactory( fs.get() ), + pageCacheRule.getPageCache( fs.get() ), fs.get(), NullLogProvider.getInstance() ); + + // when + NeoStores neoStores = sf.openAllNeoStores( true ); + MetaDataStore metaDataStore = neoStores.getMetaDataStore(); + + // then the default is 0 + assertEquals( 0l, metaDataStore.getLatestConstraintIntroducingTx() ); + + // when + metaDataStore.setLatestConstraintIntroducingTx( 10l ); + + // then + assertEquals( 10l, metaDataStore.getLatestConstraintIntroducingTx() ); + + // when + neoStores.flush(); + neoStores.close(); + neoStores = sf.openAllNeoStores(); + + // then the value should have been stored + assertEquals( 10l, metaDataStore.getLatestConstraintIntroducingTx() ); + neoStores.close(); } - private void validateRelTypes( int relType1, int relType2 ) - throws IOException + @Test + public void shouldInitializeTheTxIdToOne() { - Token data = rtStore.getToken( relType1 ); - assertEquals( relType1, data.id() ); - assertEquals( "relationshiptype1", data.name() ); - data = rtStore.getToken( relType2 ); - assertEquals( relType2, data.id() ); - assertEquals( "relationshiptype2", data.name() ); - List allData = rtStore.getTokens( Integer.MAX_VALUE ); - assertEquals( 2, allData.size() ); - for ( int i = 0; i < 2; i++ ) + StoreFactory factory = + new StoreFactory( fs.get(), new File( "graph.db/neostore" ), pageCache, NullLogProvider.getInstance() ); + + try ( NeoStores neoStores = factory.openAllNeoStores( true ) ) { - if ( allData.get(i).id() == relType1 ) - { - assertEquals( relType1, allData.get(i).id() ); - assertEquals( "relationshiptype1", allData.get(i).name() ); - } - else if ( allData.get(i).id() == relType2 ) - { - assertEquals( relType2, allData.get(i).id() ); - assertEquals( "relationshiptype2", allData.get(i).name() ); - } - else - { - throw new IOException(); - } + neoStores.getMetaDataStore(); } - } - private void deleteRel1( long rel, DefinedProperty prop1, DefinedProperty prop2, - DefinedProperty prop3, long firstNode, long secondNode, int relType ) - throws IOException - { - ArrayMap> props = new ArrayMap<>(); - propertyLoader.relLoadProperties( rel, newPropertyReceiver( props ) ); - int count = 0; - for ( int keyId : props.keySet() ) + try ( NeoStores neoStores = factory.openAllNeoStores() ) { - long id = props.get( keyId ).other(); - PropertyRecord record = pStore.getRecord( id ); - PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); - DefinedProperty data = block.newPropertyData( pStore ); - if ( data.propertyKeyId() == prop1.propertyKeyId() ) - { - assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( "-string1", data.value() ); - } - else if ( data.propertyKeyId() == prop2.propertyKeyId() ) - { - assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( -1, data.value() ); - } - else if ( data.propertyKeyId() == prop3.propertyKeyId() ) - { - assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( false, data.value() ); - transaction.relRemoveProperty( rel, prop3.propertyKeyId() ); - } - else - { - throw new IOException(); - } - count++; + long lastCommittedTransactionId = neoStores.getMetaDataStore().getLastCommittedTransactionId(); + assertEquals( TransactionIdStore.BASE_TX_ID, lastCommittedTransactionId ); } - assertEquals( 3, count ); - CountingPropertyReceiver propertyCounter = new CountingPropertyReceiver(); - propertyLoader.relLoadProperties( rel, propertyCounter ); - assertEquals( 3, propertyCounter.count ); - assertRelationshipData( rel, firstNode, secondNode, relType ); - transaction.relDelete( rel ); - - assertHasRelationships( firstNode ); - - assertHasRelationships( secondNode ); } - private static class CountingPropertyReceiver implements PropertyReceiver + @Test + public void shouldThrowUnderlyingStorageExceptionWhenFailingToLoadStorage() { - private int count; + FileSystemAbstraction fileSystem = fs.get(); + File neoStoreDir = new File( "/tmp/graph.db/neostore" ).getAbsoluteFile(); + StoreFactory factory = new StoreFactory( fileSystem, neoStoreDir, pageCache, NullLogProvider.getInstance() ); - @Override - public void receive( DefinedProperty property, long propertyRecordId ) + try ( NeoStores neoStores = factory.openAllNeoStores( true ) ) { - count++; + neoStores.getMetaDataStore(); + } + File file = new File( neoStoreDir, MetaDataStore.DEFAULT_NAME ); + fileSystem.deleteFile( file ); + + exception.expect( StoreNotFoundException.class ); + try ( NeoStores neoStores = factory.openAllNeoStores() ) + { + neoStores.getMetaDataStore(); } } - private void deleteRel2( long rel, DefinedProperty prop1, DefinedProperty prop2, - DefinedProperty prop3, long firstNode, long secondNode, int relType ) - throws IOException + @Test + public void shouldAddUpgradeFieldsToTheNeoStoreIfNotPresent() throws IOException { - ArrayMap> props = new ArrayMap<>(); - propertyLoader.relLoadProperties( rel, newPropertyReceiver( props ) ); - int count = 0; - for ( int keyId : props.keySet() ) + FileSystemAbstraction fileSystem = fs.get(); + File neoStoreDir = new File( "/tmp/graph.db/neostore" ).getAbsoluteFile(); + StoreFactory factory = new StoreFactory( fileSystem, neoStoreDir, pageCache, NullLogProvider.getInstance() ); + + try ( NeoStores neoStores = factory.openAllNeoStores( true ) ) { - long id = props.get( keyId ).other(); - PropertyRecord record = pStore.getRecord( id ); - PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); - DefinedProperty data = block.newPropertyData( pStore ); - if ( data.propertyKeyId() == prop1.propertyKeyId() ) - { - assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( "-string2", data.value() ); - } - else if ( data.propertyKeyId() == prop2.propertyKeyId() ) - { - assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( -2, data.value() ); - } - else if ( data.propertyKeyId() == prop3.propertyKeyId() ) - { - assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( - keyId ).name() ); - assertEquals( true, data.value() ); - transaction.relRemoveProperty( rel, prop3.propertyKeyId() ); - } - else - { - throw new IOException(); - } - count++; + MetaDataStore metaDataStore = neoStores.getMetaDataStore(); + metaDataStore.setCreationTime( 3 ); + metaDataStore.setRandomNumber( 4 ); + metaDataStore.setCurrentLogVersion( 5 ); + metaDataStore.setLastCommittedAndClosedTransactionId( 6, 0, 0, 0 ); + metaDataStore.setStoreVersion( 7 ); + metaDataStore.setGraphNextProp( 8 ); + metaDataStore.setLatestConstraintIntroducingTx( 9 ); } - assertEquals( 3, count ); - CountingPropertyReceiver propertyCounter = new CountingPropertyReceiver(); - propertyLoader.relLoadProperties( rel, propertyCounter ); - assertEquals( 3, propertyCounter.count ); - assertRelationshipData( rel, firstNode, secondNode, relType ); - transaction.relDelete( rel ); - assertHasRelationships( firstNode ); + File file = new File( neoStoreDir, MetaDataStore.DEFAULT_NAME ); - assertHasRelationships( secondNode ); + assertNotEquals( 10, MetaDataStore.getRecord( pageCache, file, Position.UPGRADE_TRANSACTION_ID ) ); + assertNotEquals( 11, MetaDataStore.getRecord( pageCache, file, Position.UPGRADE_TRANSACTION_CHECKSUM ) ); + MetaDataStore.setRecord( pageCache, file, Position.UPGRADE_TRANSACTION_ID, 10 ); + MetaDataStore.setRecord( pageCache, file, Position.UPGRADE_TRANSACTION_CHECKSUM, 11 ); + MetaDataStore.setRecord( pageCache, file, Position.UPGRADE_TIME, 12 ); + + try ( NeoStores neoStores = factory.openAllNeoStores() ) + { + MetaDataStore metaDataStore = neoStores.getMetaDataStore(); + assertEquals( 3, metaDataStore.getCreationTime() ); + assertEquals( 4, metaDataStore.getRandomNumber() ); + assertEquals( 5, metaDataStore.getCurrentLogVersion() ); + assertEquals( 6, metaDataStore.getLastCommittedTransactionId() ); + assertEquals( 7, metaDataStore.getStoreVersion() ); + assertEquals( 8, metaDataStore.getGraphNextProp() ); + assertEquals( 9, metaDataStore.getLatestConstraintIntroducingTx() ); + assertEquals( new TransactionId( 10, 11 ), metaDataStore.getUpgradeTransaction() ); + assertEquals( 12, metaDataStore.getUpgradeTime() ); + } } - private void assertHasRelationships( long node ) + @Test + public void shouldSetHighestTransactionIdWhenNeeded() throws Throwable { - try ( Cursor nodeCursor = ((KernelStatement) tx.acquireStatement()).getStoreStatement() - .acquireSingleNodeCursor( + // GIVEN + FileSystemAbstraction fileSystem = fs.get(); + fileSystem.mkdirs( storeDir ); + StoreFactory factory = new StoreFactory( fileSystem, storeDir, pageCache, NullLogProvider.getInstance() ); - node ) ) + try ( NeoStores neoStore = factory.openAllNeoStores( true ) ) { - nodeCursor.next(); - PrimitiveLongIterator rels = nodeCursor.get().getRelationships( Direction.BOTH ); - assertTrue( rels.hasNext() ); + MetaDataStore store = neoStore.getMetaDataStore(); + store.setLastCommittedAndClosedTransactionId( 40, 4444, 0, LogHeader.LOG_HEADER_SIZE ); + + // WHEN + store.transactionCommitted( 42, 6666 ); + + // THEN + assertEquals( new TransactionId( 42, 6666 ), store.getLastCommittedTransaction() ); } } - private void deleteNode1( long node, DefinedProperty prop1, - DefinedProperty prop2, DefinedProperty prop3 ) - throws IOException + @Test + public void shouldNotSetHighestTransactionIdWhenNeeded() throws Throwable + { + // GIVEN + FileSystemAbstraction fileSystem = fs.get(); + fileSystem.mkdirs( storeDir ); + StoreFactory factory = new StoreFactory( fileSystem, storeDir, pageCache, NullLogProvider.getInstance() ); + + try ( NeoStores neoStore = factory.openAllNeoStores( true ) ) + { + MetaDataStore store = neoStore.getMetaDataStore(); + store.setLastCommittedAndClosedTransactionId( 40, 4444, 0, LogHeader.LOG_HEADER_SIZE ); + + // WHEN + store.transactionCommitted( 39, 3333 ); + + // THEN + assertEquals( new TransactionId( 40, 4444 ), store.getLastCommittedTransaction() ); + } + } + + private static class MyPropertyKeyToken extends Token + { + private static Map stringToIndex = new HashMap<>(); + private static Map intToIndex = new HashMap<>(); + + protected MyPropertyKeyToken( String key, int keyId ) + { + super( key, keyId ); + } + + public static Iterable index( String key ) + { + if ( stringToIndex.containsKey( key ) ) + { + return Collections.singletonList( stringToIndex.get( key ) ); + } + return Collections.emptyList(); + } + + public static Token getIndexFor( int index ) + { + return intToIndex.get( index ); + } + + public static void add( MyPropertyKeyToken index ) + { + stringToIndex.put( index.name(), index ); + intToIndex.put( index.id(), index ); + } + } + + private Token createDummyIndex( int id, String key ) + { + MyPropertyKeyToken index = new MyPropertyKeyToken( key, id ); + MyPropertyKeyToken.add( index ); + return index; + } + + private void initializeStores( File storeDir, Map additionalConfig ) throws IOException + { + ds = dsRule.getDataSource( storeDir, fs.get(), pageCache, additionalConfig ); + ds.init(); + ds.start(); + + NeoStores neoStores = ds.get(); + pStore = neoStores.getPropertyStore(); + rtStore = neoStores.getRelationshipTypeTokenStore(); + storeLayer = ds.getStoreLayer(); + propertyLoader = new PropertyLoader( neoStores ); + } + + + private void startTx() throws TransactionFailureException + { + tx = ds.getKernel().newTransaction(); + transaction = ((KernelTransactionImplementation) tx).getTransactionRecordState(); + } + + private void commitTx() throws TransactionFailureException + { + tx.success(); + tx.close(); + } + + private int index( String key ) + { + Iterator itr = MyPropertyKeyToken.index( key ).iterator(); + if ( !itr.hasNext() ) + { + int id = (int) nextId( PropertyKeyTokenRecord.class ); + createDummyIndex( id, key ); + transaction.createPropertyKeyToken( key, id ); + return id; + } + return itr.next().id(); + } + + private long nextId( Class clazz ) + { + NeoStores neoStores = ds.get(); + if ( clazz.equals( PropertyKeyTokenRecord.class ) ) + { + return neoStores.getPropertyKeyTokenStore().nextId(); + } + if ( clazz.equals( RelationshipType.class ) ) + { + return neoStores.getRelationshipTypeTokenStore().nextId(); + } + if ( clazz.equals( Node.class ) ) + { + return neoStores.getNodeStore().nextId(); + } + if ( clazz.equals( Relationship.class ) ) + { + return neoStores.getRelationshipStore().nextId(); + } + throw new IllegalArgumentException( clazz.getName() ); + } + + private void validateNodeRel1( final long node, DefinedProperty prop1, + DefinedProperty prop2, DefinedProperty prop3, long rel1, long rel2, + final int relType1, final int relType2 ) throws IOException, EntityNotFoundException { + assertTrue( nodeExists( node ) ); ArrayMap> props = new ArrayMap<>(); - propertyLoader.nodeLoadProperties( node, newPropertyReceiver( props ) ); + PropertyReceiver receiver = newPropertyReceiver( props ); + propertyLoader.nodeLoadProperties( node, receiver ); int count = 0; for ( int keyId : props.keySet() ) { @@ -786,20 +764,22 @@ private void deleteNode1( long node, DefinedProperty prop1, { assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( keyId ).name() ); - assertEquals( "-string1", data.value() ); + assertEquals( "string1", data.value() ); + transaction.nodeChangeProperty( node, prop1.propertyKeyId(), "-string1" ); } else if ( data.propertyKeyId() == prop2.propertyKeyId() ) { assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( keyId ).name() ); - assertEquals( -1, data.value() ); + assertEquals( 1, data.value() ); + transaction.nodeChangeProperty( node, prop2.propertyKeyId(), new Integer( -1 ) ); } else if ( data.propertyKeyId() == prop3.propertyKeyId() ) { assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( keyId ).name() ); - assertEquals( false, data.value() ); - transaction.nodeRemoveProperty( node, prop3.propertyKeyId() ); + assertEquals( true, data.value() ); + transaction.nodeChangeProperty( node, prop3.propertyKeyId(), false ); } else { @@ -808,17 +788,59 @@ else if ( data.propertyKeyId() == prop3.propertyKeyId() ) count++; } assertEquals( 3, count ); - CountingPropertyReceiver propertyCounter = new CountingPropertyReceiver(); - propertyLoader.nodeLoadProperties( node, propertyCounter ); - assertEquals( 3, propertyCounter.count ); - assertHasRelationships( node ); - transaction.nodeDelete( node ); + count = 0; + + try ( Cursor nodeCursor = ((KernelStatement) tx.acquireStatement()).getStoreStatement() + .acquireSingleNodeCursor( + node ) ) + { + nodeCursor.next(); + + try ( Cursor relationships = nodeCursor.get().relationships( Direction.BOTH ) ) + { + while ( relationships.next() ) + { + long rel = relationships.get().id(); + if ( rel == rel1 ) + { + assertEquals( node, relationships.get().startNode() ); + assertEquals( relType1, relationships.get().type() ); + } + else if ( rel == rel2 ) + { + assertEquals( node, relationships.get().endNode() ); + assertEquals( relType2, relationships.get().type() ); + } + else + { + throw new IOException(); + } + count++; + + } + } + } + assertEquals( 2, count ); } - private void deleteNode2( long node, DefinedProperty prop1, - DefinedProperty prop2, DefinedProperty prop3 ) - throws IOException + private PropertyReceiver newPropertyReceiver( final ArrayMap> props ) + { + return new PropertyReceiver() + { + @Override + public void receive( DefinedProperty property, long propertyRecordId ) + { + props.put( property.propertyKeyId(), Pair.of( property, propertyRecordId ) ); + } + }; + } + + private void validateNodeRel2( final long node, DefinedProperty prop1, + DefinedProperty prop2, DefinedProperty prop3, + long rel1, long rel2, final int relType1, final int relType2 ) + throws IOException, EntityNotFoundException, RuntimeException { + assertTrue( nodeExists( node ) ); ArrayMap> props = new ArrayMap<>(); propertyLoader.nodeLoadProperties( node, newPropertyReceiver( props ) ); int count = 0; @@ -832,20 +854,22 @@ private void deleteNode2( long node, DefinedProperty prop1, { assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( keyId ).name() ); - assertEquals( "-string2", data.value() ); + assertEquals( "string2", data.value() ); + transaction.nodeChangeProperty( node, prop1.propertyKeyId(), "-string2" ); } else if ( data.propertyKeyId() == prop2.propertyKeyId() ) { assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( keyId ).name() ); - assertEquals( -2, data.value() ); + assertEquals( 2, data.value() ); + transaction.nodeChangeProperty( node, prop2.propertyKeyId(), new Integer( -2 ) ); } else if ( data.propertyKeyId() == prop3.propertyKeyId() ) { assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( keyId ).name() ); - assertEquals( true, data.value() ); - transaction.nodeRemoveProperty( node, prop3.propertyKeyId() ); + assertEquals( false, data.value() ); + transaction.nodeChangeProperty( node, prop3.propertyKeyId(), true ); } else { @@ -854,409 +878,422 @@ else if ( data.propertyKeyId() == prop3.propertyKeyId() ) count++; } assertEquals( 3, count ); - CountingPropertyReceiver propertyCounter = new CountingPropertyReceiver(); - propertyLoader.nodeLoadProperties( node, propertyCounter ); - assertEquals( 3, propertyCounter.count ); + count = 0; - assertHasRelationships( node ); + try ( Cursor nodeCursor = ((KernelStatement) tx.acquireStatement()).getStoreStatement() + .acquireSingleNodeCursor( + node ) ) + { + nodeCursor.next(); - transaction.nodeDelete( node ); + try ( Cursor relationships = nodeCursor.get().relationships( Direction.BOTH ) ) + { + while ( relationships.next() ) + { + long rel = relationships.get().id(); + if ( rel == rel1 ) + { + assertEquals( node, relationships.get().endNode() ); + assertEquals( relType1, relationships.get().type() ); + } + else if ( rel == rel2 ) + { + assertEquals( node, relationships.get().startNode() ); + assertEquals( relType2, relationships.get().type() ); + } + else + { + throw new IOException(); + } + count++; + + } + } + } + assertEquals( 2, count ); } - private void testGetRels( long relIds[] ) + private boolean nodeExists( long nodeId ) { try ( StoreStatement statement = storeLayer.acquireStatement() ) { - for ( long relId : relIds ) + try ( Cursor node = statement.acquireSingleNodeCursor( nodeId ) ) { - try ( Cursor relationship = statement.acquireSingleRelationshipCursor( relId ) ) - { - assertFalse( relationship.next() ); - } + return node.next(); } } } - @Test - public void testRels1() throws Exception + private void validateRel1( long rel, DefinedProperty prop1, + DefinedProperty prop2, DefinedProperty prop3, long firstNode, long secondNode, + int relType ) throws IOException { - initializeStores( storeDir, stringMap() ); - startTx(); - int relType1 = (int) nextId( RelationshipType.class ); - String typeName = "relationshiptype1"; - transaction.createRelationshipTypeToken( typeName, relType1 ); - long nodeIds[] = new long[3]; - for ( int i = 0; i < 3; i++ ) - { - nodeIds[i] = nextId( Node.class ); - transaction.nodeCreate( nodeIds[i] ); - transaction.nodeAddProperty( nodeIds[i], - index( "nisse" ), new Integer( 10 - i ) ); - } - for ( int i = 0; i < 2; i++ ) - { - transaction.relCreate( nextId( Relationship.class ), - relType1, nodeIds[i], nodeIds[i + 1] ); - } - commitTx(); - startTx(); - for ( int i = 0; i < 3; i += 2 ) + ArrayMap> props = new ArrayMap<>(); + propertyLoader.relLoadProperties( rel, newPropertyReceiver( props ) ); + int count = 0; + for ( int keyId : props.keySet() ) { - try ( Cursor nodeCursor = ((KernelStatement) tx.acquireStatement()).getStoreStatement() - .acquireSingleNodeCursor( - nodeIds[i] ) ) + long id = props.get( keyId ).other(); + PropertyRecord record = pStore.getRecord( id ); + PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); + DefinedProperty data = block.newPropertyData( pStore ); + if ( data.propertyKeyId() == prop1.propertyKeyId() ) { - nodeCursor.next(); - PrimitiveLongIterator relationships = nodeCursor.get().getRelationships( Direction.BOTH ); - while ( relationships.hasNext() ) - { - transaction.relDelete( relationships.next() ); - } + assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( "string1", data.value() ); + transaction.relChangeProperty( rel, prop1.propertyKeyId(), "-string1" ); } - - transaction.nodeDelete( nodeIds[i] ); + else if ( data.propertyKeyId() == prop2.propertyKeyId() ) + { + assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( 1, data.value() ); + transaction.relChangeProperty( rel, prop2.propertyKeyId(), new Integer( -1 ) ); + } + else if ( data.propertyKeyId() == prop3.propertyKeyId() ) + { + assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( true, data.value() ); + transaction.relChangeProperty( rel, prop3.propertyKeyId(), false ); + } + else + { + throw new IOException(); + } + count++; } - commitTx(); - ds.stop(); + assertEquals( 3, count ); + assertRelationshipData( rel, firstNode, secondNode, relType ); } - @Test - @Ignore - public void testRels2() throws Exception + private void assertRelationshipData( long rel, final long firstNode, final long secondNode, + final int relType ) { - initializeStores( storeDir, stringMap() ); - startTx(); - int relType1 = (int) nextId( RelationshipType.class ); - String typeName = "relationshiptype1"; - transaction.createRelationshipTypeToken( typeName, relType1 ); - long nodeIds[] = new long[3]; - for ( int i = 0; i < 3; i++ ) - { - nodeIds[i] = nextId( Node.class ); - transaction.nodeCreate( nodeIds[i] ); - transaction.nodeAddProperty( nodeIds[i], - index( "nisse" ), new Integer( 10 - i ) ); - } - for ( int i = 0; i < 2; i++ ) - { - transaction.relCreate( nextId( Relationship.class ), - relType1, nodeIds[i], nodeIds[i + 1] ); - } - transaction.relCreate( nextId( Relationship.class ), - relType1, nodeIds[0], nodeIds[2] ); - commitTx(); - startTx(); - for ( int i = 0; i < 3; i++ ) + try { - try ( Cursor nodeCursor = ((KernelStatement) tx.acquireStatement()).getStoreStatement() - .acquireSingleNodeCursor( - nodeIds[i] ) ) + storeLayer.relationshipVisit( rel, new RelationshipVisitor() { - nodeCursor.next(); - PrimitiveLongIterator relationships = nodeCursor.get().getRelationships( Direction.BOTH ); - while ( relationships.hasNext() ) + @Override + public void visit( long relId, int type, long startNode, long endNode ) { - transaction.relDelete( relationships.next() ); + assertEquals( firstNode, startNode ); + assertEquals( secondNode, endNode ); + assertEquals( relType, type ); } - } - - transaction.nodeDelete( nodeIds[i] ); - } - commitTx(); - ds.stop(); - } - - @Test - public void testRels3() throws Exception - { - // test linked list stuff during relationship delete - initializeStores( storeDir, stringMap() ); - startTx(); - int relType1 = (int) nextId( RelationshipType.class ); - transaction.createRelationshipTypeToken( "relationshiptype1", relType1 ); - long nodeIds[] = new long[8]; - for ( int i = 0; i < nodeIds.length; i++ ) - { - nodeIds[i] = nextId( Node.class ); - transaction.nodeCreate( nodeIds[i] ); + } ); } - for ( int i = 0; i < nodeIds.length / 2; i++ ) + catch ( EntityNotFoundException e ) { - transaction.relCreate( nextId( Relationship.class ), - relType1, nodeIds[i], nodeIds[i * 2] ); + throw new RuntimeException( e ); } - long rel5 = nextId( Relationship.class ); - transaction.relCreate( rel5, relType1, nodeIds[0], nodeIds[5] ); - long rel2 = nextId( Relationship.class ); - transaction.relCreate( rel2, relType1, nodeIds[1], nodeIds[2] ); - long rel3 = nextId( Relationship.class ); - transaction.relCreate( rel3, relType1, nodeIds[1], nodeIds[3] ); - long rel6 = nextId( Relationship.class ); - transaction.relCreate( rel6, relType1, nodeIds[1], nodeIds[6] ); - long rel1 = nextId( Relationship.class ); - transaction.relCreate( rel1, relType1, nodeIds[0], nodeIds[1] ); - long rel4 = nextId( Relationship.class ); - transaction.relCreate( rel4, relType1, nodeIds[0], nodeIds[4] ); - long rel7 = nextId( Relationship.class ); - transaction.relCreate( rel7, relType1, nodeIds[0], nodeIds[7] ); - commitTx(); - startTx(); - transaction.relDelete( rel7 ); - transaction.relDelete( rel4 ); - transaction.relDelete( rel1 ); - transaction.relDelete( rel6 ); - transaction.relDelete( rel3 ); - transaction.relDelete( rel2 ); - transaction.relDelete( rel5 ); - commitTx(); - ds.stop(); - } - - @Test - public void testProps1() throws Exception - { - initializeStores( storeDir, stringMap() ); - startTx(); - long nodeId = nextId( Node.class ); - transaction.nodeCreate( nodeId ); - pStore.nextId(); - DefinedProperty prop = transaction.nodeAddProperty( - nodeId, index( "nisse" ), - new Integer( 10 ) ); - commitTx(); - ds.stop(); - initializeStores( storeDir, stringMap() ); - startTx(); - transaction.nodeChangeProperty( nodeId, prop.propertyKeyId(), new Integer( 5 ) ); - transaction.nodeRemoveProperty( nodeId, prop.propertyKeyId() ); - transaction.nodeDelete( nodeId ); - commitTx(); - ds.stop(); } - @Test - public void testSetBlockSize() throws Exception - { - File storeDir = dir.directory( "small_store" ); - initializeStores( storeDir, stringMap( "string_block_size", "62", "array_block_size", "302" ) ); - assertEquals( 62 + AbstractDynamicStore.BLOCK_HEADER_SIZE, - pStore.getStringBlockSize() ); - assertEquals( 302 + AbstractDynamicStore.BLOCK_HEADER_SIZE, - pStore.getArrayBlockSize() ); - ds.stop(); - } - - @Test - public void setVersion() throws Exception - { - FileSystemAbstraction fileSystem = fs.get(); - File storeDir = new File( "target/test-data/set-version" ).getAbsoluteFile(); - new TestGraphDatabaseFactory().setFileSystem( fileSystem ).newImpermanentDatabase( storeDir ).shutdown(); - assertEquals( 0, MetaDataStore.setRecord( pageCache, new File( storeDir, - MetaDataStore.DEFAULT_NAME ).getAbsoluteFile(), Position.LOG_VERSION, 10 ) ); - assertEquals( 10, MetaDataStore.setRecord( pageCache, new File( storeDir, - MetaDataStore.DEFAULT_NAME ).getAbsoluteFile(), Position.LOG_VERSION, 12 ) ); - - Config config = new Config( new HashMap(), GraphDatabaseSettings.class ); - StoreFactory sf = new StoreFactory( storeDir, config, new DefaultIdGeneratorFactory( fileSystem ), pageCache, - fileSystem, NullLogProvider.getInstance() ); - - NeoStores neoStores = sf.openNeoStoresEagerly(); - assertEquals( 12, neoStores.getMetaDataStore().getCurrentLogVersion() ); - neoStores.close(); - } - - @Test - public void shouldNotReadNonRecordDataAsRecord() throws Exception + private void validateRel2( long rel, DefinedProperty prop1, + DefinedProperty prop2, DefinedProperty prop3, + long firstNode, long secondNode, int relType ) throws IOException { - FileSystemAbstraction fileSystem = fs.get(); - File neoStoreDir = new File( "/tmp/graph.db/neostore" ).getAbsoluteFile(); - StoreFactory factory = new StoreFactory( fileSystem, neoStoreDir, pageCache, NullLogProvider.getInstance() ); - - try ( NeoStores neoStores = factory.openNeoStores( SF_CREATE ) ) - { - MetaDataStore metaDataStore = neoStores.getMetaDataStore(); - metaDataStore.setCreationTime( 3 ); - metaDataStore.setRandomNumber( 4 ); - metaDataStore.setCurrentLogVersion( 5 ); - metaDataStore.setLastCommittedAndClosedTransactionId( 6, 0, 0, 0 ); - metaDataStore.setStoreVersion( 7 ); - metaDataStore.setGraphNextProp( 8 ); - metaDataStore.setLatestConstraintIntroducingTx( 9 ); - } - - File file = new File( neoStoreDir, MetaDataStore.DEFAULT_NAME ); - try ( StoreChannel channel = fileSystem.open( file, "rw" ) ) + ArrayMap> props = new ArrayMap<>(); + propertyLoader.relLoadProperties( rel, newPropertyReceiver( props ) ); + int count = 0; + for ( int keyId : props.keySet() ) { - channel.position( 0 ); - channel.write( ByteBuffer.wrap( UTF8.encode( "This is some data that is not a record." ) ) ); + long id = props.get( keyId ).other(); + PropertyRecord record = pStore.getRecord( id ); + PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); + DefinedProperty data = block.newPropertyData( pStore ); + if ( data.propertyKeyId() == prop1.propertyKeyId() ) + { + assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( "string2", data.value() ); + transaction.relChangeProperty( rel, prop1.propertyKeyId(), "-string2" ); + } + else if ( data.propertyKeyId() == prop2.propertyKeyId() ) + { + assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( 2, data.value() ); + transaction.relChangeProperty( rel, prop2.propertyKeyId(), new Integer( -2 ) ); + } + else if ( data.propertyKeyId() == prop3.propertyKeyId() ) + { + assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( false, data.value() ); + transaction.relChangeProperty( rel, prop3.propertyKeyId(), true ); + } + else + { + throw new IOException(); + } + count++; } + assertEquals( 3, count ); + assertRelationshipData( rel, firstNode, secondNode, relType ); + } - try ( NeoStores neoStores = factory.openNeoStoresEagerly() ) + private void validateRelTypes( int relType1, int relType2 ) + throws IOException + { + Token data = rtStore.getToken( relType1 ); + assertEquals( relType1, data.id() ); + assertEquals( "relationshiptype1", data.name() ); + data = rtStore.getToken( relType2 ); + assertEquals( relType2, data.id() ); + assertEquals( "relationshiptype2", data.name() ); + List allData = rtStore.getTokens( Integer.MAX_VALUE ); + assertEquals( 2, allData.size() ); + for ( int i = 0; i < 2; i++ ) { - MetaDataStore metaDataStore = neoStores.getMetaDataStore(); - assertEquals( MetaDataStore.FIELD_NOT_PRESENT, metaDataStore.getCreationTime() ); - assertEquals( MetaDataStore.FIELD_NOT_PRESENT, metaDataStore.getRandomNumber() ); - assertEquals( MetaDataStore.FIELD_NOT_PRESENT, metaDataStore.getCurrentLogVersion() ); - assertEquals( MetaDataStore.FIELD_NOT_PRESENT, metaDataStore.getLastCommittedTransactionId() ); - assertEquals( MetaDataStore.FIELD_NOT_PRESENT, metaDataStore.getStoreVersion() ); - assertEquals( 8, metaDataStore.getGraphNextProp() ); - assertEquals( 9, metaDataStore.getLatestConstraintIntroducingTx() ); + if ( allData.get(i).id() == relType1 ) + { + assertEquals( relType1, allData.get(i).id() ); + assertEquals( "relationshiptype1", allData.get(i).name() ); + } + else if ( allData.get(i).id() == relType2 ) + { + assertEquals( relType2, allData.get(i).id() ); + assertEquals( "relationshiptype2", allData.get(i).name() ); + } + else + { + throw new IOException(); + } } } - @Test - public void testSetLatestConstraintTx() throws Exception + private void deleteRel1( long rel, DefinedProperty prop1, DefinedProperty prop2, + DefinedProperty prop3, long firstNode, long secondNode, int relType ) + throws IOException { - // given - Config config = new Config( new HashMap(), GraphDatabaseSettings.class ); - StoreFactory sf = new StoreFactory( dir.directory(), config, new DefaultIdGeneratorFactory( fs.get() ), - pageCacheRule.getPageCache( fs.get() ), fs.get(), NullLogProvider.getInstance() ); - - // when - NeoStores neoStores = sf.openNeoStores( SF_CREATE ); - MetaDataStore metaDataStore = neoStores.getMetaDataStore(); - - // then the default is 0 - assertEquals( 0l, metaDataStore.getLatestConstraintIntroducingTx() ); - - // when - metaDataStore.setLatestConstraintIntroducingTx( 10l ); - - // then - assertEquals( 10l, metaDataStore.getLatestConstraintIntroducingTx() ); + ArrayMap> props = new ArrayMap<>(); + propertyLoader.relLoadProperties( rel, newPropertyReceiver( props ) ); + int count = 0; + for ( int keyId : props.keySet() ) + { + long id = props.get( keyId ).other(); + PropertyRecord record = pStore.getRecord( id ); + PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); + DefinedProperty data = block.newPropertyData( pStore ); + if ( data.propertyKeyId() == prop1.propertyKeyId() ) + { + assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( "-string1", data.value() ); + } + else if ( data.propertyKeyId() == prop2.propertyKeyId() ) + { + assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( -1, data.value() ); + } + else if ( data.propertyKeyId() == prop3.propertyKeyId() ) + { + assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( false, data.value() ); + transaction.relRemoveProperty( rel, prop3.propertyKeyId() ); + } + else + { + throw new IOException(); + } + count++; + } + assertEquals( 3, count ); + CountingPropertyReceiver propertyCounter = new CountingPropertyReceiver(); + propertyLoader.relLoadProperties( rel, propertyCounter ); + assertEquals( 3, propertyCounter.count ); + assertRelationshipData( rel, firstNode, secondNode, relType ); + transaction.relDelete( rel ); - // when - neoStores.flush(); - neoStores.close(); - neoStores = sf.openNeoStoresEagerly(); + assertHasRelationships( firstNode ); - // then the value should have been stored - assertEquals( 10l, metaDataStore.getLatestConstraintIntroducingTx() ); - neoStores.close(); + assertHasRelationships( secondNode ); } - @Test - public void shouldInitializeTheTxIdToOne() + private static class CountingPropertyReceiver implements PropertyReceiver { - StoreFactory factory = - new StoreFactory( fs.get(), new File( "graph.db/neostore" ), pageCache, NullLogProvider.getInstance() ); - - try ( NeoStores neoStores = factory.openNeoStores( SF_CREATE ) ) - { - neoStores.getMetaDataStore(); - } + private int count; - try ( NeoStores neoStores = factory.openNeoStoresEagerly() ) + @Override + public void receive( DefinedProperty property, long propertyRecordId ) { - long lastCommittedTransactionId = neoStores.getMetaDataStore().getLastCommittedTransactionId(); - assertEquals( TransactionIdStore.BASE_TX_ID, lastCommittedTransactionId ); + count++; } } - @Test - public void shouldThrowUnderlyingStorageExceptionWhenFailingToLoadStorage() + private void deleteRel2( long rel, DefinedProperty prop1, DefinedProperty prop2, + DefinedProperty prop3, long firstNode, long secondNode, int relType ) + throws IOException { - FileSystemAbstraction fileSystem = fs.get(); - File neoStoreDir = new File( "/tmp/graph.db/neostore" ).getAbsoluteFile(); - StoreFactory factory = new StoreFactory( fileSystem, neoStoreDir, pageCache, NullLogProvider.getInstance() ); - - try ( NeoStores neoStores = factory.openNeoStores( SF_CREATE ) ) + ArrayMap> props = new ArrayMap<>(); + propertyLoader.relLoadProperties( rel, newPropertyReceiver( props ) ); + int count = 0; + for ( int keyId : props.keySet() ) { - neoStores.getMetaDataStore(); + long id = props.get( keyId ).other(); + PropertyRecord record = pStore.getRecord( id ); + PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); + DefinedProperty data = block.newPropertyData( pStore ); + if ( data.propertyKeyId() == prop1.propertyKeyId() ) + { + assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( "-string2", data.value() ); + } + else if ( data.propertyKeyId() == prop2.propertyKeyId() ) + { + assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( -2, data.value() ); + } + else if ( data.propertyKeyId() == prop3.propertyKeyId() ) + { + assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( true, data.value() ); + transaction.relRemoveProperty( rel, prop3.propertyKeyId() ); + } + else + { + throw new IOException(); + } + count++; } - File file = new File( neoStoreDir, MetaDataStore.DEFAULT_NAME ); - fileSystem.deleteFile( file ); + assertEquals( 3, count ); + CountingPropertyReceiver propertyCounter = new CountingPropertyReceiver(); + propertyLoader.relLoadProperties( rel, propertyCounter ); + assertEquals( 3, propertyCounter.count ); + assertRelationshipData( rel, firstNode, secondNode, relType ); + transaction.relDelete( rel ); + + assertHasRelationships( firstNode ); + + assertHasRelationships( secondNode ); - exception.expect( StoreNotFoundException.class ); - try ( NeoStores neoStores = factory.openNeoStoresEagerly() ) - { - neoStores.getMetaDataStore(); - } } - @Test - public void shouldAddUpgradeFieldsToTheNeoStoreIfNotPresent() throws IOException + private void assertHasRelationships( long node ) { - FileSystemAbstraction fileSystem = fs.get(); - File neoStoreDir = new File( "/tmp/graph.db/neostore" ).getAbsoluteFile(); - StoreFactory factory = new StoreFactory( fileSystem, neoStoreDir, pageCache, NullLogProvider.getInstance() ); + try ( Cursor nodeCursor = ((KernelStatement) tx.acquireStatement()).getStoreStatement() + .acquireSingleNodeCursor( - try ( NeoStores neoStores = factory.openNeoStores( SF_CREATE ) ) + node ) ) { - MetaDataStore metaDataStore = neoStores.getMetaDataStore(); - metaDataStore.setCreationTime( 3 ); - metaDataStore.setRandomNumber( 4 ); - metaDataStore.setCurrentLogVersion( 5 ); - metaDataStore.setLastCommittedAndClosedTransactionId( 6, 0, 0, 0 ); - metaDataStore.setStoreVersion( 7 ); - metaDataStore.setGraphNextProp( 8 ); - metaDataStore.setLatestConstraintIntroducingTx( 9 ); + nodeCursor.next(); + PrimitiveLongIterator rels = nodeCursor.get().getRelationships( Direction.BOTH ); + assertTrue( rels.hasNext() ); } + } - File file = new File( neoStoreDir, MetaDataStore.DEFAULT_NAME ); - - assertNotEquals( 10, MetaDataStore.getRecord( pageCache, file, Position.UPGRADE_TRANSACTION_ID ) ); - assertNotEquals( 11, MetaDataStore.getRecord( pageCache, file, Position.UPGRADE_TRANSACTION_CHECKSUM ) ); - - MetaDataStore.setRecord( pageCache, file, Position.UPGRADE_TRANSACTION_ID, 10 ); - MetaDataStore.setRecord( pageCache, file, Position.UPGRADE_TRANSACTION_CHECKSUM, 11 ); - MetaDataStore.setRecord( pageCache, file, Position.UPGRADE_TIME, 12 ); - - try ( NeoStores neoStores = factory.openNeoStoresEagerly() ) + private void deleteNode1( long node, DefinedProperty prop1, + DefinedProperty prop2, DefinedProperty prop3 ) + throws IOException + { + ArrayMap> props = new ArrayMap<>(); + propertyLoader.nodeLoadProperties( node, newPropertyReceiver( props ) ); + int count = 0; + for ( int keyId : props.keySet() ) { - MetaDataStore metaDataStore = neoStores.getMetaDataStore(); - assertEquals( 3, metaDataStore.getCreationTime() ); - assertEquals( 4, metaDataStore.getRandomNumber() ); - assertEquals( 5, metaDataStore.getCurrentLogVersion() ); - assertEquals( 6, metaDataStore.getLastCommittedTransactionId() ); - assertEquals( 7, metaDataStore.getStoreVersion() ); - assertEquals( 8, metaDataStore.getGraphNextProp() ); - assertEquals( 9, metaDataStore.getLatestConstraintIntroducingTx() ); - assertEquals( new TransactionId( 10, 11 ), metaDataStore.getUpgradeTransaction() ); - assertEquals( 12, metaDataStore.getUpgradeTime() ); + long id = props.get( keyId ).other(); + PropertyRecord record = pStore.getRecord( id ); + PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); + DefinedProperty data = block.newPropertyData( pStore ); + if ( data.propertyKeyId() == prop1.propertyKeyId() ) + { + assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( "-string1", data.value() ); + } + else if ( data.propertyKeyId() == prop2.propertyKeyId() ) + { + assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( -1, data.value() ); + } + else if ( data.propertyKeyId() == prop3.propertyKeyId() ) + { + assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( false, data.value() ); + transaction.nodeRemoveProperty( node, prop3.propertyKeyId() ); + } + else + { + throw new IOException(); + } + count++; } + assertEquals( 3, count ); + CountingPropertyReceiver propertyCounter = new CountingPropertyReceiver(); + propertyLoader.nodeLoadProperties( node, propertyCounter ); + assertEquals( 3, propertyCounter.count ); + assertHasRelationships( node ); + transaction.nodeDelete( node ); } - @Test - public void shouldSetHighestTransactionIdWhenNeeded() throws Throwable + private void deleteNode2( long node, DefinedProperty prop1, + DefinedProperty prop2, DefinedProperty prop3 ) + throws IOException { - // GIVEN - FileSystemAbstraction fileSystem = fs.get(); - fileSystem.mkdirs( storeDir ); - StoreFactory factory = new StoreFactory( fileSystem, storeDir, pageCache, NullLogProvider.getInstance() ); - - try ( NeoStores neoStore = factory.openNeoStores( SF_CREATE ) ) + ArrayMap> props = new ArrayMap<>(); + propertyLoader.nodeLoadProperties( node, newPropertyReceiver( props ) ); + int count = 0; + for ( int keyId : props.keySet() ) { - MetaDataStore store = neoStore.getMetaDataStore(); - store.setLastCommittedAndClosedTransactionId( 40, 4444, 0, LogHeader.LOG_HEADER_SIZE ); + long id = props.get( keyId ).other(); + PropertyRecord record = pStore.getRecord( id ); + PropertyBlock block = record.getPropertyBlock( props.get( keyId ).first().propertyKeyId() ); + DefinedProperty data = block.newPropertyData( pStore ); + if ( data.propertyKeyId() == prop1.propertyKeyId() ) + { + assertEquals( "prop1", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( "-string2", data.value() ); + } + else if ( data.propertyKeyId() == prop2.propertyKeyId() ) + { + assertEquals( "prop2", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( -2, data.value() ); + } + else if ( data.propertyKeyId() == prop3.propertyKeyId() ) + { + assertEquals( "prop3", MyPropertyKeyToken.getIndexFor( + keyId ).name() ); + assertEquals( true, data.value() ); + transaction.nodeRemoveProperty( node, prop3.propertyKeyId() ); + } + else + { + throw new IOException(); + } + count++; + } + assertEquals( 3, count ); + CountingPropertyReceiver propertyCounter = new CountingPropertyReceiver(); + propertyLoader.nodeLoadProperties( node, propertyCounter ); + assertEquals( 3, propertyCounter.count ); - // WHEN - store.transactionCommitted( 42, 6666 ); + assertHasRelationships( node ); - // THEN - assertEquals( new TransactionId( 42, 6666 ), store.getLastCommittedTransaction() ); - } + transaction.nodeDelete( node ); } - @Test - public void shouldNotSetHighestTransactionIdWhenNeeded() throws Throwable + private void testGetRels( long relIds[] ) { - // GIVEN - FileSystemAbstraction fileSystem = fs.get(); - fileSystem.mkdirs( storeDir ); - StoreFactory factory = new StoreFactory( fileSystem, storeDir, pageCache, NullLogProvider.getInstance() ); - - try ( NeoStores neoStore = factory.openNeoStores( SF_CREATE ) ) + try ( StoreStatement statement = storeLayer.acquireStatement() ) { - MetaDataStore store = neoStore.getMetaDataStore(); - store.setLastCommittedAndClosedTransactionId( 40, 4444, 0, LogHeader.LOG_HEADER_SIZE ); - - // WHEN - store.transactionCommitted( 39, 3333 ); - - // THEN - assertEquals( new TransactionId( 40, 4444 ), store.getLastCommittedTransaction() ); + for ( long relId : relIds ) + { + try ( Cursor relationship = statement.acquireSingleRelationshipCursor( relId ) ) + { + assertFalse( relationship.next() ); + } + } } } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NodeStoreTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NodeStoreTest.java index c4667289a3fa..fb857a23162a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NodeStoreTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/NodeStoreTest.java @@ -62,7 +62,6 @@ import static org.neo4j.helpers.Exceptions.forMethod; import static org.neo4j.kernel.impl.store.DynamicArrayStore.allocateFromNumbers; import static org.neo4j.kernel.impl.store.NodeStore.readOwnerFromDynamicLabelsRecord; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; import static org.neo4j.kernel.impl.store.record.Record.NO_NEXT_PROPERTY; import static org.neo4j.kernel.impl.store.record.Record.NO_NEXT_RELATIONSHIP; @@ -312,7 +311,7 @@ private NodeStore newNodeStore( FileSystemAbstraction fs, PageCache pageCache ) IdGeneratorFactory idGeneratorFactory = new DefaultIdGeneratorFactory( fs ); StoreFactory factory = new StoreFactory( storeDir, new Config(), idGeneratorFactory, pageCache, fs, NullLogProvider.getInstance() ); - neoStores = factory.openNeoStores( SF_CREATE ); + neoStores = factory.openAllNeoStores( true ); nodeStore = neoStores.getNodeStore(); return nodeStore; } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/RecordStoreConsistentReadTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/RecordStoreConsistentReadTest.java index f04d70da122b..e194196134db 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/RecordStoreConsistentReadTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/RecordStoreConsistentReadTest.java @@ -48,7 +48,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.neo4j.helpers.collection.IteratorUtil.asList; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; + public abstract class RecordStoreConsistentReadTest> { @@ -74,7 +74,7 @@ private NeoStores storeFixture() pageCache = pageCacheRule.withInconsistentReads( pageCache, nextReadIsInconsistent ); File storeDir = new File( "stores" ); StoreFactory factory = new StoreFactory( fs, storeDir, pageCache, NullLogProvider.getInstance() ); - NeoStores neoStores = factory.openNeoStores( SF_CREATE ); + NeoStores neoStores = factory.openAllNeoStores( true ); S store = initialiseStore( neoStores ); CommonAbstractStore commonAbstractStore = (CommonAbstractStore) store; diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/RelationshipGroupStoreTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/RelationshipGroupStoreTest.java index 90a1a511bdb6..6714e61d5fd8 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/RelationshipGroupStoreTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/RelationshipGroupStoreTest.java @@ -57,7 +57,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; public class RelationshipGroupStoreTest { @@ -136,18 +135,18 @@ private void createAndVerify( Integer customThreshold ) { int expectedThreshold = customThreshold != null ? customThreshold : defaultThreshold; StoreFactory factory = factory( customThreshold ); - NeoStores neoStores = factory.openNeoStores( SF_CREATE ); + NeoStores neoStores = factory.openAllNeoStores( true ); assertEquals( expectedThreshold, neoStores.getRelationshipGroupStore().getDenseNodeThreshold() ); neoStores.close(); // Next time we open it it should be the same - neoStores = factory.openNeoStoresEagerly(); + neoStores = factory.openAllNeoStores(); assertEquals( expectedThreshold, neoStores.getRelationshipGroupStore().getDenseNodeThreshold() ); neoStores.close(); // Even if we open with a different config setting it should just ignore it factory = factory( 999999 ); - neoStores = factory.openNeoStoresEagerly(); + neoStores = factory.openAllNeoStores(); assertEquals( expectedThreshold, neoStores.getRelationshipGroupStore().getDenseNodeThreshold() ); neoStores.close(); } @@ -307,7 +306,7 @@ public void checkingIfRecordIsInUseMustHappenAfterConsistentRead() pageCache = pageCacheRule.withInconsistentReads( pageCache, nextReadIsInconsistent ); StoreFactory factory = factory( null, pageCache ); - try ( NeoStores neoStores = factory.openNeoStores( SF_CREATE ) ) + try ( NeoStores neoStores = factory.openAllNeoStores( true ) ) { RelationshipGroupStore relationshipGroupStore = neoStores.getRelationshipGroupStore(); RelationshipGroupRecord record = new RelationshipGroupRecord( 1, 2, 3, 4, 5, 6, true ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/SchemaStoreTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/SchemaStoreTest.java index d8111b7a8d13..80979809bdc5 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/SchemaStoreTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/SchemaStoreTest.java @@ -44,7 +44,6 @@ import static org.neo4j.helpers.collection.IteratorUtil.asCollection; import static org.neo4j.helpers.collection.IteratorUtil.first; import static org.neo4j.kernel.impl.api.index.TestSchemaIndexProviderDescriptor.PROVIDER_DESCRIPTOR; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; public class SchemaStoreTest { @@ -65,7 +64,7 @@ public void before() throws Exception DefaultIdGeneratorFactory idGeneratorFactory = new DefaultIdGeneratorFactory( fs.get() ); storeFactory = new StoreFactory( storeDir, config, idGeneratorFactory, pageCacheRule.getPageCache( fs.get() ), fs.get(), NullLogProvider.getInstance() ); - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); store = neoStores.getSchemaStore(); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/StoreFactoryTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/StoreFactoryTest.java index e9488529eb77..b59bc1b85615 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/StoreFactoryTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/StoreFactoryTest.java @@ -42,7 +42,6 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; public class StoreFactoryTest { @@ -80,7 +79,7 @@ public void tearDown() public void shouldHaveSameCreationTimeAndUpgradeTimeOnStartup() throws Exception { // When - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); MetaDataStore metaDataStore = neoStores.getMetaDataStore(); // Then @@ -91,7 +90,7 @@ public void shouldHaveSameCreationTimeAndUpgradeTimeOnStartup() throws Exception public void shouldHaveSameCommittedTransactionAndUpgradeTransactionOnStartup() throws Exception { // When - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); MetaDataStore metaDataStore = neoStores.getMetaDataStore(); // Then @@ -107,7 +106,7 @@ public void shouldHaveSpecificCountsTrackerForReadOnlyDatabase() throws IOExcept StoreFactory readOnlyStoreFactory = new StoreFactory( testDirectory.directory( "readOnlyStore" ), new Config( MapUtil.stringMap( GraphDatabaseSettings.read_only.name(), Settings.TRUE ) ), new DefaultIdGeneratorFactory( fs ), pageCache, fs, NullLogProvider.getInstance() ); - neoStores = readOnlyStoreFactory.openNeoStores( SF_CREATE ); + neoStores = readOnlyStoreFactory.openAllNeoStores( true ); long lastClosedTransactionId = neoStores.getMetaDataStore().getLastClosedTransactionId(); // then @@ -117,7 +116,7 @@ public void shouldHaveSpecificCountsTrackerForReadOnlyDatabase() throws IOExcept @Test( expected = StoreNotFoundException.class ) public void shouldThrowWhenOpeningNonExistingNeoStores() { - try ( NeoStores neoStores = storeFactory.openNeoStoresEagerly() ) + try ( NeoStores neoStores = storeFactory.openAllNeoStores() ) { neoStores.getMetaDataStore(); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestArrayStore.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestArrayStore.java index edf2b3e869c8..516f58a09534 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestArrayStore.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestArrayStore.java @@ -49,7 +49,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; public class TestArrayStore { @@ -72,7 +71,7 @@ public void before() throws Exception PageCache pageCache = pageCacheRule.getPageCache( fs ); StoreFactory factory = new StoreFactory( dir, config, idGeneratorFactory, pageCache, fs, NullLogProvider.getInstance() ); - neoStores = factory.openNeoStores( SF_CREATE ); + neoStores = factory.openAllNeoStores( true ); arrayStore = neoStores.getPropertyStore().getArrayStore(); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestDynamicStore.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestDynamicStore.java index 2fdddc422a75..9808b8c2fd8f 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestDynamicStore.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestDynamicStore.java @@ -47,7 +47,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.neo4j.helpers.collection.IteratorUtil.first; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; public class TestDynamicStore { @@ -94,7 +93,7 @@ public void arrayStoreCannotHaveZeroBlockSize() throws Exception private DynamicArrayStore createDynamicArrayStore() { - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); return neoStores.getPropertyStore().getArrayStore(); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestGraphProperties.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestGraphProperties.java index f46dd921bc64..b460b017237a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestGraphProperties.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestGraphProperties.java @@ -177,7 +177,7 @@ public void firstRecordOtherThanZeroIfNotFirst() throws Exception Config config = new Config( Collections.emptyMap(), GraphDatabaseSettings.class ); StoreFactory storeFactory = new StoreFactory( storeDir, config, new DefaultIdGeneratorFactory( fs.get() ), pageCacheRule.getPageCache( fs.get() ), fs.get(), NullLogProvider.getInstance() ); - NeoStores neoStores = storeFactory.openNeoStoresEagerly(); + NeoStores neoStores = storeFactory.openAllNeoStores(); long prop = neoStores.getMetaDataStore().getGraphNextProp(); assertTrue( prop != 0 ); neoStores.close(); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestGrowingFileMemoryMapping.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestGrowingFileMemoryMapping.java index c81eee7105e7..069a79a7b795 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestGrowingFileMemoryMapping.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestGrowingFileMemoryMapping.java @@ -40,7 +40,7 @@ import static org.junit.Assume.assumeTrue; import static org.neo4j.graphdb.factory.GraphDatabaseSettings.pagecache_memory; import static org.neo4j.helpers.collection.MapUtil.stringMap; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; + public class TestGrowingFileMemoryMapping { @@ -64,7 +64,7 @@ public void shouldGrowAFileWhileContinuingToMemoryMapNewRegions() throws Excepti StoreFactory storeFactory = new StoreFactory( storeDir, config, idGeneratorFactory, pageCache, fileSystemAbstraction, NullLogProvider.getInstance() ); - NeoStores neoStores = storeFactory.openNeoStores( SF_CREATE ); + NeoStores neoStores = storeFactory.openAllNeoStores( true ); NodeStore nodeStore = neoStores.getNodeStore(); // when diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestIdGeneratorRebuilding.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestIdGeneratorRebuilding.java index 2c26f6914aee..545626af926a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestIdGeneratorRebuilding.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/TestIdGeneratorRebuilding.java @@ -45,7 +45,6 @@ import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; public class TestIdGeneratorRebuilding { @@ -129,7 +128,7 @@ public void verifyDynamicSizedStoresCanRebuildIdGeneratorSlowly() throws Excepti StoreFactory storeFactory = new StoreFactory( storeDir, config, new DefaultIdGeneratorFactory( fs ), pageCacheRule.getPageCache( fs ), fs, NullLogProvider.getInstance() ); - NeoStores neoStores = storeFactory.openNeoStores( SF_CREATE ); + NeoStores neoStores = storeFactory.openAllNeoStores( true ); DynamicStringStore store = neoStores.getPropertyStore().getStringStore(); // ... that contain a number of records ... diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/counts/CountsComputerTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/counts/CountsComputerTest.java index aa4d51d239fa..bd442cef4add 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/store/counts/CountsComputerTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/store/counts/CountsComputerTest.java @@ -319,7 +319,7 @@ private void rebuildCounts( long lastCommittedTransactionId ) throws IOException StoreFactory storeFactory = new StoreFactory( fs, dir, pageCache, NullLogProvider.getInstance() ); try ( Lifespan life = new Lifespan(); - NeoStores neoStores = storeFactory.openNeoStoresEagerly() ) + NeoStores neoStores = storeFactory.openAllNeoStores() ) { NodeStore nodeStore = neoStores.getNodeStore(); RelationshipStore relationshipStore = neoStores.getRelationshipStore(); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigratorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigratorTest.java index 79550c2e0f13..f03f3215f763 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigratorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/SchemaIndexMigratorTest.java @@ -45,16 +45,44 @@ import org.neo4j.kernel.impl.store.record.SchemaRule; import org.neo4j.kernel.impl.storemigration.legacystore.v21.Legacy21Store; -import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyBoolean; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; - import static org.neo4j.kernel.api.index.SchemaIndexProvider.getRootDirectory; public class SchemaIndexMigratorTest { + private final FileSystemAbstraction fs = mock( FileSystemAbstraction.class ); + private final SchemaIndexProvider schemaIndexProvider = mock( SchemaIndexProvider.class ); + private final StoreFactory storeFactory = mock( StoreFactory.class ); + private final NeoStores neoStores = mock( NeoStores.class ); + private final PageCache pageCache = mock( PageCache.class ); + private final SchemaIndexMigrator migrator = new SchemaIndexMigrator( fs, pageCache, storeFactory ); + private final SchemaStore schemaStore = mock( SchemaStore.class ); + private final IndexAccessor accessor = mock( IndexAccessor.class ); + private final IndexReader indexReader = mock( IndexReader.class ); + private final File storeDir = new File( "store" ); + private final File migrationDir = new File( "migration" ); + private final IndexConfiguration indexConfig = new IndexConfiguration( false ); + private final IndexSamplingConfig samplingConfig = new IndexSamplingConfig( new Config() ); + private final int indexRuleId = 0; + + @Before + public void setup() throws IOException + { + when( schemaIndexProvider.getProviderDescriptor() ).thenReturn( new SchemaIndexProvider.Descriptor( "key", "version" ) ); + + when( storeFactory.openNeoStores( NeoStores.StoreType.SCHEMA) ).thenReturn( neoStores ); + when( storeFactory.openAllNeoStores( anyBoolean() ) ).thenReturn( neoStores ); + when( neoStores.getSchemaStore() ).thenReturn( schemaStore ); + Iterator iterator = Arrays.asList( schemaRule( indexRuleId, 42, 21 ) ).iterator(); + when( schemaStore.loadAllSchemaRules() ).thenReturn( iterator ); + when( schemaIndexProvider.getOnlineAccessor( indexRuleId, indexConfig, samplingConfig )).thenReturn( accessor ); + when( accessor.newReader() ).thenReturn( indexReader ); + } + @Test public void shouldDeleteTheIndexIfItContainsIndexedArrayValues() throws Exception { @@ -134,32 +162,5 @@ private SchemaRule schemaRule( int id, int labelId, int propertyKeyId ) return IndexRule.indexRule( id, labelId, propertyKeyId, schemaIndexProvider.getProviderDescriptor() ); } - @Before - public void setup() throws IOException - { - when( schemaIndexProvider.getProviderDescriptor() ).thenReturn( new SchemaIndexProvider.Descriptor( "key", "version" ) ); - when( storeFactory.openNeoStoresEagerly() ).thenReturn( neoStores ); - when( storeFactory.openNeoStores( anyInt() ) ).thenReturn( neoStores ); - when( neoStores.getSchemaStore() ).thenReturn( schemaStore ); - Iterator iterator = Arrays.asList( schemaRule( indexRuleId, 42, 21 ) ).iterator(); - when( schemaStore.loadAllSchemaRules() ).thenReturn( iterator ); - when( schemaIndexProvider.getOnlineAccessor( indexRuleId, indexConfig, samplingConfig )).thenReturn( accessor ); - when( accessor.newReader() ).thenReturn( indexReader ); - } - - private final FileSystemAbstraction fs = mock( FileSystemAbstraction.class ); - private final SchemaIndexProvider schemaIndexProvider = mock( SchemaIndexProvider.class ); - private final StoreFactory storeFactory = mock( StoreFactory.class ); - private final NeoStores neoStores = mock( NeoStores.class ); - private final PageCache pageCache = mock( PageCache.class ); - private final SchemaIndexMigrator migrator = new SchemaIndexMigrator( fs, pageCache, storeFactory ); - private final SchemaStore schemaStore = mock( SchemaStore.class ); - private final IndexAccessor accessor = mock( IndexAccessor.class ); - private final IndexReader indexReader = mock( IndexReader.class ); - private final File storeDir = new File( "store" ); - private final File migrationDir = new File( "migration" ); - private final IndexConfiguration indexConfig = new IndexConfiguration( false ); - private final IndexSamplingConfig samplingConfig = new IndexSamplingConfig( new Config() ); - private final int indexRuleId = 0; } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/StoreMigratorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/StoreMigratorTest.java index 76e06281d794..d44b8fcbebaa 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/StoreMigratorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/StoreMigratorTest.java @@ -58,7 +58,7 @@ public class StoreMigratorTest private final SchemaIndexProvider schemaIndexProvider = new InMemoryIndexProvider(); @Parameterized.Parameter(0) - public String version; + public String version; @Parameterized.Parameters(name = "{0}") public static Collection versions() @@ -99,7 +99,7 @@ public void shouldBeAbleToResumeMigrationOnMoving() throws Exception // THEN starting the new store should be successful StoreFactory storeFactory = new StoreFactory( fs, storeDirectory, pageCache, logService.getInternalLogProvider() ); - storeFactory.openNeoStoresEagerly().close(); + storeFactory.openAllNeoStores().close(); } @Test @@ -131,6 +131,6 @@ public void shouldBeAbleToResumeMigrationOnRebuildingCounts() throws Exception // THEN starting the new store should be successful StoreFactory storeFactory = new StoreFactory( fs, storeDirectory, pageCache, logService.getInternalLogProvider() ); - storeFactory.openNeoStoresEagerly().close(); + storeFactory.openAllNeoStores().close(); } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/ApplyRecoveredTransactionsTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/ApplyRecoveredTransactionsTest.java index 8fc4bd618a81..9bf0df2b5b5b 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/ApplyRecoveredTransactionsTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/ApplyRecoveredTransactionsTest.java @@ -52,7 +52,6 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; public class ApplyRecoveredTransactionsTest { @@ -119,7 +118,7 @@ public void before() File storeDir = new File( "dir" ); StoreFactory storeFactory = new StoreFactory( storeDir, new Config(), new DefaultIdGeneratorFactory( fs ), pageCacheRule.getPageCache( fs ), fs, NullLogProvider.getInstance() ); - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); } @After diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NeoStoreTransactionTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NeoStoreTransactionTest.java index 33b1c0d254b2..1c227702d488 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NeoStoreTransactionTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NeoStoreTransactionTest.java @@ -144,7 +144,7 @@ import static org.neo4j.kernel.api.index.SchemaIndexProvider.NO_INDEX_PROVIDER; import static org.neo4j.kernel.impl.api.TransactionApplicationMode.INTERNAL; import static org.neo4j.kernel.impl.api.index.TestSchemaIndexProviderDescriptor.PROVIDER_DESCRIPTOR; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; + import static org.neo4j.kernel.impl.store.record.IndexRule.indexRule; import static org.neo4j.kernel.impl.store.record.UniquePropertyConstraintRule.uniquenessConstraintRule; import static org.neo4j.kernel.impl.transaction.log.TransactionIdStore.BASE_TX_ID; @@ -1295,7 +1295,7 @@ public void testRecordTransactionClosed() throws Exception // WHEN neoStores.close(); - neoStores = storeFactory.openNeoStoresEagerly(); + neoStores = storeFactory.openAllNeoStores(); // EXPECT long[] lastClosedTransactionFlags = neoStores.getMetaDataStore().getLastClosedTransaction(); @@ -1435,7 +1435,7 @@ private void instantiateNeoStore( int denseNodeThreshold ) throws Exception File storeDir = new File( "dir" ); fs.mkdir( storeDir ); storeFactory = new StoreFactory( storeDir, config, idGeneratorFactory, pageCache, fs, NULL_LOG_PROVIDER ); - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); neoStores.rebuildCountStoreIfNeeded(); lockMocks.clear(); locks = mock( LockService.class, new Answer() diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NodeCommandTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NodeCommandTest.java index 26dbb3eba202..b3bd6c90fcd9 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NodeCommandTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NodeCommandTest.java @@ -54,7 +54,7 @@ import static org.neo4j.kernel.impl.store.DynamicNodeLabels.dynamicPointer; import static org.neo4j.kernel.impl.store.NodeLabelsField.parseLabelsField; import static org.neo4j.kernel.impl.store.ShortArray.LONG; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; + import static org.neo4j.kernel.impl.store.record.DynamicRecord.dynamicRecord; import static org.neo4j.kernel.impl.util.IoPrimitiveUtils.safeCastLongToInt; @@ -213,7 +213,7 @@ public void before() throws Exception @SuppressWarnings("deprecation") StoreFactory storeFactory = new StoreFactory( dir, new Config(), new DefaultIdGeneratorFactory( fs.get() ), pageCacheRule.getPageCache( fs.get() ), fs.get(), NullLogProvider.getInstance() ); - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); nodeStore = neoStores.getNodeStore(); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NodeLabelsFieldTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NodeLabelsFieldTest.java index 4ee8a5707502..3e0efd1e81d8 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NodeLabelsFieldTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/NodeLabelsFieldTest.java @@ -62,7 +62,7 @@ import static org.neo4j.helpers.collection.IteratorUtil.count; import static org.neo4j.helpers.collection.IteratorUtil.first; import static org.neo4j.helpers.collection.IteratorUtil.single; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; + import static org.neo4j.kernel.impl.util.Bits.bits; import static org.neo4j.kernel.impl.util.IoPrimitiveUtils.safeCastLongToInt; @@ -459,7 +459,7 @@ public void startUp() fs.get().mkdirs( storeDir ); StoreFactory storeFactory = new StoreFactory( storeDir, new Config(), new DefaultIdGeneratorFactory( fs.get() ), pageCacheRule.getPageCache( fs.get() ), fs.get(), NullLogProvider.getInstance() ); - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); nodeStore = neoStores.getNodeStore(); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/TransactionRecordStateTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/TransactionRecordStateTest.java index de22659d77f4..0539a822317c 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/TransactionRecordStateTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/state/TransactionRecordStateTest.java @@ -73,7 +73,7 @@ import static org.mockito.Mockito.mock; import static org.neo4j.helpers.collection.IteratorUtil.single; import static org.neo4j.helpers.collection.MapUtil.stringMap; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; + public class TransactionRecordStateTest { @@ -275,7 +275,7 @@ private NeoStores newNeoStores( String... config ) Config configuration = new Config( stringMap( config ) ); StoreFactory storeFactory = new StoreFactory( storeDir, configuration, new DefaultIdGeneratorFactory( fs ), pageCacheRule.getPageCache( fs ), fs, NullLogProvider.getInstance() ); - return cleanup.add( storeFactory.openNeoStores( SF_CREATE ) ); + return cleanup.add( storeFactory.openAllNeoStores( true ) ); } private TransactionRecordState nodeWithDynamicLabelRecord( NeoStores store, diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/batchinsert/BatchInsertTest.java b/community/kernel/src/test/java/org/neo4j/unsafe/batchinsert/BatchInsertTest.java index 946bd294a1e7..deafc84463e2 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/batchinsert/BatchInsertTest.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/batchinsert/BatchInsertTest.java @@ -318,7 +318,7 @@ private NeoStores switchToNeoStores( BatchInserter inserter ) File dir = new File( inserter.getStoreDir() ); PageCache pageCache = pageCacheRule.getPageCache( fs ); StoreFactory storeFactory = new StoreFactory( fs, dir, pageCache, NullLogProvider.getInstance() ); - return storeFactory.openNeoStoresEagerly(); + return storeFactory.openAllNeoStores(); } @Test diff --git a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/PropertyEncoderStepTest.java b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/PropertyEncoderStepTest.java index 3fca9899191e..74c7b63d4be3 100644 --- a/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/PropertyEncoderStepTest.java +++ b/community/kernel/src/test/java/org/neo4j/unsafe/impl/batchimport/PropertyEncoderStepTest.java @@ -44,7 +44,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; + import static org.neo4j.unsafe.impl.batchimport.Configuration.DEFAULT; public class PropertyEncoderStepTest @@ -61,7 +61,7 @@ public void setUpNeoStore() pageCache = pageCacheRule.getPageCache( fsRule.get() ); StoreFactory storeFactory = new StoreFactory( fsRule.get(), storeDir, pageCache, NullLogProvider.getInstance() ); - neoStores = storeFactory.openNeoStores( SF_CREATE ); + neoStores = storeFactory.openAllNeoStores( true ); } @After diff --git a/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java b/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java index 694d9383e6ce..34ba6c8cf574 100644 --- a/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java +++ b/community/neo4j/src/test/java/upgrade/StoreUpgraderTest.java @@ -322,7 +322,7 @@ public void upgradedNeoStoreShouldHaveNewUpgradeTimeAndUpgradeId() throws Except // Then StoreFactory storeFactory = new StoreFactory( fileSystem, dbDirectory, pageCache, NullLogProvider.getInstance() ); - NeoStores neoStores = storeFactory.openNeoStoresEagerly(); + NeoStores neoStores = storeFactory.openAllNeoStores(); assertThat( neoStores.getMetaDataStore().getUpgradeTransaction(), equalTo( neoStores.getMetaDataStore() .getLastCommittedTransaction() ) ); diff --git a/enterprise/com/src/test/java/org/neo4j/com/storecopy/ResponsePackerIT.java b/enterprise/com/src/test/java/org/neo4j/com/storecopy/ResponsePackerIT.java index 9b0da6cd9077..bde7374477df 100644 --- a/enterprise/com/src/test/java/org/neo4j/com/storecopy/ResponsePackerIT.java +++ b/enterprise/com/src/test/java/org/neo4j/com/storecopy/ResponsePackerIT.java @@ -47,7 +47,6 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; public class ResponsePackerIT { @@ -110,6 +109,6 @@ private NeoStores createNeoStore( FileSystemAbstraction fs, PageCache pageCache, File storeDir = new File( "/store/" ); fs.mkdirs( storeDir ); StoreFactory storeFactory = new StoreFactory( fs, storeDir, pageCache, NullLogProvider.getInstance() ); - return storeFactory.openNeoStores( SF_CREATE ); + return storeFactory.openAllNeoStores( true ); } } diff --git a/enterprise/enterprise-performance-tests/src/main/java/org/neo4j/perftest/enterprise/ccheck/ConsistencyPerformanceCheck.java b/enterprise/enterprise-performance-tests/src/main/java/org/neo4j/perftest/enterprise/ccheck/ConsistencyPerformanceCheck.java index b6c14483433d..b6cb02724be7 100644 --- a/enterprise/enterprise-performance-tests/src/main/java/org/neo4j/perftest/enterprise/ccheck/ConsistencyPerformanceCheck.java +++ b/enterprise/enterprise-performance-tests/src/main/java/org/neo4j/perftest/enterprise/ccheck/ConsistencyPerformanceCheck.java @@ -49,7 +49,6 @@ import org.neo4j.perftest.enterprise.util.Setting; import static org.neo4j.consistency.ConsistencyCheckService.defaultConsistencyCheckThreadsNumber; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; import static org.neo4j.perftest.enterprise.util.Configuration.SYSTEM_PROPERTIES; import static org.neo4j.perftest.enterprise.util.Configuration.settingsOf; import static org.neo4j.perftest.enterprise.util.DirectlyCorrelatedParameter.param; @@ -142,7 +141,7 @@ private static DirectStoreAccess createScannableStores( File storeDir, Config tu { StoreFactory factory = new StoreFactory( storeDir, tuningConfiguration, new DefaultIdGeneratorFactory( fileSystem ), pageCache, fileSystem, NullLogProvider.getInstance() ); - NeoStores neoStores = factory.openNeoStores( SF_CREATE ); + NeoStores neoStores = factory.openAllNeoStores( true ); SchemaIndexProvider indexes = new LuceneSchemaIndexProvider( fileSystem, DirectoryFactory.PERSISTENT, diff --git a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/transaction/OnDiskLastTxIdGetter.java b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/transaction/OnDiskLastTxIdGetter.java index deb01061017b..ceb997fa336b 100644 --- a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/transaction/OnDiskLastTxIdGetter.java +++ b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/transaction/OnDiskLastTxIdGetter.java @@ -33,15 +33,22 @@ public OnDiskLastTxIdGetter( Supplier neoStoresSupplier ) this.neoStoresSupplier = neoStoresSupplier; } - // This method is used to construct credentials for election process. - // And can be invoked at any moment of instance lifecycle. - // It mean that its possible that we will be invoked when neo stores are stopped - // (for example while we copy store) + /* This method is used to construct credentials for election process. + And can be invoked at any moment of instance lifecycle. + It mean that its possible that we will be invoked when neo stores are stopped + (for example while we copy store) in that case we will return TransactionIdStore.BASE_TX_ID */ @Override public long getLastTxId() { - TransactionIdStore neoStore = getNeoStores().getMetaDataStore(); - return neoStore != null ? neoStore.getLastCommittedTransactionId() : TransactionIdStore.BASE_TX_ID; + try + { + TransactionIdStore neoStore = getNeoStores().getMetaDataStore(); + return neoStore.getLastCommittedTransactionId(); + } + catch ( Throwable e ) + { + return TransactionIdStore.BASE_TX_ID; + } } private NeoStores getNeoStores() diff --git a/enterprise/ha/src/test/java/org/neo4j/kernel/ha/OnDiskLastTxIdGetterTest.java b/enterprise/ha/src/test/java/org/neo4j/kernel/ha/OnDiskLastTxIdGetterTest.java index 7b482472f0c6..38a6723b2348 100644 --- a/enterprise/ha/src/test/java/org/neo4j/kernel/ha/OnDiskLastTxIdGetterTest.java +++ b/enterprise/ha/src/test/java/org/neo4j/kernel/ha/OnDiskLastTxIdGetterTest.java @@ -67,7 +67,7 @@ public void lastTransactionIdIsBaseTxIdWhileNeoStoresAreStopped() { final StoreFactory storeFactory = new StoreFactory( fs.get(), new File( "store" ), pageCacheRule.getPageCache( fs.get() ), NullLogProvider.getInstance() ); - final NeoStores neoStores = storeFactory.openNeoStores( StoreFactory.SF_CREATE ); + final NeoStores neoStores = storeFactory.openAllNeoStores( true ); neoStores.close(); Supplier neoStoresSupplier = new NeoStoresSupplier() diff --git a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom19IT.java b/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom19IT.java index e1386ebb21a7..c24c8af56891 100644 --- a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom19IT.java +++ b/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom19IT.java @@ -65,7 +65,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; + import static upgrade.StoreMigratorTestUtil.buildClusterWithMasterDirIn; import static java.lang.Integer.MAX_VALUE; @@ -107,7 +107,7 @@ public void shouldMigrate() throws IOException, ConsistencyCheckIncompleteExcept database.shutdown(); } - try ( NeoStores neoStores = storeFactory.openNeoStores( SF_CREATE ) ) + try ( NeoStores neoStores = storeFactory.openAllNeoStores( true ) ) { verifyNeoStore( neoStores ); } @@ -170,7 +170,7 @@ public void shouldDeduplicateUniquePropertyIndexKeys() throws Exception // THEN // verify that there are no duplicate keys in the store - try ( NeoStores neoStores = storeFactory.openNeoStoresEagerly() ) + try ( NeoStores neoStores = storeFactory.openAllNeoStores() ) { PropertyKeyTokenStore tokenStore = neoStores.getPropertyKeyTokenStore(); List tokens = tokenStore.getTokens( MAX_VALUE ); diff --git a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom20IT.java b/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom20IT.java index 779c2324a54c..fc87c689fffd 100644 --- a/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom20IT.java +++ b/enterprise/neo4j-enterprise/src/test/java/upgrade/StoreMigratorFrom20IT.java @@ -59,7 +59,6 @@ import static org.neo4j.consistency.store.StoreAssertions.assertConsistentStore; import static org.neo4j.kernel.impl.ha.ClusterManager.allSeesAllAsAvailable; import static org.neo4j.kernel.impl.store.CommonAbstractStore.ALL_STORES_VERSION; -import static org.neo4j.kernel.impl.store.StoreFactory.SF_CREATE; import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.find20FormatStoreDirectory; import static org.neo4j.kernel.impl.storemigration.UpgradeConfiguration.ALLOW_UPGRADE; import static upgrade.StoreMigratorTestUtil.buildClusterWithMasterDirIn; @@ -92,7 +91,7 @@ public void shouldMigrate() throws IOException, ConsistencyCheckIncompleteExcept database.shutdown(); } - try ( NeoStores neoStores = storeFactory.openNeoStores( SF_CREATE ) ) + try ( NeoStores neoStores = storeFactory.openAllNeoStores( true ) ) { verifyNeoStore( neoStores ); }