diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexReader.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexReader.java index 2fdd851823f93..eef3a5207b2ed 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexReader.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSchemaIndexReader.java @@ -33,7 +33,6 @@ import org.neo4j.internal.kernel.api.IndexOrder; import org.neo4j.internal.kernel.api.IndexQuery; import org.neo4j.io.IOUtils; -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; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/TemporalIndexAccessor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/TemporalIndexAccessor.java index 663b2a62dad8c..ee5f34ac80f3a 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/TemporalIndexAccessor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/TemporalIndexAccessor.java @@ -32,6 +32,7 @@ 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; @@ -91,9 +92,12 @@ public void close() throws IOException, IndexEntryConflictException } @Override - public void force() throws IOException + public void force( IOLimiter ioLimiter ) throws IOException { - forAll( NativeSchemaIndexAccessor::force, this ); + for ( NativeSchemaIndexAccessor part : this ) + { + part.force( ioLimiter ); + } } @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 488f116dcf3af..c2fee9b0a84d0 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 @@ -43,19 +43,27 @@ class FusionIndexAccessor implements IndexAccessor { - private final IndexAccessor nativeAccessor; + private final IndexAccessor numberAccessor; private final IndexAccessor spatialAccessor; + private final IndexAccessor temporalAccessor; private final IndexAccessor luceneAccessor; private final Selector selector; private final long indexId; private final IndexDescriptor descriptor; private final DropAction dropAction; - FusionIndexAccessor( IndexAccessor nativeAccessor, IndexAccessor spatialAccessor, IndexAccessor luceneAccessor, - Selector selector, long indexId, IndexDescriptor descriptor, DropAction dropAction ) + FusionIndexAccessor( IndexAccessor numberAccessor, + IndexAccessor spatialAccessor, + IndexAccessor temporalAccessor, + IndexAccessor luceneAccessor, + Selector selector, + long indexId, + IndexDescriptor descriptor, + DropAction dropAction ) { - this.nativeAccessor = nativeAccessor; + this.numberAccessor = numberAccessor; this.spatialAccessor = spatialAccessor; + this.temporalAccessor = temporalAccessor; this.luceneAccessor = luceneAccessor; this.selector = selector; this.indexId = indexId; @@ -66,71 +74,99 @@ class FusionIndexAccessor implements IndexAccessor @Override public void drop() throws IOException { - forAll( IndexAccessor::drop, nativeAccessor, spatialAccessor, luceneAccessor ); + forAll( IndexAccessor::drop, numberAccessor, spatialAccessor, temporalAccessor, luceneAccessor ); dropAction.drop( indexId ); } @Override public IndexUpdater newUpdater( IndexUpdateMode mode ) { - return new FusionIndexUpdater( nativeAccessor.newUpdater( mode ), spatialAccessor.newUpdater( mode ), luceneAccessor.newUpdater( mode ), selector ); + return new FusionIndexUpdater( + numberAccessor.newUpdater( mode ), + spatialAccessor.newUpdater( mode ), + temporalAccessor.newUpdater( mode ), + luceneAccessor.newUpdater( mode ), selector ); } @Override public void force( IOLimiter ioLimiter ) throws IOException { - nativeAccessor.force( ioLimiter ); + numberAccessor.force( ioLimiter ); spatialAccessor.force( ioLimiter ); + temporalAccessor.force( ioLimiter ); luceneAccessor.force( ioLimiter ); } @Override public void refresh() throws IOException { - nativeAccessor.refresh(); + numberAccessor.refresh(); + spatialAccessor.refresh(); + temporalAccessor.refresh(); luceneAccessor.refresh(); } @Override public void close() throws IOException { - forAll( IndexAccessor::close, nativeAccessor, spatialAccessor, luceneAccessor ); + forAll( IndexAccessor::close, numberAccessor, spatialAccessor, temporalAccessor, luceneAccessor ); } @Override public IndexReader newReader() { - return new FusionIndexReader( nativeAccessor.newReader(), spatialAccessor.newReader(), luceneAccessor.newReader(), selector, descriptor ); + return new FusionIndexReader( + numberAccessor.newReader(), + spatialAccessor.newReader(), + temporalAccessor.newReader(), + luceneAccessor.newReader(), + selector, + descriptor ); } @Override public BoundedIterable newAllEntriesReader() { - BoundedIterable nativeAllEntries = nativeAccessor.newAllEntriesReader(); + BoundedIterable numberAllEntries = numberAccessor.newAllEntriesReader(); BoundedIterable spatialAllEntries = spatialAccessor.newAllEntriesReader(); + BoundedIterable temporalAllEntries = temporalAccessor.newAllEntriesReader(); BoundedIterable luceneAllEntries = luceneAccessor.newAllEntriesReader(); return new BoundedIterable() { @Override public long maxCount() { - long nativeMaxCount = nativeAllEntries.maxCount(); + long numberMaxCount = numberAllEntries.maxCount(); long spatialMaxCount = spatialAllEntries.maxCount(); + long temporalMaxCount = temporalAllEntries.maxCount(); long luceneMaxCount = luceneAllEntries.maxCount(); - return nativeMaxCount == UNKNOWN_MAX_COUNT || spatialMaxCount == UNKNOWN_MAX_COUNT || luceneMaxCount == UNKNOWN_MAX_COUNT ? - UNKNOWN_MAX_COUNT : nativeMaxCount + spatialMaxCount + luceneMaxCount; + return existsUnknownMaxCount( numberMaxCount, spatialMaxCount, temporalMaxCount, luceneMaxCount ) ? + UNKNOWN_MAX_COUNT : numberMaxCount + spatialMaxCount + temporalMaxCount + luceneMaxCount; } + private boolean existsUnknownMaxCount( long... maxCounts ) + { + for ( long maxCount : maxCounts ) + { + if ( maxCount == UNKNOWN_MAX_COUNT ) + { + return true; + } + } + return false; + } + + @SuppressWarnings( "unchecked" ) @Override public void close() throws Exception { - forAll( BoundedIterable::close, nativeAllEntries, spatialAllEntries, luceneAllEntries ); + forAll( BoundedIterable::close, numberAllEntries, spatialAllEntries, temporalAllEntries, luceneAllEntries ); } @Override public Iterator iterator() { - return Iterables.concat( nativeAllEntries, spatialAllEntries, luceneAllEntries ).iterator(); + return Iterables.concat( numberAllEntries, spatialAllEntries, temporalAllEntries, luceneAllEntries ).iterator(); } }; } @@ -139,21 +175,25 @@ public Iterator iterator() public ResourceIterator snapshotFiles() throws IOException { return concatResourceIterators( - asList( nativeAccessor.snapshotFiles(), spatialAccessor.snapshotFiles(), luceneAccessor.snapshotFiles() ).iterator() ); + asList( numberAccessor.snapshotFiles(), + spatialAccessor.snapshotFiles(), + temporalAccessor.snapshotFiles(), + luceneAccessor.snapshotFiles() ).iterator() ); } @Override public void verifyDeferredConstraints( PropertyAccessor propertyAccessor ) throws IndexEntryConflictException, IOException { - nativeAccessor.verifyDeferredConstraints( propertyAccessor ); + numberAccessor.verifyDeferredConstraints( propertyAccessor ); spatialAccessor.verifyDeferredConstraints( propertyAccessor ); + temporalAccessor.verifyDeferredConstraints( propertyAccessor ); luceneAccessor.verifyDeferredConstraints( propertyAccessor ); } @Override public boolean isDirty() { - return nativeAccessor.isDirty(); + return numberAccessor.isDirty() || spatialAccessor.isDirty() || temporalAccessor.isDirty() || luceneAccessor.isDirty(); } } 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 ad5d2db941483..1463020651372 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 @@ -37,18 +37,20 @@ class FusionIndexPopulator implements IndexPopulator { - private final IndexPopulator nativePopulator; + private final IndexPopulator numberPopulator; private final IndexPopulator spatialPopulator; + private final IndexPopulator temporalPopulator; private final IndexPopulator lucenePopulator; private final Selector selector; private final long indexId; private final DropAction dropAction; - FusionIndexPopulator( IndexPopulator nativePopulator, IndexPopulator spatialPopulator, + FusionIndexPopulator( IndexPopulator numberPopulator, IndexPopulator spatialPopulator, IndexPopulator temporalPopulator, IndexPopulator lucenePopulator, Selector selector, long indexId, DropAction dropAction ) { - this.nativePopulator = nativePopulator; + this.numberPopulator = numberPopulator; this.spatialPopulator = spatialPopulator; + this.temporalPopulator = temporalPopulator; this.lucenePopulator = lucenePopulator; this.selector = selector; this.indexId = indexId; @@ -58,15 +60,16 @@ class FusionIndexPopulator implements IndexPopulator @Override public void create() throws IOException { - nativePopulator.create(); + numberPopulator.create(); spatialPopulator.create(); + temporalPopulator.create(); lucenePopulator.create(); } @Override public void drop() throws IOException { - forAll( IndexPopulator::drop, nativePopulator, spatialPopulator, lucenePopulator ); + forAll( IndexPopulator::drop, numberPopulator, spatialPopulator, temporalPopulator, lucenePopulator ); dropAction.drop( indexId ); } @@ -75,22 +78,25 @@ public void add( Collection> updates ) throws Inde { Collection> luceneBatch = new ArrayList<>(); Collection> spatialBatch = new ArrayList<>(); - Collection> nativeBatch = new ArrayList<>(); + Collection> temporalBatch = new ArrayList<>(); + Collection> numberBatch = new ArrayList<>(); for ( IndexEntryUpdate update : updates ) { - selector.select( nativeBatch, spatialBatch, luceneBatch, update.values() ).add( update ); + selector.select( numberBatch, spatialBatch, temporalBatch, luceneBatch, update.values() ).add( update ); } lucenePopulator.add( luceneBatch ); spatialPopulator.add( spatialBatch ); - nativePopulator.add( nativeBatch ); + temporalPopulator.add( temporalBatch ); + numberPopulator.add( numberBatch ); } @Override public void verifyDeferredConstraints( PropertyAccessor propertyAccessor ) throws IndexEntryConflictException, IOException { - nativePopulator.verifyDeferredConstraints( propertyAccessor ); + numberPopulator.verifyDeferredConstraints( propertyAccessor ); spatialPopulator.verifyDeferredConstraints( propertyAccessor ); + temporalPopulator.verifyDeferredConstraints( propertyAccessor ); lucenePopulator.verifyDeferredConstraints( propertyAccessor ); } @@ -98,32 +104,37 @@ public void verifyDeferredConstraints( PropertyAccessor propertyAccessor ) public IndexUpdater newPopulatingUpdater( PropertyAccessor accessor ) throws IOException { return new FusionIndexUpdater( - nativePopulator.newPopulatingUpdater( accessor ), + numberPopulator.newPopulatingUpdater( accessor ), spatialPopulator.newPopulatingUpdater( accessor ), + temporalPopulator.newPopulatingUpdater( accessor ), lucenePopulator.newPopulatingUpdater( accessor ), selector ); } @Override public void close( boolean populationCompletedSuccessfully ) throws IOException { - forAll( populator -> populator.close( populationCompletedSuccessfully ), nativePopulator, spatialPopulator, lucenePopulator ); + forAll( populator -> populator.close( populationCompletedSuccessfully ), numberPopulator, spatialPopulator, temporalPopulator, lucenePopulator ); } @Override public void markAsFailed( String failure ) throws IOException { - forAll( populator -> populator.markAsFailed( failure ), nativePopulator, spatialPopulator, lucenePopulator ); + forAll( populator -> populator.markAsFailed( failure ), numberPopulator, spatialPopulator, temporalPopulator, lucenePopulator ); } @Override public void includeSample( IndexEntryUpdate update ) { - selector.select( nativePopulator, spatialPopulator, lucenePopulator, update.values() ).includeSample( update ); + selector.select( numberPopulator, spatialPopulator, temporalPopulator, lucenePopulator, update.values() ).includeSample( update ); } @Override public IndexSample sampleResult() { - return combineSamples( nativePopulator.sampleResult(), spatialPopulator.sampleResult() , lucenePopulator.sampleResult() ); + return combineSamples( + numberPopulator.sampleResult(), + spatialPopulator.sampleResult(), + temporalPopulator.sampleResult(), + lucenePopulator.sampleResult() ); } } 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 68dd8800188ed..005a550c3757d 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 @@ -44,17 +44,23 @@ class FusionIndexReader implements IndexReader { - private final IndexReader nativeReader; + private final IndexReader numberReader; private final IndexReader spatialReader; + private final IndexReader temporalReader; private final IndexReader luceneReader; private final Selector selector; private final IndexDescriptor descriptor; - FusionIndexReader( IndexReader nativeReader, IndexReader spatialReader, IndexReader luceneReader, Selector selector, - IndexDescriptor descriptor ) + FusionIndexReader( IndexReader numberReader, + IndexReader spatialReader, + IndexReader temporalReader, + IndexReader luceneReader, + Selector selector, + IndexDescriptor descriptor ) { - this.nativeReader = nativeReader; + this.numberReader = numberReader; this.spatialReader = spatialReader; + this.temporalReader = temporalReader; this.luceneReader = luceneReader; this.selector = selector; this.descriptor = descriptor; @@ -63,19 +69,23 @@ class FusionIndexReader implements IndexReader @Override public void close() { - forAll( Resource::close, nativeReader, spatialReader, luceneReader ); + forAll( Resource::close, numberReader, spatialReader, temporalReader, luceneReader ); } @Override public long countIndexedNodes( long nodeId, Value... propertyValues ) { - return selector.select( nativeReader, spatialReader, luceneReader, propertyValues ).countIndexedNodes( nodeId, propertyValues ); + return selector.select( numberReader, spatialReader, temporalReader, luceneReader, propertyValues ).countIndexedNodes( nodeId, propertyValues ); } @Override public IndexSampler createSampler() { - return new FusionIndexSampler( nativeReader.createSampler(), spatialReader.createSampler(), luceneReader.createSampler() ); + return new FusionIndexSampler( + numberReader.createSampler(), + spatialReader.createSampler(), + temporalReader.createSampler(), + luceneReader.createSampler() ); } @Override @@ -89,26 +99,33 @@ public PrimitiveLongResourceIterator query( IndexQuery... predicates ) throws In if ( predicates[0] instanceof ExactPredicate ) { ExactPredicate exactPredicate = (ExactPredicate) predicates[0]; - return selector.select( nativeReader, spatialReader, luceneReader, exactPredicate.value() ).query( predicates ); + return selector.select( numberReader, spatialReader, temporalReader, luceneReader, exactPredicate.value() ).query( predicates ); } if ( predicates[0] instanceof NumberRangePredicate ) { - return nativeReader.query( predicates[0] ); + return numberReader.query( predicates ); } if ( predicates[0] instanceof GeometryRangePredicate ) { - return spatialReader.query( predicates[0] ); + return spatialReader.query( predicates ); } +// TODO: support temporal range queries +// if ( predicates[0] instanceof TemporalRangePredicate ) +// { +// return temporalReader.query( predicates[0] ); +// } + // todo: There will be no ordering of the node ids here. Is this a problem? if ( predicates[0] instanceof ExistsPredicate ) { - PrimitiveLongResourceIterator nativeResult = nativeReader.query( predicates[0] ); - PrimitiveLongResourceIterator spatialResult = spatialReader.query( predicates[0] ); - PrimitiveLongResourceIterator luceneResult = luceneReader.query( predicates[0] ); - return PrimitiveLongResourceCollections.concat( nativeResult, spatialResult, luceneResult ); + PrimitiveLongResourceIterator numberResult = numberReader.query( predicates ); + PrimitiveLongResourceIterator spatialResult = spatialReader.query( predicates ); + PrimitiveLongResourceIterator temporalResult = temporalReader.query( predicates ); + PrimitiveLongResourceIterator luceneResult = luceneReader.query( predicates ); + return PrimitiveLongResourceCollections.concat( numberResult, spatialResult, temporalResult, luceneResult ); } return luceneReader.query( predicates ); @@ -127,22 +144,28 @@ public void query( IndexProgressor.NodeValueClient cursor, IndexOrder indexOrder if ( predicates[0] instanceof ExactPredicate ) { ExactPredicate exactPredicate = (ExactPredicate) predicates[0]; - selector.select( nativeReader, spatialReader, luceneReader, exactPredicate.value() ).query( cursor, indexOrder, predicates ); + selector.select( numberReader, spatialReader, temporalReader, luceneReader, exactPredicate.value() ).query( cursor, indexOrder, predicates ); return; } if ( predicates[0] instanceof NumberRangePredicate ) { - nativeReader.query( cursor, indexOrder, predicates[0] ); + numberReader.query( cursor, indexOrder, predicates ); return; } if ( predicates[0] instanceof GeometryRangePredicate ) { - spatialReader.query( cursor, indexOrder, predicates[0] ); + spatialReader.query( cursor, indexOrder, predicates ); return; } +// TODO: support temporal range queries +// if ( predicates[0] instanceof TemporalRangePredicate ) +// { +// return temporalReader.query( predicates[0] ); +// } + // todo: There will be no ordering of the node ids here. Is this a problem? if ( predicates[0] instanceof ExistsPredicate ) { @@ -155,9 +178,10 @@ public void query( IndexProgressor.NodeValueClient cursor, IndexOrder indexOrder BridgingIndexProgressor multiProgressor = new BridgingIndexProgressor( cursor, descriptor.schema().getPropertyIds() ); cursor.initialize( descriptor, multiProgressor, predicates ); - nativeReader.query( multiProgressor, indexOrder, predicates[0] ); - spatialReader.query( multiProgressor, indexOrder, predicates[0] ); - luceneReader.query( multiProgressor, indexOrder, predicates[0] ); + numberReader.query( multiProgressor, indexOrder, predicates ); + spatialReader.query( multiProgressor, indexOrder, predicates ); + temporalReader.query( multiProgressor, indexOrder, predicates ); + luceneReader.query( multiProgressor, indexOrder, predicates ); return; } @@ -177,10 +201,21 @@ public boolean hasFullValuePrecision( IndexQuery... predicates ) { Value value = ((ExactPredicate) predicate).value(); return selector.select( - nativeReader.hasFullValuePrecision( predicates ), + numberReader.hasFullValuePrecision( predicates ), spatialReader.hasFullValuePrecision( predicates ), + temporalReader.hasFullValuePrecision( predicates ), luceneReader.hasFullValuePrecision( predicates ), value ); } - return predicates[0] instanceof NumberRangePredicate && nativeReader.hasFullValuePrecision( predicates ); + if ( predicate instanceof NumberRangePredicate ) + { + return numberReader.hasFullValuePrecision( predicates ); + } + +// TODO: support temporal range queries +// if ( predicate instanceof temporalRangePredicate ) +// { +// return temporalReader.hasFullValuePrecision( predicates ); +// } + return false; } } 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 cad6f7d4680e7..f35f5182efc44 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 @@ -31,15 +31,21 @@ class FusionIndexUpdater implements IndexUpdater { - private final IndexUpdater nativeUpdater; + private final IndexUpdater numberUpdater; private final IndexUpdater spatialUpdater; + private final IndexUpdater temporalUpdater; private final IndexUpdater luceneUpdater; private final Selector selector; - FusionIndexUpdater( IndexUpdater nativeUpdater, IndexUpdater spatialUpdater, IndexUpdater luceneUpdater, Selector selector ) + FusionIndexUpdater( IndexUpdater numberUpdater, + IndexUpdater spatialUpdater, + IndexUpdater temporalUpdater, + IndexUpdater luceneUpdater, + Selector selector ) { - this.nativeUpdater = nativeUpdater; + this.numberUpdater = numberUpdater; this.spatialUpdater = spatialUpdater; + this.temporalUpdater = temporalUpdater; this.luceneUpdater = luceneUpdater; this.selector = selector; } @@ -50,14 +56,14 @@ public void process( IndexEntryUpdate update ) throws IOException, IndexEntry switch ( update.updateMode() ) { case ADDED: - selector.select( nativeUpdater, spatialUpdater, luceneUpdater, update.values() ).process( update ); + selector.select( numberUpdater, spatialUpdater, temporalUpdater, luceneUpdater, update.values() ).process( update ); break; case CHANGED: // Hmm, here's a little conundrum. What if we change from a value that goes into native // to a value that goes into fallback, or vice versa? We also don't want to blindly pass // all CHANGED updates to both updaters since not all values will work in them. - IndexUpdater from = selector.select( nativeUpdater, spatialUpdater, luceneUpdater, update.beforeValues() ); - IndexUpdater to = selector.select( nativeUpdater, spatialUpdater, luceneUpdater, update.values() ); + IndexUpdater from = selector.select( numberUpdater, spatialUpdater, temporalUpdater, luceneUpdater, update.beforeValues() ); + IndexUpdater to = selector.select( numberUpdater, spatialUpdater, temporalUpdater, luceneUpdater, update.values() ); // There are two cases: // - both before/after go into the same updater --> pass update into that updater if ( from == to ) @@ -74,7 +80,7 @@ public void process( IndexEntryUpdate update ) throws IOException, IndexEntry } break; case REMOVED: - selector.select( nativeUpdater, spatialUpdater, luceneUpdater, update.values() ).process( update ); + selector.select( numberUpdater, spatialUpdater, temporalUpdater, luceneUpdater, update.values() ).process( update ); break; default: throw new IllegalArgumentException( "Unknown update mode" ); @@ -86,7 +92,7 @@ public void close() throws IOException, IndexEntryConflictException { try { - forAll( IndexUpdater::close, Arrays.asList( nativeUpdater, spatialUpdater, luceneUpdater ) ); + forAll( IndexUpdater::close, Arrays.asList( numberUpdater, spatialUpdater, temporalUpdater, luceneUpdater ) ); } catch ( IOException | IndexEntryConflictException e ) { 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 97bb74185b138..1488213ad8804 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 @@ -39,6 +39,9 @@ import org.neo4j.values.storable.Value; import org.neo4j.values.storable.ValueGroup; +import static org.neo4j.internal.kernel.api.InternalIndexState.FAILED; +import static org.neo4j.internal.kernel.api.InternalIndexState.POPULATING; + /** * This {@link SchemaIndexProvider index provider} act as one logical index but is backed by two physical * indexes, the native index and the lucene index. All index entries that can be handled by the native index will be directed @@ -46,23 +49,32 @@ */ public class FusionSchemaIndexProvider extends SchemaIndexProvider { - public interface Selector + interface Selector { - T select( T nativeInstance, T spatialInstance, T luceneInstance, Value... values ); + T select( T nativeInstance, T spatialInstance, T temporalInstance, T luceneInstance, Value... values ); } - private final SchemaIndexProvider nativeProvider; + private final SchemaIndexProvider numberProvider; private final SchemaIndexProvider spatialProvider; + private final SchemaIndexProvider temporalProvider; private final SchemaIndexProvider luceneProvider; private final Selector selector; private final DropAction dropAction; - public FusionSchemaIndexProvider( SchemaIndexProvider nativeProvider, SchemaIndexProvider spatialProvider, SchemaIndexProvider luceneProvider, - Selector selector, Descriptor descriptor, int priority, IndexDirectoryStructure.Factory directoryStructure, FileSystemAbstraction fs ) + public FusionSchemaIndexProvider( SchemaIndexProvider numberProvider, + SchemaIndexProvider spatialProvider, + SchemaIndexProvider temporalProvider, + SchemaIndexProvider luceneProvider, + Selector selector, + Descriptor descriptor, + int priority, + IndexDirectoryStructure.Factory directoryStructure, + FileSystemAbstraction fs ) { super( descriptor, priority, directoryStructure ); - this.nativeProvider = nativeProvider; + this.numberProvider = numberProvider; this.spatialProvider = spatialProvider; + this.temporalProvider = temporalProvider; this.luceneProvider = luceneProvider; this.selector = selector; this.dropAction = new FileSystemDropAction( fs, directoryStructure() ); @@ -72,8 +84,9 @@ public FusionSchemaIndexProvider( SchemaIndexProvider nativeProvider, SchemaInde public IndexPopulator getPopulator( long indexId, IndexDescriptor descriptor, IndexSamplingConfig samplingConfig ) { return new FusionIndexPopulator( - nativeProvider.getPopulator( indexId, descriptor, samplingConfig ), + numberProvider.getPopulator( indexId, descriptor, samplingConfig ), spatialProvider.getPopulator( indexId, descriptor, samplingConfig ), + temporalProvider.getPopulator( indexId, descriptor, samplingConfig ), luceneProvider.getPopulator( indexId, descriptor, samplingConfig ), selector, indexId, dropAction ); } @@ -82,73 +95,72 @@ public IndexAccessor getOnlineAccessor( long indexId, IndexDescriptor descriptor IndexSamplingConfig samplingConfig ) throws IOException { return new FusionIndexAccessor( - nativeProvider.getOnlineAccessor( indexId, descriptor, samplingConfig ), + numberProvider.getOnlineAccessor( indexId, descriptor, samplingConfig ), spatialProvider.getOnlineAccessor( indexId, descriptor, samplingConfig ), + temporalProvider.getOnlineAccessor( indexId, descriptor, samplingConfig ), luceneProvider.getOnlineAccessor( indexId, descriptor, samplingConfig ), selector, indexId, descriptor, dropAction ); } @Override public String getPopulationFailure( long indexId, IndexDescriptor descriptor ) throws IllegalStateException { - String nativeFailure = null; - try - { - nativeFailure = nativeProvider.getPopulationFailure( indexId, descriptor ); - } - catch ( IllegalStateException e ) - { // Just catch - } - String spatialFailure = null; - try + StringBuilder builder = new StringBuilder(); + writeFailure( "number", builder, numberProvider, indexId, descriptor ); + writeFailure( "spatial", builder, spatialProvider, indexId, descriptor ); + writeFailure( "temporal", builder, temporalProvider, indexId, descriptor ); + writeFailure( "lucene", builder, luceneProvider, indexId, descriptor ); + String failure = builder.toString(); + if ( !failure.isEmpty() ) { - spatialFailure = spatialProvider.getPopulationFailure( indexId, descriptor ); + return failure; } - catch ( IllegalStateException e ) - { // Just catch - } - String luceneFailure = null; + throw new IllegalStateException( "None of the indexes were in a failed state" ); + } + + private void writeFailure( String indexName, StringBuilder builder, SchemaIndexProvider provider, long indexId, IndexDescriptor descriptor ) + { try { - luceneFailure = luceneProvider.getPopulationFailure( indexId, descriptor ); + String failure = provider.getPopulationFailure( indexId, descriptor ); + builder.append( indexName ); + builder.append( ": " ); + builder.append( failure ); + builder.append( ' ' ); } catch ( IllegalStateException e ) { // Just catch } - - if ( nativeFailure != null || spatialFailure != null || luceneFailure != null ) - { - return "native: " + nativeFailure + " spatial: " + spatialFailure + " lucene: " + luceneFailure; - } - throw new IllegalStateException( "None of the indexes were in a failed state" ); } @Override public InternalIndexState getInitialState( long indexId, IndexDescriptor descriptor ) { - InternalIndexState nativeState = nativeProvider.getInitialState( indexId, descriptor ); + InternalIndexState numberState = numberProvider.getInitialState( indexId, descriptor ); InternalIndexState spatialState = spatialProvider.getInitialState( indexId, descriptor ); + InternalIndexState temporalState = temporalProvider.getInitialState( indexId, descriptor ); InternalIndexState luceneState = luceneProvider.getInitialState( indexId, descriptor ); - if ( nativeState == InternalIndexState.FAILED || spatialState == InternalIndexState.FAILED || luceneState == InternalIndexState.FAILED ) + if ( numberState == FAILED || spatialState == FAILED || temporalState == FAILED || luceneState == FAILED ) { // One of the state is FAILED, the whole state must be considered FAILED - return InternalIndexState.FAILED; + return FAILED; } - if ( nativeState == InternalIndexState.POPULATING || spatialState == InternalIndexState.POPULATING || luceneState == InternalIndexState.POPULATING ) + if ( numberState == POPULATING || spatialState == POPULATING || temporalState == POPULATING || luceneState == POPULATING ) { // No state is FAILED and one of the state is POPULATING, the whole state must be considered POPULATING - return InternalIndexState.POPULATING; + return POPULATING; } - // This means that both states are ONLINE - return nativeState; + // This means that all parts are ONLINE + return InternalIndexState.ONLINE; } @Override public IndexCapability getCapability( IndexDescriptor indexDescriptor ) { - IndexCapability nativeCapability = nativeProvider.getCapability( indexDescriptor ); + IndexCapability numberCapability = numberProvider.getCapability( indexDescriptor ); IndexCapability spatialCapability = spatialProvider.getCapability( indexDescriptor ); + IndexCapability temporalCapability = temporalProvider.getCapability( indexDescriptor ); IndexCapability luceneCapability = luceneProvider.getCapability( indexDescriptor ); - return new UnionIndexCapability( nativeCapability, spatialCapability, luceneCapability ) + return new UnionIndexCapability( numberCapability, spatialCapability, temporalCapability, luceneCapability ) { @Override public IndexOrder[] orderCapability( ValueGroup... valueGroups ) diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSelector.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSelector.java similarity index 82% rename from community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSelector.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSelector.java index 13d5c9ef74598..6ad0d1d9eb226 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/NativeSelector.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSelector.java @@ -17,16 +17,15 @@ * 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; +package org.neo4j.kernel.impl.index.schema.fusion; -import org.neo4j.kernel.impl.index.schema.fusion.FusionSchemaIndexProvider; import org.neo4j.values.storable.Value; import org.neo4j.values.storable.ValueGroup; -public class NativeSelector implements FusionSchemaIndexProvider.Selector +public class FusionSelector implements FusionSchemaIndexProvider.Selector { @Override - public T select( T numberInstance, T spatialInstance, T luceneInstance, Value... values ) + public T select( T numberInstance, T spatialInstance, T temporalInstance, T luceneInstance, Value... values ) { if ( values.length > 1 ) { @@ -46,6 +45,12 @@ public T select( T numberInstance, T spatialInstance, T luceneInstance, Valu // It's a geometry, the spatial index can handle this return spatialInstance; } + + // TODO this needs to check all temporal groups + if ( singleValue.valueGroup() == ValueGroup.DATE ) + { + return temporalInstance; + } return luceneInstance; } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/api/index/IndexProviderCompatibilityTestSuite.java b/community/kernel/src/test/java/org/neo4j/kernel/api/index/IndexProviderCompatibilityTestSuite.java index 9cc2a82bac131..083c9d703cfd4 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/api/index/IndexProviderCompatibilityTestSuite.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/api/index/IndexProviderCompatibilityTestSuite.java @@ -25,6 +25,8 @@ import org.junit.runners.Suite; import java.io.File; +import java.util.Arrays; +import java.util.List; import org.neo4j.function.ThrowingConsumer; import org.neo4j.io.fs.FileSystemAbstraction; @@ -33,6 +35,10 @@ import org.neo4j.test.rule.PageCacheAndDependenciesRule; import org.neo4j.test.rule.fs.DefaultFileSystemRule; import org.neo4j.test.runner.ParameterizedSuiteRunner; +import org.neo4j.values.storable.CoordinateReferenceSystem; +import org.neo4j.values.storable.DateValue; +import org.neo4j.values.storable.Value; +import org.neo4j.values.storable.Values; @RunWith( ParameterizedSuiteRunner.class ) @Suite.SuiteClasses( { @@ -50,6 +56,14 @@ public abstract class IndexProviderCompatibilityTestSuite { protected abstract SchemaIndexProvider createIndexProvider( PageCache pageCache, FileSystemAbstraction fs, File graphDbDir ); + public abstract Iterable getSupportedValues(); + + protected List commonValues = Arrays.asList( Values.of( "string1" ), Values.of( 42 ) ); + protected List temporalValues = Arrays.asList( DateValue.epochDate( 2 ), DateValue.epochDate( 5 ) ); + protected List spatialValues = Arrays.asList( + Values.pointValue( CoordinateReferenceSystem.Cartesian, 0, 0 ), + Values.pointValue( CoordinateReferenceSystem.WGS84, 12.78, 56.7 ) ); + public abstract static class Compatibility { @Rule diff --git a/community/kernel/src/test/java/org/neo4j/kernel/api/index/SimpleIndexPopulatorCompatibility.java b/community/kernel/src/test/java/org/neo4j/kernel/api/index/SimpleIndexPopulatorCompatibility.java index ec19d6bd8a909..b2a60a0b4a6df 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/api/index/SimpleIndexPopulatorCompatibility.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/api/index/SimpleIndexPopulatorCompatibility.java @@ -22,16 +22,23 @@ import org.junit.Ignore; import org.junit.Test; +import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import org.neo4j.collection.primitive.PrimitiveLongCollections; import org.neo4j.collection.primitive.PrimitiveLongIterator; +import org.neo4j.internal.kernel.api.IndexOrder; import org.neo4j.internal.kernel.api.IndexQuery; +import org.neo4j.internal.kernel.api.schema.LabelSchemaDescriptor; import org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException; +import org.neo4j.kernel.api.exceptions.index.IndexNotApplicableKernelException; import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; +import org.neo4j.kernel.impl.index.schema.NodeValueIterator; import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.values.storable.Value; import org.neo4j.values.storable.ValueTuple; @@ -40,7 +47,9 @@ import static java.util.Collections.singletonList; import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.neo4j.helpers.collection.Iterators.asSet; import static org.neo4j.internal.kernel.api.InternalIndexState.FAILED; @@ -59,6 +68,8 @@ public SimpleIndexPopulatorCompatibility( super( testSuite, descriptor ); } + private final IndexSamplingConfig indexSamplingConfig = new IndexSamplingConfig( Config.defaults() ); + @Test public void shouldStorePopulationFailedForRetrievalFromProviderLater() throws Exception { @@ -122,15 +133,14 @@ public void shouldApplyUpdatesIdempotently() throws Exception { p.create(); long nodeId = 1; - PropertyAccessor propertyAccessor = - ( nodeId1, propertyKeyId ) -> propertyValue; - // this update (using add())... - p.add( singletonList( IndexEntryUpdate.add( nodeId, descriptor.schema(), propertyValue ) ) ); - // ...is the same as this update (using update()) - try ( IndexUpdater updater = p.newPopulatingUpdater( propertyAccessor ) ) + // update using populator... + IndexEntryUpdate update = add( nodeId, descriptor.schema(), propertyValue ); + p.add( singletonList( update ) ); + // ...is the same as update using updater + try ( IndexUpdater updater = p.newPopulatingUpdater( ( node, propertyId ) -> propertyValue ) ) { - updater.process( add( nodeId, descriptor.schema(), propertyValue ) ); + updater.process( update ); } p.close( true ); @@ -149,6 +159,112 @@ public void shouldApplyUpdatesIdempotently() throws Exception } } + private List allValues( Iterable supportedValues ) + { + long nodeIds = 0; + List result = new ArrayList<>(); + for ( Value value : supportedValues ) + { + result.add( new NodeAndValue( nodeIds++, value ) ); + } + return result; + } + + private List allValues = allValues( testSuite.getSupportedValues() ); + + static class NodeAndValue + { + final long nodeId; + final Value value; + + NodeAndValue( long nodeId, Value value ) + { + this.nodeId = nodeId; + this.value = value; + } + } + + @Test + public void shouldPopulateWithAllValues() throws Exception + { + // GIVEN + withPopulator( indexProvider.getPopulator( 17, descriptor, indexSamplingConfig ), p -> + { + p.create(); + + List> updates = new ArrayList<>(); + allValues.forEach( entry -> updates.add( IndexEntryUpdate.add( entry.nodeId, descriptor.schema(), entry.value ) ) ); + + p.add( updates ); + + p.close( true ); + } ); + + // then + assertHasAllValues(); + } + + @Test + public void shouldUpdateWithAllValuesDuringPopulation() throws Exception + { + // GIVEN + withPopulator( indexProvider.getPopulator( 17, descriptor, indexSamplingConfig ), p -> + { + p.create(); + + try ( IndexUpdater updater = p.newPopulatingUpdater( this::allValueLookup ) ) + { + for ( NodeAndValue entry : allValues ) + { + updater.process( IndexEntryUpdate.add( entry.nodeId, descriptor.schema(), entry.value ) ); + } + } + + p.close( true ); + } ); + + // then + assertHasAllValues(); + } + + private Value allValueLookup( long nodeId, int propertyId ) + { + for ( NodeAndValue x : allValues ) + { + if ( x.nodeId == nodeId ) + { + return x.value; + } + } + return Values.NO_VALUE; + } + + private void assertHasAllValues() throws IOException, IndexNotApplicableKernelException + { + try ( IndexAccessor accessor = indexProvider.getOnlineAccessor( 17, descriptor, indexSamplingConfig ) ) + { + try ( IndexReader reader = accessor.newReader() ) + { + int propertyKeyId = descriptor.schema().getPropertyId(); + for ( NodeAndValue entry : allValues ) + { + NodeValueIterator nodes = new NodeValueIterator(); + reader.query( nodes, IndexOrder.NONE, IndexQuery.exact( propertyKeyId, entry.value ) ); + assertEquals( entry.nodeId, getOnly( nodes ) ); + } + } + accessor.close(); + } + } + + private long getOnly( PrimitiveLongIterator nodes ) + { + assertTrue( nodes.hasNext() ); + long id = nodes.next(); + assertFalse( nodes.hasNext() ); + return id; + } + @Ignore( "Not a test. This is a compatibility suite" ) public static class General extends SimpleIndexPopulatorCompatibility { diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/inmemory/InMemoryIndexProviderTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/inmemory/InMemoryIndexProviderTest.java index 2613d73489bb2..a117b8c5c7e50 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/inmemory/InMemoryIndexProviderTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/inmemory/InMemoryIndexProviderTest.java @@ -21,10 +21,12 @@ import java.io.File; +import org.neo4j.helpers.collection.Iterables; import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.io.pagecache.PageCache; import org.neo4j.kernel.api.index.IndexProviderCompatibilityTestSuite; import org.neo4j.kernel.api.index.SchemaIndexProvider; +import org.neo4j.values.storable.Value; public class InMemoryIndexProviderTest extends IndexProviderCompatibilityTestSuite { @@ -33,4 +35,10 @@ protected SchemaIndexProvider createIndexProvider( PageCache pageCache, FileSyst { return new InMemoryIndexProvider(); } + + @Override + public Iterable getSupportedValues() + { + return Iterables.concat( commonValues, spatialValues, temporalValues ); + } } 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 f07db6454c442..4cbd8d4e5967f 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 @@ -30,7 +30,6 @@ import org.neo4j.helpers.collection.Iterators; import org.neo4j.kernel.api.index.IndexAccessor; import org.neo4j.kernel.api.schema.index.IndexDescriptor; -import org.neo4j.kernel.impl.index.schema.NativeSelector; import org.neo4j.kernel.impl.index.schema.fusion.FusionSchemaIndexProvider.DropAction; import static org.hamcrest.CoreMatchers.is; @@ -54,6 +53,7 @@ public class FusionIndexAccessorTest { private IndexAccessor nativeAccessor; private IndexAccessor spatialAccessor; + private IndexAccessor temporalAccessor; private IndexAccessor luceneAccessor; private FusionIndexAccessor fusionIndexAccessor; private final long indexId = 10; @@ -64,9 +64,10 @@ public void setup() { nativeAccessor = mock( IndexAccessor.class ); spatialAccessor = mock( IndexAccessor.class ); + temporalAccessor = mock( IndexAccessor.class ); luceneAccessor = mock( IndexAccessor.class ); - fusionIndexAccessor = new FusionIndexAccessor( nativeAccessor, spatialAccessor, luceneAccessor, - new NativeSelector(), indexId, mock( IndexDescriptor.class ), dropAction ); + fusionIndexAccessor = new FusionIndexAccessor( nativeAccessor, spatialAccessor, temporalAccessor, luceneAccessor, + new FusionSelector(), indexId, mock( IndexDescriptor.class ), dropAction ); } /* drop */ diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulatorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulatorTest.java index bd4ec25da81cf..2df9b1ed17292 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulatorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulatorTest.java @@ -30,7 +30,6 @@ 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.impl.index.schema.NativeSelector; import org.neo4j.kernel.impl.index.schema.fusion.FusionSchemaIndexProvider.DropAction; import org.neo4j.values.storable.Value; @@ -53,6 +52,7 @@ public class FusionIndexPopulatorTest { private IndexPopulator numberPopulator; private IndexPopulator spatialPopulator; + private IndexPopulator temporalPopulator; private IndexPopulator lucenePopulator; private IndexPopulator[] allPopulators; private FusionIndexPopulator fusionIndexPopulator; @@ -64,9 +64,11 @@ public void mockComponents() { numberPopulator = mock( IndexPopulator.class ); spatialPopulator = mock( IndexPopulator.class ); + temporalPopulator = mock( IndexPopulator.class ); lucenePopulator = mock( IndexPopulator.class ); - allPopulators = new IndexPopulator[]{numberPopulator, spatialPopulator, lucenePopulator}; - fusionIndexPopulator = new FusionIndexPopulator( numberPopulator, spatialPopulator, lucenePopulator, new NativeSelector(), indexId, dropAction ); + allPopulators = new IndexPopulator[]{numberPopulator, spatialPopulator, temporalPopulator, lucenePopulator}; + fusionIndexPopulator = + new FusionIndexPopulator( numberPopulator, spatialPopulator, temporalPopulator, lucenePopulator, new FusionSelector(), indexId, dropAction ); } /* create */ diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReaderTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReaderTest.java index 9592b2bb5b49c..a8255989b2331 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReaderTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReaderTest.java @@ -36,7 +36,6 @@ import org.neo4j.internal.kernel.api.IndexQuery.StringSuffixPredicate; import org.neo4j.kernel.api.exceptions.index.IndexNotApplicableKernelException; import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory; -import org.neo4j.kernel.impl.index.schema.NativeSelector; import org.neo4j.storageengine.api.schema.IndexReader; import org.neo4j.values.storable.CoordinateReferenceSystem; import org.neo4j.values.storable.PointValue; @@ -56,6 +55,7 @@ public class FusionIndexReaderTest private IndexReader nativeReader; private IndexReader spatialReader; private IndexReader luceneReader; + private IndexReader temporalReader; private IndexReader[] allReaders; private FusionIndexReader fusionIndexReader; private static final int PROP_KEY = 1; @@ -66,9 +66,10 @@ public void setup() { nativeReader = mock( IndexReader.class ); spatialReader = mock( IndexReader.class ); + temporalReader = mock( IndexReader.class ); luceneReader = mock( IndexReader.class ); - allReaders = new IndexReader[]{nativeReader, spatialReader, luceneReader}; - fusionIndexReader = new FusionIndexReader( nativeReader, spatialReader, luceneReader, new NativeSelector(), + allReaders = new IndexReader[]{nativeReader, spatialReader, temporalReader, luceneReader}; + fusionIndexReader = new FusionIndexReader( nativeReader, spatialReader, temporalReader, luceneReader, new FusionSelector(), IndexDescriptorFactory.forLabel( LABEL_KEY, PROP_KEY ) ); } 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 aef320fd883aa..846a15dd3ba5b 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 @@ -28,7 +28,6 @@ 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.kernel.impl.index.schema.NativeSelector; import org.neo4j.values.storable.Value; import static org.mockito.Mockito.mock; @@ -43,6 +42,7 @@ public class FusionIndexUpdaterTest { private IndexUpdater nativeUpdater; private IndexUpdater spatialUpdater; + private IndexUpdater temporalUpdater; private IndexUpdater luceneUpdater; private IndexUpdater[] allUpdaters; private FusionIndexUpdater fusionIndexUpdater; @@ -52,9 +52,10 @@ public void setup() { nativeUpdater = mock( IndexUpdater.class ); spatialUpdater = mock( IndexUpdater.class ); + temporalUpdater = mock( IndexUpdater.class ); luceneUpdater = mock( IndexUpdater.class ); - allUpdaters = new IndexUpdater[]{nativeUpdater, spatialUpdater, luceneUpdater}; - fusionIndexUpdater = new FusionIndexUpdater( nativeUpdater, spatialUpdater, luceneUpdater, new NativeSelector() ); + allUpdaters = new IndexUpdater[]{nativeUpdater, spatialUpdater, temporalUpdater, luceneUpdater}; + fusionIndexUpdater = new FusionIndexUpdater( nativeUpdater, spatialUpdater, temporalUpdater, luceneUpdater, new FusionSelector() ); } /* process */ diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProviderTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProviderTest.java index 294bc7775a362..30e851dcfce9f 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProviderTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProviderTest.java @@ -28,7 +28,6 @@ import org.neo4j.kernel.api.index.SchemaIndexProvider; import org.neo4j.kernel.api.schema.index.IndexDescriptor; import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory; -import org.neo4j.kernel.impl.index.schema.NativeSelector; import org.neo4j.kernel.impl.index.schema.fusion.FusionSchemaIndexProvider.Selector; import org.neo4j.storageengine.api.schema.IndexSample; import org.neo4j.test.rule.RandomRule; @@ -53,6 +52,7 @@ public class FusionSchemaIndexProviderTest private SchemaIndexProvider nativeProvider; private SchemaIndexProvider spatialProvider; + private SchemaIndexProvider temporalProvider; private SchemaIndexProvider luceneProvider; @Before @@ -60,9 +60,11 @@ public void setup() { nativeProvider = mock( SchemaIndexProvider.class ); spatialProvider = mock( SchemaIndexProvider.class ); + temporalProvider = mock( SchemaIndexProvider.class ); luceneProvider = mock( SchemaIndexProvider.class ); when( nativeProvider.getProviderDescriptor() ).thenReturn( new SchemaIndexProvider.Descriptor( "native", "1" ) ); when( spatialProvider.getProviderDescriptor() ).thenReturn( new SchemaIndexProvider.Descriptor( "spatial", "1" ) ); + when( temporalProvider.getProviderDescriptor() ).thenReturn( new SchemaIndexProvider.Descriptor( "temporal", "1" ) ); when( luceneProvider.getProviderDescriptor() ).thenReturn( new SchemaIndexProvider.Descriptor( "lucene", "1" ) ); } @@ -79,11 +81,11 @@ public void mustSelectCorrectTargetForAllGivenValueCombinations() Value[] allValues = FusionIndexTestHelp.allValues(); // Number values should go to native provider - Selector selector = new NativeSelector(); + Selector selector = new FusionSelector(); for ( Value numberValue : numberValues ) { // when - SchemaIndexProvider selected = selector.select( nativeProvider, spatialProvider, luceneProvider, numberValue ); + SchemaIndexProvider selected = selector.select( nativeProvider, spatialProvider, temporalProvider, luceneProvider, numberValue ); // then assertSame( nativeProvider, selected ); @@ -93,7 +95,7 @@ public void mustSelectCorrectTargetForAllGivenValueCombinations() for ( Value spatialValue : spatialValues ) { // when - SchemaIndexProvider selected = selector.select( nativeProvider, spatialProvider, luceneProvider, spatialValue ); + SchemaIndexProvider selected = selector.select( nativeProvider, spatialProvider, temporalProvider, luceneProvider, spatialValue ); // then assertSame( spatialProvider, selected ); @@ -103,7 +105,7 @@ public void mustSelectCorrectTargetForAllGivenValueCombinations() for ( Value otherValue : otherValues ) { // when - SchemaIndexProvider selected = selector.select( nativeProvider, spatialProvider, luceneProvider, otherValue ); + SchemaIndexProvider selected = selector.select( nativeProvider, spatialProvider, temporalProvider, luceneProvider, otherValue ); // then assertSame( luceneProvider, selected ); @@ -115,7 +117,7 @@ public void mustSelectCorrectTargetForAllGivenValueCombinations() for ( Value secondValue : allValues ) { // when - SchemaIndexProvider selected = selector.select( nativeProvider, spatialProvider, luceneProvider, firstValue, secondValue ); + SchemaIndexProvider selected = selector.select( nativeProvider, spatialProvider, temporalProvider, luceneProvider, firstValue, secondValue ); // then assertSame( luceneProvider, selected ); @@ -332,7 +334,7 @@ public void shouldReportPopulatingIfAnyIsPopulating() private FusionSchemaIndexProvider fusionProvider() { - return new FusionSchemaIndexProvider( nativeProvider, spatialProvider, luceneProvider, new NativeSelector(), DESCRIPTOR, 10, NONE, + return new FusionSchemaIndexProvider( nativeProvider, spatialProvider, temporalProvider, luceneProvider, new FusionSelector(), DESCRIPTOR, 10, NONE, mock( FileSystemAbstraction.class ) ); } diff --git a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/schema/NativeLuceneFusionSchemaIndexProviderFactory.java b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/schema/NativeLuceneFusionSchemaIndexProviderFactory.java index 272289e5fcf2b..41a94b31fbf85 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 @@ -33,10 +33,10 @@ import org.neo4j.kernel.extension.KernelExtensionFactory; import org.neo4j.kernel.impl.factory.OperationalMode; import org.neo4j.kernel.impl.index.schema.NumberSchemaIndexProvider; -import org.neo4j.kernel.impl.index.schema.NativeSelector; +import org.neo4j.kernel.impl.index.schema.TemporalSchemaIndexProvider; import org.neo4j.kernel.impl.index.schema.fusion.FusionSchemaIndexProvider; +import org.neo4j.kernel.impl.index.schema.fusion.FusionSelector; import org.neo4j.kernel.impl.index.schema.fusion.SpatialFusionSchemaIndexProvider; -import org.neo4j.kernel.impl.index.schema.TemporalSchemaIndexProvider; import org.neo4j.kernel.impl.spi.KernelContext; import org.neo4j.kernel.monitoring.Monitors; import org.neo4j.logging.Log; @@ -98,7 +98,7 @@ public static FusionSchemaIndexProvider newInstance( PageCache pageCache, File s boolean useNativeIndex = config.get( GraphDatabaseSettings.enable_native_schema_index ); int priority = useNativeIndex ? PRIORITY : 0; return new FusionSchemaIndexProvider( nativeProvider, - spatialProvider, temporalProvider, luceneProvider, new NativeSelector(), DESCRIPTOR, priority, directoriesByProvider( storeDir ), fs ); + spatialProvider, temporalProvider, luceneProvider, new FusionSelector(), DESCRIPTOR, priority, directoriesByProvider( storeDir ), fs ); } public static IndexDirectoryStructure.Factory subProviderDirectoryStructure( File storeDir )