in kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/common/FastHiveDecimalImpl.java [3809:3962]
public static int fastCompareTo(
int leftSignum,
long leftFast0,
long leftFast1,
long leftFast2,
int leftScale,
int rightSignum,
long rightFast0,
long rightFast1,
long rightFast2,
int rightScale) {
if (leftSignum == 0 && rightSignum == 0) {
return 0;
}
// Optimization copied from BigDecimal.
int signDiff = leftSignum - rightSignum;
if (signDiff != 0) {
return (signDiff > 0 ? 1 : -1);
}
// We are here when the left and right are non-zero and have the same sign.
if (leftScale == rightScale) {
return doCompareToSameScale(
leftSignum, leftFast0, leftFast1, leftFast2, rightFast0, rightFast1, rightFast2);
} else {
// How do we handle different scales?
// We at least know they are not equal. The one with the larger scale has non-zero digits
// below the other's scale (since the scale does not include trailing zeroes).
// For comparison purposes, we can scale away those digits. And, we can not scale up since
// that could overflow.
// Use modified portions of doFastScaleDown code here since we do not want to allocate a
// temporary FastHiveDecimal object.
long compare0;
long compare1;
long compare2;
int scaleDown;
if (leftScale < rightScale) {
// Scale down right and compare.
scaleDown = rightScale - leftScale;
// Adjust all longs using power 10 division/remainder.
if (scaleDown < LONGWORD_DECIMAL_DIGITS) {
// Part of lowest word survives.
final long divideFactor = powerOfTenTable[scaleDown];
final long multiplyFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - scaleDown];
compare0 = rightFast0 / divideFactor + ((rightFast1 % divideFactor) * multiplyFactor);
compare1 = rightFast1 / divideFactor + ((rightFast2 % divideFactor) * multiplyFactor);
compare2 = rightFast2 / divideFactor;
} else if (scaleDown < TWO_X_LONGWORD_DECIMAL_DIGITS) {
// Throw away lowest word.
final int adjustedScaleDown = scaleDown - LONGWORD_DECIMAL_DIGITS;
final long divideFactor = powerOfTenTable[adjustedScaleDown];
final long multiplyFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - adjustedScaleDown];
compare0 = rightFast1 / divideFactor + ((rightFast2 % divideFactor) * multiplyFactor);
compare1 = rightFast2 / divideFactor;
compare2 = 0;
} else {
// Throw away middle and lowest words.
final int adjustedScaleDown = scaleDown - TWO_X_LONGWORD_DECIMAL_DIGITS;
compare0 = rightFast2 / powerOfTenTable[adjustedScaleDown];
compare1 = 0;
compare2 = 0;
}
if (leftFast0 == compare0 && leftFast1 == compare1 && leftFast2 == compare2) {
// Return less than because of right's digits below left's scale.
return -leftSignum;
}
if (leftFast2 < compare2) {
return -leftSignum;
} else if (leftFast2 > compare2) {
return leftSignum;
}
if (leftFast1 < compare1) {
return -leftSignum;
} else if (leftFast1 > compare1) {
return leftSignum;
}
return (leftFast0 < compare0 ? -leftSignum : leftSignum);
} else {
// Scale down left and compare.
scaleDown = leftScale - rightScale;
// Adjust all longs using power 10 division/remainder.
if (scaleDown < LONGWORD_DECIMAL_DIGITS) {
// Part of lowest word survives.
final long divideFactor = powerOfTenTable[scaleDown];
final long multiplyFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - scaleDown];
compare1 = leftFast1 / divideFactor + ((leftFast2 % divideFactor) * multiplyFactor);
compare0 = leftFast0 / divideFactor + ((leftFast1 % divideFactor) * multiplyFactor);
compare2 = leftFast2 / divideFactor;
} else if (scaleDown < TWO_X_LONGWORD_DECIMAL_DIGITS) {
// Throw away lowest word.
final int adjustedScaleDown = scaleDown - LONGWORD_DECIMAL_DIGITS;
final long divideFactor = powerOfTenTable[adjustedScaleDown];
final long multiplyFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - adjustedScaleDown];
compare0 = leftFast1 / divideFactor + ((leftFast2 % divideFactor) * multiplyFactor);
compare1 = leftFast2 / divideFactor;
compare2 = 0;
} else {
// Throw away middle and lowest words.
final int adjustedScaleDown = scaleDown - 2 * LONGWORD_DECIMAL_DIGITS;
compare0 = leftFast2 / powerOfTenTable[adjustedScaleDown];
compare1 = 0;
compare2 = 0;
}
if (compare0 == rightFast0 && compare1 == rightFast1 && compare2 == rightFast2) {
// Return greater than because of left's digits below right's scale.
return leftSignum;
}
if (compare2 < rightFast2) {
return -leftSignum;
} else if (compare2 > rightFast2) {
return leftSignum;
}
if (compare1 < rightFast1) {
return -leftSignum;
} else if (compare1 > rightFast1) {
return leftSignum;
}
return (compare0 < rightFast0 ? -leftSignum : leftSignum);
}
}
}