From 4df248f3551835b5f29807496ee0086aba62e155 Mon Sep 17 00:00:00 2001 From: Olivia Ytterbrink Date: Fri, 6 Apr 2018 12:09:45 +0200 Subject: [PATCH] Handle range querys for line with area equal 0 Fixed SpatialSchemaIndexAccessorTest --- .../SimpleIndexAccessorCompatibility.java | 21 +++++ .../index/schema/SpatialLayoutTestUtil.java | 4 +- ...atialNonUniqueSchemaIndexAccessorTest.java | 34 +------- .../SpatialSchemaIndexAccessorTest.java | 80 +++++++++++++++++++ .../SpatialUniqueSchemaIndexAccessorTest.java | 34 +------- .../index/curves/StandardConfiguration.java | 7 +- .../SpaceFillingCurveConfigurationTest.java | 54 +++++++++++++ 7 files changed, 165 insertions(+), 69 deletions(-) create mode 100644 community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexAccessorTest.java create mode 100644 community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveConfigurationTest.java diff --git a/community/kernel/src/test/java/org/neo4j/kernel/api/index/SimpleIndexAccessorCompatibility.java b/community/kernel/src/test/java/org/neo4j/kernel/api/index/SimpleIndexAccessorCompatibility.java index e155da29d22d3..089e15a7ace39 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/api/index/SimpleIndexAccessorCompatibility.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/api/index/SimpleIndexAccessorCompatibility.java @@ -32,8 +32,11 @@ import org.neo4j.internal.kernel.api.IndexQuery; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptorFactory; +import org.neo4j.values.storable.CoordinateReferenceSystem; import org.neo4j.values.storable.DateTimeValue; +import org.neo4j.values.storable.PointValue; import org.neo4j.values.storable.Value; +import org.neo4j.values.storable.Values; import static java.time.ZoneOffset.UTC; import static java.util.Arrays.asList; @@ -176,6 +179,24 @@ public void testIndexRangeSeekByDateTimeWithSneakyZones() throws Exception assertThat( query( range( 1, d4, true, d7, true ) ), Matchers.contains( 4L, 5L, 6L, 7L ) ); } + @Test + public void testIndexRangeSeekWithSpatial() throws Exception + { + Assume.assumeTrue( testSuite.supportsSpatial() ); + + PointValue p1 = Values.pointValue( CoordinateReferenceSystem.WGS84, -180, -1 ); + PointValue p2 = Values.pointValue( CoordinateReferenceSystem.WGS84, -180, 1 ); + PointValue p3 = Values.pointValue( CoordinateReferenceSystem.WGS84, 0, 0 ); + + updateAndCommit( asList( + add( 1L, descriptor.schema(), p1 ), + add( 2L, descriptor.schema(), p2 ), + add( 3L, descriptor.schema(), p3 ) + ) ); + + assertThat( query( range( 1, p1, true, p2, true ) ), Matchers.contains( 1L, 2L ) ); + } + @Test public void shouldScanAllValues() throws Exception { diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialLayoutTestUtil.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialLayoutTestUtil.java index 12da8faa7ed0d..0f0de9f674caf 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialLayoutTestUtil.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialLayoutTestUtil.java @@ -46,10 +46,10 @@ public class SpatialLayoutTestUtil extends LayoutTestUtil +public class SpatialNonUniqueSchemaIndexAccessorTest extends SpatialSchemaIndexAccessorTest { - private static final CoordinateReferenceSystem crs = CoordinateReferenceSystem.WGS84; - private static final SpaceFillingCurveSettings settings = new SpaceFillingCurveSettingsFactory( Config.defaults() ).settingsFor( crs ); - - SpatialIndexFiles.SpatialFileLayout fileLayout; - - @Override - NativeSchemaIndexAccessor makeAccessorWithSamplingConfig( IndexSamplingConfig samplingConfig ) throws IOException - { - fileLayout = new SpatialIndexFiles.SpatialFileLayout( CoordinateReferenceSystem.WGS84, settings, super.getIndexFile() ); - SpatialIndexFiles.SpatialFileLayout fileLayout = - new SpatialIndexFiles.SpatialFileLayout( CoordinateReferenceSystem.WGS84, settings, super.getIndexFile() ); - return new SpatialIndexAccessor.PartAccessor( pageCache, fs, fileLayout, IMMEDIATE, monitor, schemaIndexDescriptor, indexId, samplingConfig, - new StandardConfiguration() ); - } - - @Override - public File getIndexFile() - { - return fileLayout.indexFile; - } - @Override protected LayoutTestUtil createLayoutTestUtil() { diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexAccessorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexAccessorTest.java new file mode 100644 index 0000000000000..361e36d7e54b9 --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexAccessorTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2002-2018 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.index.schema; + +import java.io.File; +import java.io.IOException; + +import org.neo4j.gis.spatial.index.curves.StandardConfiguration; +import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; +import org.neo4j.kernel.impl.index.schema.config.SpaceFillingCurveSettings; +import org.neo4j.kernel.impl.index.schema.config.SpaceFillingCurveSettingsFactory; +import org.neo4j.values.storable.CoordinateReferenceSystem; + +import static org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector.IMMEDIATE; + +abstract class SpatialSchemaIndexAccessorTest extends NativeSchemaIndexAccessorTest +{ + static final CoordinateReferenceSystem crs = CoordinateReferenceSystem.WGS84; + static final SpaceFillingCurveSettings settings = new SpaceFillingCurveSettingsFactory( Config.defaults() ).settingsFor( crs ); + + SpatialIndexFiles.SpatialFileLayout fileLayout; + + @Override + NativeSchemaIndexAccessor makeAccessorWithSamplingConfig( IndexSamplingConfig samplingConfig ) throws IOException + { + fileLayout = new SpatialIndexFiles.SpatialFileLayout( CoordinateReferenceSystem.WGS84, settings, super.getIndexFile() ); + SpatialIndexFiles.SpatialFileLayout fileLayout = + new SpatialIndexFiles.SpatialFileLayout( CoordinateReferenceSystem.WGS84, settings, super.getIndexFile() ); + return new SpatialIndexAccessor.PartAccessor( pageCache, fs, fileLayout, IMMEDIATE, monitor, schemaIndexDescriptor, indexId, samplingConfig, + new StandardConfiguration() ); + } + + @Override + public File getIndexFile() + { + return fileLayout.indexFile; + } + + @Override + public void shouldNotSeeFilteredEntries() + { + // This test doesn't make sense for spatial, since it needs a proper store for the values + } + + @Override + public void shouldReturnMatchingEntriesForRangePredicateWithExclusiveStartAndExclusiveEnd() + { + // Exclusive is handled via a postfilter for spatial + } + + @Override + public void shouldReturnMatchingEntriesForRangePredicateWithExclusiveStartAndInclusiveEnd() + { + // Exclusive is handled via a postfilter for spatial + } + + @Override + public void shouldReturnMatchingEntriesForRangePredicateWithInclusiveStartAndExclusiveEnd() + { + // Exclusive is handled via a postfilter for spatial + } +} diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialUniqueSchemaIndexAccessorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialUniqueSchemaIndexAccessorTest.java index 5bf617a4cf8cd..95234540ae07e 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialUniqueSchemaIndexAccessorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/SpatialUniqueSchemaIndexAccessorTest.java @@ -19,42 +19,10 @@ */ package org.neo4j.kernel.impl.index.schema; -import java.io.File; -import java.io.IOException; - -import org.neo4j.gis.spatial.index.curves.StandardConfiguration; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptorFactory; -import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; -import org.neo4j.kernel.impl.index.schema.config.SpaceFillingCurveSettings; -import org.neo4j.kernel.impl.index.schema.config.SpaceFillingCurveSettingsFactory; -import org.neo4j.values.storable.CoordinateReferenceSystem; - -import static org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector.IMMEDIATE; -public class SpatialUniqueSchemaIndexAccessorTest extends NativeSchemaIndexAccessorTest +public class SpatialUniqueSchemaIndexAccessorTest extends SpatialSchemaIndexAccessorTest { - private static final CoordinateReferenceSystem crs = CoordinateReferenceSystem.WGS84; - private static final SpaceFillingCurveSettings settings = new SpaceFillingCurveSettingsFactory( Config.defaults() ).settingsFor( crs ); - - SpatialIndexFiles.SpatialFileLayout fileLayout; - - @Override - NativeSchemaIndexAccessor makeAccessorWithSamplingConfig( IndexSamplingConfig samplingConfig ) throws IOException - { - fileLayout = new SpatialIndexFiles.SpatialFileLayout( CoordinateReferenceSystem.WGS84, settings, super.getIndexFile() ); - SpatialIndexFiles.SpatialFileLayout fileLayout = - new SpatialIndexFiles.SpatialFileLayout( CoordinateReferenceSystem.WGS84, settings, super.getIndexFile() ); - return new SpatialIndexAccessor.PartAccessor( pageCache, fs, fileLayout, IMMEDIATE, monitor, schemaIndexDescriptor, indexId, samplingConfig, - new StandardConfiguration() ); - } - - @Override - public File getIndexFile() - { - return fileLayout.indexFile; - } - @Override protected LayoutTestUtil createLayoutTestUtil() { 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 ca4e913c68cd4..d1a0ab1734abd 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 @@ -65,7 +65,12 @@ public boolean stopAtThisDepth( double overlap, int depth, int maxDepth ) public int maxDepth( Envelope referenceEnvelope, Envelope range, int nbrDim, int maxLevel ) { double searchRatio = range.getArea() / referenceEnvelope.getArea(); - return (int) (Math.log( searchRatio ) / Math.log( Math.pow( 2, nbrDim ) )) + extraLevels; + if ( Double.isInfinite( searchRatio ) ) + { + // TODO: revert to maxLevel and fix getTilesIntersectingEnvelope + return Math.min( 10, maxLevel ); + } + return Math.min( maxLevel, (int) (Math.log( searchRatio ) / Math.log( Math.pow( 2, nbrDim ) )) + extraLevels ); } @Override diff --git a/community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveConfigurationTest.java b/community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveConfigurationTest.java new file mode 100644 index 0000000000000..af2264bcceb50 --- /dev/null +++ b/community/spatial-index/src/test/java/org/neo4j/gis/spatial/index/curves/SpaceFillingCurveConfigurationTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2002-2018 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.gis.spatial.index.curves; + +import org.junit.Test; + +import org.neo4j.gis.spatial.index.Envelope; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +public class SpaceFillingCurveConfigurationTest +{ + @Test + public void shouldHandleMaxDepthWithEmptySearchArea() + { + SpaceFillingCurveConfiguration standardConfiguration = new StandardConfiguration(); + SpaceFillingCurveConfiguration partialOverlapConf = new PartialOverlapConfiguration(); + // search area is a line, thus having a search area = 0 + Envelope search = new Envelope( -180, -180, -90, 90 ); + Envelope range = new Envelope( -180, 180, -90, 90 ); + int maxLevel = 30; + assertThat( partialOverlapConf.maxDepth( search, range, 2, maxLevel ), equalTo( maxLevel ) ); + assertThat( standardConfiguration.maxDepth( search, range, 2, maxLevel ), equalTo( maxLevel ) ); + } + + @Test + public void shouldReturnMaxLevelForSmallSearchArea() + { + SpaceFillingCurveConfiguration standardConfiguration = new StandardConfiguration(); + // This isn't a valid envelope, just used to get a large but still finite searchRatio + Envelope search = new Envelope( 0, Double.MIN_VALUE, 0, 100000000000000000000.0 ); + Envelope range = new Envelope( -180, 180, -90, 90 ); + int maxLevel = 30; + assertThat( standardConfiguration.maxDepth( search, range, 2, maxLevel ), equalTo( maxLevel ) ); + } +}