Skip to content

Commit

Permalink
Use IndexOrder.NONE instead of null to indicate no ordering required
Browse files Browse the repository at this point in the history
  • Loading branch information
burqen committed Nov 16, 2017
1 parent e83bc7d commit 570e29b
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,17 @@
*/
package org.neo4j.internal.kernel.api;

import org.neo4j.values.storable.ValueGroup;

/**
* Enum used for two purposes:
* 1. As return value for {@link IndexCapability#orderCapability(ValueGroup...)}.
* Only {@link #ASCENDING} and {@link #DESCENDING} is valid for this.
* 2. As parameter for {@link Read#nodeIndexScan(IndexReference, NodeValueIndexCursor, IndexOrder)} and
* {@link Read#nodeIndexSeek(IndexReference, NodeValueIndexCursor, IndexOrder, IndexQuery...)}. Where {@link #NONE} is used when
* no ordering is available or required.
*/
public enum IndexOrder
{
ASCENDING, DESCENDING
ASCENDING, DESCENDING, NONE
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,19 @@ public interface Read
/**
* @param index {@link IndexReference} referencing index to query.
* @param cursor the cursor to use for consuming the results.
* @param indexOrder requested {@link IndexOrder} of result. Must be among the capabilities of {@link IndexReference referenced index}.
* @param indexOrder requested {@link IndexOrder} of result. Must be among the capabilities of
* {@link IndexReference referenced index}, or {@link IndexOrder#NONE}.
* @param query Combination of {@link IndexQuery index queries} to run against referenced index.
*/
void nodeIndexSeek( IndexReference index, NodeValueIndexCursor cursor, IndexOrder indexOrder, IndexQuery... query )
throws KernelException;

/**
* @param index {@link IndexReference} referencing index to query.
* @param cursor the cursor to use for consuming the results.
* @param indexOrder requested {@link IndexOrder} of result. Must be among the capabilities of
* {@link IndexReference referenced index}, or {@link IndexOrder#NONE}.
*/
void nodeIndexScan( IndexReference index, NodeValueIndexCursor cursor, IndexOrder indexOrder ) throws KernelException;

void nodeLabelScan( int label, NodeLabelIndexCursor cursor );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,63 +102,63 @@ public void shouldPerformExactLookup() throws Exception
{
// when
IndexValueCapability valueCapability = index.valueCapability( ValueGroup.TEXT );
read.nodeIndexSeek( index, node, null, IndexQuery.exact( prop, "zero" ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.exact( prop, "zero" ) );

// then
assertFoundNodesAndValue( node, uniqueIds, valueCapability );

// when
read.nodeIndexSeek( index, node, null, IndexQuery.exact( prop, "one" ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.exact( prop, "one" ) );

// then
assertFoundNodesAndValue( node, uniqueIds, valueCapability, strOne );

// when
read.nodeIndexSeek( index, node, null, IndexQuery.exact( prop, "two" ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.exact( prop, "two" ) );

// then
assertFoundNodesAndValue( node, uniqueIds, valueCapability, strTwo1, strTwo2 );

// when
read.nodeIndexSeek( index, node, null, IndexQuery.exact( prop, "three" ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.exact( prop, "three" ) );

// then
assertFoundNodesAndValue( node, uniqueIds, valueCapability, strThree1, strThree2, strThree3 );

// when
valueCapability = index.valueCapability( ValueGroup.NUMBER );
read.nodeIndexSeek( index, node, null, IndexQuery.exact( prop, 1 ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.exact( prop, 1 ) );

// then
assertFoundNodesAndValue( node, 1, uniqueIds, valueCapability );

//when
read.nodeIndexSeek( index, node, null, IndexQuery.exact( prop, 2 ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.exact( prop, 2 ) );

// then
assertFoundNodesAndValue( node, 2, uniqueIds, valueCapability );

//when
read.nodeIndexSeek( index, node, null, IndexQuery.exact( prop, 3 ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.exact( prop, 3 ) );

// then
assertFoundNodesAndValue( node, 3, uniqueIds, valueCapability );

//when
read.nodeIndexSeek( index, node, null, IndexQuery.exact( prop, 6 ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.exact( prop, 6 ) );

// then
assertFoundNodesAndValue( node, uniqueIds, valueCapability, num6 );

// when
read.nodeIndexSeek( index, node, null, IndexQuery.exact( prop, 12.0 ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.exact( prop, 12.0 ) );

// then
assertFoundNodesAndValue( node, uniqueIds, valueCapability, num12a, num12b );

// when
valueCapability = index.valueCapability( ValueGroup.BOOLEAN );
read.nodeIndexSeek( index, node, null, IndexQuery.exact( prop, true ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.exact( prop, true ) );

// then
assertFoundNodesAndValue( node, uniqueIds, valueCapability, boolTrue );
Expand All @@ -177,7 +177,7 @@ public void shouldPerformStringPrefixSearch() throws Exception
PrimitiveLongSet uniqueIds = Primitive.longSet() )
{
// when
read.nodeIndexSeek( index, node, null, IndexQuery.stringPrefix( prop, "t" ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.stringPrefix( prop, "t" ) );

// then
assertFoundNodesAndValue( node, uniqueIds, stringCapability, strTwo1, strTwo2, strThree1, strThree2, strThree3 );
Expand All @@ -196,7 +196,7 @@ public void shouldPerformStringSuffixSearch() throws Exception
PrimitiveLongSet uniqueIds = Primitive.longSet() )
{
// when
read.nodeIndexSeek( index, node, null, IndexQuery.stringSuffix( prop, "e" ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.stringSuffix( prop, "e" ) );

// then
assertFoundNodesAndValue( node, uniqueIds, stringCapability, strOne, strThree1, strThree2, strThree3 );
Expand All @@ -215,7 +215,7 @@ public void shouldPerformStringContainmentSearch() throws Exception
PrimitiveLongSet uniqueIds = Primitive.longSet() )
{
// when
read.nodeIndexSeek( index, node, null, IndexQuery.stringContains( prop, "o" ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.stringContains( prop, "o" ) );

// then
assertFoundNodesAndValue( node, uniqueIds, stringCapability, strOne, strTwo1, strTwo2 );
Expand All @@ -234,32 +234,32 @@ public void shouldPerformStringRangeSearch() throws Exception
PrimitiveLongSet uniqueIds = Primitive.longSet() )
{
// when
read.nodeIndexSeek( index, node, null, IndexQuery.range( prop, "one", true, "three", true ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.range( prop, "one", true, "three", true ) );

// then

assertFoundNodesAndValue( node, uniqueIds, stringCapability, strOne, strThree1, strThree2, strThree3 );

// when
read.nodeIndexSeek( index, node, null, IndexQuery.range( prop, "one", true, "three", false ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.range( prop, "one", true, "three", false ) );

// then
assertFoundNodesAndValue( node, uniqueIds, stringCapability, strOne );

// when
read.nodeIndexSeek( index, node, null, IndexQuery.range( prop, "one", false, "three", true ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.range( prop, "one", false, "three", true ) );

// then
assertFoundNodesAndValue( node, uniqueIds, stringCapability, strThree1, strThree2, strThree3 );

// when
read.nodeIndexSeek( index, node, null, IndexQuery.range( prop, "one", false, "two", false ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.range( prop, "one", false, "two", false ) );

// then
assertFoundNodesAndValue( node, uniqueIds, stringCapability, strThree1, strThree2, strThree3 );

// when
read.nodeIndexSeek( index, node, null, IndexQuery.range( prop, "one", true, "two", true ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.range( prop, "one", true, "two", true ) );

// then
assertFoundNodesAndValue( node, uniqueIds, stringCapability, strOne, strThree1, strThree2, strThree3, strTwo1, strTwo2 );
Expand All @@ -278,26 +278,26 @@ public void shouldPerformNumericRangeSearch() throws Exception
PrimitiveLongSet uniqueIds = Primitive.longSet() )
{
// when
read.nodeIndexSeek( index, node, null, IndexQuery.range( prop, 5, true, 12, true ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.range( prop, 5, true, 12, true ) );

// then
assertFoundNodesAndValue( node, uniqueIds, numberCapability, num5, num6, num12a, num12b );

// when
read.nodeIndexSeek( index, node, null, IndexQuery.range( prop, 5, true, 12, false ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.range( prop, 5, true, 12, false ) );

// then

assertFoundNodesAndValue( node, uniqueIds, numberCapability, num5, num6 );

// when
read.nodeIndexSeek( index, node, null, IndexQuery.range( prop, 5, false, 12, true ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.range( prop, 5, false, 12, true ) );

// then
assertFoundNodesAndValue( node, uniqueIds, numberCapability, num6, num12a, num12b );

// when
read.nodeIndexSeek( index, node, null, IndexQuery.range( prop, 5, false, 12, false ) );
read.nodeIndexSeek( index, node, IndexOrder.NONE, IndexQuery.range( prop, 5, false, 12, false ) );

// then
assertFoundNodesAndValue( node, uniqueIds, numberCapability, num6 );
Expand All @@ -316,7 +316,7 @@ public void shouldPerformIndexScan() throws Exception
PrimitiveLongSet uniqueIds = Primitive.longSet() )
{
// when
read.nodeIndexScan( index, node, null );
read.nodeIndexScan( index, node, IndexOrder.NONE );

// then
assertFoundNodesAndValue( node, 24, uniqueIds, wildcardCapability );
Expand Down Expand Up @@ -405,6 +405,9 @@ private void assertFoundNodesInOrder( NodeValueIndexCursor node, IndexOrder inde
assertTrue( "Requested ordering " + indexOrder + " was not respected.",
Values.COMPARATOR.compare( currentValue, storedValue ) >= 0 );
break;
case NONE:
// Don't verify
break;
default:
throw new UnsupportedOperationException( "Can not verify ordering for " + indexOrder );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
*/
package org.neo4j.kernel.impl.index.schema;

import org.apache.commons.lang3.ArrayUtils;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Arrays;
Expand Down Expand Up @@ -115,7 +117,7 @@ public long countIndexedNodes( long nodeId, Value... propertyValues )
public PrimitiveLongIterator query( IndexQuery... predicates ) throws IndexNotApplicableKernelException
{
NodeValueIterator nodeValueIterator = new NodeValueIterator();
query( nodeValueIterator, null, predicates );
query( nodeValueIterator, IndexOrder.NONE, predicates );
return nodeValueIterator;
}

Expand Down Expand Up @@ -159,12 +161,13 @@ private void validateQuery( IndexOrder indexOrder, IndexQuery[] predicates )
throw new UnsupportedOperationException();
}

if ( indexOrder != null )
if ( indexOrder != IndexOrder.NONE )
{
ValueGroup valueGroup = predicates[0].valueGroup();
IndexOrder[] capability = NativeSchemaNumberIndexProvider.CAPABILITY.orderCapability( valueGroup );
if ( !ArrayUtil.contains( capability, indexOrder ) )
{
capability = ArrayUtils.add( capability, 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 ), Arrays.toString( capability ) ) );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,11 @@ public void query( IndexProgressor.NodeValueClient cursor, IndexOrder indexOrder
// todo: There will be no ordering of the node ids here. Is this a problem?
if ( predicates[0] instanceof ExistsPredicate )
{
if ( indexOrder != null )
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 ), null ) );
indexOrder, Arrays.toString( predicates ), IndexOrder.NONE ) );
}
BridgingIndexProgressor multiProgressor = new BridgingIndexProgressor( cursor, propertyKeys );
cursor.initialize( multiProgressor, propertyKeys );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ default void query(
IndexOrder indexOrder,
IndexQuery... query ) throws IndexNotApplicableKernelException
{
if ( indexOrder != IndexOrder.NONE )
{
throw new UnsupportedOperationException(
String.format( "This reader only have support for index order %s. Provided index order was %s.",
IndexOrder.NONE, indexOrder ) );
}
int[] keys = new int[query.length];
for ( int i = 0; i < query.length; i++ )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

public class UnionIndexCapabilityTest
{
private static final IndexOrder[] ORDER_CAPABILITIES_ALL = IndexOrder.values();
private static final IndexOrder[] ORDER_CAPABILITIES_ALL = new IndexOrder[]{IndexOrder.ASCENDING, IndexOrder.DESCENDING};
private static final IndexOrder[] ORDER_CAPABILITIES_ONLY_ASC = new IndexOrder[]{IndexOrder.ASCENDING};
private static final IndexOrder[] ORDER_CAPABILITIES_ONLY_DES = new IndexOrder[]{IndexOrder.DESCENDING};
private static final IndexOrder[] ORDER_CAPABILITIES_NONE = new IndexOrder[0];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.neo4j.storageengine.api.schema;

import org.hamcrest.Matchers;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.internal.kernel.api.IndexOrder;
import org.neo4j.internal.kernel.api.IndexQuery;
import org.neo4j.kernel.api.exceptions.index.IndexNotApplicableKernelException;
import org.neo4j.values.storable.Value;

public class DefaultIndexReaderTest
{
@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void defaultQueryImplementationMustThrowForUnsupportedIndexOrder() throws Exception
{
// Given
IndexReader indexReader = stubIndexReader();

// Then
expectedException.expect( UnsupportedOperationException.class );
String expectedMessage = String.format( "This reader only have support for index order %s. Provided index order was %s.",
IndexOrder.NONE, IndexOrder.ASCENDING );
expectedException.expectMessage( Matchers.containsString( expectedMessage ) );
indexReader.query( new SimpleNodeValueClient(), IndexOrder.ASCENDING, IndexQuery.exists( 1 ) );
}

private IndexReader stubIndexReader()
{
return new IndexReader()
{
@Override
public long countIndexedNodes( long nodeId, Value... propertyValues )
{
return 0;
}

@Override
public IndexSampler createSampler()
{
return null;
}

@Override
public PrimitiveLongIterator query( IndexQuery... predicates ) throws IndexNotApplicableKernelException
{
return null;
}

@Override
public boolean hasFullNumberPrecision( IndexQuery... predicates )
{
return false;
}

@Override
public void close()
{
}
};
}
}

0 comments on commit 570e29b

Please sign in to comment.