Skip to content

Commit 41b11bf

Browse files
Add Decimal Vector APIs to write Big Endian data
1 parent c8b6467 commit 41b11bf

4 files changed

Lines changed: 67 additions & 0 deletions

File tree

java/vector/src/main/codegen/templates/AbstractFieldWriter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ public void write(${name}Holder holder) {
6767
public void write${minor.class}(${friendlyType} value) {
6868
fail("${name}");
6969
}
70+
71+
public void writeBigEndianBytesToDecimal(byte[] value) {
72+
fail("${name}");
73+
}
7074
</#if>
7175

7276
</#list></#list>

java/vector/src/main/codegen/templates/AbstractPromotableFieldWriter.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
* limitations under the License.
1717
*/
1818

19+
import io.netty.buffer.ArrowBuf;
20+
import org.apache.arrow.vector.types.Types;
1921
import org.apache.drill.common.types.TypeProtos.MinorType;
2022

2123
<@pp.dropOutputFile />
@@ -82,6 +84,12 @@ public void write(${name}Holder holder) {
8284
getWriter(MinorType.${name?upper_case}).write${minor.class}(<#list fields as field>${field.name}<#if field_has_next>, </#if></#list>);
8385
}
8486

87+
<#if minor.class == "Decimal">
88+
public void writeBigEndianBytesToDecimal(byte[] value) {
89+
getWriter(Types.MinorType.DECIMAL).writeBigEndianBytesToDecimal(value);
90+
}
91+
</#if>
92+
8593
</#list></#list>
8694
public void writeNull() {
8795
}

java/vector/src/main/codegen/templates/ComplexWriters.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ public void write(Nullable${minor.class}Holder h) {
120120
vector.setSafe(idx(), value);
121121
vector.setValueCount(idx()+1);
122122
}
123+
124+
public void writeBigEndianBytesToDecimal(byte[] value) {
125+
vector.setBigEndianSafe(idx(), value);
126+
vector.setValueCount(idx()+1);
127+
}
123128
</#if>
124129
125130
<#if mode == "Nullable">
@@ -148,6 +153,8 @@ public interface ${eName}Writer extends BaseWriter {
148153
<#if minor.class == "Decimal">
149154

150155
public void write${minor.class}(${friendlyType} value);
156+
157+
public void writeBigEndianBytesToDecimal(byte[] value);
151158
</#if>
152159
}
153160

java/vector/src/main/java/org/apache/arrow/vector/NullableDecimalVector.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
package org.apache.arrow.vector;
2020

21+
import com.google.common.base.Preconditions;
2122
import io.netty.buffer.ArrowBuf;
2223
import org.apache.arrow.memory.BufferAllocator;
2324
import org.apache.arrow.vector.complex.impl.DecimalReaderImpl;
@@ -199,6 +200,43 @@ public void set(int index, ArrowBuf buffer) {
199200
valueBuffer.setBytes(index * TYPE_WIDTH, buffer, 0, TYPE_WIDTH);
200201
}
201202

203+
/**
204+
* Set the decimal element at given index to the provided array of bytes.
205+
* Decimal is now implemented as Little Endian. This API allows the user
206+
* to pass a decimal value in the form of byte array in BE byte order.
207+
*
208+
* Consumers of Arrow code can use this API instead of first swapping
209+
* the source bytes (doing a write and read) and then finally writing to
210+
* ArrowBuf of decimal vector.
211+
*
212+
* This method takes care of adding the necessary padding if the length
213+
* of byte array is less then 16 (length of decimal type).
214+
*
215+
* @param index position of element
216+
* @param value array of bytes containing decimal in big endian byte order.
217+
*/
218+
public void setBigEndian(int index, byte[] value) {
219+
assert value.length <= TYPE_WIDTH;
220+
BitVectorHelper.setValidityBitToOne(validityBuffer, index);
221+
final int length = value.length;
222+
int startIndex = index * TYPE_WIDTH;
223+
if (length == TYPE_WIDTH) {
224+
for (int i = TYPE_WIDTH - 1; i >= 3; i-=4) {
225+
valueBuffer.setByte(startIndex, value[i]);
226+
valueBuffer.setByte(startIndex + 1, value[i-1]);
227+
valueBuffer.setByte(startIndex + 2, value[i-2]);
228+
valueBuffer.setByte(startIndex + 3, value[i-3]);
229+
startIndex += 4;
230+
}
231+
} else {
232+
for (int i = length - 1; i >= 0; i--) {
233+
valueBuffer.setByte(startIndex, value[i]);
234+
startIndex++;
235+
}
236+
valueBuffer.setZero(startIndex, TYPE_WIDTH - length);
237+
}
238+
}
239+
202240
/**
203241
* Set the element at the given index to the given value.
204242
*
@@ -266,6 +304,16 @@ public void setSafe(int index, ArrowBuf buffer) {
266304
set(index, buffer);
267305
}
268306

307+
/**
308+
* Same as {@link #setBigEndian(int, byte[])} except that it handles the
309+
* case when index is greater than or equal to existing
310+
* value capacity {@link #getValueCapacity()}.
311+
*/
312+
public void setBigEndianSafe(int index, byte[] value) {
313+
handleSafe(index);
314+
setBigEndian(index, value);
315+
}
316+
269317
/**
270318
* Same as {@link #set(int, int, ArrowBuf)} except that it handles the
271319
* case when index is greater than or equal to existing

0 commit comments

Comments
 (0)