Skip to content

Commit

Permalink
IndexProviderCompatibilityTestSuite consistency checks GB+Tree
Browse files Browse the repository at this point in the history
After each accessor/populator test
  • Loading branch information
tinwelint committed Sep 11, 2018
1 parent 136e95e commit 5186166
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 3 deletions.
Expand Up @@ -25,7 +25,11 @@

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.neo4j.internal.kernel.api.IndexQuery;
import org.neo4j.internal.kernel.api.schema.SchemaDescriptor;
Expand All @@ -37,16 +41,20 @@
import org.neo4j.values.storable.DateTimeValue;
import org.neo4j.values.storable.PointArray;
import org.neo4j.values.storable.PointValue;
import org.neo4j.values.storable.RandomValues;
import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.ValueGroup;
import org.neo4j.values.storable.ValueTuple;
import org.neo4j.values.storable.Values;

import static java.time.LocalDate.ofEpochDay;
import static java.util.Arrays.asList;
import static java.util.Collections.EMPTY_LIST;
import static java.util.Collections.singletonList;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.neo4j.helpers.collection.Iterables.single;
import static org.neo4j.internal.kernel.api.IndexQuery.exists;
import static org.neo4j.internal.kernel.api.IndexQuery.range;
import static org.neo4j.kernel.api.index.IndexQueryHelper.exact;
Expand Down Expand Up @@ -606,6 +614,37 @@ public void testIndexSeekRangeWithExistsBySpatialArray() throws Exception
pointArray( new PointValue[] {pointValue( Cartesian, 40D, 4D ), pointValue( Cartesian, 40D, 5D )} ) );
}

@Test
public void testExactMatchOnRandomCompositeValues() throws Exception
{
// given
List<RandomValues.Types> types = testSuite.supportedValueTypes();
List<IndexEntryUpdate<?>> updates = new ArrayList<>();
Set<ValueTuple> duplicateChecker = new HashSet<>();
for ( long id = 0; id < 10_000; id++ )
{
IndexEntryUpdate<SchemaDescriptor> update;
do
{
update = add( id, descriptor.schema(),
random.nextValue( random.among( types ) ),
random.nextValue( random.among( types ) ) );
}
while ( !duplicateChecker.add( ValueTuple.of( update.values() ) ) );
updates.add( update );
}
updateAndCommit( updates );

// when
for ( IndexEntryUpdate<?> update : updates )
{
// then
List<Long> hits = query( exact( 0, update.values()[0] ), exact( 1, update.values()[1] ) );
assertEquals( update + " " + hits.toString(), 1, hits.size() );
assertThat( single( hits ), equalTo( update.getEntityId() ) );
}
}

private void testIndexSeekRangeWithExists( Object obj1, Object obj2, Object obj3, Object obj4, Object obj5 ) throws Exception
{
testIndexSeekRangeWithExists( Values.of( obj1 ), Values.of( obj2 ), Values.of( obj3 ), Values.of( obj4 ), Values.of( obj5 ) );
Expand Down
Expand Up @@ -27,6 +27,8 @@
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.impl.factory.OperationalMode;
import org.neo4j.kernel.impl.index.schema.GenericNativeIndexProviderFactory;
import org.neo4j.kernel.impl.index.schema.NativeIndexAccessor;
import org.neo4j.kernel.impl.index.schema.NativeIndexPopulator;

import static org.neo4j.graphdb.factory.GraphDatabaseSettings.SchemaIndex.NATIVE_BTREE10;
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.default_schema_provider;
Expand Down Expand Up @@ -61,4 +63,16 @@ public boolean supportsBooleanRangeQueries()
{
return true;
}

@Override
public void consistencyCheck( IndexAccessor accessor )
{
((NativeIndexAccessor) accessor).consistencyCheck();
}

@Override
public void consistencyCheck( IndexPopulator populator )
{
((NativeIndexPopulator) populator).consistencyCheck();
}
}
Expand Up @@ -22,6 +22,7 @@
import org.junit.After;
import org.junit.Before;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
Expand Down Expand Up @@ -63,8 +64,15 @@ public void before() throws Exception
@After
public void after()
{
accessor.drop();
accessor.close();
try
{
testSuite.consistencyCheck( accessor );
}
finally
{
accessor.drop();
accessor.close();
}
}

protected List<Long> query( IndexQuery... predicates ) throws Exception
Expand Down Expand Up @@ -117,7 +125,7 @@ private boolean passesFilter( long entityId, IndexQuery[] predicates )
* Commit these updates to the index. Also store the values, which currently are stored for all types except geometry,
* so therefore it's done explicitly here so that we can filter on them later.
*/
void updateAndCommit( List<IndexEntryUpdate<?>> updates ) throws IndexEntryConflictException
void updateAndCommit( Collection<IndexEntryUpdate<?>> updates ) throws IndexEntryConflictException
{
try ( IndexUpdater updater = accessor.newUpdater( IndexUpdateMode.ONLINE ) )
{
Expand Down
Expand Up @@ -52,6 +52,7 @@
import org.neo4j.values.storable.DurationValue;
import org.neo4j.values.storable.LocalDateTimeValue;
import org.neo4j.values.storable.LocalTimeValue;
import org.neo4j.values.storable.RandomValues;
import org.neo4j.values.storable.TimeValue;
import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.Values;
Expand Down Expand Up @@ -91,6 +92,29 @@ public boolean supportsBooleanRangeQueries()
return false;
};

public List<RandomValues.Types> supportedValueTypes()
{
List<RandomValues.Types> types = new ArrayList<>( Arrays.asList( RandomValues.Types.values() ) );
if ( !supportsSpatial() )
{
types.remove( RandomValues.Types.CARTESIAN_POINT );
types.remove( RandomValues.Types.CARTESIAN_POINT_3D );
types.remove( RandomValues.Types.GEOGRAPHIC_POINT );
types.remove( RandomValues.Types.GEOGRAPHIC_POINT_3D );
}
return types;
}

public void consistencyCheck( IndexAccessor accessor )
{
// no-op by default
}

public void consistencyCheck( IndexPopulator populator )
{
// no-op by default
}

public abstract static class Compatibility
{
private final PageCacheAndDependenciesRule pageCacheAndDependenciesRule;
Expand Down Expand Up @@ -254,6 +278,10 @@ void withPopulator( IndexPopulator populator, ThrowingConsumer<IndexPopulator,Ex
{
populator.create();
runWithPopulator.accept( populator );
if ( closeSuccessfully )
{
testSuite.consistencyCheck( populator );
}
}
finally
{
Expand Down
Expand Up @@ -34,12 +34,14 @@
import java.util.function.Supplier;

import org.neo4j.internal.kernel.api.IndexQuery;
import org.neo4j.internal.kernel.api.schema.SchemaDescriptor;
import org.neo4j.kernel.api.schema.index.TestIndexDescriptorFactory;
import org.neo4j.storageengine.api.schema.IndexDescriptor;
import org.neo4j.values.storable.BooleanValue;
import org.neo4j.values.storable.CoordinateReferenceSystem;
import org.neo4j.values.storable.DateTimeValue;
import org.neo4j.values.storable.PointValue;
import org.neo4j.values.storable.RandomValues;
import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.Values;

Expand All @@ -49,7 +51,9 @@
import static java.util.Collections.singletonList;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.neo4j.helpers.collection.Iterables.single;
import static org.neo4j.internal.kernel.api.IndexQuery.exact;
import static org.neo4j.internal.kernel.api.IndexQuery.exists;
import static org.neo4j.internal.kernel.api.IndexQuery.range;
Expand Down Expand Up @@ -584,6 +588,35 @@ public void testIndexShouldHandleLargeAmountOfDuplicatesStringArray() throws Exc
doTestShouldHandleLargeAmountOfDuplicates( arrayValue );
}

@Test
public void testExactMatchOnRandomValues() throws Exception
{
// given
List<RandomValues.Types> types = testSuite.supportedValueTypes();
List<IndexEntryUpdate<?>> updates = new ArrayList<>();
Set<Value> duplicateChecker = new HashSet<>();
for ( long id = 0; id < 10_000; id++ )
{
IndexEntryUpdate<SchemaDescriptor> update;
do
{
update = add( id, descriptor.schema(), random.nextValue( random.among( types ) ) );
}
while ( !duplicateChecker.add( update.values()[0] ) );
updates.add( update );
}
updateAndCommit( updates );

// when
for ( IndexEntryUpdate<?> update : updates )
{
// then
List<Long> hits = query( IndexQuery.exact( 0, update.values()[0] ) );
assertEquals( hits.toString(), 1, hits.size() );
assertThat( single( hits ), equalTo( update.getEntityId() ) );
}
}

private void doTestShouldHandleLargeAmountOfDuplicates( Object value ) throws Exception
{
List<IndexEntryUpdate<?>> updates = new ArrayList<>();
Expand Down
Expand Up @@ -101,6 +101,18 @@ void assertOpen()
}
}

public void consistencyCheck()
{
try
{
tree.consistencyCheck();
}
catch ( IOException e )
{
throw new UncheckedIOException( e );
}
}

private class NativeIndexTreeMonitor extends GBPTree.Monitor.Adaptor
{
@Override
Expand Down

0 comments on commit 5186166

Please sign in to comment.