Skip to content

Commit 6cda2f7

Browse files
committed
Updated compareTo implementation for UUID, Decimal, Void and Null
1 parent d91d52c commit 6cda2f7

File tree

5 files changed

+30
-99
lines changed

5 files changed

+30
-99
lines changed

table/src/main/java/tech/ydb/table/values/DecimalValue.java

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -289,52 +289,14 @@ public int compareTo(Value<?> other) {
289289

290290
DecimalValue decimal = (DecimalValue) other;
291291

292-
// Handle special values first
293-
if (isNan() || decimal.isNan()) {
294-
// NaN is not comparable, but we need to provide a consistent ordering
295-
if (isNan() && decimal.isNan()) {
296-
return 0;
297-
}
298-
if (isNan()) {
299-
return 1; // NaN is considered greater than any other value
300-
}
301-
return -1;
302-
}
303-
304-
if (isInf() && decimal.isInf()) {
305-
return 0;
306-
}
307-
if (isInf()) {
308-
return 1; // Positive infinity is greater than any finite value
309-
}
310-
if (decimal.isInf()) {
311-
return -1;
312-
}
313-
314-
if (isNegativeInf() && decimal.isNegativeInf()) {
315-
return 0;
316-
}
317-
if (isNegativeInf()) {
318-
return -1; // Negative infinity is less than any finite value
319-
}
320-
321-
if (decimal.isNegativeInf()) {
322-
return 1;
323-
}
324-
325-
// Compare finite values
326-
if (isNegative() != decimal.isNegative()) {
327-
return isNegative() ? -1 : 1;
328-
}
329-
330-
// Both have the same sign, compare magnitudes
331-
int highComparison = Long.compareUnsigned(high, decimal.high);
332-
if (highComparison != 0) {
333-
return isNegative() ? -highComparison : highComparison;
292+
// Fast way to compare decimals with the same scale or with special values
293+
boolean isSpecial = isNan() || isInf() || isNegativeInf();
294+
boolean otherIsSpecial = decimal.isNan() || decimal.isInf() || decimal.isNegativeInf();
295+
if (isSpecial || otherIsSpecial || (getType().getScale() == decimal.getType().getScale())) {
296+
return high != decimal.high ? Long.compare(high, decimal.high) : Long.compare(low, decimal.low);
334297
}
335298

336-
int lowComparison = Long.compareUnsigned(low, decimal.low);
337-
return isNegative() ? -lowComparison : lowComparison;
299+
return toBigDecimal().compareTo(decimal.toBigDecimal());
338300
}
339301

340302
/**

table/src/main/java/tech/ydb/table/values/NullValue.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ public int compareTo(Value<?> other) {
4747
return compareTo(optional.get());
4848
}
4949

50-
if (!getType().equals(other.getType())) {
51-
throw new IllegalArgumentException("Cannot compare value " + getType() + " with " + other.getType());
50+
if (other instanceof VoidValue || other instanceof NullValue) {
51+
// All VoidValue and NullValue are equal
52+
return 0;
5253
}
5354

54-
// All NullValue instances are equal
55-
return 0;
55+
throw new IllegalArgumentException("Cannot compare value " + getType() + " with " + other.getType());
5656
}
5757
}

table/src/main/java/tech/ydb/table/values/PrimitiveValue.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.google.protobuf.UnsafeByteOperations;
2121

2222
import tech.ydb.proto.ValueProtos;
23+
import tech.ydb.table.utils.LittleEndian;
2324
import tech.ydb.table.values.proto.ProtoValue;
2425

2526

@@ -423,17 +424,6 @@ private static void checkType(PrimitiveType expected, PrimitiveType actual) {
423424
}
424425
}
425426

426-
private static int compareByteArrays(byte[] a, byte[] b) {
427-
int minLength = Math.min(a.length, b.length);
428-
for (int i = 0; i < minLength; i++) {
429-
int comparison = Byte.compare(a[i], b[i]);
430-
if (comparison != 0) {
431-
return comparison;
432-
}
433-
}
434-
return Integer.compare(a.length, b.length);
435-
}
436-
437427
@Override
438428
public int compareTo(Value<?> other) {
439429
if (other == null) {
@@ -473,22 +463,23 @@ public int compareTo(Value<?> other) {
473463
case Int64:
474464
return Long.compare(getInt64(), otherValue.getInt64());
475465
case Uint64:
476-
return Long.compare(getUint64(), otherValue.getUint64());
466+
return Long.compareUnsigned(getUint64(), otherValue.getUint64());
477467
case Float:
478468
return Float.compare(getFloat(), otherValue.getFloat());
479469
case Double:
480470
return Double.compare(getDouble(), otherValue.getDouble());
481471
case Bytes:
472+
return Arrays.compare(getBytesUnsafe(), otherValue.getBytesUnsafe());
482473
case Yson:
483-
return compareByteArrays(getBytesUnsafe(), otherValue.getBytesUnsafe());
474+
return Arrays.compare(getYsonUnsafe(), otherValue.getYsonUnsafe());
484475
case Text:
485476
return getText().compareTo(otherValue.getText());
486477
case Json:
487478
return getJson().compareTo(otherValue.getJson());
488479
case JsonDocument:
489480
return getJsonDocument().compareTo(otherValue.getJsonDocument());
490481
case Uuid:
491-
return getUuidJdk().compareTo(otherValue.getUuidJdk());
482+
return compareUUID(this, otherValue);
492483
case Date:
493484
return getDate().compareTo(otherValue.getDate());
494485
case Date32:
@@ -516,6 +507,16 @@ public int compareTo(Value<?> other) {
516507
}
517508
}
518509

510+
@SuppressWarnings("deprecation")
511+
private static int compareUUID(PrimitiveValue a, PrimitiveValue b) {
512+
long ah = LittleEndian.bswap(a.getUuidHigh());
513+
long bh = LittleEndian.bswap(b.getUuidHigh());
514+
long al = LittleEndian.bswap(a.getUuidLow());
515+
long bl = LittleEndian.bswap(b.getUuidLow());
516+
517+
return (al != bl) ? Long.compareUnsigned(al, bl) : Long.compareUnsigned(ah, bh);
518+
}
519+
519520
// -- implementations --
520521

521522
private static final class Bool extends PrimitiveValue {

table/src/main/java/tech/ydb/table/values/VariantValue.java

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -97,38 +97,6 @@ public int compareTo(Value<?> other) {
9797
return indexComparison;
9898
}
9999

100-
// If type indices are the same, compare the items
101-
return compareValues(item, variant.item);
102-
}
103-
104-
private static int compareValues(Value<?> a, Value<?> b) {
105-
// Handle null values
106-
if (a == null && b == null) {
107-
return 0;
108-
}
109-
if (a == null) {
110-
return -1;
111-
}
112-
if (b == null) {
113-
return 1;
114-
}
115-
116-
// Check that the types are the same
117-
if (!a.getType().equals(b.getType())) {
118-
throw new IllegalArgumentException("Cannot compare values of different types: " +
119-
a.getType() + " vs " + b.getType());
120-
}
121-
122-
// Use the actual compareTo method of the values
123-
if (a instanceof Comparable && b instanceof Comparable) {
124-
try {
125-
return ((Comparable<Value<?>>) a).compareTo((Value<?>) b);
126-
} catch (ClassCastException e) {
127-
// Fall back to error
128-
}
129-
}
130-
131-
throw new IllegalArgumentException("Cannot compare values of different types: " +
132-
a.getClass().getSimpleName() + " vs " + b.getClass().getSimpleName());
100+
return item.compareTo(variant.item);
133101
}
134102
}

table/src/main/java/tech/ydb/table/values/VoidValue.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ public int compareTo(Value<?> other) {
4747
return compareTo(optional.get());
4848
}
4949

50-
if (!getType().equals(other.getType())) {
51-
throw new IllegalArgumentException("Cannot compare value " + getType() + " with " + other.getType());
50+
if (other instanceof VoidValue || other instanceof NullValue) {
51+
// All VoidValue and NullValue are equal
52+
return 0;
5253
}
5354

54-
// All VoidValue instances are equal
55-
return 0;
55+
throw new IllegalArgumentException("Cannot compare value " + getType() + " with " + other.getType());
5656
}
5757
}

0 commit comments

Comments
 (0)