This is an automated email from the ASF dual-hosted git repository. ravindra pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/master by this push: new 34481c2 ARROW-4808: [Java][Vector] More util methods to set decimal vector. 34481c2 is described below commit 34481c2070e79a7bfa97576c6219ad57f96b7afd Author: Praveen <prav...@dremio.com> AuthorDate: Tue Mar 12 13:01:47 2019 +0530 ARROW-4808: [Java][Vector] More util methods to set decimal vector. - Supports setting using an arrow buf of little endian bytes. - Supports arrow bufs of size less than 16 bytes. Author: Praveen <prav...@dremio.com> Closes #3844 from praveenbingo/ARROW-4808 and squashes the following commits: e481ad66 <Praveen> Minor fix. 6cd256b2 <Praveen> ARROW-4808: More util methods to set decimal vector. --- .../org/apache/arrow/vector/DecimalVector.java | 51 ++++++++++++ .../org/apache/arrow/vector/TestDecimalVector.java | 95 ++++++++++++++++++++++ 2 files changed, 146 insertions(+) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/DecimalVector.java b/java/vector/src/main/java/org/apache/arrow/vector/DecimalVector.java index 091c906..1045b23 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/DecimalVector.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/DecimalVector.java @@ -270,6 +270,57 @@ public class DecimalVector extends BaseFixedWidthVector { } /** + * Sets the element at given index using the buffer whose size maybe <= 16 bytes. + * @param index index to write the decimal to + * @param start start of value in the buffer + * @param buffer contains the decimal in little endian bytes + * @param length length of the value in the buffer + */ + public void setSafe(int index, int start, ArrowBuf buffer, int length) { + handleSafe(index); + BitVectorHelper.setValidityBitToOne(validityBuffer, index); + int startIndexInVector = index * TYPE_WIDTH; + valueBuffer.setBytes(startIndexInVector, buffer, start, length); + // sign extend + if (length < 16) { + byte msb = buffer.getByte(start + length - 1); + final byte pad = (byte) (msb < 0 ? 0xFF : 0x00); + int startIndex = startIndexInVector + length; + int endIndex = startIndexInVector + TYPE_WIDTH; + for (int i = startIndex; i < endIndex; i++) { + valueBuffer.setByte(i, pad); + } + } + } + + + /** + * Sets the element at given index using the buffer whose size maybe <= 16 bytes. + * @param index index to write the decimal to + * @param start start of value in the buffer + * @param buffer contains the decimal in big endian bytes + * @param length length of the value in the buffer + */ + public void setBigEndianSafe(int index, int start, ArrowBuf buffer, int length) { + handleSafe(index); + BitVectorHelper.setValidityBitToOne(validityBuffer, index); + int startIndexInVector = index * TYPE_WIDTH; + for (int i = start + length - 1; i >= start; i--) { + valueBuffer.setByte(startIndexInVector, buffer.getByte(i)); + startIndexInVector++; + } + // sign extend + if (length < 16) { + byte msb = buffer.getByte(start); + final byte pad = (byte) (msb < 0 ? 0xFF : 0x00); + int endIndex = startIndexInVector + TYPE_WIDTH - length; + for (int i = startIndexInVector; i < endIndex; i++) { + valueBuffer.setByte(i, pad); + } + } + } + + /** * Set the element at the given index to the given value. * * @param index position of element diff --git a/java/vector/src/test/java/org/apache/arrow/vector/TestDecimalVector.java b/java/vector/src/test/java/org/apache/arrow/vector/TestDecimalVector.java index 2d91746..6ec7b53 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/TestDecimalVector.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/TestDecimalVector.java @@ -32,6 +32,8 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import io.netty.buffer.ArrowBuf; + public class TestDecimalVector { private static long[] intValues; @@ -248,4 +250,97 @@ public class TestDecimalVector { assertEquals(BigInteger.valueOf(0), decimalVector.getObject(outputIdx).unscaledValue()); } } + + @Test + public void setUsingArrowBufOfLEInts() { + try (DecimalVector decimalVector = TestUtils.newVector(DecimalVector.class, "decimal", + new ArrowType.Decimal(5, 2), allocator); + ArrowBuf buf = allocator.buffer(8);) { + decimalVector.allocateNew(); + + // add a positive value equivalen to 705.32 + int val = 70532; + buf.setInt(0, val); + decimalVector.setSafe(0, 0, buf, 4); + + // add a -ve value equivalen to -705.32 + val = -70532; + buf.setInt(4, val); + decimalVector.setSafe(1, 4, buf, 4); + + decimalVector.setValueCount(2); + + BigDecimal [] expectedValues = new BigDecimal[] {BigDecimal.valueOf(705.32), BigDecimal + .valueOf(-705.32)}; + for (int i = 0; i < 2; i ++) { + BigDecimal value = decimalVector.getObject(i); + assertEquals(expectedValues[i], value); + } + } + + } + + @Test + public void setUsingArrowLongLEBytes() { + try (DecimalVector decimalVector = TestUtils.newVector(DecimalVector.class, "decimal", + new ArrowType.Decimal(18, 0), allocator); + ArrowBuf buf = allocator.buffer(16);) { + decimalVector.allocateNew(); + + long val = Long.MAX_VALUE; + buf.setLong(0, val); + decimalVector.setSafe(0, 0, buf, 8); + + val = Long.MIN_VALUE; + buf.setLong(8, val); + decimalVector.setSafe(1, 8, buf, 8); + + decimalVector.setValueCount(2); + + BigDecimal [] expectedValues = new BigDecimal[] {BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal + .valueOf(Long.MIN_VALUE)}; + for (int i = 0; i < 2; i ++) { + BigDecimal value = decimalVector.getObject(i); + assertEquals(expectedValues[i], value); + } + } + } + + @Test + public void setUsingArrowBufOfBEBytes() { + try (DecimalVector decimalVector = TestUtils.newVector(DecimalVector.class, "decimal", + new ArrowType.Decimal(5, 2), allocator); + ArrowBuf buf = allocator.buffer(9);) { + BigDecimal [] expectedValues = new BigDecimal[] {BigDecimal.valueOf(705.32), BigDecimal + .valueOf(-705.32),BigDecimal.valueOf(705.32)}; + verifyWritingArrowBufWithBigEndianBytes(decimalVector, buf, expectedValues, 3); + } + + try (DecimalVector decimalVector = TestUtils.newVector(DecimalVector.class, "decimal", + new ArrowType.Decimal(36, 2), allocator); + ArrowBuf buf = allocator.buffer(45);) { + BigDecimal[] expectedValues = new BigDecimal[] {new BigDecimal("2982346298346289346293467923465345.63"), + new BigDecimal("-2982346298346289346293467923465345.63"), + new BigDecimal("2982346298346289346293467923465345.63")}; + verifyWritingArrowBufWithBigEndianBytes(decimalVector, buf, expectedValues, 15); + } + } + + private void verifyWritingArrowBufWithBigEndianBytes(DecimalVector decimalVector, + ArrowBuf buf, BigDecimal[] expectedValues, + int length) { + decimalVector.allocateNew(); + for (int i = 0; i < expectedValues.length; i++) { + byte []bigEndianBytes = expectedValues[i].unscaledValue().toByteArray(); + buf.setBytes(length * i , bigEndianBytes, 0 , bigEndianBytes.length); + decimalVector.setBigEndianSafe(i, length * i, buf, bigEndianBytes.length); + } + + decimalVector.setValueCount(3); + + for (int i = 0; i < expectedValues.length; i ++) { + BigDecimal value = decimalVector.getObject(i); + assertEquals(expectedValues[i], value); + } + } }