diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/FailureHeaderWriter.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/FailureHeaderWriter.java index 6d8a57751fabb..17d1fdaa78d67 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/FailureHeaderWriter.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/FailureHeaderWriter.java @@ -28,7 +28,7 @@ /** * Writes a failure message to a header in a {@link GBPTree}. */ -public class FailureHeaderWriter implements Consumer +class FailureHeaderWriter implements Consumer { /** * The {@code short} length field containing the length (number of bytes) of the failure message. @@ -37,7 +37,7 @@ public class FailureHeaderWriter implements Consumer private final byte[] failureBytes; - public FailureHeaderWriter( byte[] failureBytes ) + FailureHeaderWriter( byte[] failureBytes ) { this.failureBytes = failureBytes; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexPopulator.java index 4285f67f59418..253fedb8cc1dd 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexPopulator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexPopulator.java @@ -51,7 +51,7 @@ * @param type of {@link NativeSchemaKey}. * @param type of {@link NativeSchemaValue}. */ -public abstract class NativeSchemaIndexPopulator +abstract class NativeSchemaIndexPopulator extends NativeSchemaIndex implements IndexPopulator { static final byte BYTE_FAILED = 0; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SamplingUtil.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SamplingUtil.java index f0d7af6c574e4..99f3d5b9aa147 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SamplingUtil.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SamplingUtil.java @@ -26,11 +26,11 @@ /** * Utilities for implementing {@link IndexSampler sampling}. */ -public class SamplingUtil +class SamplingUtil { private static final String DELIMITER = "\u001F"; - public static String encodedStringValuesForSampling( Object... values ) + static String encodedStringValuesForSampling( Object... values ) { return StringUtils.join( values, DELIMITER ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/KnownSpatialIndex.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialKnownIndex.java similarity index 67% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/KnownSpatialIndex.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialKnownIndex.java index 00c249d6d64dd..e7f19f1938b01 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/KnownSpatialIndex.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialKnownIndex.java @@ -17,7 +17,7 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema; import java.io.File; import java.io.IOException; @@ -25,33 +25,35 @@ import org.neo4j.index.internal.gbptree.GBPTree; import org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector; +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.IndexAccessor; import org.neo4j.kernel.api.index.IndexDirectoryStructure; import org.neo4j.kernel.api.index.IndexPopulator; -import org.neo4j.kernel.api.index.InternalIndexState; import org.neo4j.kernel.api.index.SchemaIndexProvider; import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; +import org.neo4j.kernel.impl.index.schema.fusion.SpatialFusionSchemaIndexProvider; import org.neo4j.values.storable.CoordinateReferenceSystem; import org.neo4j.values.storable.Value; -import static org.neo4j.kernel.impl.index.schema.spatial.SpatialSchemaIndexPopulator.BYTE_FAILED; -import static org.neo4j.kernel.impl.index.schema.spatial.SpatialSchemaIndexPopulator.BYTE_ONLINE; -import static org.neo4j.kernel.impl.index.schema.spatial.SpatialSchemaIndexPopulator.BYTE_POPULATING; +import static org.neo4j.kernel.impl.index.schema.NativeSchemaIndexPopulator.BYTE_FAILED; +import static org.neo4j.kernel.impl.index.schema.NativeSchemaIndexPopulator.BYTE_ONLINE; +import static org.neo4j.kernel.impl.index.schema.NativeSchemaIndexPopulator.BYTE_POPULATING; /** * An instance of this class represents a dynamically created sub-index specific to a particular coordinate reference system. * This allows the fusion index design to be extended to an unknown number of sub-indexes, one for each CRS. */ -public class KnownSpatialIndex +public class SpatialKnownIndex { - interface Factory + public interface Factory { - KnownSpatialIndex selectAndCreate( Map indexMap, long indexId, Value... values ); - KnownSpatialIndex selectAndCreate( Map indexMap, long indexId, CoordinateReferenceSystem crs ); + SpatialKnownIndex selectAndCreate( Map indexMap, long indexId, Value... values ); + + SpatialKnownIndex selectAndCreate( Map indexMap, long indexId, CoordinateReferenceSystem crs ); } private final File indexFile; @@ -62,12 +64,12 @@ interface Factory private final SchemaIndexProvider.Monitor monitor; private final RecoveryCleanupWorkCollector recoveryCleanupWorkCollector; private SpatialSchemaIndexAccessor indexAccessor; - private SpatialSchemaIndexPopulator indexPopulator; + private NativeSchemaIndexPopulator indexPopulator; /** * Create a representation of a spatial index for a specific coordinate reference system. This constructure should be used for first time creation. */ - KnownSpatialIndex( IndexDirectoryStructure directoryStructure, CoordinateReferenceSystem crs, long indexId, PageCache pageCache, + public SpatialKnownIndex( IndexDirectoryStructure directoryStructure, CoordinateReferenceSystem crs, long indexId, PageCache pageCache, FileSystemAbstraction fs, SchemaIndexProvider.Monitor monitor, RecoveryCleanupWorkCollector recoveryCleanupWorkCollector ) { this.crs = crs; @@ -78,7 +80,8 @@ interface Factory this.recoveryCleanupWorkCollector = recoveryCleanupWorkCollector; // Depends on crs - SchemaIndexProvider.Descriptor crsDescriptor = new SchemaIndexProvider.Descriptor( Integer.toString( crs.getTable().getTableId() ), Integer.toString( crs.getCode() ) ); + SchemaIndexProvider.Descriptor crsDescriptor = + new SchemaIndexProvider.Descriptor( Integer.toString( crs.getTable().getTableId() ), Integer.toString( crs.getCode() ) ); IndexDirectoryStructure indexDir = IndexDirectoryStructure.directoriesBySubProvider( directoryStructure ).forProvider( crsDescriptor ); indexFile = new File( indexDir.directoryForIndex( indexId ), indexFileName( indexId ) ); } @@ -88,22 +91,22 @@ private static String indexFileName( long indexId ) return "index-" + indexId; } - boolean indexExists() + public boolean indexExists() { return fs.fileExists( indexFile ); } public String readPopupationFailure() throws IOException { - SpatialSchemaIndexHeaderReader headerReader = new SpatialSchemaIndexHeaderReader(); - GBPTree.readHeader( pageCache, indexFile, new SpatialSchemaIndexProvider.ReadOnlyMetaNumberLayout(), headerReader ); + NativeSchemaIndexHeaderReader headerReader = new NativeSchemaIndexHeaderReader(); + GBPTree.readHeader( pageCache, indexFile, new SpatialFusionSchemaIndexProvider.ReadOnlyMetaNumberLayout(), headerReader ); return headerReader.failureMessage; } - InternalIndexState readState() throws IOException + public InternalIndexState readState() throws IOException { - SpatialSchemaIndexHeaderReader headerReader = new SpatialSchemaIndexHeaderReader(); - GBPTree.readHeader( pageCache, indexFile, new SpatialSchemaIndexProvider.ReadOnlyMetaNumberLayout(), headerReader ); + NativeSchemaIndexHeaderReader headerReader = new NativeSchemaIndexHeaderReader(); + GBPTree.readHeader( pageCache, indexFile, new SpatialFusionSchemaIndexProvider.ReadOnlyMetaNumberLayout(), headerReader ); switch ( headerReader.state ) { case BYTE_FAILED: @@ -117,21 +120,21 @@ InternalIndexState readState() throws IOException } } - private SpatialSchemaIndexPopulator makeIndexPopulator(IndexDescriptor descriptor, IndexSamplingConfig samplingConfig) + private NativeSchemaIndexPopulator makeIndexPopulator( IndexDescriptor descriptor, IndexSamplingConfig samplingConfig ) { switch ( descriptor.type() ) { case GENERAL: - return new SpatialNonUniqueSchemaIndexPopulator<>( pageCache, fs, indexFile, new NonUniqueSpatialLayout(), samplingConfig, monitor, descriptor, + return new NativeNonUniqueSchemaIndexPopulator<>( pageCache, fs, indexFile, new SpatialLayoutNonUnique(), samplingConfig, monitor, descriptor, indexId ); case UNIQUE: - return new SpatialUniqueSchemaIndexPopulator<>( pageCache, fs, indexFile, new UniqueSpatialLayout(), monitor, descriptor, indexId ); + return new NativeUniqueSchemaIndexPopulator<>( pageCache, fs, indexFile, new SpatialLayoutUnique(), monitor, descriptor, indexId ); default: throw new UnsupportedOperationException( "Can not create index populator of type " + descriptor.type() ); } } - IndexPopulator getPopulator(IndexDescriptor descriptor, IndexSamplingConfig samplingConfig) + public IndexPopulator getPopulator( IndexDescriptor descriptor, IndexSamplingConfig samplingConfig ) { if ( indexPopulator == null ) { @@ -150,31 +153,30 @@ IndexPopulator getPopulator(IndexDescriptor descriptor, IndexSamplingConfig samp return indexPopulator; } - void closePopulator( IndexDescriptor descriptor, IndexSamplingConfig samplingConfig, boolean populationCompletedSuccessfully ) throws IOException + public void closePopulator( IndexDescriptor descriptor, IndexSamplingConfig samplingConfig, boolean populationCompletedSuccessfully ) throws IOException { getPopulator( descriptor, samplingConfig ).close( populationCompletedSuccessfully ); this.indexPopulator = null; } - private SpatialSchemaIndexAccessor makeOnlineAccessor(IndexDescriptor descriptor, IndexSamplingConfig samplingConfig) throws IOException + private SpatialSchemaIndexAccessor makeOnlineAccessor( IndexDescriptor descriptor, IndexSamplingConfig samplingConfig ) throws IOException { SpatialLayout layout; switch ( descriptor.type() ) { case GENERAL: - layout = new NonUniqueSpatialLayout(); + layout = new SpatialLayoutNonUnique(); break; case UNIQUE: - layout = new UniqueSpatialLayout(); + layout = new SpatialLayoutUnique(); break; default: throw new UnsupportedOperationException( "Can not create index accessor of type " + descriptor.type() ); } - return new SpatialSchemaIndexAccessor<>( pageCache, fs, indexFile, layout, recoveryCleanupWorkCollector, monitor, descriptor, indexId, - samplingConfig ); + return new SpatialSchemaIndexAccessor<>( pageCache, fs, indexFile, layout, recoveryCleanupWorkCollector, monitor, descriptor, indexId, samplingConfig ); } - IndexAccessor getOnlineAccessor( IndexDescriptor descriptor, IndexSamplingConfig samplingConfig ) throws IOException + public IndexAccessor getOnlineAccessor( IndexDescriptor descriptor, IndexSamplingConfig samplingConfig ) throws IOException { if ( indexAccessor == null ) { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialLayout.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialLayout.java similarity index 74% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialLayout.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialLayout.java index 08c7063a52f3e..40ae00867dfef 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialLayout.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialLayout.java @@ -17,7 +17,7 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema; import org.neo4j.index.internal.gbptree.Layout; import org.neo4j.io.pagecache.PageCursor; @@ -25,7 +25,7 @@ /** * {@link Layout} for numbers where numbers doesn't need to be unique. */ -abstract class SpatialLayout extends Layout.Adapter +public abstract class SpatialLayout extends Layout.Adapter { @Override public SpatialSchemaKey newKey() @@ -39,15 +39,15 @@ public SpatialSchemaKey copyKey( SpatialSchemaKey key, { into.type = key.type; into.rawValueBits = key.rawValueBits; - into.entityId = key.entityId; - into.entityIdIsSpecialTieBreaker = key.entityIdIsSpecialTieBreaker; + into.setEntityId( key.getEntityId() ); + into.setEntityIdIsSpecialTieBreaker( key.getEntityIdIsSpecialTieBreaker() ); return into; } @Override - public SpatialSchemaValue newValue() + public NativeSchemaValue newValue() { - return SpatialSchemaValue.INSTANCE; + return NativeSchemaValue.INSTANCE; } @Override @@ -59,7 +59,7 @@ public int keySize() @Override public int valueSize() { - return SpatialSchemaValue.SIZE; + return NativeSchemaValue.SIZE; } @Override @@ -67,11 +67,11 @@ public void writeKey( PageCursor cursor, SpatialSchemaKey key ) { cursor.putByte( key.type ); cursor.putLong( key.rawValueBits ); - cursor.putLong( key.entityId ); + cursor.putLong( key.getEntityId() ); } @Override - public void writeValue( PageCursor cursor, SpatialSchemaValue value ) + public void writeValue( PageCursor cursor, NativeSchemaValue value ) { } @@ -80,11 +80,11 @@ public void readKey( PageCursor cursor, SpatialSchemaKey into ) { into.type = cursor.getByte(); into.rawValueBits = cursor.getLong(); - into.entityId = cursor.getLong(); + into.setEntityId( cursor.getLong() ); } @Override - public void readValue( PageCursor cursor, SpatialSchemaValue into ) + public void readValue( PageCursor cursor, NativeSchemaValue into ) { } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/NonUniqueSpatialLayout.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialLayoutNonUnique.java similarity index 76% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/NonUniqueSpatialLayout.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialLayoutNonUnique.java index bce1f3e2aab2a..5a840cbe33313 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/NonUniqueSpatialLayout.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialLayoutNonUnique.java @@ -17,16 +17,16 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema; import org.neo4j.index.internal.gbptree.Layout; -public class NonUniqueSpatialLayout extends SpatialLayout +public class SpatialLayoutNonUnique extends SpatialLayout { private static final String IDENTIFIER_NAME = "NUNI"; - static final int MAJOR_VERSION = 0; - static final int MINOR_VERSION = 1; - static long IDENTIFIER = Layout.namedIdentifier( IDENTIFIER_NAME, SpatialSchemaValue.SIZE ); + public static final int MAJOR_VERSION = 0; + public static final int MINOR_VERSION = 1; + public static long IDENTIFIER = Layout.namedIdentifier( IDENTIFIER_NAME, NativeSchemaValue.SIZE ); @Override public long identifier() @@ -50,6 +50,6 @@ public int minorVersion() public int compare( SpatialSchemaKey o1, SpatialSchemaKey o2 ) { int comparison = o1.compareValueTo( o2 ); - return comparison != 0 ? comparison : Long.compare( o1.entityId, o2.entityId ); + return comparison != 0 ? comparison : Long.compare( o1.getEntityId(), o2.getEntityId() ); } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/UniqueSpatialLayout.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialLayoutUnique.java similarity index 77% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/UniqueSpatialLayout.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialLayoutUnique.java index 014f7f4428f0b..6f6981e1ee0f6 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/UniqueSpatialLayout.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialLayoutUnique.java @@ -17,19 +17,19 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema; import org.neo4j.index.internal.gbptree.Layout; /** * {@link Layout} for numbers where numbers need to be unique. */ -public class UniqueSpatialLayout extends SpatialLayout +public class SpatialLayoutUnique extends SpatialLayout { private static final String IDENTIFIER_NAME = "UNI"; - static final int MAJOR_VERSION = 0; - static final int MINOR_VERSION = 1; - static long IDENTIFIER = Layout.namedIdentifier( IDENTIFIER_NAME, SpatialSchemaValue.SIZE ); + public static final int MAJOR_VERSION = 0; + public static final int MINOR_VERSION = 1; + public static long IDENTIFIER = Layout.namedIdentifier( IDENTIFIER_NAME, NativeSchemaValue.SIZE ); @Override public long identifier() @@ -57,9 +57,9 @@ public int compare( SpatialSchemaKey o1, SpatialSchemaKey o2 ) if ( comparison == 0 ) { // This is a special case where we need also compare entityId to support inclusive/exclusive - if ( o1.entityIdIsSpecialTieBreaker || o2.entityIdIsSpecialTieBreaker ) + if ( o1.getEntityIdIsSpecialTieBreaker() || o2.getEntityIdIsSpecialTieBreaker() ) { - return Long.compare( o1.entityId, o2.entityId ); + return Long.compare( o1.getEntityId(), o2.getEntityId() ); } } return comparison; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialUniqueSchemaIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexAccessor.java similarity index 51% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialUniqueSchemaIndexPopulator.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexAccessor.java index f3275cd1de296..80abe2a95e19c 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialUniqueSchemaIndexPopulator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexAccessor.java @@ -17,43 +17,34 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema; import java.io.File; +import java.io.IOException; import org.neo4j.index.internal.gbptree.Layout; +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.IndexEntryUpdate; import org.neo4j.kernel.api.index.SchemaIndexProvider; import org.neo4j.kernel.api.schema.index.IndexDescriptor; -import org.neo4j.kernel.impl.api.index.sampling.UniqueIndexSampler; -import org.neo4j.storageengine.api.schema.IndexSample; +import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; +import org.neo4j.storageengine.api.schema.IndexReader; -/** - * {@link SpatialSchemaIndexPopulator} which can enforces unique values. - */ -class SpatialUniqueSchemaIndexPopulator - extends SpatialSchemaIndexPopulator +class SpatialSchemaIndexAccessor + extends NativeSchemaIndexAccessor { - private final UniqueIndexSampler sampler; - - SpatialUniqueSchemaIndexPopulator( PageCache pageCache, FileSystemAbstraction fs, File storeFile, Layout layout, - SchemaIndexProvider.Monitor monitor, IndexDescriptor descriptor, long indexId ) - { - super( pageCache, fs, storeFile, layout, monitor, descriptor, indexId ); - this.sampler = new UniqueIndexSampler(); - } - - @Override - public void includeSample( IndexEntryUpdate update ) + SpatialSchemaIndexAccessor( PageCache pageCache, FileSystemAbstraction fs, File storeFile, Layout layout, + RecoveryCleanupWorkCollector recoveryCleanupWorkCollector, SchemaIndexProvider.Monitor monitor, IndexDescriptor descriptor, long indexId, + IndexSamplingConfig samplingConfig ) throws IOException { - sampler.increment( 1 ); + super( pageCache, fs, storeFile, layout, recoveryCleanupWorkCollector, monitor, descriptor, indexId, samplingConfig ); } @Override - public IndexSample sampleResult() + public IndexReader newReader() { - return sampler.result(); + assertOpen(); + return new SpatialSchemaIndexReader<>( tree, layout, samplingConfig, descriptor ); } } 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 new file mode 100644 index 0000000000000..de0a592a5a24c --- /dev/null +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaIndexReader.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2002-2017 "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.util.Arrays; + +import org.neo4j.index.internal.gbptree.GBPTree; +import org.neo4j.index.internal.gbptree.Layout; +import org.neo4j.internal.kernel.api.IndexOrder; +import org.neo4j.internal.kernel.api.IndexQuery; +import org.neo4j.internal.kernel.api.IndexQuery.ExactPredicate; +import org.neo4j.internal.kernel.api.IndexQuery.GeometryRangePredicate; +import org.neo4j.kernel.api.exceptions.index.IndexNotApplicableKernelException; +import org.neo4j.kernel.api.schema.index.IndexDescriptor; +import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; +import org.neo4j.storageengine.api.schema.IndexProgressor; +import org.neo4j.values.storable.Value; +import org.neo4j.values.storable.ValueGroup; + +import static java.lang.String.format; + +public class SpatialSchemaIndexReader extends NativeSchemaIndexReader +{ + SpatialSchemaIndexReader( GBPTree tree, Layout layout, IndexSamplingConfig samplingConfig, IndexDescriptor descriptor ) + { + super( tree, layout, samplingConfig, descriptor ); + } + + @Override + void validateQuery( IndexOrder indexOrder, IndexQuery[] predicates ) + { + if ( predicates.length != 1 ) + { + throw new UnsupportedOperationException( "Spatial index doesn't handle composite queries" ); + } + + if ( indexOrder != IndexOrder.NONE ) + { + throw new UnsupportedOperationException( + format( "Tried to query index with unsupported order %s. Supported orders for query %s are %s.", indexOrder, Arrays.toString( predicates ), + IndexOrder.NONE ) ); + } + } + + @Override + void initializeRangeForQuery( KEY treeKeyFrom, KEY treeKeyTo, IndexQuery[] predicates ) + { + IndexQuery predicate = predicates[0]; + switch ( predicate.type() ) + { + case exists: + treeKeyFrom.initAsLowest(); + treeKeyTo.initAsHighest(); + break; + case exact: + ExactPredicate exactPredicate = (ExactPredicate) predicate; + treeKeyFrom.from( Long.MIN_VALUE, exactPredicate.value() ); + treeKeyTo.from( Long.MAX_VALUE, exactPredicate.value() ); + break; + case rangeGeometric: + GeometryRangePredicate rangePredicate = (GeometryRangePredicate) predicate; + initFromForRange( rangePredicate, treeKeyFrom ); + initToForRange( rangePredicate, treeKeyTo ); + break; + default: + throw new IllegalArgumentException( "IndexQuery of type " + predicate.type() + " is not supported." ); + } + } + + private void initToForRange( GeometryRangePredicate rangePredicate, KEY treeKeyTo ) + { + Value toValue = rangePredicate.toAsValue(); + if ( toValue.valueGroup() == ValueGroup.NO_VALUE ) + { + treeKeyTo.initAsHighest(); + } + else + { + treeKeyTo.from( rangePredicate.toInclusive() ? Long.MAX_VALUE : Long.MIN_VALUE, toValue ); + treeKeyTo.setEntityIdIsSpecialTieBreaker( true ); + } + } + + private void initFromForRange( GeometryRangePredicate rangePredicate, KEY treeKeyFrom ) + { + Value fromValue = rangePredicate.fromAsValue(); + if ( fromValue.valueGroup() == ValueGroup.NO_VALUE ) + { + treeKeyFrom.initAsLowest(); + } + else + { + treeKeyFrom.from( rangePredicate.fromInclusive() ? Long.MIN_VALUE : Long.MAX_VALUE, fromValue ); + treeKeyFrom.setEntityIdIsSpecialTieBreaker( true ); + } + } + + @Override + public boolean hasFullNumberPrecision( IndexQuery... predicates ) + { + return false; + } +} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaKey.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaKey.java similarity index 63% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaKey.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaKey.java index e47647c1d698b..2771492dfc33c 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaKey.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialSchemaKey.java @@ -17,9 +17,10 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema; + +import java.util.Arrays; -import org.neo4j.index.internal.gbptree.GBPTree; import org.neo4j.values.storable.CoordinateReferenceSystem; import org.neo4j.values.storable.NumberValue; import org.neo4j.values.storable.PointValue; @@ -33,7 +34,7 @@ * A value can be any {@link PointValue} and is represented as a {@code long} to store the 1D mapped version * and a type describing the geomtry type and number of dimensions. */ -class SpatialSchemaKey +class SpatialSchemaKey implements NativeSchemaKey { static final int SIZE = Byte.BYTES + /* type of value */ @@ -42,92 +43,116 @@ class SpatialSchemaKey // TODO this could use 6 bytes instead and have the highest 2 bits stored in the type byte Long.BYTES; /* entityId */ + private long entityId; + private boolean entityIdIsSpecialTieBreaker; + byte type; long rawValueBits; - public long entityId; - /** - * Marks that comparisons with this key requires also comparing entityId, this allows functionality - * of inclusive/exclusive bounds of range queries. - * This is because {@link GBPTree} only support from inclusive and to exclusive. - *

- * Note that {@code entityIdIsSpecialTieBreaker} is only an in memory state. - */ - boolean entityIdIsSpecialTieBreaker; + @Override + public void setEntityIdIsSpecialTieBreaker( boolean entityIdIsSpecialTieBreaker ) + { + this.entityIdIsSpecialTieBreaker = entityIdIsSpecialTieBreaker; + } + + @Override + public boolean getEntityIdIsSpecialTieBreaker() + { + return entityIdIsSpecialTieBreaker; + } + + @Override + public long getEntityId() + { + return entityId; + } - void from( long entityId, Value... values ) + @Override + public void setEntityId( long entityId ) { - writePoint( assertValidSingleGeometry( values ) ); this.entityId = entityId; - entityIdIsSpecialTieBreaker = false; } - private static PointValue assertValidSingleGeometry( Value... values ) + @Override + public void from( long entityId, Value... values ) { - // TODO: support multiple values, right? - if ( values.length > 1 ) - { - throw new IllegalArgumentException( "Tried to create composite key with non-composite schema key layout" ); - } - if ( values.length < 1 ) - { - throw new IllegalArgumentException( "Tried to create key without value" ); - } - if ( !Values.isGeometryValue( values[0] ) ) - { - throw new IllegalArgumentException( - "Key layout does only support geometries, tried to create key from " + values[0] ); - } - return (PointValue) values[0]; + extractRawBitsAndType( assertValidValue( values ) ); + this.entityId = entityId; + entityIdIsSpecialTieBreaker = false; } - String propertiesAsString() + @Override + public String propertiesAsString() { return asValue().toString(); } - NumberValue asValue() + @Override + public NumberValue asValue() { // throw new UnsupportedOperationException( "Cannot extract value from spatial index" ); return (NumberValue) Values.of( Double.longBitsToDouble( rawValueBits ) ); } - void initAsLowest() + @Override + public void initAsLowest() { - writePoint( Values.pointValue( CoordinateReferenceSystem.WGS84, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY ) ); + double[] limit = new double[2]; + Arrays.fill(limit, Double.NEGATIVE_INFINITY); + writePoint( CoordinateReferenceSystem.WGS84, limit ); entityId = Long.MIN_VALUE; entityIdIsSpecialTieBreaker = true; } - void initAsHighest() + @Override + public void initAsHighest() { - writePoint( Values.pointValue( CoordinateReferenceSystem.WGS84, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY ) ); + double[] limit = new double[2]; + Arrays.fill(limit, Double.POSITIVE_INFINITY); + writePoint( CoordinateReferenceSystem.WGS84, limit ); entityId = Long.MAX_VALUE; entityIdIsSpecialTieBreaker = true; } - /** - * Compares the value of this key to that of another key. - * This method is expected to be called in scenarios where inconsistent reads may happen (and later retried). - * - * @param other the {@link SpatialSchemaKey} to compare to. - * @return comparison against the {@code other} {@link SpatialSchemaKey}. - */ + // TODO this is incorrect! only adding to handle rebase int compareValueTo( SpatialSchemaKey other ) { - return Long.compare( rawValueBits, other.rawValueBits ); + return RawBits.compare( rawValueBits, type, other.rawValueBits, other.type ); + } + + private PointValue assertValidValue( Value... values ) + { + // TODO: support multiple values, right? + if ( values.length > 1 ) + { + throw new IllegalArgumentException( "Tried to create composite key with non-composite schema key layout" ); + } + if ( values.length < 1 ) + { + throw new IllegalArgumentException( "Tried to create key without value" ); + } + if ( !Values.isGeometryValue( values[0] ) ) + { + throw new IllegalArgumentException( + "Key layout does only support geometries, tried to create key from " + values[0] ); + } + return (PointValue) values[0]; + } + + // TODO this should change + private void extractRawBitsAndType( PointValue value ) + { + writePoint( value.getCoordinateReferenceSystem(), value.coordinate() ); } /** * Extracts raw bits and type from a {@link PointValue} and store as state of this {@link SpatialSchemaKey} instance. - * - * @param value actual {@link PointValue} value. */ - private void writePoint( PointValue value ) + private void writePoint( CoordinateReferenceSystem crs, double[] coordinate ) { //TODO: Support 2D to 1D mapper like space filling curves - type = (byte)value.coordinate().length; - rawValueBits = Double.doubleToLongBits( value.coordinate()[0] ); + type = (byte)coordinate.length; + rawValueBits = Double.doubleToLongBits( coordinate[0] ); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessor.java index 7f4585710a4ab..ae1b1e3e34fc9 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessor.java @@ -65,7 +65,7 @@ class FusionIndexAccessor implements IndexAccessor @Override public void drop() throws IOException { - forAll( ( accessor ) -> ((IndexAccessor) accessor).drop(), nativeAccessor, spatialAccessor, luceneAccessor ); + forAll( accessor -> ((IndexAccessor) accessor).drop(), nativeAccessor, spatialAccessor, luceneAccessor ); dropAction.drop( indexId ); } @@ -93,7 +93,7 @@ public void refresh() throws IOException @Override public void close() throws IOException { - forAll( ( accessor ) -> ((IndexAccessor) accessor).close(), nativeAccessor, spatialAccessor, luceneAccessor ); + forAll( accessor -> ((IndexAccessor) accessor).close(), nativeAccessor, spatialAccessor, luceneAccessor ); } @Override @@ -123,7 +123,7 @@ public long maxCount() @Override public void close() throws Exception { - forAll( ( entries ) -> ((BoundedIterable) entries).close(), nativeAllEntries, spatialAllEntries, luceneAllEntries ); + forAll( entries -> ((BoundedIterable) entries).close(), nativeAllEntries, spatialAllEntries, luceneAllEntries ); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulator.java index 1986e01852430..d683b69d7cac7 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulator.java @@ -66,7 +66,7 @@ public void create() throws IOException @Override public void drop() throws IOException { - forAll( ( entries ) -> ((IndexPopulator) entries).drop(), nativePopulator, spatialPopulator, lucenePopulator ); + forAll( entries -> ((IndexPopulator) entries).drop(), nativePopulator, spatialPopulator, lucenePopulator ); dropAction.drop( indexId ); } @@ -106,13 +106,13 @@ public IndexUpdater newPopulatingUpdater( PropertyAccessor accessor ) throws IOE @Override public void close( boolean populationCompletedSuccessfully ) throws IOException { - forAll( ( entries ) -> ((IndexPopulator) entries).close( populationCompletedSuccessfully ), nativePopulator, spatialPopulator, lucenePopulator ); + forAll( entries -> ((IndexPopulator) entries).close( populationCompletedSuccessfully ), nativePopulator, spatialPopulator, lucenePopulator ); } @Override public void markAsFailed( String failure ) throws IOException { - forAll( ( entries ) -> ((IndexPopulator) entries).markAsFailed( failure ), nativePopulator, spatialPopulator, lucenePopulator ); + forAll( entries -> ((IndexPopulator) entries).markAsFailed( failure ), nativePopulator, spatialPopulator, lucenePopulator ); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReader.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReader.java index ebdbc9c60480b..360902edb3238 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReader.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReader.java @@ -27,8 +27,8 @@ import org.neo4j.internal.kernel.api.IndexQuery; import org.neo4j.internal.kernel.api.IndexQuery.ExactPredicate; import org.neo4j.internal.kernel.api.IndexQuery.ExistsPredicate; -import org.neo4j.internal.kernel.api.IndexQuery.NumberRangePredicate; import org.neo4j.internal.kernel.api.IndexQuery.GeometryRangePredicate; +import org.neo4j.internal.kernel.api.IndexQuery.NumberRangePredicate; import org.neo4j.kernel.api.exceptions.index.IndexNotApplicableKernelException; import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.impl.api.schema.BridgingIndexProgressor; @@ -62,7 +62,7 @@ class FusionIndexReader implements IndexReader @Override public void close() { - forAll( ( reader ) -> ((IndexReader) reader).close(), nativeReader, spatialReader, luceneReader ); + forAll( reader -> ((IndexReader) reader).close(), nativeReader, spatialReader, luceneReader ); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdater.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdater.java index f751559331ea6..95c6d6900d558 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdater.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdater.java @@ -83,6 +83,6 @@ public void process( IndexEntryUpdate update ) throws IOException, IndexEntry @Override public void close() throws IOException, IndexEntryConflictException { - forAll( ( updater ) -> ((IndexUpdater) updater).close(), nativeUpdater, spatialUpdater, luceneUpdater ); + forAll( updater -> ((IndexUpdater) updater).close(), nativeUpdater, spatialUpdater, luceneUpdater ); } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProvider.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProvider.java index 06f71cc5eaab5..06466b0b3ac4d 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProvider.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProvider.java @@ -176,7 +176,7 @@ public static IndexSample combineSamples( IndexSample... samples ) long indexSize = Arrays.stream(samples).mapToLong( IndexSample::indexSize ).sum(); long uniqueValues = Arrays.stream(samples).mapToLong( IndexSample::uniqueValues ).sum(); long sampleSize = Arrays.stream(samples).mapToLong( IndexSample::sampleSize ).sum(); - return new IndexSample(indexSize, uniqueValues, sampleSize); + return new IndexSample( indexSize, uniqueValues, sampleSize ); } /** diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexAccessor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexAccessor.java similarity index 78% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexAccessor.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexAccessor.java index 98d4ade8d5749..a256a04b11769 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexAccessor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexAccessor.java @@ -17,7 +17,7 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema.fusion; import java.io.File; import java.io.IOException; @@ -26,7 +26,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import org.neo4j.graphdb.ResourceIterator; import org.neo4j.helpers.collection.BoundedIterable; @@ -38,6 +37,7 @@ import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.impl.api.index.IndexUpdateMode; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; +import org.neo4j.kernel.impl.index.schema.SpatialKnownIndex; import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.values.storable.CoordinateReferenceSystem; @@ -46,14 +46,15 @@ class SpatialFusionIndexAccessor implements IndexAccessor { - private final Map indexMap; + private final Map indexMap; private final long indexId; private final IndexDescriptor descriptor; private final IndexSamplingConfig samplingConfig; - private final KnownSpatialIndex.Factory indexFactory; + private final SpatialKnownIndex.Factory indexFactory; - SpatialFusionIndexAccessor( Map indexMap, long indexId, IndexDescriptor descriptor, - IndexSamplingConfig samplingConfig, KnownSpatialIndex.Factory indexFactory ) { + SpatialFusionIndexAccessor( Map indexMap, long indexId, IndexDescriptor descriptor, + IndexSamplingConfig samplingConfig, SpatialKnownIndex.Factory indexFactory ) + { this.indexMap = indexMap; this.indexId = indexId; this.descriptor = descriptor; @@ -64,7 +65,7 @@ class SpatialFusionIndexAccessor implements IndexAccessor @Override public void drop() throws IOException { - forAll( ( index ) -> ((KnownSpatialIndex) index).getOnlineAccessor( descriptor, samplingConfig ).drop(), indexMap.values().toArray() ); + forAll( index -> ((SpatialKnownIndex) index).getOnlineAccessor( descriptor, samplingConfig ).drop(), indexMap.values().toArray() ); } @Override @@ -76,26 +77,26 @@ public IndexUpdater newUpdater( IndexUpdateMode mode ) @Override public void force() throws IOException { - forAll( ( entry ) -> ((KnownSpatialIndex) entry).getOnlineAccessor( descriptor, samplingConfig ).force(), indexMap.values().toArray() ); + forAll( entry -> ((SpatialKnownIndex) entry).getOnlineAccessor( descriptor, samplingConfig ).force(), indexMap.values().toArray() ); } @Override public void refresh() throws IOException { - forAll( ( entry ) -> ((KnownSpatialIndex) entry).getOnlineAccessor( descriptor, samplingConfig ).refresh(), indexMap.values().toArray() ); + forAll( entry -> ((SpatialKnownIndex) entry).getOnlineAccessor( descriptor, samplingConfig ).refresh(), indexMap.values().toArray() ); } @Override public void close() throws IOException { - forAll( ( entry ) -> ((KnownSpatialIndex) entry).getOnlineAccessor( descriptor, samplingConfig ).close(), indexMap.values().toArray() ); + forAll( entry -> ((SpatialKnownIndex) entry).getOnlineAccessor( descriptor, samplingConfig ).close(), indexMap.values().toArray() ); } @Override public IndexReader newReader() { Map indexReaders = new HashMap<>(); - for ( Map.Entry index : indexMap.entrySet() ) + for ( Map.Entry index : indexMap.entrySet() ) { try { @@ -106,14 +107,14 @@ public IndexReader newReader() e.printStackTrace(); } } - return new SpatialFusionIndexReader( indexReaders, descriptor.schema().getPropertyIds() ); + return new SpatialFusionIndexReader( indexReaders, descriptor ); } @Override public BoundedIterable newAllEntriesReader() { ArrayList> allEntriesReader = new ArrayList<>(); - for ( KnownSpatialIndex index : indexMap.values() ) + for ( SpatialKnownIndex index : indexMap.values() ) { try { @@ -142,7 +143,7 @@ public long maxCount() @Override public void close() throws Exception { - forAll( ( entries ) -> ((BoundedIterable) entries).close(), allEntriesReader ); + forAll( entries -> ((BoundedIterable) entries).close(), allEntriesReader ); } @Override @@ -157,7 +158,7 @@ public Iterator iterator() public ResourceIterator snapshotFiles() throws IOException { List> snapshotFiles = new ArrayList<>(); - for ( KnownSpatialIndex index : indexMap.values() ) + for ( SpatialKnownIndex index : indexMap.values() ) { snapshotFiles.add( index.getOnlineAccessor( descriptor, samplingConfig ).snapshotFiles() ); } @@ -168,7 +169,7 @@ public ResourceIterator snapshotFiles() throws IOException public void verifyDeferredConstraints( PropertyAccessor propertyAccessor ) throws IndexEntryConflictException, IOException { - for ( KnownSpatialIndex index : indexMap.values() ) + for ( SpatialKnownIndex index : indexMap.values() ) { index.getOnlineAccessor( descriptor, samplingConfig ).verifyDeferredConstraints( propertyAccessor ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexPopulator.java similarity index 80% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexPopulator.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexPopulator.java index 46c8a360c9f72..d8df4a33a147e 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexPopulator.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexPopulator.java @@ -17,7 +17,7 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema.fusion; import java.io.IOException; import java.util.ArrayList; @@ -32,6 +32,7 @@ import org.neo4j.kernel.api.index.PropertyAccessor; import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; +import org.neo4j.kernel.impl.index.schema.SpatialKnownIndex; import org.neo4j.storageengine.api.schema.IndexSample; import org.neo4j.values.storable.CoordinateReferenceSystem; import org.neo4j.values.storable.PointValue; @@ -45,11 +46,11 @@ class SpatialFusionIndexPopulator implements IndexPopulator private final long indexId; private final IndexDescriptor descriptor; private final IndexSamplingConfig samplingConfig; - private final KnownSpatialIndex.Factory indexFactory; - private final Map indexMap; + private final SpatialKnownIndex.Factory indexFactory; + private final Map indexMap; - SpatialFusionIndexPopulator( Map indexMap, long indexId, IndexDescriptor descriptor, - IndexSamplingConfig samplingConfig, KnownSpatialIndex.Factory indexFactory ) + SpatialFusionIndexPopulator( Map indexMap, long indexId, IndexDescriptor descriptor, + IndexSamplingConfig samplingConfig, SpatialKnownIndex.Factory indexFactory ) { this.indexMap = indexMap; this.indexId = indexId; @@ -69,14 +70,14 @@ public void create() throws IOException @Override public void drop() throws IOException { - forAll( ( entry ) -> ((KnownSpatialIndex) entry).getPopulator( descriptor, samplingConfig ).drop(), indexMap.values().toArray() ); + forAll( entry -> ((SpatialKnownIndex) entry).getPopulator( descriptor, samplingConfig ).drop(), indexMap.values().toArray() ); } @Override public void add( Collection> updates ) throws IndexEntryConflictException, IOException { Map>> batchMap = new HashMap<>(); - for ( Map.Entry index : indexMap.entrySet() ) + for ( Map.Entry index : indexMap.entrySet() ) { batchMap.put( index.getKey(), new ArrayList<>() ); } @@ -92,7 +93,7 @@ public void add( Collection> updates ) throws Inde private Collection> selectUpdates( Map>> instances, Value... values ) { - assert (values.length == 1); + assert values.length == 1; PointValue pointValue = (PointValue) values[0]; return instances.computeIfAbsent( pointValue.getCoordinateReferenceSystem(), k -> new ArrayList<>() ); } @@ -101,7 +102,7 @@ private Collection> selectUpdates( Map ((KnownSpatialIndex) entry).getPopulator( descriptor, samplingConfig ).verifyDeferredConstraints( propertyAccessor ), + forAll( entry -> ((SpatialKnownIndex) entry).getPopulator( descriptor, samplingConfig ).verifyDeferredConstraints( propertyAccessor ), indexMap.values().toArray() ); } @@ -114,13 +115,14 @@ public IndexUpdater newPopulatingUpdater( PropertyAccessor accessor ) throws IOE @Override public void close( boolean populationCompletedSuccessfully ) throws IOException { - forAll( ( entry ) -> ((KnownSpatialIndex) entry).closePopulator( descriptor, samplingConfig, populationCompletedSuccessfully ), indexMap.values().toArray() ); + forAll( entry -> ((SpatialKnownIndex) entry).closePopulator( descriptor, samplingConfig, populationCompletedSuccessfully ), + indexMap.values().toArray() ); } @Override public void markAsFailed( String failure ) throws IOException { - forAll( ( entry ) -> ((KnownSpatialIndex) entry).getPopulator( descriptor, samplingConfig ).markAsFailed( failure ), indexMap.values().toArray() ); + forAll( entry -> ((SpatialKnownIndex) entry).getPopulator( descriptor, samplingConfig ).markAsFailed( failure ), indexMap.values().toArray() ); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexReader.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexReader.java similarity index 80% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexReader.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexReader.java index afbf534601e8f..e44f08d044045 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexReader.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexReader.java @@ -17,7 +17,7 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema.fusion; import java.util.Map; @@ -28,8 +28,9 @@ import org.neo4j.internal.kernel.api.IndexQuery.ExistsPredicate; import org.neo4j.internal.kernel.api.IndexQuery.GeometryRangePredicate; import org.neo4j.kernel.api.exceptions.index.IndexNotApplicableKernelException; +import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.impl.index.schema.NodeValueIterator; -import org.neo4j.kernel.impl.index.schema.fusion.BridgingIndexProgressor; +import org.neo4j.kernel.impl.index.schema.SpatialSchemaIndexReader; import org.neo4j.storageengine.api.schema.IndexProgressor; import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.storageengine.api.schema.IndexSampler; @@ -42,17 +43,17 @@ class SpatialFusionIndexReader implements IndexReader { private final Map readerMap; - private final int[] propertyKeys; + private final IndexDescriptor descriptor; - SpatialFusionIndexReader( Map readerMap, int[] propertyKeys ) + SpatialFusionIndexReader( Map readerMap, IndexDescriptor descriptor ) { this.readerMap = readerMap; - this.propertyKeys = propertyKeys; + this.descriptor = descriptor; } private T select( Map instances, Value... values ) { - assert(values.length == 1); + assert values.length == 1; PointValue pointValue = (PointValue) values[0]; return instances.get( pointValue.getCoordinateReferenceSystem() ); } @@ -60,22 +61,22 @@ private T select( Map instances, Value... value @Override public void close() { - forAll( ( reader ) -> ((IndexReader) reader).close(), readerMap.values().toArray() ); + forAll( reader -> ((IndexReader) reader).close(), readerMap.values().toArray() ); } @Override public long countIndexedNodes( long nodeId, Value... propertyValues ) { - Long ans = selectAndRun( ( reader ) -> reader.countIndexedNodes( nodeId, propertyValues ), propertyValues ); + Long ans = selectAndRun( reader -> reader.countIndexedNodes( nodeId, propertyValues ), propertyValues ); return ans == null ? 0L : ans; } interface ActionableWithResult { - R doIt(IndexReader reader); + R doIt( IndexReader reader ); } - private R selectAndRun(ActionableWithResult actionable, Value... values) + private R selectAndRun( ActionableWithResult actionable, Value... values ) { IndexReader reader = select( readerMap, values ); if ( reader != null ) @@ -99,8 +100,7 @@ public PrimitiveLongResourceIterator query( IndexQuery... predicates ) throws In return nodeValueIterator; } - private IndexReader selectIf(IndexQuery... predicates) - throws IndexNotApplicableKernelException + private IndexReader selectIf( IndexQuery... predicates ) throws IndexNotApplicableKernelException { if ( predicates[0] instanceof ExactPredicate ) { @@ -114,15 +114,13 @@ else if ( predicates[0] instanceof GeometryRangePredicate ) } @Override - public void query( IndexProgressor.NodeValueClient cursor, IndexOrder indexOrder, IndexQuery... predicates ) - throws IndexNotApplicableKernelException + public void query( IndexProgressor.NodeValueClient cursor, IndexOrder indexOrder, IndexQuery... predicates ) throws IndexNotApplicableKernelException { - SpatialSchemaIndexReader.validateQuery( indexOrder, predicates ); if ( predicates[0] instanceof ExistsPredicate ) { - BridgingIndexProgressor multiProgressor = new BridgingIndexProgressor( cursor, propertyKeys ); - cursor.initialize( multiProgressor, propertyKeys ); - for (IndexReader reader : readerMap.values()) + BridgingIndexProgressor multiProgressor = new BridgingIndexProgressor( cursor, descriptor.schema().getPropertyIds() ); + cursor.initialize( descriptor, multiProgressor, predicates ); + for ( IndexReader reader : readerMap.values() ) { reader.query( multiProgressor, indexOrder, predicates[0] ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexSampler.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexSampler.java similarity index 96% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexSampler.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexSampler.java index 288c3a1c06edd..3bb08b2f177b9 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexSampler.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexSampler.java @@ -17,7 +17,7 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema.fusion; import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; import org.neo4j.storageengine.api.schema.IndexSample; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexUpdater.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexUpdater.java similarity index 78% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexUpdater.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexUpdater.java index fc1c23f95d953..13647c6f4eb59 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFusionIndexUpdater.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionIndexUpdater.java @@ -17,7 +17,7 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema.fusion; import java.io.IOException; import java.util.HashMap; @@ -30,22 +30,23 @@ import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.impl.api.index.IndexUpdateMode; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; +import org.neo4j.kernel.impl.index.schema.SpatialKnownIndex; import org.neo4j.values.storable.CoordinateReferenceSystem; import org.neo4j.values.storable.PointValue; import org.neo4j.values.storable.Value; class SpatialFusionIndexUpdater implements IndexUpdater { - private final Map indexMap; - private final Map currentUpdaters = new HashMap<>(); + private final Map indexMap; + private final Map currentUpdaters = new HashMap<>(); private final long indexId; - private final KnownSpatialIndex.Factory indexFactory; + private final SpatialKnownIndex.Factory indexFactory; private final IndexDescriptor descriptor; private final IndexSamplingConfig samplingConfig; private final IndexUpdateMode mode; private final PropertyAccessor accessor; - SpatialFusionIndexUpdater( Map indexMap, long indexId, KnownSpatialIndex.Factory indexFactory, + SpatialFusionIndexUpdater( Map indexMap, long indexId, SpatialKnownIndex.Factory indexFactory, IndexDescriptor descriptor, IndexSamplingConfig samplingConfig, IndexUpdateMode mode ) { this.indexMap = indexMap; @@ -57,7 +58,7 @@ class SpatialFusionIndexUpdater implements IndexUpdater this.accessor = null; } - SpatialFusionIndexUpdater( Map indexMap, long indexId, KnownSpatialIndex.Factory indexFactory, + SpatialFusionIndexUpdater( Map indexMap, long indexId, SpatialKnownIndex.Factory indexFactory, IndexDescriptor descriptor, IndexSamplingConfig samplingConfig, PropertyAccessor accessor ) { this.indexMap = indexMap; @@ -91,10 +92,8 @@ public void process( IndexEntryUpdate update ) throws IOException, IndexEntry // - before go into one and after into the other --> REMOVED from one and ADDED into the other else { - from.process( IndexEntryUpdate.remove( - update.getEntityId(), update.indexKey(), update.beforeValues() ) ); - to.process( IndexEntryUpdate.add( - update.getEntityId(), update.indexKey(), update.values() ) ); + from.process( IndexEntryUpdate.remove( update.getEntityId(), update.indexKey(), update.beforeValues() ) ); + to.process( IndexEntryUpdate.add( update.getEntityId(), update.indexKey(), update.values() ) ); } break; case REMOVED: @@ -105,20 +104,19 @@ public void process( IndexEntryUpdate update ) throws IOException, IndexEntry } } - private IndexUpdater selectUpdater(Value... values) throws IOException + private IndexUpdater selectUpdater( Value... values ) throws IOException { - assert (values.length == 1); + assert values.length == 1; PointValue pointValue = (PointValue) values[0]; CoordinateReferenceSystem crs = pointValue.getCoordinateReferenceSystem(); IndexUpdater updater = currentUpdaters.get( crs ); - if (updater != null) + if ( updater != null ) { return updater; } if ( mode != null ) { - return remember( crs, - indexFactory.selectAndCreate( indexMap, indexId, crs ).getOnlineAccessor( descriptor, samplingConfig ).newUpdater( mode ) ); + return remember( crs, indexFactory.selectAndCreate( indexMap, indexId, crs ).getOnlineAccessor( descriptor, samplingConfig ).newUpdater( mode ) ); } else { @@ -127,9 +125,9 @@ private IndexUpdater selectUpdater(Value... values) throws IOException } } - private IndexUpdater remember(CoordinateReferenceSystem crs, IndexUpdater indexUpdader) + private IndexUpdater remember( CoordinateReferenceSystem crs, IndexUpdater indexUpdader ) { - currentUpdaters.put(crs, indexUpdader ); + currentUpdaters.put( crs, indexUpdader ); return indexUpdader; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexProvider.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionSchemaIndexProvider.java similarity index 83% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexProvider.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionSchemaIndexProvider.java index 4583fb711d1ab..14faf000b95b6 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexProvider.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/SpatialFusionSchemaIndexProvider.java @@ -17,7 +17,7 @@ * 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.spatial; +package org.neo4j.kernel.impl.index.schema.fusion; import java.io.File; import java.io.IOException; @@ -30,15 +30,18 @@ import org.neo4j.index.internal.gbptree.Layout; import org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector; import org.neo4j.internal.kernel.api.IndexCapability; +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.IndexAccessor; import org.neo4j.kernel.api.index.IndexDirectoryStructure; import org.neo4j.kernel.api.index.IndexPopulator; -import org.neo4j.kernel.api.index.InternalIndexState; import org.neo4j.kernel.api.index.SchemaIndexProvider; import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; +import org.neo4j.kernel.impl.index.schema.SpatialKnownIndex; +import org.neo4j.kernel.impl.index.schema.SpatialLayoutNonUnique; +import org.neo4j.kernel.impl.index.schema.SpatialLayoutUnique; import org.neo4j.kernel.impl.storemigration.StoreMigrationParticipant; import org.neo4j.values.storable.CoordinateReferenceSystem; import org.neo4j.values.storable.PointValue; @@ -47,7 +50,7 @@ /** * Schema index provider for native indexes backed by e.g. {@link GBPTree}. */ -public class SpatialSchemaIndexProvider extends SchemaIndexProvider implements KnownSpatialIndex.Factory +public class SpatialFusionSchemaIndexProvider extends SchemaIndexProvider implements SpatialKnownIndex.Factory { public static final String KEY = "spatial"; public static final Descriptor SPATIAL_PROVIDER_DESCRIPTOR = new Descriptor( KEY, "1.0" ); @@ -58,9 +61,9 @@ public class SpatialSchemaIndexProvider extends SchemaIndexProvider implements K private final RecoveryCleanupWorkCollector recoveryCleanupWorkCollector; private final boolean readOnly; - private Map> indexes = new HashMap<>(); + private Map> indexes = new HashMap<>(); - public SpatialSchemaIndexProvider( PageCache pageCache, FileSystemAbstraction fs, IndexDirectoryStructure.Factory directoryStructure, Monitor monitor, + public SpatialFusionSchemaIndexProvider( PageCache pageCache, FileSystemAbstraction fs, IndexDirectoryStructure.Factory directoryStructure, Monitor monitor, RecoveryCleanupWorkCollector recoveryCleanupWorkCollector, boolean readOnly ) { super( SPATIAL_PROVIDER_DESCRIPTOR, 0, directoryStructure ); @@ -88,7 +91,7 @@ public IndexAccessor getOnlineAccessor( long indexId, IndexDescriptor descriptor return new SpatialFusionIndexAccessor( indexesFor( indexId ), indexId, descriptor, samplingConfig, this ); } - private Map indexesFor( long indexId ) + private Map indexesFor( long indexId ) { return indexes.computeIfAbsent( indexId, k -> new HashMap<>() ); } @@ -100,7 +103,7 @@ public String getPopulationFailure( long indexId ) throws IllegalStateException { // This assumes a previous call to getInitialState returned that at least one index was failed // We find the first failed index failure message - for ( KnownSpatialIndex index : indexesFor( indexId ).values() ) + for ( SpatialKnownIndex index : indexesFor( indexId ).values() ) { String indexFailure = index.readPopupationFailure(); if ( indexFailure != null ) @@ -126,7 +129,7 @@ public InternalIndexState getInitialState( long indexId, IndexDescriptor descrip { return InternalIndexState.ONLINE; } - for ( KnownSpatialIndex index : indexes.get( indexId ).values() ) + for ( SpatialKnownIndex index : indexes.get( indexId ).values() ) { if ( index.indexExists() ) { @@ -138,6 +141,7 @@ public InternalIndexState getInitialState( long indexId, IndexDescriptor descrip return InternalIndexState.FAILED; case POPULATING: state = InternalIndexState.POPULATING; + default: } } catch ( IOException e ) @@ -166,19 +170,19 @@ public StoreMigrationParticipant storeMigrationParticipant( FileSystemAbstractio } @Override - public KnownSpatialIndex selectAndCreate( Map indexMap, long indexId, Value... values ) + public SpatialKnownIndex selectAndCreate( Map indexMap, long indexId, Value... values ) { - assert (values.length == 1); + assert values.length == 1; PointValue pointValue = (PointValue) values[0]; CoordinateReferenceSystem crs = pointValue.getCoordinateReferenceSystem(); return selectAndCreate( indexMap, indexId, crs ); } @Override - public KnownSpatialIndex selectAndCreate( Map indexMap, long indexId, CoordinateReferenceSystem crs ) + public SpatialKnownIndex selectAndCreate( Map indexMap, long indexId, CoordinateReferenceSystem crs ) { return indexMap.computeIfAbsent( crs, - k -> new KnownSpatialIndex( directoryStructure(), crs, indexId, pageCache, fs, monitor, recoveryCleanupWorkCollector ) ); + k -> new SpatialKnownIndex( directoryStructure(), crs, indexId, pageCache, fs, monitor, recoveryCleanupWorkCollector ) ); } private void findAndCreateKnownSpatialIndexes() @@ -203,7 +207,7 @@ private void findAndCreateKnownSpatialIndexes() int tableId = Integer.parseInt( m.group( 1 ) ); int code = Integer.parseInt( m.group( 2 ) ); CoordinateReferenceSystem crs = CoordinateReferenceSystem.get( tableId, code ); - KnownSpatialIndex index = selectAndCreate( indexesFor( indexId ), indexId, crs ); + SpatialKnownIndex index = selectAndCreate( indexesFor( indexId ), indexId, crs ); if ( index.indexExists() ) { System.out.println( "Created " + index + " crs: " + crs.getName()); @@ -235,15 +239,15 @@ private void findAndCreateKnownSpatialIndexes() } } - static class ReadOnlyMetaNumberLayout extends Layout.ReadOnlyMetaLayout + public static class ReadOnlyMetaNumberLayout extends Layout.ReadOnlyMetaLayout { @Override public boolean compatibleWith( long layoutIdentifier, int majorVersion, int minorVersion ) { - return (layoutIdentifier == UniqueSpatialLayout.IDENTIFIER && majorVersion == UniqueSpatialLayout.MAJOR_VERSION && - minorVersion == UniqueSpatialLayout.MINOR_VERSION) || - (layoutIdentifier == NonUniqueSpatialLayout.IDENTIFIER && majorVersion == NonUniqueSpatialLayout.MAJOR_VERSION && - minorVersion == NonUniqueSpatialLayout.MINOR_VERSION); + return (layoutIdentifier == SpatialLayoutUnique.IDENTIFIER && majorVersion == SpatialLayoutUnique.MAJOR_VERSION && + minorVersion == SpatialLayoutUnique.MINOR_VERSION) || + (layoutIdentifier == SpatialLayoutNonUnique.IDENTIFIER && majorVersion == SpatialLayoutNonUnique.MAJOR_VERSION && + minorVersion == SpatialLayoutNonUnique.MINOR_VERSION); } } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/ConflictDetectingPointValueMerger.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/ConflictDetectingPointValueMerger.java deleted file mode 100644 index 13b3a0c18652d..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/ConflictDetectingPointValueMerger.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import org.neo4j.index.internal.gbptree.ValueMerger; -import org.neo4j.index.internal.gbptree.Writer; - -/** - * {@link ValueMerger} which will merely detect conflict, not change any value if conflict, i.e. if the - * key already exists. After this merge has been used in a call to {@link Writer#merge(Object, Object, ValueMerger)} - * the {@link #wasConflict()} accessor can be called to check whether or not that call conflicted with - * an existing key. A call to {@link #wasConflict()} will also clear the conflict flag. - * - * @param type of values being merged. - */ -class ConflictDetectingPointValueMerger implements ValueMerger -{ - private boolean conflict; - private long existingNodeId; - private long addedNodeId; - - @Override - public VALUE merge( KEY existingKey, KEY newKey, VALUE existingValue, VALUE newValue ) - { - if ( existingKey.entityId != newKey.entityId ) - { - conflict = true; - existingNodeId = existingKey.entityId; - addedNodeId = newKey.entityId; - } - return null; - } - - /** - * @return whether or not merge conflicted with an existing key. This call also clears the conflict flag. - */ - boolean wasConflict() - { - boolean result = conflict; - if ( conflict ) - { - conflict = false; - } - return result; - } - - long existingNodeId() - { - return existingNodeId; - } - - long addedNodeId() - { - return addedNodeId; - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialAllEntriesReader.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialAllEntriesReader.java deleted file mode 100644 index 450394b788cdb..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialAllEntriesReader.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Iterator; - -import org.neo4j.cursor.RawCursor; -import org.neo4j.helpers.collection.BoundedIterable; -import org.neo4j.helpers.collection.PrefetchingIterator; -import org.neo4j.index.internal.gbptree.GBPTree; -import org.neo4j.index.internal.gbptree.Hit; -import org.neo4j.index.internal.gbptree.Layout; - -public class SpatialAllEntriesReader implements BoundedIterable -{ - private final GBPTree tree; - private final Layout layout; - private RawCursor,IOException> seeker; - - SpatialAllEntriesReader( GBPTree tree, Layout layout ) - { - this.tree = tree; - this.layout = layout; - } - - @Override - public Iterator iterator() - { - KEY from = layout.newKey(); - from.initAsLowest(); - KEY to = layout.newKey(); - to.initAsHighest(); - try - { - closeSeeker(); - seeker = tree.seek( from, to ); - return new PrefetchingIterator() - { - @Override - protected Long fetchNextOrNull() - { - try - { - return seeker.next() ? seeker.get().key().entityId : null; - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - } - }; - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - } - - private void closeSeeker() throws IOException - { - if ( seeker != null ) - { - seeker.close(); - seeker = null; - } - } - - @Override - public void close() throws Exception - { - closeSeeker(); - } - - @Override - public long maxCount() - { - return UNKNOWN_MAX_COUNT; - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFullScanNonUniqueIndexSampler.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFullScanNonUniqueIndexSampler.java deleted file mode 100644 index 19fb6db3e66c3..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialFullScanNonUniqueIndexSampler.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import java.io.IOException; -import java.io.UncheckedIOException; - -import org.neo4j.cursor.RawCursor; -import org.neo4j.index.internal.gbptree.GBPTree; -import org.neo4j.index.internal.gbptree.Hit; -import org.neo4j.index.internal.gbptree.Layout; -import org.neo4j.kernel.impl.api.index.sampling.DefaultNonUniqueIndexSampler; -import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; -import org.neo4j.kernel.impl.api.index.sampling.NonUniqueIndexSampler; -import org.neo4j.storageengine.api.schema.IndexSample; - -/** - * {@link NonUniqueIndexSampler} which performs a full scans of a {@link GBPTree} in {@link #result()}. - * - * @param type of keys in tree. - * @param type of values in tree. - */ -class SpatialFullScanNonUniqueIndexSampler - extends NonUniqueIndexSampler.Adapter -{ - private final GBPTree gbpTree; - private final Layout layout; - private final IndexSamplingConfig samplingConfig; - - SpatialFullScanNonUniqueIndexSampler( GBPTree gbpTree, Layout layout, IndexSamplingConfig samplingConfig ) - { - this.gbpTree = gbpTree; - this.layout = layout; - this.samplingConfig = samplingConfig; - } - - @Override - public IndexSample result() - { - KEY lowest = layout.newKey(); - lowest.initAsLowest(); - KEY highest = layout.newKey(); - highest.initAsHighest(); - try ( RawCursor,IOException> seek = gbpTree.seek( lowest, highest ) ) - { - NonUniqueIndexSampler sampler = new DefaultNonUniqueIndexSampler( samplingConfig.sampleSizeLimit() ); - while ( seek.next() ) - { - Hit hit = seek.get(); - sampler.include( hit.key().propertiesAsString() ); - } - return sampler.result(); - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - } - - @Override - public IndexSample result( int numDocs ) - { - throw new UnsupportedOperationException(); - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialHitIndexProgressor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialHitIndexProgressor.java deleted file mode 100644 index e3c46bfd0bb4c..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialHitIndexProgressor.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Collection; - -import org.neo4j.cursor.RawCursor; -import org.neo4j.index.internal.gbptree.Hit; -import org.neo4j.storageengine.api.schema.IndexProgressor; - -public class SpatialHitIndexProgressor implements IndexProgressor -{ - private final RawCursor,IOException> seeker; - private final NodeValueClient client; - private final Collection,IOException>> toRemoveFromOnClose; - private boolean closed; - - public SpatialHitIndexProgressor( RawCursor,IOException> seeker, NodeValueClient client, - Collection,IOException>> toRemoveFromOnClose ) - { - this.seeker = seeker; - this.client = client; - this.toRemoveFromOnClose = toRemoveFromOnClose; - } - - @Override - public boolean next() - { - try - { - if ( seeker.next() ) - { - KEY key = seeker.get().key(); - client.acceptNode( key.entityId, key.asValue() ); - return true; - } - return false; - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - } - - @Override - public void close() - { - if ( !closed ) - { - closed = true; - try - { - seeker.close(); - toRemoveFromOnClose.remove( seeker ); - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - } - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialNonUniqueSchemaIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialNonUniqueSchemaIndexPopulator.java deleted file mode 100644 index 88088c3bb33a7..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialNonUniqueSchemaIndexPopulator.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; - -import org.neo4j.index.internal.gbptree.Layout; -import org.neo4j.io.fs.FileSystemAbstraction; -import org.neo4j.io.pagecache.PageCache; -import org.neo4j.kernel.api.index.IndexEntryUpdate; -import org.neo4j.kernel.api.index.SchemaIndexProvider; -import org.neo4j.kernel.api.schema.index.IndexDescriptor; -import org.neo4j.kernel.impl.api.index.sampling.DefaultNonUniqueIndexSampler; -import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; -import org.neo4j.kernel.impl.api.index.sampling.NonUniqueIndexSampler; -import org.neo4j.kernel.impl.index.schema.SamplingUtil; -import org.neo4j.storageengine.api.schema.IndexSample; - -/** - * {@link SpatialSchemaIndexPopulator} which can accept duplicate values (for different entity ids). - */ -class SpatialNonUniqueSchemaIndexPopulator - extends SpatialSchemaIndexPopulator -{ - private NonUniqueIndexSampler sampler; - - SpatialNonUniqueSchemaIndexPopulator( PageCache pageCache, FileSystemAbstraction fs, File storeFile, Layout layout, - IndexSamplingConfig samplingConfig, SchemaIndexProvider.Monitor monitor, IndexDescriptor descriptor, long indexId ) - { - super( pageCache, fs, storeFile, layout, monitor, descriptor, indexId ); - this.sampler = new DefaultNonUniqueIndexSampler( samplingConfig.sampleSizeLimit() ); - } - - @Override - public void includeSample( IndexEntryUpdate update ) - { - sampler.include( SamplingUtil.encodedStringValuesForSampling( (Object[]) update.values() ) ); - } - - @Override - public IndexSample sampleResult() - { - // Close the writer before scanning - try - { - closeWriter(); - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - - try - { - return sampler.result(); - } - finally - { - try - { - instantiateWriter(); - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - } - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndex.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndex.java deleted file mode 100644 index 0ef8f278cefa7..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndex.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.util.function.Consumer; - -import org.neo4j.index.internal.gbptree.GBPTree; -import org.neo4j.index.internal.gbptree.Layout; -import org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector; -import org.neo4j.io.fs.FileSystemAbstraction; -import org.neo4j.io.pagecache.PageCache; -import org.neo4j.io.pagecache.PageCursor; -import org.neo4j.kernel.api.index.SchemaIndexProvider; -import org.neo4j.kernel.api.schema.index.IndexDescriptor; -import org.neo4j.kernel.impl.index.GBPTreeFileUtil; -import org.neo4j.kernel.impl.index.schema.GBPTreeFileSystemFileUtil; - -import static org.neo4j.helpers.Format.duration; -import static org.neo4j.helpers.collection.MapUtil.map; -import static org.neo4j.index.internal.gbptree.GBPTree.NO_HEADER_READER; - -class SpatialSchemaIndex -{ - final PageCache pageCache; - final File storeFile; - final Layout layout; - final GBPTreeFileUtil gbpTreeFileUtil; - final IndexDescriptor descriptor; - private final long indexId; - private final SchemaIndexProvider.Monitor monitor; - - GBPTree tree; - - SpatialSchemaIndex( PageCache pageCache, FileSystemAbstraction fs, File storeFile, Layout layout, - SchemaIndexProvider.Monitor monitor, IndexDescriptor descriptor, long indexId ) - { - this.pageCache = pageCache; - this.storeFile = storeFile; - this.layout = layout; - this.gbpTreeFileUtil = new GBPTreeFileSystemFileUtil( fs ); - this.descriptor = descriptor; - this.indexId = indexId; - this.monitor = monitor; - } - - void instantiateTree( RecoveryCleanupWorkCollector recoveryCleanupWorkCollector, Consumer headerWriter ) - throws IOException - { - ensureDirectoryExist(); - GBPTree.Monitor monitor = treeMonitor(); - tree = new GBPTree<>( pageCache, storeFile, layout, 0, monitor, NO_HEADER_READER, headerWriter, recoveryCleanupWorkCollector ); - } - - private GBPTree.Monitor treeMonitor( ) - { - return new GBPTree.Monitor.Adaptor() - { - @Override - public void cleanupFinished( long numberOfPagesVisited, long numberOfCleanedCrashPointers, long durationMillis ) - { - monitor.recoveryCompleted( indexId, descriptor, map( - "Number of pages visited", numberOfPagesVisited, - "Number of cleaned crashed pointers", numberOfCleanedCrashPointers, - "Time spent", duration( durationMillis ) ) ); - } - }; - } - - private void ensureDirectoryExist() throws IOException - { - // This will create the directory on the "normal" file system. - // When native index is put on blockdevice, page cache file system should be used instead. - gbpTreeFileUtil.mkdirs( storeFile.getParentFile() ); - } - - void closeTree() throws IOException - { - tree = closeIfPresent( tree ); - } - - T closeIfPresent( T closeable ) throws IOException - { - if ( closeable != null ) - { - closeable.close(); - } - return null; - } - - void assertOpen() - { - if ( tree == null ) - { - throw new IllegalStateException( "Index has been closed" ); - } - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexAccessor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexAccessor.java deleted file mode 100644 index 342c18df1f029..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexAccessor.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; - -import org.neo4j.graphdb.ResourceIterator; -import org.neo4j.helpers.collection.BoundedIterable; -import org.neo4j.index.internal.gbptree.Layout; -import org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector; -import org.neo4j.io.fs.FileSystemAbstraction; -import org.neo4j.io.pagecache.IOLimiter; -import org.neo4j.io.pagecache.PageCache; -import org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException; -import org.neo4j.kernel.api.index.IndexAccessor; -import org.neo4j.kernel.api.index.IndexUpdater; -import org.neo4j.kernel.api.index.PropertyAccessor; -import org.neo4j.kernel.api.index.SchemaIndexProvider; -import org.neo4j.kernel.api.schema.index.IndexDescriptor; -import org.neo4j.kernel.impl.api.index.IndexUpdateMode; -import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; -import org.neo4j.storageengine.api.schema.IndexReader; - -import static org.neo4j.helpers.collection.Iterators.asResourceIterator; -import static org.neo4j.helpers.collection.Iterators.iterator; -import static org.neo4j.index.internal.gbptree.GBPTree.NO_HEADER_WRITER; - -public class SpatialSchemaIndexAccessor - extends SpatialSchemaIndex implements IndexAccessor -{ - private final SpatialSchemaIndexUpdater singleUpdater; - private final IndexSamplingConfig samplingConfig; - - SpatialSchemaIndexAccessor( - PageCache pageCache, - FileSystemAbstraction fs, - File storeFile, - Layout layout, - RecoveryCleanupWorkCollector recoveryCleanupWorkCollector, - SchemaIndexProvider.Monitor monitor, - IndexDescriptor descriptor, - long indexId, - IndexSamplingConfig samplingConfig ) throws IOException - { - super( pageCache, fs, storeFile, layout, monitor, descriptor, indexId ); - singleUpdater = new SpatialSchemaIndexUpdater<>( layout.newKey(), layout.newValue() ); - this.samplingConfig = samplingConfig; - instantiateTree( recoveryCleanupWorkCollector, NO_HEADER_WRITER ); - } - - @Override - public void drop() throws IOException - { - closeTree(); - gbpTreeFileUtil.deleteFile( storeFile ); - } - - @Override - public IndexUpdater newUpdater( IndexUpdateMode mode ) - { - assertOpen(); - try - { - return singleUpdater.initialize( tree.writer(), true ); - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - } - - @Override - public void force() throws IOException - { - // TODO add IOLimiter arg - tree.checkpoint( IOLimiter.unlimited() ); - } - - @Override - public void close() throws IOException - { - closeTree(); - } - - @Override - public void refresh() - { - // not required in this implementation - } - - @Override - public IndexReader newReader() - { - assertOpen(); - return new SpatialSchemaIndexReader<>( tree, layout, samplingConfig, descriptor.schema().getPropertyIds() ); - } - - @Override - public BoundedIterable newAllEntriesReader() - { - return new SpatialAllEntriesReader<>( tree, layout ); - } - - @Override - public ResourceIterator snapshotFiles() throws IOException - { - return asResourceIterator( iterator( storeFile ) ); - } - - @Override - public void verifyDeferredConstraints( PropertyAccessor propertyAccessor ) - throws IndexEntryConflictException, IOException - { // Not needed since uniqueness is verified automatically w/o cost for every update. - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexHeaderReader.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexHeaderReader.java deleted file mode 100644 index a1a6dedc87ded..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexHeaderReader.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; - -import org.neo4j.index.internal.gbptree.Header; - -import static org.neo4j.kernel.impl.index.schema.spatial.SpatialSchemaIndexPopulator.BYTE_FAILED; - -class SpatialSchemaIndexHeaderReader implements Header.Reader -{ - byte state; - String failureMessage; - - @Override - public void read( ByteBuffer headerData ) - { - state = headerData.get(); - if ( state == BYTE_FAILED ) - { - short messageLength = headerData.getShort(); - byte[] failureMessageBytes = new byte[messageLength]; - headerData.get( failureMessageBytes ); - failureMessage = new String( failureMessageBytes, StandardCharsets.UTF_8 ); - } - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexHeaderWriter.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexHeaderWriter.java deleted file mode 100644 index 5f93a74ab2340..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexHeaderWriter.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import java.util.function.Consumer; - -import org.neo4j.index.internal.gbptree.GBPTree; -import org.neo4j.io.pagecache.PageCursor; - -/** - * Writes index state in the {@link GBPTree} header. - */ -class SpatialSchemaIndexHeaderWriter implements Consumer -{ - private final byte state; - - SpatialSchemaIndexHeaderWriter( byte state ) - { - this.state = state; - } - - @Override - public void accept( PageCursor cursor ) - { - cursor.putByte( state ); - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexPopulator.java deleted file mode 100644 index 41be8c413c1e7..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexPopulator.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.ExecutionException; - -import org.neo4j.concurrent.Work; -import org.neo4j.concurrent.WorkSync; -import org.neo4j.helpers.Exceptions; -import org.neo4j.index.internal.gbptree.GBPTree; -import org.neo4j.index.internal.gbptree.Layout; -import org.neo4j.index.internal.gbptree.RecoveryCleanupWorkCollector; -import org.neo4j.index.internal.gbptree.Writer; -import org.neo4j.io.fs.FileSystemAbstraction; -import org.neo4j.io.pagecache.IOLimiter; -import org.neo4j.io.pagecache.PageCache; -import org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException; -import org.neo4j.kernel.api.index.IndexEntryUpdate; -import org.neo4j.kernel.api.index.IndexPopulator; -import org.neo4j.kernel.api.index.IndexUpdater; -import org.neo4j.kernel.api.index.PropertyAccessor; -import org.neo4j.kernel.api.index.SchemaIndexProvider; -import org.neo4j.kernel.api.schema.index.IndexDescriptor; -import org.neo4j.kernel.impl.index.schema.FailureHeaderWriter; - -import static org.neo4j.index.internal.gbptree.GBPTree.NO_HEADER_WRITER; - -/** - * {@link IndexPopulator} backed by a {@link GBPTree}. - * - * @param type of {@link SpatialSchemaKey}. - * @param type of {@link SpatialSchemaValue}. - */ -public abstract class SpatialSchemaIndexPopulator - extends SpatialSchemaIndex implements IndexPopulator -{ - static final byte BYTE_FAILED = 0; - static final byte BYTE_ONLINE = 1; - static final byte BYTE_POPULATING = 2; - - private final KEY treeKey; - private final VALUE treeValue; - private final ConflictDetectingPointValueMerger conflictDetectingValueMerger; - private WorkSync,IndexUpdateWork> workSync; - - private Writer singleTreeWriter; - private byte[] failureBytes; - private boolean dropped; - - SpatialSchemaIndexPopulator( PageCache pageCache, FileSystemAbstraction fs, File storeFile, Layout layout, - SchemaIndexProvider.Monitor monitor, IndexDescriptor descriptor, long indexId ) - { - super( pageCache, fs, storeFile, layout, monitor, descriptor, indexId ); - this.treeKey = layout.newKey(); - this.treeValue = layout.newValue(); - this.conflictDetectingValueMerger = new ConflictDetectingPointValueMerger<>(); - } - - @Override - public synchronized void create() throws IOException - { - gbpTreeFileUtil.deleteFileIfPresent( storeFile ); - instantiateTree( RecoveryCleanupWorkCollector.IMMEDIATE, new SpatialSchemaIndexHeaderWriter( BYTE_POPULATING ) ); - instantiateWriter(); - workSync = new WorkSync<>( new IndexUpdateApply<>( treeKey, treeValue, singleTreeWriter, conflictDetectingValueMerger ) ); - } - - void instantiateWriter() throws IOException - { - assert singleTreeWriter == null; - singleTreeWriter = tree.writer(); - } - - @Override - public synchronized void drop() throws IOException - { - try - { - closeWriter(); - closeTree(); - gbpTreeFileUtil.deleteFileIfPresent( storeFile ); - } - finally - { - dropped = true; - } - } - - @Override - public void add( Collection> updates ) throws IndexEntryConflictException, IOException - { - applyWithWorkSync( updates ); - } - - @Override - public void verifyDeferredConstraints( PropertyAccessor propertyAccessor ) - throws IndexEntryConflictException, IOException - { - // No-op, uniqueness is checked for each update in add(IndexEntryUpdate) - } - - @Override - public IndexUpdater newPopulatingUpdater( PropertyAccessor accessor ) throws IOException - { - return new IndexUpdater() - { - private boolean closed; - private final Collection> updates = new ArrayList<>(); - - @Override - public void process( IndexEntryUpdate update ) throws IOException, IndexEntryConflictException - { - assertOpen(); - updates.add( update ); - } - - @Override - public void close() throws IOException, IndexEntryConflictException - { - applyWithWorkSync( updates ); - closed = true; - } - - private void assertOpen() - { - if ( closed ) - { - throw new IllegalStateException( "Updater has been closed" ); - } - } - }; - } - - @Override - public synchronized void close( boolean populationCompletedSuccessfully ) throws IOException - { - closeWriter(); - if ( populationCompletedSuccessfully && failureBytes != null ) - { - throw new IllegalStateException( "Can't mark index as online after it has been marked as failure" ); - } - - try - { - if ( populationCompletedSuccessfully ) - { - assertPopulatorOpen(); - markTreeAsOnline(); - } - else - { - assertNotDropped(); - ensureTreeInstantiated(); - markTreeAsFailed(); - } - } - finally - { - closeTree(); - } - } - - private void applyWithWorkSync( Collection> updates ) throws IOException - { - try - { - if ( workSync == null ) - { - throw new IllegalStateException( "Trying to populate an index without first calling create()" ); - } - workSync.apply( new IndexUpdateWork<>( updates ) ); - } - catch ( ExecutionException e ) - { - throw Exceptions.launderedException( IOException.class, e ); - } - } - - private void assertNotDropped() - { - if ( dropped ) - { - throw new IllegalStateException( "Populator has already been dropped." ); - } - } - - @Override - public void markAsFailed( String failure ) throws IOException - { - failureBytes = failure.getBytes( StandardCharsets.UTF_8 ); - } - - private void ensureTreeInstantiated() throws IOException - { - if ( tree == null ) - { - instantiateTree( RecoveryCleanupWorkCollector.NULL, NO_HEADER_WRITER ); - } - } - - private void assertPopulatorOpen() - { - if ( tree == null ) - { - throw new IllegalStateException( "Populator has already been closed." ); - } - } - - private void markTreeAsFailed() throws IOException - { - if ( failureBytes == null ) - { - failureBytes = new byte[0]; - } - tree.checkpoint( IOLimiter.unlimited(), new FailureHeaderWriter( failureBytes ) ); - } - - private void markTreeAsOnline() throws IOException - { - tree.checkpoint( IOLimiter.unlimited(), pc -> pc.putByte( BYTE_ONLINE ) ); - } - - void closeWriter() throws IOException - { - singleTreeWriter = closeIfPresent( singleTreeWriter ); - } - - private static class IndexUpdateApply - { - private final KEY treeKey; - private final VALUE treeValue; - private final Writer writer; - private final ConflictDetectingPointValueMerger conflictDetectingValueMerger; - - IndexUpdateApply( KEY treeKey, VALUE treeValue, Writer writer, - ConflictDetectingPointValueMerger conflictDetectingValueMerger ) - { - this.treeKey = treeKey; - this.treeValue = treeValue; - this.writer = writer; - this.conflictDetectingValueMerger = conflictDetectingValueMerger; - } - - public void process( IndexEntryUpdate indexEntryUpdate ) throws Exception - { - SpatialSchemaIndexUpdater.processUpdate( treeKey, treeValue, indexEntryUpdate, writer, conflictDetectingValueMerger ); - } - } - - private static class IndexUpdateWork - implements Work,IndexUpdateWork> - { - private final Collection> updates; - - IndexUpdateWork( Collection> updates ) - { - this.updates = updates; - } - - @Override - public IndexUpdateWork combine( IndexUpdateWork work ) - { - ArrayList> combined = new ArrayList<>( updates ); - combined.addAll( work.updates ); - return new IndexUpdateWork<>( combined ); - } - - @Override - public void apply( IndexUpdateApply indexUpdateApply ) throws Exception - { - for ( IndexEntryUpdate indexEntryUpdate : updates ) - { - indexUpdateApply.process( indexEntryUpdate ); - } - } - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexReader.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexReader.java deleted file mode 100644 index 7602aac549cdb..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexReader.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import org.neo4j.collection.primitive.PrimitiveLongResourceIterator; -import org.neo4j.cursor.RawCursor; -import org.neo4j.index.internal.gbptree.GBPTree; -import org.neo4j.index.internal.gbptree.Hit; -import org.neo4j.index.internal.gbptree.Layout; -import org.neo4j.internal.kernel.api.IndexOrder; -import org.neo4j.internal.kernel.api.IndexQuery; -import org.neo4j.internal.kernel.api.IndexQuery.ExactPredicate; -import org.neo4j.internal.kernel.api.IndexQuery.GeometryRangePredicate; -import org.neo4j.io.IOUtils; -import org.neo4j.kernel.api.exceptions.index.IndexNotApplicableKernelException; -import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; -import org.neo4j.kernel.impl.index.schema.NodeValueIterator; -import org.neo4j.storageengine.api.schema.IndexProgressor; -import org.neo4j.storageengine.api.schema.IndexReader; -import org.neo4j.storageengine.api.schema.IndexSampler; -import org.neo4j.values.storable.Value; -import org.neo4j.values.storable.ValueGroup; - -import static java.lang.String.format; - -class SpatialSchemaIndexReader - implements IndexReader -{ - private final GBPTree tree; - private final Layout layout; - private final IndexSamplingConfig samplingConfig; - private final Set,IOException>> openSeekers; - private final int[] propertyKeys; - - SpatialSchemaIndexReader( GBPTree tree, Layout layout, IndexSamplingConfig samplingConfig, - int[] propertyKeys ) - { - this.tree = tree; - this.layout = layout; - this.samplingConfig = samplingConfig; - this.propertyKeys = propertyKeys; - this.openSeekers = new HashSet<>(); - } - - @Override - public void close() - { - ensureOpenSeekersClosed(); - } - - @Override - public IndexSampler createSampler() - { - // For an unique index there's an optimization, knowing that all values in it are unique, to simply count - // the number of indexes values and create a sample for that count. The GBPTree doesn't have an O(1) - // count mechanism, it will have to manually count the indexed values in it to get it. - // For that reason this implementation opts for keeping complexity down by just using the existing - // non-unique sampler which scans the index and counts (potentially duplicates, of which there will - // be none in a unique index). - - SpatialFullScanNonUniqueIndexSampler sampler = - new SpatialFullScanNonUniqueIndexSampler<>( tree, layout, samplingConfig ); - return sampler::result; - } - - @Override - public long countIndexedNodes( long nodeId, Value... propertyValues ) - { - KEY treeKeyFrom = layout.newKey(); - KEY treeKeyTo = layout.newKey(); - treeKeyFrom.from( nodeId, propertyValues ); - treeKeyTo.from( nodeId, propertyValues ); - try ( RawCursor,IOException> seeker = tree.seek( treeKeyFrom, treeKeyTo ) ) - { - long count = 0; - while ( seeker.next() ) - { - if ( seeker.get().key().entityId == nodeId ) - { - count++; - } - } - return count; - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - } - - @Override - public PrimitiveLongResourceIterator query( IndexQuery... predicates ) throws IndexNotApplicableKernelException - { - NodeValueIterator nodeValueIterator = new NodeValueIterator(); - query( nodeValueIterator, IndexOrder.NONE, predicates ); - return nodeValueIterator; - } - - @Override - public void query( IndexProgressor.NodeValueClient cursor, IndexOrder indexOrder, IndexQuery... predicates ) - { - KEY treeKeyFrom = layout.newKey(); - KEY treeKeyTo = layout.newKey(); - - IndexQuery predicate = predicates[0]; - switch ( predicate.type() ) - { - case exists: - treeKeyFrom.initAsLowest(); - treeKeyTo.initAsHighest(); - startSeekForInitializedRange( cursor, treeKeyFrom, treeKeyTo ); - break; - case exact: - ExactPredicate exactPredicate = (ExactPredicate) predicate; - treeKeyFrom.from( Long.MIN_VALUE, exactPredicate.value() ); - treeKeyTo.from( Long.MAX_VALUE, exactPredicate.value() ); - startSeekForInitializedRange( cursor, treeKeyFrom, treeKeyTo ); - break; - case rangeGeometric: - GeometryRangePredicate rangePredicate = (GeometryRangePredicate) predicate; - initFromForRange( rangePredicate, treeKeyFrom ); - initToForRange( rangePredicate, treeKeyTo ); - startSeekForInitializedRange( cursor, treeKeyFrom, treeKeyTo ); - break; - default: - throw new IllegalArgumentException( "IndexQuery of type " + predicate.type() + " is not supported." ); - } - } - - public static void validateQuery( IndexOrder indexOrder, IndexQuery[] predicates ) throws IndexNotApplicableKernelException - { - if ( predicates.length != 1 ) - { - throw new IndexNotApplicableKernelException( "Spatial index doesn't handle composite queries" ); - } - - if ( indexOrder != IndexOrder.NONE ) - { - throw new UnsupportedOperationException( - format( "Tried to query index with unsupported order %s. Supported orders for query %s are %s.", indexOrder, Arrays.toString( predicates ), - IndexOrder.NONE ) ); - } - } - - private void initToForRange( GeometryRangePredicate rangePredicate, KEY treeKeyTo ) - { - Value toValue = rangePredicate.toAsValue(); - if ( toValue.valueGroup() == ValueGroup.NO_VALUE ) - { - treeKeyTo.initAsHighest(); - } - else - { - treeKeyTo.from( rangePredicate.toInclusive() ? Long.MAX_VALUE : Long.MIN_VALUE, toValue ); - treeKeyTo.entityIdIsSpecialTieBreaker = true; - } - } - - private void initFromForRange( GeometryRangePredicate rangePredicate, KEY treeKeyFrom ) - { - Value fromValue = rangePredicate.fromAsValue(); - if ( fromValue.valueGroup() == ValueGroup.NO_VALUE ) - { - treeKeyFrom.initAsLowest(); - } - else - { - treeKeyFrom.from( rangePredicate.fromInclusive() ? Long.MIN_VALUE : Long.MAX_VALUE, fromValue ); - treeKeyFrom.entityIdIsSpecialTieBreaker = true; - } - } - - @Override - public boolean hasFullNumberPrecision( IndexQuery... predicates ) - { - return false; - } - - private void startSeekForInitializedRange( IndexProgressor.NodeValueClient client, KEY treeKeyFrom, KEY treeKeyTo ) - { - if ( layout.compare( treeKeyFrom, treeKeyTo ) > 0 ) - { - client.initialize( IndexProgressor.EMPTY, propertyKeys ); - return; - } - try - { - RawCursor,IOException> seeker = tree.seek( treeKeyFrom, treeKeyTo ); - openSeekers.add( seeker ); - IndexProgressor hitProgressor = new SpatialHitIndexProgressor<>( seeker, client, openSeekers ); - client.initialize( hitProgressor, propertyKeys ); - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - } - - private void ensureOpenSeekersClosed() - { - try - { - IOUtils.closeAll( openSeekers ); - openSeekers.clear(); - } - catch ( IOException e ) - { - throw new UncheckedIOException( e ); - } - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexUpdater.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexUpdater.java deleted file mode 100644 index 7c773d693d846..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaIndexUpdater.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import java.io.IOException; - -import org.neo4j.index.internal.gbptree.Writer; -import org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException; -import org.neo4j.kernel.api.index.IndexEntryUpdate; -import org.neo4j.kernel.api.index.IndexUpdater; -import org.neo4j.values.storable.ValueTuple; - -class SpatialSchemaIndexUpdater - implements IndexUpdater -{ - private final KEY treeKey; - private final VALUE treeValue; - private final ConflictDetectingPointValueMerger conflictDetectingValueMerger; - private Writer writer; - - private boolean closed = true; - private boolean manageClosingOfWriter; - - SpatialSchemaIndexUpdater( KEY treeKey, VALUE treeValue ) - { - this.treeKey = treeKey; - this.treeValue = treeValue; - this.conflictDetectingValueMerger = new ConflictDetectingPointValueMerger<>(); - } - - SpatialSchemaIndexUpdater initialize( Writer writer, boolean manageClosingOfWriter ) - { - if ( !closed ) - { - throw new IllegalStateException( "Updater still open" ); - } - - this.manageClosingOfWriter = manageClosingOfWriter; - this.writer = writer; - closed = false; - return this; - } - - @Override - public void process( IndexEntryUpdate update ) throws IOException, IndexEntryConflictException - { - assertOpen(); - processUpdate( treeKey, treeValue, update, writer, conflictDetectingValueMerger ); - } - - @Override - public void close() throws IOException, IndexEntryConflictException - { - if ( manageClosingOfWriter ) - { - writer.close(); - } - closed = true; - } - - private void assertOpen() - { - if ( closed ) - { - throw new IllegalStateException( "Updater has been closed" ); - } - } - - static void processUpdate( KEY treeKey, VALUE treeValue, - IndexEntryUpdate update, Writer writer, ConflictDetectingPointValueMerger conflictDetectingValueMerger ) - throws IOException, IndexEntryConflictException - { - switch ( update.updateMode() ) - { - case ADDED: - processAdd( treeKey, treeValue, update, writer, conflictDetectingValueMerger ); - break; - case CHANGED: - processChange( treeKey, treeValue, update, writer, conflictDetectingValueMerger ); - break; - case REMOVED: - processRemove( treeKey, update, writer ); - break; - default: - throw new IllegalArgumentException(); - } - } - - private static void processRemove( KEY treeKey, - IndexEntryUpdate update, Writer writer ) throws IOException - { - // todo Do we need to verify that we actually removed something at all? - // todo Difference between online and recovery? - treeKey.from( update.getEntityId(), update.values() ); - writer.remove( treeKey ); - } - - private static void processChange( KEY treeKey, VALUE treeValue, - IndexEntryUpdate update, Writer writer, - ConflictDetectingPointValueMerger conflictDetectingValueMerger ) - throws IOException, IndexEntryConflictException - { - // Remove old entry - treeKey.from( update.getEntityId(), update.beforeValues() ); - writer.remove( treeKey ); - // Insert new entry - treeKey.from( update.getEntityId(), update.values() ); - treeValue.from( update.values() ); - writer.merge( treeKey, treeValue, conflictDetectingValueMerger ); - assertNoConflict( update, conflictDetectingValueMerger ); - } - - static void processAdd( KEY treeKey, VALUE treeValue, - IndexEntryUpdate update, Writer writer, - ConflictDetectingPointValueMerger conflictDetectingValueMerger ) - throws IOException, IndexEntryConflictException - { - treeKey.from( update.getEntityId(), update.values() ); - treeValue.from( update.values() ); - writer.merge( treeKey, treeValue, conflictDetectingValueMerger ); - assertNoConflict( update, conflictDetectingValueMerger ); - } - - private static void assertNoConflict( IndexEntryUpdate update, - ConflictDetectingPointValueMerger conflictDetectingValueMerger ) throws IndexEntryConflictException - { - if ( conflictDetectingValueMerger.wasConflict() ) - { - long existingNodeId = conflictDetectingValueMerger.existingNodeId(); - long addedNodeId = conflictDetectingValueMerger.addedNodeId(); - throw new IndexEntryConflictException( existingNodeId, addedNodeId, ValueTuple.of( update.values() ) ); - } - } -} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaValue.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaValue.java deleted file mode 100644 index 3c801b1a94fd0..0000000000000 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/spatial/SpatialSchemaValue.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2002-2017 "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.spatial; - -import org.neo4j.index.internal.gbptree.GBPTree; -import org.neo4j.values.storable.Value; - -/** - * Value in a {@link GBPTree} handling geometries suitable for schema indexing. - * - * NOTE: For the time being no data exists in {@link SpatialSchemaValue}, but since the layout is under development - * it's very convenient to have this class still exist so that it's very easy to try out different types - * of layouts without changing the entire stack of arguments. In the end it may just be that this class - * will be deleted, but for now it sticks around. - */ -class SpatialSchemaValue -{ - static final int SIZE = 0; - - static final SpatialSchemaValue INSTANCE = new SpatialSchemaValue(); - - void from( Value... values ) - { - // not needed a.t.m. - } - - @Override - public String toString() - { - return "[no value]"; - } -} diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessorTest.java index 3eeeba47182ff..f2e51b36d71fa 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessorTest.java @@ -91,7 +91,6 @@ public void dropMustThrowIfDropNativeFail() throws Exception verifyFailOnSingleDropFailure( nativeAccessor, fusionIndexAccessor ); } - @Test public void dropMustThrowIfDropSpatialFail() throws Exception { diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexTestHelp.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexTestHelp.java index 9300d40f1ffd9..0764a65349156 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexTestHelp.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexTestHelp.java @@ -161,7 +161,8 @@ static IndexEntryUpdate change( Value before, Value after return IndexEntryUpdate.change( 0, indexKey, before, after ); } - static void verifyOtherIsClosedOnSingleThrow( AutoCloseable failingCloseable, AutoCloseable fusionCloseable, AutoCloseable... successfulCloseables ) throws Exception + static void verifyOtherIsClosedOnSingleThrow( AutoCloseable failingCloseable, AutoCloseable fusionCloseable, AutoCloseable... successfulCloseables ) + throws Exception { IOException failure = new IOException( "fail" ); doThrow( failure ).when( failingCloseable ).close(); @@ -203,7 +204,7 @@ static void verifyFusionCloseThrowIfAllThrow( AutoCloseable fusionCloseable, Aut { // given IOException[] failures = new IOException[autoCloseables.length]; - for(int i=0;i> matchers = new ArrayList<>(); - for ( int i = 0; i < failures.length; i++ ) + for ( IOException failure : failures ) { - matchers.add( sameInstance( failures[i] ) ); + matchers.add( sameInstance( failure ) ); } assertThat( e, anyOf( matchers ) ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdaterTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdaterTest.java index 74ac376c8ae69..aef320fd883aa 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdaterTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdaterTest.java @@ -121,7 +121,7 @@ public void processMustSelectCorrectForRemove() throws Exception // when // ... value supported by spatial - for ( Value value : supportedBySpatial) + for ( Value value : supportedBySpatial ) { //then verifyRemoveWithCorrectUpdater( spatialUpdater, value ); 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 c99726c0d6cae..38ab04b88aea1 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 @@ -35,7 +35,7 @@ import org.neo4j.kernel.impl.index.schema.NumberSchemaIndexProvider; import org.neo4j.kernel.impl.index.schema.NativeSelector; import org.neo4j.kernel.impl.index.schema.fusion.FusionSchemaIndexProvider; -import org.neo4j.kernel.impl.index.schema.spatial.SpatialSchemaIndexProvider; +import org.neo4j.kernel.impl.index.schema.fusion.SpatialFusionSchemaIndexProvider; import org.neo4j.kernel.impl.spi.KernelContext; import org.neo4j.kernel.monitoring.Monitors; import org.neo4j.logging.Log; @@ -88,8 +88,8 @@ public static FusionSchemaIndexProvider newInstance( PageCache pageCache, File s boolean readOnly = isReadOnly( config, operationalMode ); NumberSchemaIndexProvider nativeProvider = new NumberSchemaIndexProvider( pageCache, fs, childDirectoryStructure, monitor, recoveryCleanupWorkCollector, readOnly ); - SpatialSchemaIndexProvider spatialProvider = - new SpatialSchemaIndexProvider( pageCache, fs, childDirectoryStructure, monitor, recoveryCleanupWorkCollector, readOnly ); + SpatialFusionSchemaIndexProvider spatialProvider = + new SpatialFusionSchemaIndexProvider( pageCache, fs, childDirectoryStructure, monitor, recoveryCleanupWorkCollector, readOnly ); LuceneSchemaIndexProvider luceneProvider = LuceneSchemaIndexProviderFactory.create( fs, childDirectoryStructure, monitor, config, operationalMode ); boolean useNativeIndex = config.get( GraphDatabaseSettings.enable_native_schema_index );