private static int doFastToBytes()

in kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/common/FastHiveDecimalImpl.java [8985:9134]


  private static int doFastToBytes(
      int fastSignum,
      long fast0,
      long fast1,
      long fast2,
      int fastIntegerDigitCount,
      int fastScale,
      int fastTrailingZeroesScale,
      byte[] scratchBuffer) {

    int index = scratchBuffer.length - 1;

    int trailingZeroCount =
        (fastTrailingZeroesScale != -1 ? fastTrailingZeroesScale - fastScale : 0);
    // Virtual trailing zeroes.
    if (trailingZeroCount > 0) {
      for (int i = 0; i < trailingZeroCount; i++) {
        scratchBuffer[index--] = BYTE_DIGIT_ZERO;
      }
    }

    // Scale fractional digits, dot, integer digits.

    final int scale = fastScale;

    final boolean isZeroFast1AndFast2 = (fast1 == 0 && fast2 == 0);
    final boolean isZeroFast2 = (fast2 == 0);

    int lowerLongwordScale = 0;
    int middleLongwordScale = 0;
    int highLongwordScale = 0;
    long longWord = fast0;
    if (scale > 0) {

      // Fraction digits from lower longword.

      lowerLongwordScale = Math.min(scale, LONGWORD_DECIMAL_DIGITS);

      for (int i = 0; i < lowerLongwordScale; i++) {
        scratchBuffer[index--] = (byte) (BYTE_DIGIT_ZERO + longWord % 10);
        longWord /= 10;
      }
      if (lowerLongwordScale == LONGWORD_DECIMAL_DIGITS) {
        longWord = fast1;
      }

      if (scale > LONGWORD_DECIMAL_DIGITS) {

        // Fraction digits continue into middle longword.

        middleLongwordScale = Math.min(scale - LONGWORD_DECIMAL_DIGITS, LONGWORD_DECIMAL_DIGITS);
        for (int i = 0; i < middleLongwordScale; i++) {
          scratchBuffer[index--] = (byte) (BYTE_DIGIT_ZERO + longWord % 10);
          longWord /= 10;
        }
        if (middleLongwordScale == LONGWORD_DECIMAL_DIGITS) {
          longWord = fast2;
        }

        if (scale > TWO_X_LONGWORD_DECIMAL_DIGITS) {

          // Fraction digit continue into highest longword.

          highLongwordScale = scale - TWO_X_LONGWORD_DECIMAL_DIGITS;
          for (int i = 0; i < highLongwordScale; i++) {
            scratchBuffer[index--] = (byte) (BYTE_DIGIT_ZERO + longWord % 10);
            longWord /= 10;
          }
        }
      }
      scratchBuffer[index--] = BYTE_DOT;
    } else if (trailingZeroCount > 0) {
      scratchBuffer[index--] = BYTE_DOT;
    }

    // Integer digits; stop on zeroes above.

    boolean atLeastOneIntegerDigit = false;
    if (scale <= LONGWORD_DECIMAL_DIGITS) {

      // Handle remaining lower long word digits as integer digits.

      final int remainingLowerLongwordDigits = LONGWORD_DECIMAL_DIGITS - lowerLongwordScale;
      for (int i = 0; i < remainingLowerLongwordDigits; i++) {
        scratchBuffer[index--] = (byte) (BYTE_DIGIT_ZERO + longWord % 10);
        atLeastOneIntegerDigit = true;
        longWord /= 10;
        if (longWord == 0 && isZeroFast1AndFast2) {
          // Suppress leading zeroes.
          break;
        }
      }
      if (isZeroFast1AndFast2) {
        if (!atLeastOneIntegerDigit) {
          scratchBuffer[index--] = BYTE_DIGIT_ZERO;
        }
        if (fastSignum == -1) {
          scratchBuffer[index--] = BYTE_MINUS;
        }
        return index + 1;
      }
      longWord = fast1;
    }

    if (scale <= TWO_X_LONGWORD_DECIMAL_DIGITS) {

      // Handle remaining middle long word digits.

      final int remainingMiddleLongwordDigits = LONGWORD_DECIMAL_DIGITS - middleLongwordScale;

      for (int i = 0; i < remainingMiddleLongwordDigits; i++) {
        scratchBuffer[index--] = (byte) (BYTE_DIGIT_ZERO + longWord % 10);
        atLeastOneIntegerDigit = true;
        longWord /= 10;
        if (longWord == 0 && isZeroFast2) {
          // Suppress leading zeroes.
          break;
        }
      }
      if (isZeroFast2) {
        if (!atLeastOneIntegerDigit) {
          scratchBuffer[index--] = BYTE_DIGIT_ZERO;
        }
        if (fastSignum == -1) {
          scratchBuffer[index--] = BYTE_MINUS;
        }
        return index + 1;
      }
      longWord = fast2;
    }

    final int remainingHighwordDigits = HIGHWORD_DECIMAL_DIGITS - highLongwordScale;

    for (int i = 0; i < remainingHighwordDigits; i++) {
      scratchBuffer[index--] = (byte) (BYTE_DIGIT_ZERO + longWord % 10);
      atLeastOneIntegerDigit = true;
      longWord /= 10;
      if (longWord == 0) {
        // Suppress leading zeroes.
        break;
      }
    }
    if (!atLeastOneIntegerDigit) {
      scratchBuffer[index--] = BYTE_DIGIT_ZERO;
    }
    if (fastSignum == -1) {
      scratchBuffer[index--] = BYTE_MINUS;
    }
    return index + 1;
  }