Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JNI: Support appending DECIMAL128 into ColumnBuilder in terms of byte array #10338

Merged
merged 1 commit into from
Feb 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions java/src/main/java/ai/rapids/cudf/HostColumnVector.java
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,23 @@ public ColumnBuilder appendUTF8String(byte[] value, int srcOffset, int length) {
return this;
}

/**
* Accepts a byte array containing the two's-complement representation of the unscaled value, which
* is in big-endian byte-order. Then, transforms it into the representation of cuDF Decimal128 for
* appending.
* This method is more efficient than `append(BigInteger unscaledVal)` if we can directly access the
* two's-complement representation of a BigDecimal without encoding via the method `toByteArray`.
*/
public ColumnBuilder appendDecimal128(byte[] binary) {
growFixedWidthBuffersAndRows();
assert type.getTypeId().equals(DType.DTypeEnum.DECIMAL128);
assert currentIndex < rows;
assert binary.length <= type.getSizeInBytes();
byte[] cuBinary = convertDecimal128FromJavaToCudf(binary);
data.setBytes(currentIndex++ << bitShiftBySize, cuBinary, 0, cuBinary.length);
return this;
}

public ColumnBuilder getChild(int index) {
return childBuilders.get(index);
}
Expand Down
12 changes: 12 additions & 0 deletions java/src/test/java/ai/rapids/cudf/ColumnBuilderHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package ai.rapids.cudf;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Comparator;
Expand Down Expand Up @@ -49,6 +50,17 @@ public static ColumnVector buildOnDevice(
}
}

public static HostColumnVector decimalFromBigInts(int scale, BigInteger... values) {
return ColumnBuilderHelper.build(
new HostColumnVector.BasicType(true, DType.create(DType.DTypeEnum.DECIMAL128, -scale)),
values.length,
(b) -> {
for (BigInteger v : values)
if (v == null) b.appendNull();
else b.appendDecimal128(v.toByteArray());
});
}

public static HostColumnVector fromBoxedBytes(boolean signed, Byte... values) {
DType dt = signed ? DType.INT8 : DType.UINT8;
return ColumnBuilderHelper.build(
Expand Down
22 changes: 20 additions & 2 deletions java/src/test/java/ai/rapids/cudf/DecimalColumnVectorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class DecimalColumnVectorTest extends CudfTestBase {
private static final BigDecimal[] decimal128Zoo = new BigDecimal[20];
private static final int[] unscaledDec32Zoo = new int[decimal32Zoo.length];
private static final long[] unscaledDec64Zoo = new long[decimal64Zoo.length];
private static final BigInteger[] unscaledDec128Zoo = new BigInteger[decimal128Zoo.length];

private final BigDecimal[] boundaryDecimal32 = new BigDecimal[]{
new BigDecimal("999999999"), new BigDecimal("-999999999")};
Expand All @@ -67,6 +68,7 @@ public static void setup() {
for (int i = 0; i < decimal32Zoo.length; i++) {
unscaledDec32Zoo[i] = rdSeed.nextInt() / 100;
unscaledDec64Zoo[i] = rdSeed.nextLong() / 100;
unscaledDec128Zoo[i] = BigInteger.valueOf(rdSeed.nextLong()).multiply(BigInteger.valueOf(rdSeed.nextLong()));
if (rdSeed.nextBoolean()) {
// Create BigDecimal with slight variance on scale, in order to test building cv from inputs with different scales.
decimal32Zoo[i] = BigDecimal.valueOf(rdSeed.nextInt() / 100, dec32Scale - rdSeed.nextInt(2));
Expand Down Expand Up @@ -245,7 +247,7 @@ private static void testDecimalImpl(DType.DTypeEnum decimalType, int scale, BigD
}

@Test
private void testDecimalFromInts() {
public void testDecimalFromInts() {
try (ColumnVector cv = ColumnVector.decimalFromInts(-DecimalColumnVectorTest.dec32Scale, DecimalColumnVectorTest.unscaledDec32Zoo)) {
try (HostColumnVector hcv = cv.copyToHost()) {
for (int i = 0; i < DecimalColumnVectorTest.unscaledDec32Zoo.length; i++) {
Expand All @@ -257,7 +259,7 @@ private void testDecimalFromInts() {
}

@Test
private static void testDecimalFromLongs() {
public void testDecimalFromLongs() {
try (ColumnVector cv = ColumnVector.decimalFromLongs(-DecimalColumnVectorTest.dec64Scale, DecimalColumnVectorTest.unscaledDec64Zoo)) {
try (HostColumnVector hcv = cv.copyToHost()) {
for (int i = 0; i < DecimalColumnVectorTest.unscaledDec64Zoo.length; i++) {
Expand All @@ -268,6 +270,22 @@ private static void testDecimalFromLongs() {
}
}

@Test
public void testDecimalFromBigInts() {
try (ColumnVector cv = ColumnVector.decimalFromBigInt(-DecimalColumnVectorTest.dec128Scale, DecimalColumnVectorTest.unscaledDec128Zoo)) {
try (HostColumnVector hcv = cv.copyToHost()) {
for (int i = 0; i < DecimalColumnVectorTest.unscaledDec128Zoo.length; i++) {
assertEquals(DecimalColumnVectorTest.unscaledDec128Zoo[i], hcv.getBigDecimal(i).unscaledValue());
}
}
}
try (HostColumnVector hcv = ColumnBuilderHelper.decimalFromBigInts(-DecimalColumnVectorTest.dec128Scale, DecimalColumnVectorTest.unscaledDec128Zoo)) {
for (int i = 0; i < DecimalColumnVectorTest.unscaledDec128Zoo.length; i++) {
assertEquals(DecimalColumnVectorTest.unscaledDec128Zoo[i], hcv.getBigDecimal(i).unscaledValue());
}
}
}

@Test
public void testDecimalFromDoubles() {
DType dt = DType.create(DType.DTypeEnum.DECIMAL32, -3);
Expand Down