diff --git storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimal.java storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimal.java index 7fa9fdf..eece4d1 100644 --- storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimal.java +++ storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimal.java @@ -273,6 +273,20 @@ protected boolean fastSerializationUtilsWrite(OutputStream outputStream, scratchLongs); } + // Deserializes 64-bit decimals up to the maximum 64-bit precision (18 decimal digits). + protected void fastDeserialize64(long decimalLong, int scale) { + FastHiveDecimalImpl.fastDeserialize64( + decimalLong, scale, this); + } + + // Serializes 64-bit decimals up to the maximum 64-bit precision (18 decimal digits). + protected long fastSerialize64(int scale) { + return + FastHiveDecimalImpl.fastSerialize64( + scale, + fastSignum, fast1, fast0, fastScale); + } + // The fastBigIntegerBytes method returns 3 56 bit (7 byte) words and a possible sign byte. // However, the fastBigIntegerBytes can take on trailing zeroes -- so make it larger. protected static final int FAST_SCRATCH_BUFFER_LEN_BIG_INTEGER_BYTES = 1 + 48; diff --git storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java index ef9cbcf..63ff5dc 100644 --- storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java +++ storage-api/src/java/org/apache/hadoop/hive/common/type/FastHiveDecimalImpl.java @@ -154,6 +154,9 @@ private static final long MAX_LONGWORD_DECIMAL = powerOfTenTable[LONGWORD_DECIMAL_DIGITS] - 1; private static final long MULTIPLER_LONGWORD_DECIMAL = powerOfTenTable[LONGWORD_DECIMAL_DIGITS]; + public static final int DECIMAL64_DECIMAL_DIGITS = 18; + public static final long MAX_ABS_DECIMAL64 = 999999999999999999L; // 18 9's -- quite reliable! + private static final int TWO_X_LONGWORD_DECIMAL_DIGITS = 2 * LONGWORD_DECIMAL_DIGITS; private static final int THREE_X_LONGWORD_DECIMAL_DIGITS = 3 * LONGWORD_DECIMAL_DIGITS; private static final int FOUR_X_LONGWORD_DECIMAL_DIGITS = 4 * LONGWORD_DECIMAL_DIGITS; @@ -2138,6 +2141,54 @@ public static boolean fastSerializationUtilsWrite(OutputStream outputStream, throw new RuntimeException("Unexpected"); } + // Deserializes 64-bit decimals up to the maximum 64-bit precision (18 decimal digits). + public static void fastDeserialize64( + final long inputDecimal64Long, final int inputScale, + FastHiveDecimal fastResult) { + + long decimal64Long; + if (inputDecimal64Long == 0) { + fastResult.fastReset(); + return; + } else if (inputDecimal64Long > 0) { + fastResult.fastSignum = 1; + decimal64Long = inputDecimal64Long; + } else { + fastResult.fastSignum = -1; + decimal64Long = -inputDecimal64Long; + } + + // Trim trailing zeroes -- but only below the decimal point. + int trimScale = inputScale; + while (trimScale > 0 && decimal64Long % 10 == 0) { + decimal64Long /= 10; + trimScale--; + } + + fastResult.fast2 = 0; + fastResult.fast1 = decimal64Long / MULTIPLER_LONGWORD_DECIMAL; + fastResult.fast0 = decimal64Long % MULTIPLER_LONGWORD_DECIMAL; + + fastResult.fastScale = trimScale; + + fastResult.fastIntegerDigitCount = + Math.max(0, fastRawPrecision(fastResult) - fastResult.fastScale); + } + + // Serializes 64-bit decimals up to the maximum 64-bit precision (18 decimal digits). + public static long fastSerialize64( + int scale, + int fastSignum, long fast1, long fast0, int fastScale) { + + if (fastSignum == 0) { + return 0; + } else if (fastSignum == 1) { + return (fast1 * MULTIPLER_LONGWORD_DECIMAL + fast0) * powerOfTenTable[scale - fastScale]; + } else { + return -(fast1 * MULTIPLER_LONGWORD_DECIMAL + fast0) * powerOfTenTable[scale - fastScale]; + } + } + //************************************************************************************************ // Emulate BigInteger deserialization used by LazyBinary and others. diff --git storage-api/src/java/org/apache/hadoop/hive/serde2/io/HiveDecimalWritable.java storage-api/src/java/org/apache/hadoop/hive/serde2/io/HiveDecimalWritable.java index ffbe31a..83867b5 100644 --- storage-api/src/java/org/apache/hadoop/hive/serde2/io/HiveDecimalWritable.java +++ storage-api/src/java/org/apache/hadoop/hive/serde2/io/HiveDecimalWritable.java @@ -488,6 +488,38 @@ public boolean serializationUtilsWrite( scratchLongs); } + @HiveDecimalWritableVersionV2 + public static boolean isPrecisionDecimal64(int precision) { + return (precision <= FastHiveDecimalImpl.DECIMAL64_DECIMAL_DIGITS); + } + + @HiveDecimalWritableVersionV2 + public static long getAbsMaxDecimal64() { + return FastHiveDecimalImpl.MAX_ABS_DECIMAL64; + } + + // Deserializes 64-bit decimals up to the maximum 64-bit precision (18). + @HiveDecimalWritableVersionV2 + public void deserialize64( + long decimalLong, int scale) { + fastDeserialize64(decimalLong, scale); + isSet = true; + } + + // Serializes 64-bit decimals up to the maximum 64-bit precision (18). + @HiveDecimalWritableVersionV2 + public long serialize64(int scale) { + return fastSerialize64(scale); + } + + @HiveDecimalWritableVersionV2 + public boolean isValid() { + if (!isSet) { + return false; + } + return FastHiveDecimalImpl.fastIsValid(this); + } + /** * Returns the length of the decimal converted to bytes. * Call bigIntegerBytesBuffer() to get a reference to the converted bytes.