You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by go...@apache.org on 2019/03/11 05:53:07 UTC
[hive] 02/02: HIVE-21371: Make NonSyncByteArrayOutputStream
Overflow Conscious (David Mollitor, reviewed by Gopal V)
This is an automated email from the ASF dual-hosted git repository.
gopalv pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
commit c3939dab9c7d9429464add3e95741de76e78a3ab
Author: David Mollitor <da...@gmail.com>
AuthorDate: Sun Mar 10 22:50:44 2019 -0700
HIVE-21371: Make NonSyncByteArrayOutputStream Overflow Conscious (David Mollitor, reviewed by Gopal V)
Signed-off-by: Gopal V <go...@apache.org>
---
.../common/io/NonSyncByteArrayOutputStream.java | 37 +++++++++++++++-------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/common/src/java/org/apache/hadoop/hive/common/io/NonSyncByteArrayOutputStream.java b/common/src/java/org/apache/hadoop/hive/common/io/NonSyncByteArrayOutputStream.java
index ea49231..7e09cc8 100644
--- a/common/src/java/org/apache/hadoop/hive/common/io/NonSyncByteArrayOutputStream.java
+++ b/common/src/java/org/apache/hadoop/hive/common/io/NonSyncByteArrayOutputStream.java
@@ -21,12 +21,22 @@ import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.Arrays;
/**
* A thread-not-safe version of ByteArrayOutputStream, which removes all
* synchronized modifiers.
*/
public class NonSyncByteArrayOutputStream extends ByteArrayOutputStream {
+
+ /**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
public NonSyncByteArrayOutputStream(int size) {
super(size);
}
@@ -71,18 +81,22 @@ public class NonSyncByteArrayOutputStream extends ByteArrayOutputStream {
count += 1;
}
- private int enLargeBuffer(int increment) {
- int temp = count + increment;
- int newLen = temp;
- if (temp > buf.length) {
- if ((buf.length << 1) > temp) {
- newLen = buf.length << 1;
+ private void enLargeBuffer(final int increment) {
+ final int requestCapacity = Math.addExact(count, increment);
+ final int currentCapacity = buf.length;
+
+ if (requestCapacity > currentCapacity) {
+ // Increase size by a factor of 1.5x
+ int newCapacity = currentCapacity + (currentCapacity >> 1);
+
+ // Check for overflow scenarios
+ if (newCapacity < 0 || newCapacity > MAX_ARRAY_SIZE) {
+ newCapacity = MAX_ARRAY_SIZE;
+ } else if (newCapacity < requestCapacity) {
+ newCapacity = requestCapacity;
}
- byte newbuf[] = new byte[newLen];
- System.arraycopy(buf, 0, newbuf, 0, count);
- buf = newbuf;
+ buf = Arrays.copyOf(buf, newCapacity);
}
- return newLen;
}
/**
@@ -93,7 +107,8 @@ public class NonSyncByteArrayOutputStream extends ByteArrayOutputStream {
if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length)
|| ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
- } else if (len == 0) {
+ }
+ if (len == 0) {
return;
}
enLargeBuffer(len);