From cf06935e7bb01aa2f13ee19fd8936653dd15e397 Mon Sep 17 00:00:00 2001 From: Anton Persson Date: Tue, 5 Mar 2019 11:29:14 +0100 Subject: [PATCH] GenericNativeIndex use IndexDropAction for Accessor and Populator IndexDropAction moves into three classes: - BlockBasedIndexPopulator - GenericNativeIndexAccessor - GenericNativeIndexPopulator Behaviour change: BlockBasedIndexPopulator and GenericNativeIndexPopulator now delete whole index directory on drop(). This was already the case for GenericNativeIndexAccessor. --- .../api/constraints/ConstraintCreationIT.java | 2 +- .../schema/BlockBasedIndexPopulator.java | 16 +++- .../GenericBlockBasedIndexPopulator.java | 7 +- .../schema/GenericNativeIndexAccessor.java | 19 +---- .../schema/GenericNativeIndexPopulator.java | 13 +++- .../schema/GenericNativeIndexProvider.java | 8 +- .../schema/BlockBasedIndexPopulatorTest.java | 72 +++++++++++++---- .../schema/GenericAccessorPointsTest.java | 3 +- .../GenericNativeIndexAccessorTest.java | 3 +- .../GenericNativeIndexPopulatorTest.java | 77 +++++++++++++++++++ .../index/schema/NativeIndexAccessorTest.java | 7 +- .../schema/NativeIndexPopulatorTestCases.java | 17 +++- 12 files changed, 196 insertions(+), 48 deletions(-) create mode 100644 community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexPopulatorTest.java diff --git a/community/community-it/index-it/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintCreationIT.java b/community/community-it/index-it/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintCreationIT.java index 20a19ad18aca2..34bfe6f4f91c5 100644 --- a/community/community-it/index-it/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintCreationIT.java +++ b/community/community-it/index-it/src/test/java/org/neo4j/kernel/impl/api/constraints/ConstraintCreationIT.java @@ -74,7 +74,7 @@ public void shouldNotLeaveNativeIndexFilesHangingAroundIfConstraintCreationFails db.getDependencyResolver().resolveDependency( IndexProviderMap.class ).getDefaultProvider(); File indexDir = indexProvider.directoryStructure().directoryForIndex( indexId ); - assertEquals( 0, indexDir.listFiles().length ); + assertFalse( indexDir.exists() ); } private void attemptAndFailConstraintCreation() diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockBasedIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockBasedIndexPopulator.java index fa5dd4263da58..e59a046162c02 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockBasedIndexPopulator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/BlockBasedIndexPopulator.java @@ -59,6 +59,7 @@ import org.neo4j.values.storable.Value; import static org.neo4j.helpers.collection.Iterables.first; +import static org.neo4j.kernel.impl.index.schema.BlockStorage.Monitor.NO_MONITOR; import static org.neo4j.kernel.impl.index.schema.NativeIndexUpdater.initializeKeyFromUpdate; import static org.neo4j.kernel.impl.index.schema.NativeIndexes.deleteIndex; @@ -86,6 +87,7 @@ public abstract class BlockBasedIndexPopulator,V private static final int MERGE_FACTOR = FeatureToggles.getInteger( BlockBasedIndexPopulator.class, "mergeFactor", 8 ); private final IndexDirectoryStructure directoryStructure; + private final IndexDropAction dropAction; private final boolean archiveFailedIndex; private final int blockSize; private final int mergeFactor; @@ -107,18 +109,20 @@ public abstract class BlockBasedIndexPopulator,V BlockBasedIndexPopulator( PageCache pageCache, FileSystemAbstraction fs, File file, IndexLayout layout, IndexProvider.Monitor monitor, StoreIndexDescriptor descriptor, IndexSpecificSpaceFillingCurveSettingsCache spatialSettings, - IndexDirectoryStructure directoryStructure, boolean archiveFailedIndex ) + IndexDirectoryStructure directoryStructure, IndexDropAction dropAction, boolean archiveFailedIndex ) { - this( pageCache, fs, file, layout, monitor, descriptor, spatialSettings, directoryStructure, archiveFailedIndex, parseBlockSize(), MERGE_FACTOR, - BlockStorage.Monitor.NO_MONITOR ); + this( pageCache, fs, file, layout, monitor, descriptor, spatialSettings, directoryStructure, dropAction, archiveFailedIndex, parseBlockSize(), + MERGE_FACTOR, NO_MONITOR ); } BlockBasedIndexPopulator( PageCache pageCache, FileSystemAbstraction fs, File file, IndexLayout layout, IndexProvider.Monitor monitor, StoreIndexDescriptor descriptor, IndexSpecificSpaceFillingCurveSettingsCache spatialSettings, - IndexDirectoryStructure directoryStructure, boolean archiveFailedIndex, int blockSize, int mergeFactor, BlockStorage.Monitor blockStorageMonitor ) + IndexDirectoryStructure directoryStructure, IndexDropAction dropAction, boolean archiveFailedIndex, + int blockSize, int mergeFactor, BlockStorage.Monitor blockStorageMonitor ) { super( pageCache, fs, file, layout, monitor, descriptor, new SpaceFillingCurveSettingsWriter( spatialSettings ) ); this.directoryStructure = directoryStructure; + this.dropAction = dropAction; this.archiveFailedIndex = archiveFailedIndex; this.blockSize = blockSize; this.mergeFactor = mergeFactor; @@ -471,11 +475,15 @@ public synchronized void drop() { try { + // Close internal resources closeBlockStorage(); } finally { + // Super drop will close inherited resources super.drop(); + // Cleanup files + dropAction.drop( descriptor.getId(), archiveFailedIndex ); } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericBlockBasedIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericBlockBasedIndexPopulator.java index 3ecac1a4b0b98..cca9cacef7111 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericBlockBasedIndexPopulator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericBlockBasedIndexPopulator.java @@ -29,16 +29,17 @@ import org.neo4j.kernel.impl.index.schema.config.IndexSpecificSpaceFillingCurveSettingsCache; import org.neo4j.storageengine.api.schema.StoreIndexDescriptor; -public class GenericBlockBasedIndexPopulator extends BlockBasedIndexPopulator +class GenericBlockBasedIndexPopulator extends BlockBasedIndexPopulator { private final IndexSpecificSpaceFillingCurveSettingsCache spatialSettings; private final SpaceFillingCurveConfiguration configuration; GenericBlockBasedIndexPopulator( PageCache pageCache, FileSystemAbstraction fs, File file, IndexLayout layout, IndexProvider.Monitor monitor, StoreIndexDescriptor descriptor, IndexSpecificSpaceFillingCurveSettingsCache spatialSettings, - IndexDirectoryStructure directoryStructure, SpaceFillingCurveConfiguration configuration, boolean archiveFailedIndex ) + IndexDirectoryStructure directoryStructure, SpaceFillingCurveConfiguration configuration, + IndexDropAction dropAction, boolean archiveFailedIndex ) { - super( pageCache, fs, file, layout, monitor, descriptor, spatialSettings, directoryStructure, archiveFailedIndex ); + super( pageCache, fs, file, layout, monitor, descriptor, spatialSettings, directoryStructure, dropAction, archiveFailedIndex ); this.spatialSettings = spatialSettings; this.configuration = configuration; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexAccessor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexAccessor.java index 3213e095aff88..8c4abc4f72688 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexAccessor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexAccessor.java @@ -20,8 +20,6 @@ package org.neo4j.kernel.impl.index.schema; import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; import org.neo4j.gis.spatial.index.curves.SpaceFillingCurveConfiguration; import org.neo4j.index.internal.gbptree.GBPTree; @@ -29,7 +27,6 @@ import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.io.pagecache.IOLimiter; import org.neo4j.io.pagecache.PageCache; -import org.neo4j.kernel.api.index.IndexDirectoryStructure; import org.neo4j.kernel.api.index.IndexProvider; import org.neo4j.kernel.impl.index.schema.config.IndexSpecificSpaceFillingCurveSettingsCache; import org.neo4j.kernel.impl.index.schema.config.SpaceFillingCurveSettingsWriter; @@ -41,19 +38,18 @@ class GenericNativeIndexAccessor extends NativeIndexAccessor { private final IndexSpecificSpaceFillingCurveSettingsCache spaceFillingCurveSettings; - private final IndexDirectoryStructure directoryStructure; private final SpaceFillingCurveConfiguration configuration; + private final IndexDropAction dropAction; private Validator validator; GenericNativeIndexAccessor( PageCache pageCache, FileSystemAbstraction fs, File storeFile, IndexLayout layout, RecoveryCleanupWorkCollector recoveryCleanupWorkCollector, IndexProvider.Monitor monitor, StoreIndexDescriptor descriptor, - IndexSpecificSpaceFillingCurveSettingsCache spaceFillingCurveSettings, IndexDirectoryStructure directoryStructure, - SpaceFillingCurveConfiguration configuration ) + IndexSpecificSpaceFillingCurveSettingsCache spaceFillingCurveSettings, SpaceFillingCurveConfiguration configuration, IndexDropAction dropAction ) { super( pageCache, fs, storeFile, layout, monitor, descriptor, new SpaceFillingCurveSettingsWriter( spaceFillingCurveSettings ) ); this.spaceFillingCurveSettings = spaceFillingCurveSettings; - this.directoryStructure = directoryStructure; this.configuration = configuration; + this.dropAction = dropAction; instantiateTree( recoveryCleanupWorkCollector, headerWriter ); } @@ -61,14 +57,7 @@ class GenericNativeIndexAccessor extends NativeIndexAccessor layout, IndexProvider.Monitor monitor, StoreIndexDescriptor descriptor, IndexSpecificSpaceFillingCurveSettingsCache spatialSettings, - IndexDirectoryStructure directoryStructure, SpaceFillingCurveConfiguration configuration, boolean archiveFailedIndex ) + IndexDirectoryStructure directoryStructure, SpaceFillingCurveConfiguration configuration, IndexDropAction dropAction, boolean archiveFailedIndex ) { super( pageCache, fs, storeFile, layout, monitor, descriptor, new SpaceFillingCurveSettingsWriter( spatialSettings ) ); this.spatialSettings = spatialSettings; this.directoryStructure = directoryStructure; this.configuration = configuration; + this.dropAction = dropAction; this.archiveFailedIndex = archiveFailedIndex; } @@ -70,6 +72,15 @@ public void create() } } + @Override + public synchronized void drop() + { + // Close resources + super.drop(); + // Cleanup directory + dropAction.drop( descriptor.getId(), archiveFailedIndex ); + } + @Override NativeIndexReader newReader() { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexProvider.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexProvider.java index e85038e38e43f..47b6f99f7a1f5 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexProvider.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexProvider.java @@ -122,6 +122,7 @@ public class GenericNativeIndexProvider extends NativeIndexProvider( new GenericNativeIndexPopulator( pageCache, fs, storeFile, layout, monitor, descriptor, layout.getSpaceFillingCurveSettings(), - directoryStructure(), configuration, archiveFailedIndex ) ); + directoryStructure(), configuration, dropAction, archiveFailedIndex ) ); } @Override protected IndexAccessor newIndexAccessor( File storeFile, GenericLayout layout, StoreIndexDescriptor descriptor ) { return new GenericNativeIndexAccessor( pageCache, fs, storeFile, layout, recoveryCleanupWorkCollector, monitor, descriptor, - layout.getSpaceFillingCurveSettings(), directoryStructure(), configuration ); + layout.getSpaceFillingCurveSettings(), configuration, dropAction ); } @Override diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/BlockBasedIndexPopulatorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/BlockBasedIndexPopulatorTest.java index 781fe190eb3fa..68f0c9682ea81 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/BlockBasedIndexPopulatorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/BlockBasedIndexPopulatorTest.java @@ -19,9 +19,11 @@ */ package org.neo4j.kernel.impl.index.schema; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -30,12 +32,11 @@ import org.neo4j.graphdb.mockfs.EphemeralFileSystemAbstraction; import org.neo4j.internal.kernel.api.schema.IndexProviderDescriptor; +import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.kernel.api.index.IndexDirectoryStructure; import org.neo4j.kernel.api.index.IndexEntryUpdate; -import org.neo4j.kernel.api.index.IndexProvider; import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.impl.api.index.PhaseTracker; import org.neo4j.kernel.impl.index.schema.config.ConfiguredSpaceFillingCurveSettingsCache; import org.neo4j.kernel.impl.index.schema.config.IndexSpecificSpaceFillingCurveSettingsCache; import org.neo4j.storageengine.api.schema.IndexDescriptorFactory; @@ -47,8 +48,12 @@ import org.neo4j.test.rule.concurrent.OtherThreadRule; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.neo4j.kernel.api.index.IndexDirectoryStructure.directoriesByProvider; +import static org.neo4j.kernel.api.index.IndexProvider.Monitor.EMPTY; +import static org.neo4j.kernel.impl.api.index.PhaseTracker.nullInstance; +import static org.neo4j.kernel.impl.index.schema.BlockStorage.Monitor.NO_MONITOR; import static org.neo4j.test.OtherThreadExecutor.command; import static org.neo4j.test.Race.throwing; import static org.neo4j.values.storable.Values.stringValue; @@ -66,6 +71,23 @@ public class BlockBasedIndexPopulatorTest @Rule public final OtherThreadRule t3 = new OtherThreadRule<>( "CLOSER" ); + private IndexDirectoryStructure directoryStructure; + private File indexDir; + private File indexFile; + private FileSystemAbstraction fs; + private IndexDropAction dropAction; + + @Before + public void setup() + { + IndexProviderDescriptor providerDescriptor = new IndexProviderDescriptor( "test", "v1" ); + directoryStructure = directoriesByProvider( storage.directory().databaseDir() ).forProvider( providerDescriptor ); + indexDir = directoryStructure.directoryForIndex( INDEX_DESCRIPTOR.getId() ); + indexFile = new File( indexDir, "index" ); + fs = storage.fileSystem(); + dropAction = new FileSystemIndexDropAction( fs, directoryStructure ); + } + @Test public void shouldAwaitMergeToBeFullyAbortedBeforeLeavingCloseMethod() throws Exception { @@ -74,7 +96,7 @@ public void shouldAwaitMergeToBeFullyAbortedBeforeLeavingCloseMethod() throws Ex BlockBasedIndexPopulator populator = instantiatePopulatorWithSomeData( monitor ); // when starting to merge (in a separate thread) - Future mergeFuture = t2.execute( command( () -> populator.scanCompleted( PhaseTracker.nullInstance ) ) ); + Future mergeFuture = t2.execute( command( () -> populator.scanCompleted( nullInstance ) ) ); // and waiting for merge to get going monitor.barrier.awaitUninterruptibly(); // calling close here should wait for the merge future, so that checking the merge future for "done" immediately afterwards must say true @@ -96,7 +118,7 @@ public void shouldReportAccurateProgressThroughoutThePhases() throws Exception try { // when starting to merge (in a separate thread) - Future mergeFuture = t2.execute( command( () -> populator.scanCompleted( PhaseTracker.nullInstance ) ) ); + Future mergeFuture = t2.execute( command( () -> populator.scanCompleted( nullInstance ) ) ); // and waiting for merge to get going monitor.barrier.awaitUninterruptibly(); // this is a bit fuzzy, but what we want is to assert that the scan doesn't represent 100% of the work @@ -118,30 +140,54 @@ public void shouldReportAccurateProgressThroughoutThePhases() throws Exception public void shouldCorrectlyDecideToAwaitMergeDependingOnProgress() throws Throwable { // given - BlockBasedIndexPopulator populator = instantiatePopulatorWithSomeData( BlockStorage.Monitor.NO_MONITOR ); + BlockBasedIndexPopulator populator = instantiatePopulatorWithSomeData( NO_MONITOR ); // when Race race = new Race(); - race.addContestant( throwing( () -> populator.scanCompleted( PhaseTracker.nullInstance ) ) ); + race.addContestant( throwing( () -> populator.scanCompleted( nullInstance ) ) ); race.addContestant( throwing( () -> populator.close( false ) ) ); race.go(); // then regardless of who wins (close/merge) after close call returns no files should still be mapped - EphemeralFileSystemAbstraction ephemeralFileSystem = (EphemeralFileSystemAbstraction) storage.fileSystem(); + EphemeralFileSystemAbstraction ephemeralFileSystem = (EphemeralFileSystemAbstraction) fs; ephemeralFileSystem.assertNoOpenFiles(); } + @Test + public void shouldDeleteDirectoryOnDrop() throws Exception + { + // given + TrappingMonitor monitor = new TrappingMonitor( false ); + BlockBasedIndexPopulator populator = instantiatePopulatorWithSomeData( monitor ); + + // when starting to merge (in a separate thread) + Future mergeFuture = t2.execute( command( () -> populator.scanCompleted( nullInstance ) ) ); + // and waiting for merge to get going + monitor.barrier.awaitUninterruptibly(); + // calling drop here should wait for the merge future and then delete index directory + assertTrue( fs.fileExists( indexDir ) ); + assertTrue( fs.isDirectory( indexDir ) ); + assertTrue( fs.listFiles( indexDir ).length > 0 ); + + Future dropFuture = t3.execute( command( populator::drop ) ); + t3.get().waitUntilWaiting(); + monitor.barrier.release(); + dropFuture.get(); + + // then + assertTrue( mergeFuture.isDone() ); + assertFalse( fs.fileExists( indexDir ) ); + } + private BlockBasedIndexPopulator instantiatePopulatorWithSomeData( BlockStorage.Monitor monitor ) { - IndexProviderDescriptor providerDescriptor = new IndexProviderDescriptor( "test", "v1" ); Config config = Config.defaults(); - IndexSpecificSpaceFillingCurveSettingsCache spatialSettings = - new IndexSpecificSpaceFillingCurveSettingsCache( new ConfiguredSpaceFillingCurveSettingsCache( config ), new HashMap<>() ); + ConfiguredSpaceFillingCurveSettingsCache settingsCache = new ConfiguredSpaceFillingCurveSettingsCache( config ); + IndexSpecificSpaceFillingCurveSettingsCache spatialSettings = new IndexSpecificSpaceFillingCurveSettingsCache( settingsCache, new HashMap<>() ); GenericLayout layout = new GenericLayout( 1, spatialSettings ); - IndexDirectoryStructure directoryStructure = directoriesByProvider( storage.directory().directory( "schema" ) ).forProvider( providerDescriptor ); BlockBasedIndexPopulator populator = - new BlockBasedIndexPopulator( storage.pageCache(), storage.fileSystem(), storage.directory().file( "file" ), - layout, IndexProvider.Monitor.EMPTY, INDEX_DESCRIPTOR, spatialSettings, directoryStructure, false, 100, 2, monitor ) + new BlockBasedIndexPopulator( storage.pageCache(), fs, indexFile, layout, EMPTY, + INDEX_DESCRIPTOR, spatialSettings, directoryStructure, dropAction, false, 100, 2, monitor ) { @Override NativeIndexReader newReader() diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericAccessorPointsTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericAccessorPointsTest.java index b2a6bbb7bc4f7..0f3137b248b9c 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericAccessorPointsTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericAccessorPointsTest.java @@ -96,7 +96,8 @@ public void setup() descriptor = TestIndexDescriptorFactory.forLabel( 1, 1 ).withId( 1 ); IndexDirectoryStructure.Factory factory = IndexDirectoryStructure.directoriesByProvider( directory.storeDir() ); IndexDirectoryStructure structure = factory.forProvider( GenericNativeIndexProvider.DESCRIPTOR ); - accessor = new GenericNativeIndexAccessor( pc, fs, file, layout, collector, EMPTY, descriptor, indexSettings, structure, new StandardConfiguration() ); + IndexDropAction dropAction = new FileSystemIndexDropAction( fs, structure ); + accessor = new GenericNativeIndexAccessor( pc, fs, file, layout, collector, EMPTY, descriptor, indexSettings, new StandardConfiguration(), dropAction ); } @After diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexAccessorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexAccessorTest.java index d94846181d0bb..cd2746267406b 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexAccessorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexAccessorTest.java @@ -56,8 +56,9 @@ public void dropShouldDeleteEntireIndexFolder() StoreIndexDescriptor descriptor = IndexDescriptorFactory.forSchema( SchemaDescriptorFactory.forLabel( 1, 1 ) ).withId( indexId ); IndexSpecificSpaceFillingCurveSettingsCache spatialSettings = mock( IndexSpecificSpaceFillingCurveSettingsCache.class ); FileSystemAbstraction fs = storage.fileSystem(); + IndexDropAction dropAction = new FileSystemIndexDropAction( fs, directoryStructure ); GenericNativeIndexAccessor accessor = new GenericNativeIndexAccessor( storage.pageCache(), fs, indexFile, new GenericLayout( 1, spatialSettings ), - immediate(), EMPTY, descriptor, spatialSettings, directoryStructure, mock( SpaceFillingCurveConfiguration.class ) ); + immediate(), EMPTY, descriptor, spatialSettings, mock( SpaceFillingCurveConfiguration.class ), dropAction ); // when accessor.drop(); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexPopulatorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexPopulatorTest.java new file mode 100644 index 0000000000000..eabfcb32d65fb --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/GenericNativeIndexPopulatorTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2002-2019 "Neo4j," + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.index.schema; + +import org.junit.Rule; +import org.junit.Test; + +import java.io.File; + +import org.neo4j.gis.spatial.index.curves.SpaceFillingCurveConfiguration; +import org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector; +import org.neo4j.io.fs.FileSystemAbstraction; +import org.neo4j.io.pagecache.PageCache; +import org.neo4j.kernel.api.index.IndexDirectoryStructure; +import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; +import org.neo4j.kernel.impl.index.schema.config.IndexSpecificSpaceFillingCurveSettingsCache; +import org.neo4j.storageengine.api.schema.IndexDescriptorFactory; +import org.neo4j.storageengine.api.schema.StoreIndexDescriptor; +import org.neo4j.test.rule.PageCacheAndDependenciesRule; +import org.neo4j.test.rule.fs.DefaultFileSystemRule; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector.immediate; +import static org.neo4j.kernel.api.index.IndexProvider.Monitor.EMPTY; + +public class GenericNativeIndexPopulatorTest +{ + @Rule + public final PageCacheAndDependenciesRule storage = new PageCacheAndDependenciesRule().with( new DefaultFileSystemRule() ); + + @Test + public void dropShouldDeleteEntireIndexFolder() + { + // given + File root = storage.directory().directory( "root" ); + IndexDirectoryStructure directoryStructure = IndexDirectoryStructure.directoriesByProvider( root ).forProvider( GenericNativeIndexProvider.DESCRIPTOR ); + long indexId = 8; + File indexDirectory = directoryStructure.directoryForIndex( indexId ); + StoreIndexDescriptor descriptor = IndexDescriptorFactory.forSchema( SchemaDescriptorFactory.forLabel( 1, 1 ) ).withId( indexId ); + IndexSpecificSpaceFillingCurveSettingsCache spatialSettings = mock( IndexSpecificSpaceFillingCurveSettingsCache.class ); + PageCache pageCache = storage.pageCache(); + FileSystemAbstraction fs = storage.fileSystem(); + File indexFile = new File( indexDirectory, "my-index" ); + GenericLayout layout = new GenericLayout( 1, spatialSettings ); + RecoveryCleanupWorkCollector immediate = immediate(); + IndexDropAction dropAction = new FileSystemIndexDropAction( fs, directoryStructure ); + GenericNativeIndexPopulator populator = new GenericNativeIndexPopulator( pageCache, fs, indexFile, layout, + EMPTY, descriptor, spatialSettings, directoryStructure, mock( SpaceFillingCurveConfiguration.class ), dropAction, false ); + populator.create(); + + // when + assertTrue( fs.listFiles( indexDirectory ).length > 0 ); + populator.drop(); + + // then + assertFalse( fs.fileExists( indexDirectory ) ); + } +} diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeIndexAccessorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeIndexAccessorTest.java index dca839077dec7..54c770a432ad7 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeIndexAccessorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeIndexAccessorTest.java @@ -189,8 +189,11 @@ private static > AccessorFactory genericAccessorFactory() { return ( pageCache, fs, storeFile, layout, cleanup, monitor, descriptor, directory ) -> - new GenericNativeIndexAccessor( pageCache, fs, storeFile, layout, cleanup, monitor, descriptor, spaceFillingCurveSettings, - directory, configuration ); + { + IndexDropAction dropAction = new FileSystemIndexDropAction( fs, directory ); + return new GenericNativeIndexAccessor( pageCache, fs, storeFile, layout, cleanup, monitor, descriptor, spaceFillingCurveSettings, + configuration, dropAction ); + }; } @FunctionalInterface diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeIndexPopulatorTestCases.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeIndexPopulatorTestCases.java index d925ea8663df8..b3e19d389168a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeIndexPopulatorTestCases.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/NativeIndexPopulatorTestCases.java @@ -28,6 +28,7 @@ import org.neo4j.gis.spatial.index.curves.StandardConfiguration; import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.io.pagecache.PageCache; +import org.neo4j.kernel.api.index.IndexDirectoryStructure; import org.neo4j.kernel.api.index.IndexProvider; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.index.schema.config.ConfiguredSpaceFillingCurveSettingsCache; @@ -133,15 +134,23 @@ private static > PopulatorFactory genericPopulatorFactory() { return ( pageCache, fs, storeFile, layout, monitor, descriptor ) -> - new GenericNativeIndexPopulator( pageCache, fs, storeFile, layout, monitor, descriptor, spaceFillingCurveSettings, - SimpleIndexDirectoryStructures.onIndexFile( storeFile ), configuration, false ); + { + IndexDirectoryStructure directoryStructure = SimpleIndexDirectoryStructures.onIndexFile( storeFile ); + IndexDropAction dropAction = new FileSystemIndexDropAction( fs, directoryStructure ); + return new GenericNativeIndexPopulator( pageCache, fs, storeFile, layout, monitor, descriptor, spaceFillingCurveSettings, + directoryStructure, configuration, dropAction, false ); + }; } private static PopulatorFactory genericBlockBasedPopulatorFactory() { return ( pageCache, fs, storeFile, layout, monitor, descriptor ) -> - new GenericBlockBasedIndexPopulator( pageCache, fs, storeFile, layout, monitor, descriptor, spaceFillingCurveSettings, - SimpleIndexDirectoryStructures.onIndexFile( storeFile ), configuration, false ); + { + IndexDirectoryStructure directoryStructure = SimpleIndexDirectoryStructures.onIndexFile( storeFile ); + IndexDropAction dropAction = new FileSystemIndexDropAction( fs, directoryStructure ); + return new GenericBlockBasedIndexPopulator( pageCache, fs, storeFile, layout, monitor, descriptor, spaceFillingCurveSettings, + directoryStructure, configuration, dropAction, false ); + }; } @FunctionalInterface