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

Reply via email to