Skip to content

Commit

Permalink
add orderability support for Nodes, Relationships, and Paths
Browse files Browse the repository at this point in the history
- fix cases where orderability of Lists failed: Integer[], Long[], Float[], Double, float[], double[]
  • Loading branch information
alexaverbuch committed Feb 14, 2017
1 parent 6448b53 commit ea9e5f9
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 29 deletions.
Expand Up @@ -24,11 +24,14 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;

import org.neo4j.cypher.UnorderableValueException;
import org.neo4j.cypher.internal.frontend.v3_2.IncomparableValuesException;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.helpers.MathUtil;

import static java.lang.String.format;
Expand Down Expand Up @@ -124,10 +127,10 @@ else if ( rhs == null )
public enum SuperType
{
MAP( 0, FALLBACK_COMPARATOR /*TODO*/ ),
NODE( 1, FALLBACK_COMPARATOR /*TODO*/ ),
RELATIONSHIP( 2, FALLBACK_COMPARATOR /*TODO*/ ),
NODE( 1, NODE_COMPARATOR ),
RELATIONSHIP( 2, RELATIONSHIP_COMPARATOR ),
LIST( 3, LIST_COMPARATOR ),
PATH( 4, FALLBACK_COMPARATOR /*TODO*/ ),
PATH( 4, PATH_COMPARATOR ),
STRING( 5, STRING_COMPARATOR ),
BOOLEAN( 6, BOOLEAN_COMPARATOR ),
NUMBER( 7, NUMBER_COMPARATOR ),
Expand Down Expand Up @@ -185,6 +188,7 @@ else if ( value instanceof RelationshipIdWrapper )
}
return RELATIONSHIP;
}
// TODO is Path really the class that compiled runtime will be using?
else if ( value instanceof Path )
{
return PATH;
Expand All @@ -205,7 +209,7 @@ public int compare( SuperType left, SuperType right )
// NOTE: nulls are handled at the top of the public compare() method
// so the type-specific comparators should not check arguments for null

private static Comparator FALLBACK_COMPARATOR = new Comparator<Object>()
private static Comparator<Object> FALLBACK_COMPARATOR = new Comparator<Object>()
{
@Override
public int compare( Object lhs, Object rhs )
Expand All @@ -221,7 +225,7 @@ public int compare( Object lhs, Object rhs )
}
};

private static Comparator VOID_COMPARATOR = new Comparator<Object>()
private static Comparator<Object> VOID_COMPARATOR = new Comparator<Object>()
{
@Override
public int compare( Object lhs, Object rhs )
Expand All @@ -230,7 +234,7 @@ public int compare( Object lhs, Object rhs )
}
};

private static Comparator NUMBER_COMPARATOR = new Comparator<Number>()
private static Comparator<Number> NUMBER_COMPARATOR = new Comparator<Number>()
{
@Override
public int compare( Number lhs, Number rhs )
Expand Down Expand Up @@ -267,7 +271,7 @@ else if ( (rhs instanceof Double || rhs instanceof Float) )
}
};

private static Comparator STRING_COMPARATOR = new Comparator<Object>()
private static Comparator<Object> STRING_COMPARATOR = new Comparator<Object>()
{
@Override
public int compare( Object lhs, Object rhs )
Expand All @@ -285,7 +289,7 @@ else if ( lhs instanceof String && rhs instanceof Character )
}
};

private static Comparator BOOLEAN_COMPARATOR = new Comparator<Boolean>()
private static Comparator<Boolean> BOOLEAN_COMPARATOR = new Comparator<Boolean>()
{
@Override
public int compare( Boolean lhs, Boolean rhs )
Expand All @@ -294,13 +298,53 @@ public int compare( Boolean lhs, Boolean rhs )
}
};

private static Comparator LIST_COMPARATOR = new Comparator<Object>()
private static Comparator<NodeIdWrapper> NODE_COMPARATOR = new Comparator<NodeIdWrapper>()
{
@Override
public int compare( NodeIdWrapper lhs, NodeIdWrapper rhs )
{
return Long.compare( lhs.id(), rhs.id() );
}
};

private static Comparator<RelationshipIdWrapper> RELATIONSHIP_COMPARATOR = new Comparator<RelationshipIdWrapper>()
{
@Override
public int compare( RelationshipIdWrapper lhs, RelationshipIdWrapper rhs )
{
return Long.compare( lhs.id(), rhs.id() );
}
};

// TODO test
private static Comparator<Path> PATH_COMPARATOR = new Comparator<Path>()
{
@Override
public int compare( Path lhs, Path rhs )
{
Iterator<PropertyContainer> lhsIter = lhs.iterator();
Iterator<PropertyContainer> rhsIter = lhs.iterator();
while ( lhsIter.hasNext() && rhsIter.hasNext() )
{
int result = CompiledOrderabilityUtils.compare( lhsIter.next(), rhsIter.next() );
if ( 0 != result )
{
return result;
}
}
return (lhsIter.hasNext()) ? 1
: (rhsIter.hasNext()) ? -1
: 0;
}
};

private static Comparator<Object> LIST_COMPARATOR = new Comparator<Object>()
{
@Override
public int compare( Object lhs, Object rhs )
{
Iterator lhsIter = (lhs.getClass().isArray()) ? arrayToIterator( lhs ) : ((List) lhs).iterator();
Iterator rhsIter = (rhs.getClass().isArray()) ? arrayToIterator( rhs ) : ((List) rhs).iterator();
Iterator lhsIter = toIterator( lhs );
Iterator rhsIter = toIterator( rhs );
while ( lhsIter.hasNext() && rhsIter.hasNext() )
{
int result = CompiledOrderabilityUtils.compare( lhsIter.next(), rhsIter.next() );
Expand All @@ -314,28 +358,32 @@ public int compare( Object lhs, Object rhs )
: 0;
}

private Iterator arrayToIterator( Object o )
private Iterator toIterator( Object o )
{
Class clazz = o.getClass();
if ( clazz.equals( Object[].class ) )
if ( Iterable.class.isAssignableFrom( clazz) )
{
return ((Iterable) o).iterator();
}
else if ( Object[].class.isAssignableFrom( clazz) )
{
return Arrays.stream( (Object[]) o ).iterator();
}
else if ( clazz.equals( int[].class ) )
{
return Arrays.stream( (int[]) o ).iterator();
return IntStream.of( (int[]) o ).iterator();
}
else if ( clazz.equals( Integer[].class ) )
else if ( clazz.equals( long[].class ) )
{
return Arrays.stream( (Integer[]) o ).iterator();
return LongStream.of( (long[]) o ).iterator();
}
else if ( clazz.equals( long[].class ) )
else if ( clazz.equals( float[].class ) )
{
return Arrays.stream( (long[]) o ).iterator();
return IntStream.range( 0, ((float[]) o).length ).mapToObj( i -> ((float[]) o)[i] ).iterator();
}
else if ( clazz.equals( Long[].class ) )
else if ( clazz.equals( double[].class ) )
{
return Arrays.stream( (Long[]) o ).iterator();
return DoubleStream.of( (double[]) o ).iterator();
}
else if ( clazz.equals( String[].class ) )
{
Expand Down
Expand Up @@ -44,26 +44,35 @@ public class CompiledOrderabilityUtilsTest

// NODE
new NodeIdWrapper( 1 ),
//new NodeIdWrapper( 2 ), TODO: FIXME
new NodeIdWrapper( 2 ),

// RELATIONSHIP
new RelationshipIdWrapper( 1 ),
//new RelationshipIdWrapper( 2 ), TODO: FIXME
new RelationshipIdWrapper( 2 ),

// LIST
new String[]{"boo"},
new String[]{"foo"},
new boolean[]{false},
new Boolean[]{true},
new Object[]{1, "foo"},
new Object[]{1, "foo", 3},
new Object[]{1, true, "car"},
new Object[]{1, 2, "bar"},
new Object[]{1, 2, "car"},
new int[] {1, 2, 3},
new Object[]{1, 2, 3L, Double.NEGATIVE_INFINITY},
new long[] {1, 2, 3, Long.MIN_VALUE},
new int[] {1, 2, 3, Integer.MIN_VALUE},
new Object[]{1L, 2, 3, Double.NaN},
new Object[]{1L, 2, 3, new NodeIdWrapper(-1)},
new int[] {2},
new int[]{1, 2, 3},
new Object[]{1, 2, 3L, Double.NEGATIVE_INFINITY},
new long[]{1, 2, 3, Long.MIN_VALUE},
new int[]{1, 2, 3, Integer.MIN_VALUE},
new Object[]{1L, 2, 3, Double.NaN},
new Object[]{1L, 2, 3, new NodeIdWrapper(-1)},
new Long[]{1L, 2L, 4L},
new int[]{2},
new Integer[]{3},
new double[]{4D},
new Double[]{5D},
new float[]{6},
new Float[]{7F},
new Object[]{new RelationshipIdWrapper(-1)},

// TODO: PATH
Expand Down

0 comments on commit ea9e5f9

Please sign in to comment.