public static boolean fastSetFromDigitsOnlyBytesAndScale()

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


  public static boolean fastSetFromDigitsOnlyBytesAndScale(
      boolean isNegative,
      byte[] bytes,
      int offset,
      int length,
      int scale,
      FastHiveDecimal fastResult) {

    final int bytesLength = bytes.length;

    if (offset < 0 || offset >= bytesLength) {
      return false;
    }
    final int end = offset + length;
    if (end <= offset || end > bytesLength) {
      return false;
    }

    // We start here with at least one byte.
    int index = offset;

    // A stripped down version of fastSetFromBytes.

    int precision = 0;

    // We fill starting with highest digit in highest longword (HIGHWORD_DECIMAL_DIGITS) and
    // move down.  At end will will shift everything down if necessary.

    int longWordIndex = 0; // Where 0 is the highest longword; 1 is middle longword, etc.

    int digitNum = HIGHWORD_DECIMAL_DIGITS;
    long multiplier = powerOfTenTable[HIGHWORD_DECIMAL_DIGITS - 1];

    int digitValue;
    long longWord = 0;

    long fast0 = 0;
    long fast1 = 0;
    long fast2 = 0;

    byte work;

    // Parse digits.

    boolean haveInteger = false;
    while (true) {
      work = bytes[index];
      if (work < BYTE_DIGIT_ZERO || work > BYTE_DIGIT_NINE) {
        if (!haveInteger) {
          return false;
        }
        break;
      }
      haveInteger = true;
      if (precision == 0 && work == BYTE_DIGIT_ZERO) {
        // Ignore leading zeroes.
        if (++index >= end) {
          break;
        }
        continue;
      }
      digitValue = work - BYTE_DIGIT_ZERO;
      if (digitNum == 0) {

        // Integer parsing move to next lower longword.

        // Save previous longword.
        if (longWordIndex == 0) {
          fast2 = longWord;
        } else if (longWordIndex == 1) {
          fast1 = longWord;
        } else if (longWordIndex == 2) {

          // We have filled HiveDecimal.MAX_PRECISION digits and have no more room in our limit
          // precision
          // fast decimal.
          return false;
        }
        longWordIndex++;

        // The middle and lowest longwords highest digit number is LONGWORD_DECIMAL_DIGITS.
        digitNum = LONGWORD_DECIMAL_DIGITS;
        multiplier = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - 1];
        longWord = 0;
      }
      longWord += digitValue * multiplier;
      multiplier /= 10;
      digitNum--;
      precision++;
      if (++index >= end) {
        break;
      }
    }

    // Just an digits?
    if (index < end) {
      return false;
    }

    if (precision == 0) {
      // We just had leading zeroes.
      // Value is 0.
      return true;
    }

    // Save last longword.
    if (longWordIndex == 0) {
      fast2 = longWord;
    } else if (longWordIndex == 1) {
      fast1 = longWord;
    } else {
      fast0 = longWord;
    }
    fastResult.fastSignum = (isNegative ? -1 : 1);
    fastResult.fastIntegerDigitCount = Math.max(0, precision - scale);
    fastResult.fastScale = scale;
    final int scaleDown = HiveDecimal.MAX_PRECISION - precision;
    if (scaleDown > 0) {
      doFastScaleDown(fast0, fast1, fast2, scaleDown, fastResult);
    } else {
      fastResult.fast0 = fast0;
      fastResult.fast1 = fast1;
      fastResult.fast2 = fast2;
    }
    return true;
  }