Skip to content

Commit

Permalink
Add support for Temporal in InMemoryIndexProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
burqen authored and tinwelint committed Mar 27, 2018
1 parent cac705a commit a5f2171
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 25 deletions.
Expand Up @@ -35,13 +35,15 @@
import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor; import org.neo4j.kernel.api.schema.index.SchemaIndexDescriptor;
import org.neo4j.storageengine.api.schema.IndexSampler; import org.neo4j.storageengine.api.schema.IndexSampler;
import org.neo4j.values.storable.Value; import org.neo4j.values.storable.Value;
import org.neo4j.values.storable.ValueGroup;
import org.neo4j.values.storable.Values; import org.neo4j.values.storable.Values;


import static java.lang.String.format; import static java.lang.String.format;
import static org.neo4j.collection.primitive.PrimitiveLongCollections.emptyIterator; import static org.neo4j.collection.primitive.PrimitiveLongCollections.emptyIterator;
import static org.neo4j.collection.primitive.PrimitiveLongCollections.resourceIterator; import static org.neo4j.collection.primitive.PrimitiveLongCollections.resourceIterator;
import static org.neo4j.collection.primitive.PrimitiveLongCollections.toPrimitiveIterator; import static org.neo4j.collection.primitive.PrimitiveLongCollections.toPrimitiveIterator;
import static org.neo4j.internal.kernel.api.IndexQuery.IndexQueryType.exact; import static org.neo4j.internal.kernel.api.IndexQuery.IndexQueryType.exact;
import static org.neo4j.values.storable.ValueGroup.NO_VALUE;


class HashBasedIndex extends InMemoryIndexImplementation class HashBasedIndex extends InMemoryIndexImplementation
{ {
Expand Down Expand Up @@ -86,26 +88,9 @@ synchronized PrimitiveLongResourceIterator doIndexSeek( Object... propertyValues
return asResource( nodes == null ? emptyIterator() : toPrimitiveIterator( nodes.iterator() ) ); return asResource( nodes == null ? emptyIterator() : toPrimitiveIterator( nodes.iterator() ) );
} }


private synchronized PrimitiveLongResourceIterator rangeSeekByNumberInclusive( Number lower, Number upper ) private synchronized PrimitiveLongResourceIterator rangeSeek( Value lower, boolean includeLower, Value upper, boolean includeUpper,
ValueGroup targetValueGroup, IndexQuery query )
{ {
IndexQuery query = IndexQuery.range( -1, lower, true, upper, true );

Set<Long> nodeIds = new HashSet<>();
for ( Map.Entry<List<Object>,Set<Long>> entry : data.entrySet() )
{
Value key = Values.of( entry.getKey().get( 0 ) );
if ( query.acceptsValue( key ) )
{
nodeIds.addAll( entry.getValue() );
}
}
return asResource( toPrimitiveIterator( nodeIds.iterator() ) );
}

private synchronized PrimitiveLongResourceIterator rangeSeekByString( String lower, boolean includeLower, String upper,
boolean includeUpper )
{
IndexQuery query = IndexQuery.range( -1, lower, includeLower, upper, includeUpper );
Set<Long> nodeIds = new HashSet<>(); Set<Long> nodeIds = new HashSet<>();
for ( Map.Entry<List<Object>,Set<Long>> entry : data.entrySet() ) for ( Map.Entry<List<Object>,Set<Long>> entry : data.entrySet() )
{ {
Expand Down Expand Up @@ -244,19 +229,25 @@ public PrimitiveLongResourceIterator query( IndexQuery... predicates )
case exact: case exact:
return seek( ((IndexQuery.ExactPredicate) predicate).value() ); return seek( ((IndexQuery.ExactPredicate) predicate).value() );
case range: case range:
switch ( predicate.valueGroup() ) switch ( predicate.valueGroup().category() )
{ {
case NUMBER: case NUMBER:
IndexQuery.NumberRangePredicate np = (IndexQuery.NumberRangePredicate) predicate; IndexQuery.NumberRangePredicate np = (IndexQuery.NumberRangePredicate) predicate;
return rangeSeekByNumberInclusive( np.from(), np.to() ); return rangeSeek( np.fromValue(), np.fromInclusive(), np.toValue(), np.toInclusive(), ValueGroup.NUMBER, np );


case TEXT: case TEXT:
IndexQuery.TextRangePredicate srp = (IndexQuery.TextRangePredicate) predicate; IndexQuery.TextRangePredicate srp = (IndexQuery.TextRangePredicate) predicate;
return rangeSeekByString( srp.from(), srp.fromInclusive(), srp.to(), srp.toInclusive() ); return rangeSeek( srp.fromValue(), srp.fromInclusive(), srp.toValue(), srp.toInclusive(), ValueGroup.TEXT, srp );


case TEMPORAL:
IndexQuery.RangePredicate trp = (IndexQuery.RangePredicate) predicate;
Value lower = trp.fromValue();
Value upper = trp.toValue();
return rangeSeek( lower, trp.fromInclusive(), upper, trp.toInclusive(), extractValueGroup( lower, upper ), trp );
case GEOMETRY:
default: default:
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
format( "Range scan of valueGroup %s is not supported", predicate.valueGroup() ) ); format( "Range scan of valueCategory %s is not supported", predicate.valueGroup().category() ) );
} }
case stringPrefix: case stringPrefix:
IndexQuery.StringPrefixPredicate spp = (IndexQuery.StringPrefixPredicate) predicate; IndexQuery.StringPrefixPredicate spp = (IndexQuery.StringPrefixPredicate) predicate;
Expand Down Expand Up @@ -310,4 +301,22 @@ boolean hasSameContentsAs( InMemoryIndexImplementation other )
{ {
return this.data.equals( ((HashBasedIndex)other).data ); return this.data.equals( ((HashBasedIndex)other).data );
} }

private ValueGroup extractValueGroup( Value o1, Value o2 )
{
if ( o1.valueGroup() != NO_VALUE && o2.valueGroup() != NO_VALUE )
{
assert o1.valueGroup() == o2.valueGroup() : "o1.valueGroup=" + o1.valueGroup() + ", o2.valueGroup=" + o2.valueGroup();
return o1.valueGroup();
}
else if ( o1.valueGroup() != NO_VALUE )
{
return o1.valueGroup();
}
else if ( o2.valueGroup() != NO_VALUE )
{
return o2.valueGroup();
}
throw new IllegalArgumentException( "Can't decide ValueGroup from null values" );
}
} }
Expand Up @@ -43,6 +43,6 @@ public boolean supportsSpatial()
@Override @Override
public boolean supportsTemporal() public boolean supportsTemporal()
{ {
return false; return true;
} }
} }

0 comments on commit a5f2171

Please sign in to comment.