diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/IndexSamplerWrapper.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/IndexSamplerWrapper.java
new file mode 100644
index 0000000000000..51a42307fcaca
--- /dev/null
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/IndexSamplerWrapper.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2002-2018 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.neo4j.kernel.impl.index.schema;
+
+import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor;
+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.UniqueIndexSampler;
+import org.neo4j.storageengine.api.schema.IndexSample;
+import org.neo4j.values.storable.Value;
+
+class IndexSamplerWrapper
+{
+ private final DefaultNonUniqueIndexSampler generalSampler;
+ private final UniqueIndexSampler uniqueSampler;
+
+ IndexSamplerWrapper( SchemaIndexDescriptor descriptor, IndexSamplingConfig samplingConfig )
+ {
+ switch ( descriptor.type() )
+ {
+ case GENERAL:
+ generalSampler = new DefaultNonUniqueIndexSampler( samplingConfig.sampleSizeLimit() );
+ uniqueSampler = null;
+ break;
+ case UNIQUE:
+ generalSampler = null;
+ uniqueSampler = new UniqueIndexSampler();
+ break;
+ default:
+ throw new UnsupportedOperationException( "Unexpected index type " + descriptor.type() );
+ }
+ }
+
+ void includeSample( Value[] values )
+ {
+ if ( uniqueSampler != null )
+ {
+ uniqueSampler.increment( 1 );
+ }
+ else
+ {
+ generalSampler.include( SamplingUtil.encodedStringValuesForSampling( (Object[]) values ) );
+ }
+ }
+
+ IndexSample sampleResult()
+ {
+ if ( uniqueSampler != null )
+ {
+ return uniqueSampler.result();
+ }
+ else
+ {
+ return generalSampler.result();
+ }
+ }
+}
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexAccessor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexAccessor.java
index a65e1a72ee7b5..3884b5eda5658 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexAccessor.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexAccessor.java
@@ -206,6 +206,7 @@ static class PartAccessor extends NativeSchemaIndexAccessor newReader()
{
+ assertOpen();
return new SpatialIndexPartReader<>( tree, layout, samplingConfig, descriptor, searchConfiguration );
}
}
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexFiles.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexFiles.java
index 756a7134cd693..837768d787b57 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexFiles.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexFiles.java
@@ -96,7 +96,7 @@ static class SpatialFileLayout
private final CoordinateReferenceSystem crs;
Layout layout;
- private SpatialFileLayout( CoordinateReferenceSystem crs, SpaceFillingCurveSettings settings, File indexDirectory )
+ SpatialFileLayout( CoordinateReferenceSystem crs, SpaceFillingCurveSettings settings, File indexDirectory )
{
this.crs = crs;
this.settings = settings;
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexPopulator.java
index 6b87b45892daa..715e7bbda2fdf 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexPopulator.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/SpatialIndexPopulator.java
@@ -24,6 +24,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
+import java.util.stream.StreamSupport;
import java.util.Map;
import org.neo4j.gis.spatial.index.curves.SpaceFillingCurveConfiguration;
@@ -37,9 +38,7 @@
import org.neo4j.kernel.api.index.IndexUpdater;
import org.neo4j.kernel.api.index.PropertyAccessor;
import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor;
-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.UniqueIndexSampler;
import org.neo4j.kernel.impl.index.schema.config.SpaceFillingCurveSettings;
import org.neo4j.storageengine.api.schema.IndexReader;
import org.neo4j.storageengine.api.schema.IndexSample;
@@ -48,11 +47,10 @@
import org.neo4j.values.storable.Value;
import static org.neo4j.kernel.impl.index.schema.fusion.FusionIndexBase.forAll;
+import static org.neo4j.kernel.impl.index.schema.fusion.FusionIndexSampler.combineSamples;
class SpatialIndexPopulator extends SpatialIndexCache implements IndexPopulator
{
- private final IndexSamplerWrapper sampler;
-
SpatialIndexPopulator( long indexId,
SchemaIndexDescriptor descriptor,
IndexSamplingConfig samplingConfig,
@@ -63,7 +61,6 @@ class SpatialIndexPopulator extends SpatialIndexCache update )
{
- sampler.includeSample( update.values() );
+ Value[] values = update.values();
+ assert values.length == 1;
+ uncheckedSelect( ((PointValue) values[0]).getCoordinateReferenceSystem() ).includeSample( update );
}
@Override
public IndexSample sampleResult()
{
- return sampler.sampleResult();
- }
-
- private static class IndexSamplerWrapper
- {
- private final DefaultNonUniqueIndexSampler generalSampler;
- private final UniqueIndexSampler uniqueSampler;
-
- IndexSamplerWrapper( SchemaIndexDescriptor descriptor, IndexSamplingConfig samplingConfig )
- {
- switch ( descriptor.type() )
- {
- case GENERAL:
- generalSampler = new DefaultNonUniqueIndexSampler( samplingConfig.sampleSizeLimit() );
- uniqueSampler = null;
- break;
- case UNIQUE:
- generalSampler = null;
- uniqueSampler = new UniqueIndexSampler();
- break;
- default:
- throw new UnsupportedOperationException( "Unexpected index type " + descriptor.type() );
- }
- }
-
- void includeSample( Value[] values )
- {
- if ( uniqueSampler != null )
- {
- uniqueSampler.increment( 1 );
- }
- else
- {
- generalSampler.include( SamplingUtil.encodedStringValuesForSampling( (Object[]) values ) );
- }
- }
-
- IndexSample sampleResult()
- {
- if ( uniqueSampler != null )
- {
- return uniqueSampler.result();
- }
- else
- {
- return generalSampler.result();
- }
- }
+ IndexSample[] indexSamples = StreamSupport.stream( this.spliterator(), false )
+ .map( PartPopulator::sampleResult )
+ .toArray( IndexSample[]::new );
+ return combineSamples( indexSamples );
}
static class PartPopulator extends NativeSchemaIndexPopulator
{
private final SpaceFillingCurveConfiguration configuration;
private final SpaceFillingCurveSettings settings;
+ private final IndexSamplerWrapper sampler;
PartPopulator( PageCache pageCache, FileSystemAbstraction fs, SpatialIndexFiles.SpatialFileLayout fileLayout,
IndexProvider.Monitor monitor, SchemaIndexDescriptor descriptor, long indexId, IndexSamplingConfig samplingConfig,
@@ -197,6 +153,7 @@ static class PartPopulator extends NativeSchemaIndexPopulator update )
{
- throw new UnsupportedOperationException( "please to not get here!" );
+ sampler.includeSample( update.values() );
}
@Override
public IndexSample sampleResult()
{
- throw new UnsupportedOperationException( "this sampling code needs a rewrite." );
+ return sampler.sampleResult();
}
@Override
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 ac7ccc43b33e1..b2aab992c5922 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
@@ -193,6 +193,7 @@ static class PartAccessor> extends NativeSchema
@Override
public TemporalIndexPartReader newReader()
{
+ assertOpen();
return new TemporalIndexPartReader<>( tree, layout, samplingConfig, descriptor );
}
}
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/TemporalIndexPopulator.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/TemporalIndexPopulator.java
index a488922197260..d90ea94f26e20 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/TemporalIndexPopulator.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/TemporalIndexPopulator.java
@@ -24,6 +24,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
+import java.util.stream.StreamSupport;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
@@ -36,20 +37,17 @@
import org.neo4j.kernel.api.index.IndexUpdater;
import org.neo4j.kernel.api.index.PropertyAccessor;
import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor;
-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.UniqueIndexSampler;
import org.neo4j.storageengine.api.schema.IndexReader;
import org.neo4j.storageengine.api.schema.IndexSample;
import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.ValueGroup;
import static org.neo4j.kernel.impl.index.schema.fusion.FusionIndexBase.forAll;
+import static org.neo4j.kernel.impl.index.schema.fusion.FusionIndexSampler.combineSamples;
class TemporalIndexPopulator extends TemporalIndexCache> implements IndexPopulator
{
- private final IndexSamplerWrapper sampler;
-
TemporalIndexPopulator( long indexId,
SchemaIndexDescriptor descriptor,
IndexSamplingConfig samplingConfig,
@@ -59,7 +57,6 @@ class TemporalIndexPopulator extends TemporalIndexCache update )
{
- sampler.includeSample( update.values() );
+ Value[] values = update.values();
+ assert values.length == 1;
+ uncheckedSelect( values[0].valueGroup() ).includeSample( update );
}
@Override
public IndexSample sampleResult()
{
- return sampler.sampleResult();
- }
-
- private static class IndexSamplerWrapper
- {
- private final DefaultNonUniqueIndexSampler generalSampler;
- private final UniqueIndexSampler uniqueSampler;
-
- IndexSamplerWrapper( SchemaIndexDescriptor descriptor, IndexSamplingConfig samplingConfig )
- {
- switch ( descriptor.type() )
- {
- case GENERAL:
- generalSampler = new DefaultNonUniqueIndexSampler( samplingConfig.sampleSizeLimit() );
- uniqueSampler = null;
- break;
- case UNIQUE:
- generalSampler = null;
- uniqueSampler = new UniqueIndexSampler();
- break;
- default:
- throw new UnsupportedOperationException( "Unexpected index type " + descriptor.type() );
- }
- }
-
- void includeSample( Value[] values )
- {
- if ( uniqueSampler != null )
- {
- uniqueSampler.increment( 1 );
- }
- else
- {
- generalSampler.include( SamplingUtil.encodedStringValuesForSampling( (Object[]) values ) );
- }
- }
-
- IndexSample sampleResult()
- {
- if ( uniqueSampler != null )
- {
- return uniqueSampler.result();
- }
- else
- {
- return generalSampler.result();
- }
- }
+ IndexSample[] indexSamples = StreamSupport.stream( this.spliterator(), false )
+ .map( PartPopulator::sampleResult )
+ .toArray( IndexSample[]::new );
+ return combineSamples( indexSamples );
}
static class PartPopulator> extends NativeSchemaIndexPopulator
{
+ private final IndexSamplerWrapper sampler;
+
PartPopulator( PageCache pageCache, FileSystemAbstraction fs, TemporalIndexFiles.FileLayout fileLayout,
IndexProvider.Monitor monitor, SchemaIndexDescriptor descriptor, long indexId, IndexSamplingConfig samplingConfig )
{
super( pageCache, fs, fileLayout.indexFile, fileLayout.layout, monitor, descriptor, indexId, samplingConfig );
+ this.sampler = new IndexSamplerWrapper( descriptor, samplingConfig );
}
@Override
@@ -197,13 +155,13 @@ IndexReader newReader()
@Override
public void includeSample( IndexEntryUpdate> update )
{
- throw new UnsupportedOperationException( "please to not get here!" );
+ sampler.includeSample( update.values() );
}
@Override
public IndexSample sampleResult()
{
- throw new UnsupportedOperationException( "this sampling code needs a rewrite." );
+ return sampler.sampleResult();
}
}
diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexSampler.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexSampler.java
index 89ee8cf1a1ca7..9a1a76c5a6d6c 100644
--- a/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexSampler.java
+++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexSampler.java
@@ -19,8 +19,6 @@
*/
package org.neo4j.kernel.impl.index.schema.fusion;
-import java.util.Arrays;
-
import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException;
import org.neo4j.storageengine.api.schema.IndexSample;
import org.neo4j.storageengine.api.schema.IndexSampler;
@@ -45,11 +43,17 @@ public IndexSample sampleIndex() throws IndexNotFoundKernelException
return combineSamples( samples );
}
- static IndexSample combineSamples( IndexSample... samples )
+ public static IndexSample combineSamples( IndexSample... samples )
{
- return new IndexSample(
- Arrays.stream( samples ).mapToLong( IndexSample::indexSize ).sum(),
- Arrays.stream( samples ).mapToLong( IndexSample::uniqueValues ).sum(),
- Arrays.stream( samples ).mapToLong( IndexSample::sampleSize ).sum() );
+ long indexSize = 0;
+ long uniqueValues = 0;
+ long sampleSize = 0;
+ for ( IndexSample sample : samples )
+ {
+ indexSize += sample.indexSize();
+ uniqueValues += sample.uniqueValues();
+ sampleSize += sample.sampleSize();
+ }
+ return new IndexSample( indexSize, uniqueValues, sampleSize );
}
}
diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/DateLayoutTestUtil.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/DateLayoutTestUtil.java
new file mode 100644
index 0000000000000..e5e031eb5ea76
--- /dev/null
+++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/DateLayoutTestUtil.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2002-2018 "Neo Technology,"
+ * Network Engine for Objects in Lund AB [http://neotechnology.com]
+ *
+ * This file is part of Neo4j.
+ *
+ * Neo4j is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.neo4j.kernel.impl.index.schema;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Set;
+
+import org.neo4j.index.internal.gbptree.Layout;
+import org.neo4j.internal.kernel.api.IndexQuery;
+import org.neo4j.kernel.api.index.IndexEntryUpdate;
+import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor;
+import org.neo4j.test.rule.RandomRule;
+import org.neo4j.values.storable.DateValue;
+import org.neo4j.values.storable.Value;
+import org.neo4j.values.storable.Values;
+
+public class DateLayoutTestUtil extends LayoutTestUtil
+{
+ private static final LocalDate[] ALL_EXTREME_VALUES = new LocalDate[]
+ {
+ LocalDate.of( -999999999, 1, 1),
+ LocalDate.of( 999999999, 12, 31),
+ LocalDate.of( 0, 1, 1),
+ LocalDate.of( 0, 1, 2),
+ LocalDate.of( 0, 1, 3),
+ LocalDate.of( -1, 12, 31)
+ };
+
+ DateLayoutTestUtil( SchemaIndexDescriptor schemaIndexDescriptor )
+ {
+ super( schemaIndexDescriptor );
+ }
+
+ @Override
+ Layout createLayout()
+ {
+ return new DateLayout();
+ }
+
+ @Override
+ IndexEntryUpdate[] someUpdates()
+ {
+ return someUpdatesWithDuplicateValues();
+ }
+
+ @Override
+ IndexQuery rangeQuery( Object from, boolean fromInclusive, Object to, boolean toInclusive )
+ {
+ return IndexQuery.range( 0, (DateValue) from, fromInclusive, (DateValue) to, toInclusive );
+ }
+
+ @Override
+ int compareIndexedPropertyValue( DateSchemaKey key1, DateSchemaKey key2 )
+ {
+ return Values.COMPARATOR.compare( key1.asValue(), key2.asValue() );
+ }
+
+ @Override
+ Value newUniqueValue( RandomRule random, Set