Skip to content

Commit

Permalink
Fixed value comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
fickludd committed May 31, 2017
1 parent 291d03b commit 7c2e4d8
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 105 deletions.
6 changes: 6 additions & 0 deletions community/values/src/main/java/org/neo4j/values/NoValue.java
Expand Up @@ -123,4 +123,10 @@ void writeTo( ValueWriter writer )
{
writer.writeNull();
}

@Override
public ValueGroup.Id valueGroupId()
{
return ValueGroup.Id.NO_VALUE;
}
}
7 changes: 1 addition & 6 deletions community/values/src/main/java/org/neo4j/values/Value.java
Expand Up @@ -19,7 +19,7 @@
*/
package org.neo4j.values;

public abstract class Value
public abstract class Value implements ValueGroup.WithId
{
@Override
public boolean equals( Object other )
Expand Down Expand Up @@ -58,9 +58,4 @@ public int hashCode()
abstract boolean equals( String[] x );

abstract void writeTo( ValueWriter writer );

public interface WithStringValue
{
String stringValue();
}
}
172 changes: 81 additions & 91 deletions community/values/src/main/java/org/neo4j/values/ValueComparator.java
Expand Up @@ -23,140 +23,124 @@

import static java.lang.String.format;

// TODO: redo with ValueGroup instead of SemanticType
class ValueComparator implements Comparator<Value>
{
private final Comparator<Values.SemanticType> semanticTypeComparator;
private final Comparator<ValueGroup.Id> valueGroupComparator;

ValueComparator( Comparator<Values.SemanticType> semanticTypeComparator )
ValueComparator( Comparator<ValueGroup.Id> valueGroupComparator )
{
this.semanticTypeComparator = semanticTypeComparator;
this.valueGroupComparator = valueGroupComparator;
}

@Override
public int compare( Value o1, Value o2 )
public int compare( Value v1, Value v2 )
{
assert o1 != null && o2 != null : "null values are not supported, use NoValue.NO_VALUE instead";
assert v1 != null && v2 != null : "null values are not supported, use NoValue.NO_VALUE instead";

Values.SemanticType semType1 = semanticType( o1 );
Values.SemanticType semType2 = semanticType( o2 );
ValueGroup.Id id1 = v1.valueGroupId();
ValueGroup.Id id2 = v2.valueGroupId();

int x = semanticTypeComparator.compare( semType1, semType2 );
int x = valueGroupComparator.compare( id1, id2 );

if ( x == 0 )
{
switch ( semType1 )
switch ( id1 )
{
case NO_VALUE:
return x;

case BOOLEAN:
return ((DirectBoolean) o1).compareTo( (DirectBoolean) o2 );
case INTEGER:
return compareNumberScalar( (ValueGroup.VInteger)v1, v2 );

case FLOAT:
return compareNumberScalar( (ValueGroup.VFloatingPoint)v1, v2 );

case TEXT:
return ((ValueGroup.VText) v1).compareTo( (ValueGroup.VText) v2 );

case NUMBER:
return compareScalarNumbers( o1, o2 );
case BOOLEAN:
return ((ValueGroup.VBoolean) v1).compareTo( (ValueGroup.VBoolean) v2 );

case STRING:
return ((DirectString) o1).compareTo( (DirectString) o2 );
case INTEGER_ARRAY:
return compareNumberArray( (ValueGroup.VIntegerArray)v1, v2 );

case BOOLEAN_ARR:
return ((DirectBooleanArray) o1).compareTo( (DirectBooleanArray) o2 );
case FLOAT_ARRAY:
return compareNumberArray( (ValueGroup.VFloatingPointArray)v1, v2 );

case NUMBER_ARR:
return compareNumberArrays( o1, o2 );
case TEXT_ARRAY:
return ((ValueGroup.VTextArray) v1).compareTo( (ValueGroup.VTextArray) v2 );

case STRING_ARR:
return ((DirectStringArray) o1).compareTo( (DirectStringArray) o2 );
case BOOLEAN_ARRAY:
return ((ValueGroup.VBooleanArray) v1).compareTo( (ValueGroup.VBooleanArray) v2 );

default:
throw new UnsupportedOperationException( format( "Unknown semantic type '%s'", semType1 ) );
throw new UnsupportedOperationException( format( "Unknown ValueGroup id '%s'", id1 ) );
}
}
return x;
}

private Values.SemanticType semanticType( Value value )
private int compareNumberScalar( ValueGroup.VInteger v1, Value v2 )
{
if ( value instanceof NoValue )
{
return Values.SemanticType.NO_VALUE;
}
if ( value instanceof DirectString )
{
return Values.SemanticType.STRING;
}
if ( value instanceof ValueGroup.VNumber )
{
return Values.SemanticType.NUMBER;
}
if ( value instanceof DirectBoolean )
{
return Values.SemanticType.BOOLEAN;
}
if ( value instanceof DirectStringArray )
switch ( v2.valueGroupId() )
{
return Values.SemanticType.STRING_ARR;
}
if ( value instanceof DirectIntegralArray || value instanceof DirectFloatingPointArray )
{
return Values.SemanticType.NUMBER_ARR;
}
if ( value instanceof DirectBooleanArray )
{
return Values.SemanticType.BOOLEAN_ARR;
}
case INTEGER:
return v1.compareTo( (ValueGroup.VInteger)v2 );

case FLOAT:
return v1.compareTo( (ValueGroup.VFloatingPoint)v2 );

throw new UnsupportedOperationException(
format( "Semantic type for value class '%s' is not defined", value.getClass().getName() ) );
default:
throw new UnsupportedOperationException( format(
"Cannot compare values of type %s with type %s", ValueGroup.Id.INTEGER, v2.valueGroupId() ) );
}
}

private int compareScalarNumbers( Value o1, Value o2 )
private int compareNumberScalar( ValueGroup.VFloatingPoint v1, Value v2 )
{
boolean isInt1 = o1 instanceof DirectIntegralNumber;
boolean isInt2 = o2 instanceof DirectIntegralNumber;
if ( isInt1 )
{
if ( isInt2 )
{
return ((DirectIntegralNumber) o1).compareTo( (DirectIntegralNumber) o2 );
}
else
{
return ((DirectIntegralNumber) o1).compareTo( (DirectFloatingPointNumber) o2 );
}
}
if ( isInt2 )
{
return ((DirectFloatingPointNumber) o1).compareTo( (DirectIntegralNumber) o2 );
}
else
switch ( v2.valueGroupId() )
{
return ((DirectFloatingPointNumber) o1).compareTo( (DirectFloatingPointNumber) o2 );
case INTEGER:
return v1.compareTo( (ValueGroup.VInteger)v2 );

case FLOAT:
return v1.compareTo( (ValueGroup.VFloatingPoint)v2 );

default:
throw new UnsupportedOperationException( format(
"Cannot compare values of type %s with type %s", ValueGroup.Id.FLOAT, v2.valueGroupId() ) );
}
}

private int compareNumberArrays( Value o1, Value o2 )
private int compareNumberArray( ValueGroup.VIntegerArray v1, Value v2 )
{
boolean isInt1 = o1 instanceof DirectIntegralArray;
boolean isInt2 = o2 instanceof DirectIntegralArray;
if ( isInt1 )
{
if ( isInt2 )
{
return ((DirectIntegralArray) o1).compareTo( (DirectIntegralArray) o2 );
}
else
{
return ((DirectIntegralArray) o1).compareTo( (DirectFloatingPointArray) o2 );
}
}
if ( isInt2 )
switch ( v2.valueGroupId() )
{
return ((DirectFloatingPointArray) o1).compareTo( (DirectIntegralArray) o2 );
case INTEGER:
return v1.compareTo( (ValueGroup.VIntegerArray)v2 );

case FLOAT:
return v1.compareTo( (ValueGroup.VFloatingPointArray)v2 );

default:
throw new UnsupportedOperationException( format(
"Cannot compare values of type %s with type %s", ValueGroup.Id.INTEGER, v2.valueGroupId() ) );
}
else
}

private int compareNumberArray( ValueGroup.VFloatingPointArray v1, Value v2 )
{
switch ( v2.valueGroupId() )
{
return ((DirectFloatingPointArray) o1).compareTo( (DirectFloatingPointArray) o2 );
case INTEGER:
return v1.compareTo( (ValueGroup.VIntegerArray)v2 );

case FLOAT:
return v1.compareTo( (ValueGroup.VFloatingPointArray)v2 );

default:
throw new UnsupportedOperationException( format(
"Cannot compare values of type %s with type %s", ValueGroup.Id.FLOAT, v2.valueGroupId() ) );
}
}

Expand All @@ -165,4 +149,10 @@ public boolean equals( Object obj )
{
return obj != null && obj instanceof ValueComparator;
}

@Override
public int hashCode()
{
return 1;
}
}
82 changes: 76 additions & 6 deletions community/values/src/main/java/org/neo4j/values/ValueGroup.java
Expand Up @@ -25,7 +25,37 @@ private ValueGroup()
{
}

interface VNumber
enum Id
{
NO_VALUE( -1 ),
TEXT( 0 ),
BOOLEAN( 1 ),
INTEGER( 2 ),
FLOAT( 2 ),
INTEGER_ARRAY( 3 ),
FLOAT_ARRAY( 3 ),
TEXT_ARRAY( 4 ),
BOOLEAN_ARRAY( 5 );

private final int comparabilityGroup;

Id( int comparabilityGroup )
{
this.comparabilityGroup = comparabilityGroup;
}

public int comparabilityGroup()
{
return comparabilityGroup;
}
}

interface WithId
{
Id valueGroupId();
}

interface VNumber extends WithId
{
int compareTo( VInteger other );

Expand All @@ -35,28 +65,48 @@ interface VNumber
interface VInteger extends VNumber
{
long longValue();

default Id valueGroupId()
{
return Id.INTEGER;
}
}

interface VFloatingPoint extends VNumber
{
double doubleValue();

default Id valueGroupId()
{
return Id.FLOAT;
}
}

interface VBoolean
interface VBoolean extends WithId
{
boolean booleanValue();

default Id valueGroupId()
{
return Id.BOOLEAN;
}

int compareTo( VBoolean other );
}

interface VText
interface VText extends WithId
{
String stringValue();

default Id valueGroupId()
{
return Id.TEXT;
}

int compareTo( VText other );
}

interface VNumberArray
interface VNumberArray extends WithId
{
int length();

Expand All @@ -68,28 +118,48 @@ interface VNumberArray
interface VIntegerArray extends VNumberArray
{
long longValue( int offset );

default Id valueGroupId()
{
return Id.INTEGER_ARRAY;
}
}

interface VFloatingPointArray extends VNumberArray
{
double doubleValue( int offset );

default Id valueGroupId()
{
return Id.FLOAT_ARRAY;
}
}

interface VBooleanArray
interface VBooleanArray extends WithId
{
int length();

boolean booleanValue( int offset );

default Id valueGroupId()
{
return Id.BOOLEAN_ARRAY;
}

int compareTo( VBooleanArray other );
}

interface VTextArray
interface VTextArray extends WithId
{
int length();

String stringValue( int offset );

default Id valueGroupId()
{
return Id.TEXT_ARRAY;
}

int compareTo( VTextArray other );
}
}

0 comments on commit 7c2e4d8

Please sign in to comment.