in kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/common/FastHiveDecimalImpl.java [2521:2854]
public static int fastBigIntegerBytesUnscaled(
final int fastSignum,
long fast0,
long fast1,
long fast2,
long[] scratchLongs,
byte[] buffer) {
/*
* Algorithm:
* 1) Convert decimal to three 56-bit words (three is enough for the decimal since we
* represent the decimal with trailing zeroes trimmed).
* 2) Skip leading zeroes in the words.
* 3) Once we find real data (i.e. a non-zero byte), add a sign byte to buffer if necessary.
* 4) Add bytes from the (rest of) 56-bit words.
* 5) Return byte count.
*/
if (fastSignum == 0) {
buffer[0] = 0;
return 1;
}
boolean isNegative = (fastSignum == -1);
/*
* Use common conversion method we share with fastSerializationUtilsWrite.
*/
if (!doDecimalToBinaryConversion(
fast0,
fast1,
fast2,
FAST_HIVE_DECIMAL_TWO_POWER_56_INVERSE,
BIG_INTEGER_BYTES_QUOTIENT_INTEGER_WORD_NUM,
BIG_INTEGER_BYTES_QUOTIENT_INTEGER_DIGIT_NUM,
FAST_HIVE_DECIMAL_TWO_POWER_56,
scratchLongs)) {
// Overflow. This is not expected.
return 0;
}
int byteIndex = 0;
long word0 = scratchLongs[0];
long word1 = scratchLongs[1];
long word2 = scratchLongs[2];
if (!isNegative) {
// Positive number.
long longWork = 0;
int shift = INITIAL_SHIFT;
if (word2 != 0L) {
// Skip leading zeroes in word2.
while (true) {
longWork = (word2 >> shift) & LONG_BYTE_MASK;
if (longWork != 0) {
break;
}
if (shift == 0) {
throw new RuntimeException("Unexpected #1");
}
shift -= Byte.SIZE;
}
// Now that we have found real data, emit sign byte if necessary.
if ((longWork & LONG_BYTE_HIGH_BIT_MASK) != 0) {
// Add sign byte since high bit is on.
buffer[byteIndex++] = (byte) 0;
}
// Emit the rest of word2
while (true) {
buffer[byteIndex++] = (byte) longWork;
if (shift == 0) {
break;
}
shift -= Byte.SIZE;
longWork = (word2 >> shift) & LONG_BYTE_MASK;
}
shift = INITIAL_SHIFT;
}
if (byteIndex == 0 && word1 == 0L) {
// Skip word1, also.
} else {
if (byteIndex == 0) {
// Skip leading zeroes in word1.
while (true) {
longWork = (word1 >> shift) & LONG_BYTE_MASK;
if (longWork != 0) {
break;
}
if (shift == 0) {
throw new RuntimeException("Unexpected #2");
}
shift -= Byte.SIZE;
}
// Now that we have found real data, emit sign byte if necessary.
if ((longWork & LONG_BYTE_HIGH_BIT_MASK) != 0) {
// Add sign byte since high bit is on.
buffer[byteIndex++] = (byte) 0;
}
} else {
longWork = (word1 >> shift) & LONG_BYTE_MASK;
}
// Emit the rest of word1
while (true) {
buffer[byteIndex++] = (byte) longWork;
if (shift == 0) {
break;
}
shift -= Byte.SIZE;
longWork = (word1 >> shift) & LONG_BYTE_MASK;
}
shift = INITIAL_SHIFT;
}
if (byteIndex == 0) {
// Skip leading zeroes in word0.
while (true) {
longWork = (word0 >> shift) & LONG_BYTE_MASK;
if (longWork != 0) {
break;
}
if (shift == 0) {
// All zeroes -- we should have handled this earlier.
throw new RuntimeException("Unexpected #3");
}
shift -= Byte.SIZE;
}
// Now that we have found real data, emit sign byte if necessary.
if ((longWork & LONG_BYTE_HIGH_BIT_MASK) != 0) {
// Add sign byte since high bit is on.
buffer[byteIndex++] = (byte) 0;
}
} else {
longWork = (word0 >> shift) & LONG_BYTE_MASK;
}
// Emit the rest of word0.
while (true) {
buffer[byteIndex++] = (byte) longWork;
if (shift == 0) {
break;
}
shift -= Byte.SIZE;
longWork = (word0 >> shift) & LONG_BYTE_MASK;
}
} else {
// Negative number.
// Subtract 1 for two's compliment adjustment.
word0--;
if (word0 < 0) {
word0 += LONG_TWO_TO_56_POWER;
word1--;
if (word1 < 0) {
word1 += LONG_TWO_TO_56_POWER;
word2--;
if (word2 < 0) {
// Underflow.
return 0;
}
}
}
long longWork = 0;
int shift = INITIAL_SHIFT;
if (word2 != 0L) {
// Skip leading zeroes in word2.
while (true) {
longWork = (word2 >> shift) & LONG_BYTE_MASK;
if (longWork != 0) {
break;
}
if (shift == 0) {
throw new RuntimeException("Unexpected #1");
}
shift -= Byte.SIZE;
}
// Now that we have found real data, emit sign byte if necessary and do negative fixup.
longWork = (~longWork & LONG_BYTE_MASK);
if (((longWork) & LONG_BYTE_HIGH_BIT_MASK) == 0) {
// Add sign byte since high bit is off.
buffer[byteIndex++] = BYTE_ALL_BITS;
}
// Invert words.
word2 = ~word2;
word1 = ~word1;
word0 = ~word0;
// Emit the rest of word2
while (true) {
buffer[byteIndex++] = (byte) longWork;
if (shift == 0) {
break;
}
shift -= Byte.SIZE;
longWork = (word2 >> shift) & LONG_BYTE_MASK;
}
shift = INITIAL_SHIFT;
}
if (byteIndex == 0 && word1 == 0L) {
// Skip word1, also.
} else {
if (byteIndex == 0) {
// Skip leading zeroes in word1.
while (true) {
longWork = (word1 >> shift) & LONG_BYTE_MASK;
if (longWork != 0) {
break;
}
if (shift == 0) {
throw new RuntimeException("Unexpected #2");
}
shift -= Byte.SIZE;
}
// Now that we have found real data, emit sign byte if necessary and do negative fixup.
longWork = (~longWork & LONG_BYTE_MASK);
if ((longWork & LONG_BYTE_HIGH_BIT_MASK) == 0) {
// Add sign byte since high bit is off.
buffer[byteIndex++] = BYTE_ALL_BITS;
}
// Invert words.
word1 = ~word1;
word0 = ~word0;
} else {
longWork = (word1 >> shift) & LONG_BYTE_MASK;
}
// Emit the rest of word1
while (true) {
buffer[byteIndex++] = (byte) longWork;
if (shift == 0) {
break;
}
shift -= Byte.SIZE;
longWork = (word1 >> shift) & LONG_BYTE_MASK;
}
shift = INITIAL_SHIFT;
}
if (byteIndex == 0) {
// Skip leading zeroes in word0.
while (true) {
longWork = (word0 >> shift) & LONG_BYTE_MASK;
if (longWork != 0) {
break;
}
if (shift == 0) {
// All zeroes.
// -1 special case. Unsigned magnitude 1 - two's compliment adjustment 1 = 0.
buffer[0] = BYTE_ALL_BITS;
return 1;
}
shift -= Byte.SIZE;
}
// Now that we have found real data, emit sign byte if necessary and do negative fixup.
longWork = (~longWork & LONG_BYTE_MASK);
if ((longWork & LONG_BYTE_HIGH_BIT_MASK) == 0) {
// Add sign byte since high bit is off.
buffer[byteIndex++] = BYTE_ALL_BITS;
}
// Invert words.
word0 = ~word0;
} else {
longWork = (word0 >> shift) & LONG_BYTE_MASK;
}
// Emit the rest of word0.
while (true) {
buffer[byteIndex++] = (byte) longWork;
if (shift == 0) {
break;
}
shift -= Byte.SIZE;
longWork = (word0 >> shift) & LONG_BYTE_MASK;
}
}
return byteIndex;
}