Skip to content

Commit

Permalink
[#398] Add support for comparison of different PropertyValue number t…
Browse files Browse the repository at this point in the history
…ypes (#853)

* [398] Add support for comparing different number types

* [398] Minor changes

* [#398] Update outdated test
  • Loading branch information
timo95 authored and merando committed Jul 5, 2018
1 parent 56c956a commit 0a2b3e4
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 27 deletions.
Expand Up @@ -318,6 +318,15 @@ public boolean isDateTime() {
return rawBytes[0] == TYPE_DATETIME;
}

/**
* True, if the wrapped value is a subtype of {@code Number}.
*
* @return true, if {@code Number} value
*/
public boolean isNumber() {
return !isNull() && Number.class.isAssignableFrom(getType());
}

//----------------------------------------------------------------------------
// Getter
//----------------------------------------------------------------------------
Expand Down Expand Up @@ -848,22 +857,12 @@ public int compareTo(PropertyValue o) {

if (this.isNull() && o.isNull()) {
result = 0;
} else if (this.isNumber() && o.isNumber()) {
result = PropertyValueUtils.Numeric.compare(this, o);
} else if (this.isBoolean() && o.isBoolean()) {
result = Boolean.compare(this.getBoolean(), o.getBoolean());
} else if (this.isShort() && o.isShort()) {
result = Short.compare(this.getShort(), o.getShort());
} else if (this.isInt() && o.isInt()) {
result = Integer.compare(this.getInt(), o.getInt());
} else if (this.isLong() && o.isLong()) {
result = Long.compare(this.getLong(), o.getLong());
} else if (this.isFloat() && o.isFloat()) {
result = Float.compare(this.getFloat(), o.getFloat());
} else if (this.isDouble() && o.isDouble()) {
result = Double.compare(this.getDouble(), o.getDouble());
} else if (this.isString() && o.isString()) {
result = this.getString().compareTo(o.getString());
} else if (this.isBigDecimal() && o.isBigDecimal()) {
result = this.getBigDecimal().compareTo(o.getBigDecimal());
} else if (this.isGradoopId() && o.isGradoopId()) {
result = this.getGradoopId().compareTo(o.getGradoopId());
} else if (this.isDate() && o.isDate()) {
Expand Down
Expand Up @@ -284,6 +284,104 @@ public static PropertyValue multiply(
return aValue;
}

/**
* Compares two numerical property values
*
* @param aValue first value
* @param bValue second value
*
* @return 0 if a is equal to b, < 0 if a is less than b and > 0 if a is greater than b
*/
public static int compare(PropertyValue aValue, PropertyValue bValue) {

int aType = checkNumericalAndGetType(aValue);
int bType = checkNumericalAndGetType(bValue);

boolean sameType = aType == bType;

int maxType = Math.max(aType, bType);

int result;

if (maxType == SHORT) {
result = Short.compare(aValue.getShort(), bValue.getShort());

} else if (maxType == INT) {
int a;
int b;

if (sameType) {
a = aValue.getInt();
b = bValue.getInt();
} else {
a = aType == INT ? aValue.getInt() : aValue.getShort();
b = bType == INT ? bValue.getInt() : bValue.getShort();
}

result = Integer.compare(a, b);

} else if (maxType == FLOAT) {
float a;
float b;

if (sameType) {
a = aValue.getFloat();
b = bValue.getFloat();
} else {
a = aType == FLOAT ? aValue.getFloat() : floatValue(aValue, aType);
b = bType == FLOAT ? bValue.getFloat() : floatValue(bValue, bType);
}

result = Float.compare(a, b);

} else if (maxType == LONG) {
long a;
long b;

if (sameType) {
a = aValue.getLong();
b = bValue.getLong();
} else {
a = aType == LONG ? aValue.getLong() : longValue(aValue, aType);
b = bType == LONG ? bValue.getLong() : longValue(bValue, bType);
}

result = Long.compare(a, b);

} else if (maxType == DOUBLE) {
double a;
double b;

if (sameType) {
a = aValue.getDouble();
b = bValue.getDouble();
} else {
a = aType == DOUBLE ? aValue.getDouble() : doubleValue(aValue, aType);
b = bType == DOUBLE ? bValue.getDouble() : doubleValue(bValue, bType);
}

result = Double.compare(a, b);

} else {
BigDecimal a;
BigDecimal b;

if (sameType) {
a = aValue.getBigDecimal();
b = bValue.getBigDecimal();
} else {
a = aType == BIG_DECIMAL ? aValue.getBigDecimal() :
bigDecimalValue(aValue, aType);
b = bType == BIG_DECIMAL ? bValue.getBigDecimal() :
bigDecimalValue(bValue, bType);
}

result = a.compareTo(b);
}

return result;
}

/**
* Compares two numerical property values and returns the smaller one.
*
Expand Down
Expand Up @@ -709,6 +709,40 @@ public void testSetDateTime() throws Exception {
assertEquals(DATETIME_VAL_d, p.getDateTime());
}

@Test
public void testIsNumber() throws Exception {
PropertyValue p = PropertyValue.create(SHORT_VAL_e);
assertTrue(p.isNumber());
p = PropertyValue.create(INT_VAL_2);
assertTrue(p.isNumber());
p = PropertyValue.create(LONG_VAL_3);
assertTrue(p.isNumber());
p = PropertyValue.create(FLOAT_VAL_4);
assertTrue(p.isNumber());
p = PropertyValue.create(DOUBLE_VAL_5);
assertTrue(p.isNumber());
p = PropertyValue.create(BIG_DECIMAL_VAL_7);
assertTrue(p.isNumber());

p = PropertyValue.create(NULL_VAL_0);
assertFalse(p.isNumber());
p = PropertyValue.create(BOOL_VAL_1);
assertFalse(p.isNumber());
p = PropertyValue.create(STRING_VAL_6);
assertFalse(p.isNumber());
p = PropertyValue.create(GRADOOP_ID_VAL_8);
assertFalse(p.isNumber());
p = PropertyValue.create(MAP_VAL_9);
assertFalse(p.isNumber());
p = PropertyValue.create(LIST_VAL_a);
assertFalse(p.isNumber());
p = PropertyValue.create(DATE_VAL_b);
assertFalse(p.isNumber());
p = PropertyValue.create(TIME_VAL_c);
assertFalse(p.isNumber());
p = PropertyValue.create(DATETIME_VAL_d);
assertFalse(p.isNumber());
}

@Test
public void testEqualsAndHashCode() throws Exception {
Expand Down Expand Up @@ -782,41 +816,97 @@ private void validateEqualsAndHashCode(PropertyValue p1, PropertyValue p2,
assertEquals(p1, p2);
assertNotEquals(p1, p3);

assertTrue(p1.hashCode() == p1.hashCode());
assertTrue(p1.hashCode() == p2.hashCode());
assertFalse(p1.hashCode() == p3.hashCode());
assertEquals(p1.hashCode(), p1.hashCode());
assertEquals(p1.hashCode(), p2.hashCode());
assertNotEquals(p1.hashCode(), p3.hashCode());
}

@Test
public void testCompareTo() throws Exception {
// null
assertTrue(create(null).compareTo(create(null)) == 0);
assertEquals(create(null).compareTo(create(null)), 0);
// boolean
validateCompareTo(create(false), create(false), create(true));
// short
validateCompareTo(create((short)-10), create((short)-10), create((short)10));
validateCompareTo(create((short)-10), create((short)-10), create((short)12));
validateCompareTo(create((short)10), create((short)10), create((short)12));
validateCompareTo(create((short)-10), create(-10), create(12));
validateCompareTo(create((short)10), create(10), create(12));
validateCompareTo(create((short)-10), create(-10L), create(12L));
validateCompareTo(create((short)10), create(10L), create(12L));
validateCompareTo(create((short)-10), create(-10F), create(12F));
validateCompareTo(create((short)10), create(10F), create(12F));
validateCompareTo(create((short)-10), create(-10D), create(12D));
validateCompareTo(create((short)10), create(10D), create(12D));
validateCompareTo(create((short)-10), create(BigDecimal.valueOf(-10)), create(BigDecimal.valueOf(12)));
validateCompareTo(create((short)10), create(BigDecimal.valueOf(10)), create(BigDecimal.valueOf(12)));
// int
validateCompareTo(create(-10), create(-10), create(10));
validateCompareTo(create(-10), create((short)-10), create((short)12));
validateCompareTo(create(10), create((short)10), create((short)12));
validateCompareTo(create(-10), create(-10), create(12));
validateCompareTo(create(10), create(10), create(12));
validateCompareTo(create(-10), create(-10L), create(12L));
validateCompareTo(create(10), create(10L), create(12L));
validateCompareTo(create(-10), create(-10F), create(12F));
validateCompareTo(create(10), create(10F), create(12F));
validateCompareTo(create(-10), create(-10D), create(12D));
validateCompareTo(create(10), create(10D), create(12D));
validateCompareTo(create(-10), create(BigDecimal.valueOf(-10)), create(BigDecimal.valueOf(12)));
validateCompareTo(create(10), create(BigDecimal.valueOf(10)), create(BigDecimal.valueOf(12)));
// long
validateCompareTo(create(-10L), create((short)-10), create((short)12));
validateCompareTo(create(10L), create((short)10), create((short)12));
validateCompareTo(create(-10L), create(-10), create(12));
validateCompareTo(create(10L), create(10), create(12));
validateCompareTo(create(-10L), create(-10L), create(12L));
validateCompareTo(create(10L), create(10L), create(12L));
validateCompareTo(create(-10L), create(-10F), create(12F));
validateCompareTo(create(10L), create(10F), create(12F));
validateCompareTo(create(-10L), create(-10D), create(12D));
validateCompareTo(create(10L), create(10D), create(12D));
validateCompareTo(create(-10L), create(BigDecimal.valueOf(-10)), create(BigDecimal.valueOf(12)));
validateCompareTo(create(10L), create(BigDecimal.valueOf(10)), create(BigDecimal.valueOf(12)));
// float
validateCompareTo(create(-10F), create((short)-10), create((short)12));
validateCompareTo(create(10F), create((short)10), create((short)12));
validateCompareTo(create(-10F), create(-10), create(12));
validateCompareTo(create(10F), create(10), create(12));
validateCompareTo(create(-10F), create(-10L), create(12L));
validateCompareTo(create(10F), create(10L), create(12L));
validateCompareTo(create(-10F), create(-10F), create(12F));
validateCompareTo(create(10F), create(10F), create(12F));
validateCompareTo(create(-10F), create(-10D), create(12D));
validateCompareTo(create(10F), create(10D), create(12D));
validateCompareTo(create(-10F), create(BigDecimal.valueOf(-10)), create(BigDecimal.valueOf(12)));
validateCompareTo(create(10F), create(BigDecimal.valueOf(10)), create(BigDecimal.valueOf(12)));
// double
validateCompareTo(create(-10.), create(-10.), create(12.));
validateCompareTo(create(10.), create(10.), create(12.));
validateCompareTo(create(-10D), create((short)-10), create((short)12));
validateCompareTo(create(10D), create((short)10), create((short)12));
validateCompareTo(create(-10D), create(-10), create(12));
validateCompareTo(create(10D), create(10), create(12));
validateCompareTo(create(-10D), create(-10L), create(12L));
validateCompareTo(create(10D), create(10L), create(12L));
validateCompareTo(create(-10D), create(-10F), create(12F));
validateCompareTo(create(10D), create(10F), create(12F));
validateCompareTo(create(-10D), create(-10D), create(12D));
validateCompareTo(create(10D), create(10D), create(12D));
validateCompareTo(create(-10D), create(BigDecimal.valueOf(-10)), create(BigDecimal.valueOf(12)));
validateCompareTo(create(10D), create(BigDecimal.valueOf(10)), create(BigDecimal.valueOf(12)));
//string
validateCompareTo(create("10"), create("10"), create("12"));
// BigDecimal
validateCompareTo(create(new BigDecimal(-10)),
create(new BigDecimal(-10)),
create(new BigDecimal(11)));
validateCompareTo(create(new BigDecimal(10)),
create(new BigDecimal(10)),
create(new BigDecimal(11)));
validateCompareTo(create(BigDecimal.valueOf(-10)), create((short)-10), create((short)12));
validateCompareTo(create(BigDecimal.valueOf(10)), create((short)10), create((short)12));
validateCompareTo(create(BigDecimal.valueOf(-10)), create(-10), create(12));
validateCompareTo(create(BigDecimal.valueOf(10)), create(10), create(12));
validateCompareTo(create(BigDecimal.valueOf(-10)), create(-10L), create(12L));
validateCompareTo(create(BigDecimal.valueOf(10)), create(10L), create(12L));
validateCompareTo(create(BigDecimal.valueOf(-10)), create(-10F), create(12F));
validateCompareTo(create(BigDecimal.valueOf(10)), create(10F), create(12F));
validateCompareTo(create(BigDecimal.valueOf(-10)), create(-10D), create(12D));
validateCompareTo(create(BigDecimal.valueOf(10)), create(10D), create(12D));
validateCompareTo(create(BigDecimal.valueOf(-10)), create(BigDecimal.valueOf(-10)), create(BigDecimal.valueOf(12)));
validateCompareTo(create(BigDecimal.valueOf(10)), create(BigDecimal.valueOf(10)), create(BigDecimal.valueOf(12)));
// GradoopId
validateCompareTo(
create(GradoopId.fromString("583ff8ffbd7d222690a90999")),
Expand Down Expand Up @@ -845,7 +935,7 @@ public void testCompareTo() throws Exception {

@Test(expected = IllegalArgumentException.class)
public void testCompareToWithIncompatibleTypes() {
create(10).compareTo(create(10L));
create(10).compareTo(create("10"));
}

@Test(expected = UnsupportedOperationException.class)
Expand Down

0 comments on commit 0a2b3e4

Please sign in to comment.