diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialCRSSchemaIndex.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialCRSSchemaIndex.java index 5104a0e113da..df08da2cc2fa 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialCRSSchemaIndex.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialCRSSchemaIndex.java @@ -37,7 +37,6 @@ import org.neo4j.graphdb.ResourceIterator; import org.neo4j.helpers.collection.BoundedIterable; import org.neo4j.helpers.collection.Pair; -import org.neo4j.index.internal.gbptree.GBPTree; import org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector; import org.neo4j.index.internal.gbptree.Writer; import org.neo4j.internal.kernel.api.InternalIndexState; @@ -94,7 +93,8 @@ public SpatialCRSSchemaIndex( IndexDescriptor descriptor, FileSystemAbstraction fs, SchemaIndexProvider.Monitor monitor, RecoveryCleanupWorkCollector recoveryCleanupWorkCollector, - SpaceFillingCurveConfiguration configuration ) + SpaceFillingCurveConfiguration configuration, + int maxLevels ) { this.crs = crs; this.pageCache = pageCache; @@ -110,11 +110,11 @@ public SpatialCRSSchemaIndex( IndexDescriptor descriptor, indexFile = new File( indexDir.directoryForIndex( indexId ), "index-" + indexId ); if ( crs.getDimension() == 2 ) { - curve = new HilbertSpaceFillingCurve2D( envelopeFromCRS( crs ), configuration.maxLevels() ); + curve = new HilbertSpaceFillingCurve2D( envelopeFromCRS( crs ), maxLevels ); } else if ( crs.getDimension() == 3 ) { - curve = new HilbertSpaceFillingCurve3D( envelopeFromCRS( crs ), configuration.maxLevels() ); + curve = new HilbertSpaceFillingCurve3D( envelopeFromCRS( crs ), maxLevels ); } else { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexReader.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexReader.java index c2888ecb6d8f..1e35983e4545 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexReader.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexReader.java @@ -134,7 +134,6 @@ private void startSeekForRange( IndexProgressor.NodeValueClient client, Geometry double[] from = rangePredicate.from() == null ? completeEnvelope.getMin() : rangePredicate.from().coordinate(); double[] to = rangePredicate.to() == null ? completeEnvelope.getMax() : rangePredicate.to().coordinate(); Envelope envelope = new Envelope( from, to ); - List ranges = curve.getTilesIntersectingEnvelope( envelope, configuration ); for ( SpaceFillingCurve.LongRange range : ranges ) { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionSchemaIndexProvider.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionSchemaIndexProvider.java index 69b7204d0e41..05f46372b6a0 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionSchemaIndexProvider.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionSchemaIndexProvider.java @@ -26,7 +26,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.neo4j.gis.spatial.index.curves.PartialOverlapConfiguration; import org.neo4j.gis.spatial.index.curves.SpaceFillingCurveConfiguration; +import org.neo4j.gis.spatial.index.curves.StandardConfiguration; +import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.index.internal.gbptree.GBPTree; import org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector; import org.neo4j.internal.kernel.api.IndexCapability; @@ -38,6 +41,7 @@ import org.neo4j.kernel.api.index.IndexPopulator; import org.neo4j.kernel.api.index.SchemaIndexProvider; import org.neo4j.kernel.api.schema.index.IndexDescriptor; +import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; import org.neo4j.kernel.impl.index.schema.SpatialCRSSchemaIndex; import org.neo4j.kernel.impl.storemigration.StoreMigrationParticipant; @@ -58,12 +62,13 @@ public class SpatialFusionSchemaIndexProvider extends SchemaIndexProvider implem private final RecoveryCleanupWorkCollector recoveryCleanupWorkCollector; private final boolean readOnly; private final SpaceFillingCurveConfiguration configuration; + private final int maxLevels; private Map> indexes = new HashMap<>(); public SpatialFusionSchemaIndexProvider( PageCache pageCache, FileSystemAbstraction fs, IndexDirectoryStructure.Factory directoryStructure, Monitor monitor, RecoveryCleanupWorkCollector recoveryCleanupWorkCollector, boolean readOnly, - SpaceFillingCurveConfiguration configuration ) + Config config ) { super( SPATIAL_PROVIDER_DESCRIPTOR, 0, directoryStructure ); this.pageCache = pageCache; @@ -71,7 +76,24 @@ public SpatialFusionSchemaIndexProvider( PageCache pageCache, FileSystemAbstract this.monitor = monitor; this.recoveryCleanupWorkCollector = recoveryCleanupWorkCollector; this.readOnly = readOnly; - this.configuration = configuration; + this.configuration = getConfiguredSpaceFillingCurveConfiguration( config ); + this.maxLevels = config.get( GraphDatabaseSettings.space_filling_curve_max_levels ); + } + + private static SpaceFillingCurveConfiguration getConfiguredSpaceFillingCurveConfiguration( Config config ) + { + int extraLevels = config.get( GraphDatabaseSettings.space_filling_curve_extra_levels ); + double topThreshold = config.get( GraphDatabaseSettings.space_filling_curve_top_threshold ); + double bottomThreshold = config.get( GraphDatabaseSettings.space_filling_curve_bottom_threshold ); + + if ( topThreshold == 0.0 || bottomThreshold == 0.0 ) + { + return new StandardConfiguration( extraLevels ); + } + else + { + return new PartialOverlapConfiguration( extraLevels, topThreshold, bottomThreshold ); + } } @Override @@ -171,7 +193,7 @@ public SpatialCRSSchemaIndex get( IndexDescriptor descriptor, { return indexMap.computeIfAbsent( crs, crsKey -> new SpatialCRSSchemaIndex( descriptor, directoryStructure(), crsKey, indexId, pageCache, fs, monitor, - recoveryCleanupWorkCollector, configuration ) ); + recoveryCleanupWorkCollector, configuration, maxLevels ) ); } /** diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialKnownIndexTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialKnownIndexTest.java index 730a77c4dffd..d551c67c327b 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialKnownIndexTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialKnownIndexTest.java @@ -85,7 +85,7 @@ public void setup() throws IOException IndexDirectoryStructure dirStructure = IndexDirectoryStructure.directoriesByProvider( storeDir ).forProvider( SPATIAL_PROVIDER_DESCRIPTOR ); descriptor = IndexDescriptorFactory.forLabel( 42, 1337 ); index = new SpatialCRSSchemaIndex( descriptor, dirStructure, crs, 1L, pageCacheRule.getPageCache( fs ), fs, - SchemaIndexProvider.Monitor.EMPTY, RecoveryCleanupWorkCollector.IMMEDIATE, new StandardConfiguration() ); + SchemaIndexProvider.Monitor.EMPTY, RecoveryCleanupWorkCollector.IMMEDIATE, new StandardConfiguration(), 30 ); samplingConfig = mock( IndexSamplingConfig.class ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionSchemaIndexProviderTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionSchemaIndexProviderTest.java index 3d25bdef9dde..d1c2b9f70d63 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionSchemaIndexProviderTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionSchemaIndexProviderTest.java @@ -26,13 +26,13 @@ import java.io.IOException; import java.util.Map; -import org.neo4j.gis.spatial.index.curves.StandardConfiguration; import org.neo4j.internal.kernel.api.InternalIndexState; import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.io.pagecache.PageCache; import org.neo4j.kernel.api.index.SchemaIndexProvider; import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory; +import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.index.schema.SpatialCRSSchemaIndex; import org.neo4j.test.rule.RandomRule; import org.neo4j.values.storable.CoordinateReferenceSystem; @@ -64,7 +64,9 @@ public void setup() mock( FileSystemAbstraction.class ), NONE, SchemaIndexProvider.Monitor.EMPTY, - null, false, new StandardConfiguration() ); + null, + false, + Config.defaults() ); indexMap = provider.indexesFor( 0 ); indexMap.put( CoordinateReferenceSystem.WGS84, mock( SpatialCRSSchemaIndex.class ) ); indexMap.put( CoordinateReferenceSystem.Cartesian, mock( SpatialCRSSchemaIndex.class ) ); diff --git a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/schema/NativeLuceneFusionSchemaIndexProviderFactory.java b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/schema/NativeLuceneFusionSchemaIndexProviderFactory.java index 2d292b50bd3f..82ffe506957e 100644 --- a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/schema/NativeLuceneFusionSchemaIndexProviderFactory.java +++ b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/schema/NativeLuceneFusionSchemaIndexProviderFactory.java @@ -21,9 +21,6 @@ import java.io.File; -import org.neo4j.gis.spatial.index.curves.PartialOverlapConfiguration; -import org.neo4j.gis.spatial.index.curves.SpaceFillingCurveConfiguration; -import org.neo4j.gis.spatial.index.curves.StandardConfiguration; import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.helpers.Service; import org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector; @@ -92,10 +89,8 @@ public static FusionSchemaIndexProvider newInstance( PageCache pageCache, File s boolean readOnly = isReadOnly( config, operationalMode ); NumberSchemaIndexProvider nativeProvider = new NumberSchemaIndexProvider( pageCache, fs, childDirectoryStructure, monitor, recoveryCleanupWorkCollector, readOnly ); - - SpaceFillingCurveConfiguration sfcConfig = getConfiguredSpaceFillingCurveConfiguration( config ); SpatialFusionSchemaIndexProvider spatialProvider = - new SpatialFusionSchemaIndexProvider( pageCache, fs, childDirectoryStructure, monitor, recoveryCleanupWorkCollector, readOnly, sfcConfig ); + new SpatialFusionSchemaIndexProvider( pageCache, fs, childDirectoryStructure, monitor, recoveryCleanupWorkCollector, readOnly, config ); TemporalSchemaIndexProvider temporalProvider = new TemporalSchemaIndexProvider( pageCache, fs, childDirectoryStructure, monitor, recoveryCleanupWorkCollector, readOnly ); LuceneSchemaIndexProvider luceneProvider = LuceneSchemaIndexProviderFactory.create( fs, childDirectoryStructure, monitor, config, @@ -106,23 +101,6 @@ public static FusionSchemaIndexProvider newInstance( PageCache pageCache, File s spatialProvider, temporalProvider, luceneProvider, new FusionSelector(), DESCRIPTOR, priority, directoriesByProvider( storeDir ), fs ); } - private static SpaceFillingCurveConfiguration getConfiguredSpaceFillingCurveConfiguration( Config config ) - { - int extraLevels = config.get( GraphDatabaseSettings.space_filling_curve_extra_levels ); - double topThreshold = config.get( GraphDatabaseSettings.space_filling_curve_top_threshold ); - double bottomThreshold = config.get( GraphDatabaseSettings.space_filling_curve_bottom_threshold ); - int maxLevels = config.get( GraphDatabaseSettings.space_filling_curve_max_levels ); - - if ( topThreshold == 0.0 || bottomThreshold == 0.0 ) - { - return new StandardConfiguration( extraLevels, maxLevels ); - } - else - { - return new PartialOverlapConfiguration( extraLevels, maxLevels, topThreshold, bottomThreshold ); - } - } - public static IndexDirectoryStructure.Factory subProviderDirectoryStructure( File storeDir ) { IndexDirectoryStructure parentDirectoryStructure = directoriesByProvider( storeDir ).forProvider( DESCRIPTOR ); diff --git a/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/PartialOverlapConfiguration.java b/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/PartialOverlapConfiguration.java index 4e8adf4e9986..3cecb9520f59 100644 --- a/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/PartialOverlapConfiguration.java +++ b/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/PartialOverlapConfiguration.java @@ -28,12 +28,12 @@ public class PartialOverlapConfiguration extends StandardConfiguration public PartialOverlapConfiguration() { - this( StandardConfiguration.DEFAULT_EXTRA_LEVELS, StandardConfiguration.DEFAULT_MAX_LEVELS, TOP_THRESHOLD, BOTTOM_THRESHOLD ); + this( StandardConfiguration.DEFAULT_EXTRA_LEVELS, TOP_THRESHOLD, BOTTOM_THRESHOLD ); } - public PartialOverlapConfiguration( int extraLevels, int maxLevels, double topThreshold, double bottomThreshold ) + public PartialOverlapConfiguration( int extraLevels, double topThreshold, double bottomThreshold ) { - super( extraLevels, maxLevels ); + super( extraLevels ); this.topThreshold = topThreshold; this.bottomThreshold = bottomThreshold; } diff --git a/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveConfiguration.java b/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveConfiguration.java index 1437e39cd05a..7b1e757f9ea2 100644 --- a/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveConfiguration.java +++ b/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveConfiguration.java @@ -49,9 +49,4 @@ public interface SpaceFillingCurveConfiguration * @return the size to use when initializing the ArrayList to store ranges. */ int initialRangesListCapacity(); - - /** - * The depth of the space filling curves created for indexes. - */ - int maxLevels(); } diff --git a/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/StandardConfiguration.java b/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/StandardConfiguration.java index 1ffb17a27280..ca4e913c68cd 100644 --- a/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/StandardConfiguration.java +++ b/community/spatial-index/src/main/java/org/neo4j/gis/spatial/index/curves/StandardConfiguration.java @@ -24,7 +24,6 @@ public class StandardConfiguration implements SpaceFillingCurveConfiguration { public static final int DEFAULT_EXTRA_LEVELS = 1; - public static final int DEFAULT_MAX_LEVELS = 1; /** * After estimating the search ratio, we know the level at which tiles have approximately the same size as @@ -33,20 +32,14 @@ public class StandardConfiguration implements SpaceFillingCurveConfiguration */ protected int extraLevels; - /** - * Depth of SpaceFillingCurves at creation time. - */ - protected int maxLevels; - public StandardConfiguration() { - this( DEFAULT_EXTRA_LEVELS, DEFAULT_MAX_LEVELS ); + this( DEFAULT_EXTRA_LEVELS ); } - public StandardConfiguration( int extraLevels, int maxLevels ) + public StandardConfiguration( int extraLevels ) { this.extraLevels = extraLevels; - this.maxLevels = maxLevels; } /** @@ -87,10 +80,4 @@ public int initialRangesListCapacity() // Probably big enough to for the majority of index queries. return 1000; } - - @Override - public int maxLevels() - { - return maxLevels; - } } diff --git a/community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveTest.java b/community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveTest.java index 6aec137ffd8e..31894c0676a5 100644 --- a/community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveTest.java +++ b/community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveTest.java @@ -461,17 +461,17 @@ public void shouldHaveReasonableCoveredArea() log( "" ); log( formatHeader1 ); log( formatHeader2 ); - for ( SpaceFillingCurveConfiguration config : new SpaceFillingCurveConfiguration[]{new StandardConfiguration( 1, level ), - new StandardConfiguration( 2, level ), new StandardConfiguration( 3, level ), new StandardConfiguration( 4, level ), - new PartialOverlapConfiguration( 1, level, 0.99, 0.1 ), new PartialOverlapConfiguration( 1, level, 0.99, 0.5 ), - new PartialOverlapConfiguration( 2, level, 0.99, 0.1 ), new PartialOverlapConfiguration( 2, level, 0.99, 0.5 ), - new PartialOverlapConfiguration( 3, level, 0.99, 0.1 ), new PartialOverlapConfiguration( 3, level, 0.99, 0.5 ), - new PartialOverlapConfiguration( 4, level, 0.99, 0.1 ), new PartialOverlapConfiguration( 4, level, 0.99, 0.5 )} ) + for ( SpaceFillingCurveConfiguration config : new SpaceFillingCurveConfiguration[]{new StandardConfiguration( 1 ), + new StandardConfiguration( 2 ), new StandardConfiguration( 3 ), new StandardConfiguration( 4 ), + new PartialOverlapConfiguration( 1, 0.99, 0.1 ), new PartialOverlapConfiguration( 1, 0.99, 0.5 ), + new PartialOverlapConfiguration( 2, 0.99, 0.1 ), new PartialOverlapConfiguration( 2, 0.99, 0.5 ), + new PartialOverlapConfiguration( 3, 0.99, 0.1 ), new PartialOverlapConfiguration( 3, 0.99, 0.5 ), + new PartialOverlapConfiguration( 4, 0.99, 0.1 ), new PartialOverlapConfiguration( 4, 0.99, 0.5 )} ) { MonitorDoubleStats areaStats = new MonitorDoubleStats(); MonitorStats rangeStats = new MonitorStats(); MonitorStats maxDepthStats = new MonitorStats(); - HilbertSpaceFillingCurve2D curve = new HilbertSpaceFillingCurve2D( envelope, config.maxLevels() ); + HilbertSpaceFillingCurve2D curve = new HilbertSpaceFillingCurve2D( envelope, level ); // For differently shaped rectangles for ( double xExtent = minExtent; xExtent <= xmax; xExtent *= extensionFactor ) @@ -667,19 +667,18 @@ public void debugSingle() @Test public void shouldGet2DHilbertSearchTilesForCenterRangeAndTraverseToBottom() { + TraverseToBottomConfiguration configuration = new TraverseToBottomConfiguration(); Envelope envelope = new Envelope( -8, 8, -8, 8 ); for ( int level = 2; level <= 11; level++ ) // 12 takes 6s, 13 takes 25s, 14 takes 100s, 15 takes over 400s { - TraverseToBottomConfiguration configuration = new TraverseToBottomConfiguration( level ); - HilbertSpaceFillingCurve2D curve = new HilbertSpaceFillingCurve2D( envelope, configuration.maxLevels() ); - double fullTile = curve.getTileWidth( 0, configuration.maxLevels() ); + HilbertSpaceFillingCurve2D curve = new HilbertSpaceFillingCurve2D( envelope, level ); + double fullTile = curve.getTileWidth( 0, level ); double halfTile = fullTile / 2.0; Envelope centerWithoutOuterRing = new Envelope( envelope.getMin( 0 ) + fullTile + halfTile, envelope.getMax( 0 ) - fullTile - halfTile, envelope.getMin( 1 ) + fullTile + halfTile, envelope.getMax( 1 ) - fullTile - halfTile ); long start = System.currentTimeMillis(); List result = curve.getTilesIntersectingEnvelope( centerWithoutOuterRing, configuration, null ); - log( "Hilbert query at level " + configuration.maxLevels() + " took " + (System.currentTimeMillis() - start) + "ms to produce " + result.size() + - " tiles" ); + log( "Hilbert query at level " + level + " took " + (System.currentTimeMillis() - start) + "ms to produce " + result.size() + " tiles" ); assertTiles( result, tilesNotTouchingOuterRing( curve ).toArray( new SpaceFillingCurve.LongRange[0] ) ); } } diff --git a/community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/TraverseToBottomConfiguration.java b/community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/TraverseToBottomConfiguration.java index 2d0aa7c6da7d..5ffe1c11e884 100644 --- a/community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/TraverseToBottomConfiguration.java +++ b/community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/TraverseToBottomConfiguration.java @@ -23,13 +23,6 @@ public class TraverseToBottomConfiguration implements SpaceFillingCurveConfiguration { - private final int maxLevels; - - public TraverseToBottomConfiguration( int maxLevels ) - { - this.maxLevels = maxLevels; - } - @Override public boolean stopAtThisDepth( double overlap, int depth, int maxDepth ) { @@ -55,10 +48,4 @@ public int initialRangesListCapacity() // Thus, we can just as well start with a short list. return 10; } - - @Override - public int maxLevels() - { - return maxLevels; - } }