private void allocateBuffer(int nextElemLength) {
    // If this is a large value or shared buffer is maxed out, allocate a
    // single use buffer. Assumes that sharedBuffer length and
    // MAX_SIZE_FOR_SHARED_BUFFER are powers of 2.
    if (nextElemLength > MAX_SIZE_FOR_SMALL_ITEM ||
        sharedBufferOffset + nextElemLength >= MAX_SIZE_FOR_SHARED_BUFFER) {
      // allocate a value for the next value
      ++bufferAllocationCount;
      currentValue = new byte[nextElemLength];
      currentOffset = 0;
    } else {

      // sharedBuffer might still be out of space
      if ((sharedBufferOffset + nextElemLength) > sharedBuffer.length) {
        int newLength = sharedBuffer.length * 2;
        while (newLength < nextElemLength) {
          newLength *= 2;
        }
        sharedBuffer = new byte[newLength];
        ++bufferAllocationCount;
        sharedBufferOffset = 0;
      }
      currentValue = sharedBuffer;
      currentOffset = sharedBufferOffset;
    }
  }
Allocate/reuse enough buffer space to accommodate next element.
Sets currentValue and currentOffset to the correct buffer and offset.

This uses an exponential increase mechanism to rapidly
increase buffer size to enough to hold all data.
As batches get re-loaded, buffer space allocated will quickly
stabilize.

@param nextElemLength size of next element to be added
storage-api/src/java/org/apache/hadoop/hive/ql/exec/vector/BytesColumnVector.java