0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 package org.apache.spark.unsafe;
0019
0020 import org.apache.spark.unsafe.array.ByteArrayMethods;
0021 import org.apache.spark.unsafe.types.UTF8String;
0022
0023
0024
0025
0026
0027 public class UTF8StringBuilder {
0028
0029 private static final int ARRAY_MAX = ByteArrayMethods.MAX_ROUNDED_ARRAY_LENGTH;
0030
0031 private byte[] buffer;
0032 private int cursor = Platform.BYTE_ARRAY_OFFSET;
0033
0034 public UTF8StringBuilder() {
0035
0036 this(16);
0037 }
0038
0039 public UTF8StringBuilder(int initialSize) {
0040 if (initialSize < 0) {
0041 throw new IllegalArgumentException("Size must be non-negative");
0042 }
0043 if (initialSize > ARRAY_MAX) {
0044 throw new IllegalArgumentException(
0045 "Size " + initialSize + " exceeded maximum size of " + ARRAY_MAX);
0046 }
0047 this.buffer = new byte[initialSize];
0048 }
0049
0050
0051 private void grow(int neededSize) {
0052 if (neededSize > ARRAY_MAX - totalSize()) {
0053 throw new UnsupportedOperationException(
0054 "Cannot grow internal buffer by size " + neededSize + " because the size after growing " +
0055 "exceeds size limitation " + ARRAY_MAX);
0056 }
0057 final int length = totalSize() + neededSize;
0058 if (buffer.length < length) {
0059 int newLength = length < ARRAY_MAX / 2 ? length * 2 : ARRAY_MAX;
0060 final byte[] tmp = new byte[newLength];
0061 Platform.copyMemory(
0062 buffer,
0063 Platform.BYTE_ARRAY_OFFSET,
0064 tmp,
0065 Platform.BYTE_ARRAY_OFFSET,
0066 totalSize());
0067 buffer = tmp;
0068 }
0069 }
0070
0071 private int totalSize() {
0072 return cursor - Platform.BYTE_ARRAY_OFFSET;
0073 }
0074
0075 public void append(UTF8String value) {
0076 grow(value.numBytes());
0077 value.writeToMemory(buffer, cursor);
0078 cursor += value.numBytes();
0079 }
0080
0081 public void append(String value) {
0082 append(UTF8String.fromString(value));
0083 }
0084
0085 public void appendBytes(Object base, long offset, int length) {
0086 grow(length);
0087 Platform.copyMemory(
0088 base,
0089 offset,
0090 buffer,
0091 cursor,
0092 length);
0093 cursor += length;
0094 }
0095
0096 public UTF8String build() {
0097 return UTF8String.fromBytes(buffer, 0, totalSize());
0098 }
0099 }