Skip to content

Commit

Permalink
support appending Decimal128 in terms of byte array
Browse files Browse the repository at this point in the history
  • Loading branch information
sperlingxx committed Feb 21, 2022
1 parent 8b0737d commit a9af8b6
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
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

0 comments on commit a9af8b6

Please sign in to comment.