Skip to content

Commit

Permalink
Handle range querys for line with area equal 0
Browse files Browse the repository at this point in the history
Fixed SpatialSchemaIndexAccessorTest
  • Loading branch information
OliviaYtterbrink committed Apr 6, 2018
1 parent c079eec commit 4df248f
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 69 deletions.
Expand Up @@ -32,8 +32,11 @@
import org.neo4j.internal.kernel.api.IndexQuery; import org.neo4j.internal.kernel.api.IndexQuery;
import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor;
import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptorFactory; 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.DateTimeValue;
import org.neo4j.values.storable.PointValue;
import org.neo4j.values.storable.Value; import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.Values;


import static java.time.ZoneOffset.UTC; import static java.time.ZoneOffset.UTC;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
Expand Down Expand Up @@ -176,6 +179,24 @@ public void testIndexRangeSeekByDateTimeWithSneakyZones() throws Exception
assertThat( query( range( 1, d4, true, d7, true ) ), Matchers.contains( 4L, 5L, 6L, 7L ) ); 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 @Test
public void shouldScanAllValues() throws Exception public void shouldScanAllValues() throws Exception
{ {
Expand Down
Expand Up @@ -46,10 +46,10 @@ public class SpatialLayoutTestUtil extends LayoutTestUtil<SpatialSchemaKey,Nativ
{ {
Values.pointValue( WGS84, -180, -90 ), Values.pointValue( WGS84, -180, -90 ),
Values.pointValue( WGS84, -180, 90 ), Values.pointValue( WGS84, -180, 90 ),
Values.pointValue( WGS84, -1, -1 ),
Values.pointValue( WGS84, 0, 0 ), Values.pointValue( WGS84, 0, 0 ),
Values.pointValue( WGS84, -1, 1 ),
Values.pointValue( WGS84, 180, 90 ),
Values.pointValue( WGS84, 180, -90 ), Values.pointValue( WGS84, 180, -90 ),
Values.pointValue( WGS84, 180, 90 ),
}; };


public static PointValue randomPoint( Randoms random ) public static PointValue randomPoint( Randoms random )
Expand Down
Expand Up @@ -19,42 +19,10 @@
*/ */
package org.neo4j.kernel.impl.index.schema; 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.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 SpatialNonUniqueSchemaIndexAccessorTest extends NativeSchemaIndexAccessorTest<SpatialSchemaKey,NativeSchemaValue> 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<SpatialSchemaKey,NativeSchemaValue> 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 @Override
protected LayoutTestUtil<SpatialSchemaKey,NativeSchemaValue> createLayoutTestUtil() protected LayoutTestUtil<SpatialSchemaKey,NativeSchemaValue> createLayoutTestUtil()
{ {
Expand Down
@@ -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 <http://www.gnu.org/licenses/>.
*/
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<SpatialSchemaKey,NativeSchemaValue>
{
static final CoordinateReferenceSystem crs = CoordinateReferenceSystem.WGS84;
static final SpaceFillingCurveSettings settings = new SpaceFillingCurveSettingsFactory( Config.defaults() ).settingsFor( crs );

SpatialIndexFiles.SpatialFileLayout fileLayout;

@Override
NativeSchemaIndexAccessor<SpatialSchemaKey,NativeSchemaValue> 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
}
}
Expand Up @@ -19,42 +19,10 @@
*/ */
package org.neo4j.kernel.impl.index.schema; 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.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<SpatialSchemaKey,NativeSchemaValue> 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<SpatialSchemaKey,NativeSchemaValue> 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 @Override
protected LayoutTestUtil<SpatialSchemaKey,NativeSchemaValue> createLayoutTestUtil() protected LayoutTestUtil<SpatialSchemaKey,NativeSchemaValue> createLayoutTestUtil()
{ {
Expand Down
Expand Up @@ -65,7 +65,12 @@ public boolean stopAtThisDepth( double overlap, int depth, int maxDepth )
public int maxDepth( Envelope referenceEnvelope, Envelope range, int nbrDim, int maxLevel ) public int maxDepth( Envelope referenceEnvelope, Envelope range, int nbrDim, int maxLevel )
{ {
double searchRatio = range.getArea() / referenceEnvelope.getArea(); 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 @Override
Expand Down
@@ -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 <http://www.gnu.org/licenses/>.
*/
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 ) );
}
}

0 comments on commit 4df248f

Please sign in to comment.