public static int fastBigIntegerBytesUnscaled()

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;
  }