summaryrefslogtreecommitdiff
path: root/android/text/AutoGrowArray.java
diff options
context:
space:
mode:
Diffstat (limited to 'android/text/AutoGrowArray.java')
-rw-r--r--android/text/AutoGrowArray.java374
1 files changed, 374 insertions, 0 deletions
diff --git a/android/text/AutoGrowArray.java b/android/text/AutoGrowArray.java
new file mode 100644
index 00000000..e428377a
--- /dev/null
+++ b/android/text/AutoGrowArray.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+
+import com.android.internal.util.ArrayUtils;
+
+import libcore.util.EmptyArray;
+
+/**
+ * Implements a growing array of int primitives.
+ *
+ * These arrays are NOT thread safe.
+ *
+ * @hide
+ */
+public final class AutoGrowArray {
+ private static final int MIN_CAPACITY_INCREMENT = 12;
+ private static final int MAX_CAPACITY_TO_BE_KEPT = 10000;
+
+ /**
+ * Returns next capacity size.
+ *
+ * The returned capacity is larger than requested capacity.
+ */
+ private static int computeNewCapacity(int currentSize, int requested) {
+ final int targetCapacity = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2)
+ ? MIN_CAPACITY_INCREMENT : currentSize >> 1);
+ return targetCapacity > requested ? targetCapacity : requested;
+ }
+
+ /**
+ * An auto growing byte array.
+ */
+ public static class ByteArray {
+
+ private @NonNull byte[] mValues;
+ private @IntRange(from = 0) int mSize;
+
+ /**
+ * Creates an empty ByteArray with the default initial capacity.
+ */
+ public ByteArray() {
+ this(10);
+ }
+
+ /**
+ * Creates an empty ByteArray with the specified initial capacity.
+ */
+ public ByteArray(@IntRange(from = 0) int initialCapacity) {
+ if (initialCapacity == 0) {
+ mValues = EmptyArray.BYTE;
+ } else {
+ mValues = ArrayUtils.newUnpaddedByteArray(initialCapacity);
+ }
+ mSize = 0;
+ }
+
+ /**
+ * Changes the size of this ByteArray. If this ByteArray is shrinked, the backing array
+ * capacity is unchanged.
+ */
+ public void resize(@IntRange(from = 0) int newSize) {
+ if (newSize > mValues.length) {
+ ensureCapacity(newSize - mSize);
+ }
+ mSize = newSize;
+ }
+
+ /**
+ * Appends the specified value to the end of this array.
+ */
+ public void append(byte value) {
+ ensureCapacity(1);
+ mValues[mSize++] = value;
+ }
+
+ /**
+ * Ensures capacity to append at least <code>count</code> values.
+ */
+ private void ensureCapacity(@IntRange int count) {
+ final int requestedSize = mSize + count;
+ if (requestedSize >= mValues.length) {
+ final int newCapacity = computeNewCapacity(mSize, requestedSize);
+ final byte[] newValues = ArrayUtils.newUnpaddedByteArray(newCapacity);
+ System.arraycopy(mValues, 0, newValues, 0, mSize);
+ mValues = newValues;
+ }
+ }
+
+ /**
+ * Removes all values from this array.
+ */
+ public void clear() {
+ mSize = 0;
+ }
+
+ /**
+ * Removes all values from this array and release the internal array object if it is too
+ * large.
+ */
+ public void clearWithReleasingLargeArray() {
+ clear();
+ if (mValues.length > MAX_CAPACITY_TO_BE_KEPT) {
+ mValues = EmptyArray.BYTE;
+ }
+ }
+
+ /**
+ * Returns the value at the specified position in this array.
+ */
+ public byte get(@IntRange(from = 0) int index) {
+ return mValues[index];
+ }
+
+ /**
+ * Sets the value at the specified position in this array.
+ */
+ public void set(@IntRange(from = 0) int index, byte value) {
+ mValues[index] = value;
+ }
+
+ /**
+ * Returns the number of values in this array.
+ */
+ public @IntRange(from = 0) int size() {
+ return mSize;
+ }
+
+ /**
+ * Returns internal raw array.
+ *
+ * Note that this array may have larger size than you requested.
+ * Use size() instead for getting the actual array size.
+ */
+ public @NonNull byte[] getRawArray() {
+ return mValues;
+ }
+ }
+
+ /**
+ * An auto growing int array.
+ */
+ public static class IntArray {
+
+ private @NonNull int[] mValues;
+ private @IntRange(from = 0) int mSize;
+
+ /**
+ * Creates an empty IntArray with the default initial capacity.
+ */
+ public IntArray() {
+ this(10);
+ }
+
+ /**
+ * Creates an empty IntArray with the specified initial capacity.
+ */
+ public IntArray(@IntRange(from = 0) int initialCapacity) {
+ if (initialCapacity == 0) {
+ mValues = EmptyArray.INT;
+ } else {
+ mValues = ArrayUtils.newUnpaddedIntArray(initialCapacity);
+ }
+ mSize = 0;
+ }
+
+ /**
+ * Changes the size of this IntArray. If this IntArray is shrinked, the backing array
+ * capacity is unchanged.
+ */
+ public void resize(@IntRange(from = 0) int newSize) {
+ if (newSize > mValues.length) {
+ ensureCapacity(newSize - mSize);
+ }
+ mSize = newSize;
+ }
+
+ /**
+ * Appends the specified value to the end of this array.
+ */
+ public void append(int value) {
+ ensureCapacity(1);
+ mValues[mSize++] = value;
+ }
+
+ /**
+ * Ensures capacity to append at least <code>count</code> values.
+ */
+ private void ensureCapacity(@IntRange(from = 0) int count) {
+ final int requestedSize = mSize + count;
+ if (requestedSize >= mValues.length) {
+ final int newCapacity = computeNewCapacity(mSize, requestedSize);
+ final int[] newValues = ArrayUtils.newUnpaddedIntArray(newCapacity);
+ System.arraycopy(mValues, 0, newValues, 0, mSize);
+ mValues = newValues;
+ }
+ }
+
+ /**
+ * Removes all values from this array.
+ */
+ public void clear() {
+ mSize = 0;
+ }
+
+ /**
+ * Removes all values from this array and release the internal array object if it is too
+ * large.
+ */
+ public void clearWithReleasingLargeArray() {
+ clear();
+ if (mValues.length > MAX_CAPACITY_TO_BE_KEPT) {
+ mValues = EmptyArray.INT;
+ }
+ }
+
+ /**
+ * Returns the value at the specified position in this array.
+ */
+ public int get(@IntRange(from = 0) int index) {
+ return mValues[index];
+ }
+
+ /**
+ * Sets the value at the specified position in this array.
+ */
+ public void set(@IntRange(from = 0) int index, int value) {
+ mValues[index] = value;
+ }
+
+ /**
+ * Returns the number of values in this array.
+ */
+ public @IntRange(from = 0) int size() {
+ return mSize;
+ }
+
+ /**
+ * Returns internal raw array.
+ *
+ * Note that this array may have larger size than you requested.
+ * Use size() instead for getting the actual array size.
+ */
+ public @NonNull int[] getRawArray() {
+ return mValues;
+ }
+ }
+
+ /**
+ * An auto growing float array.
+ */
+ public static class FloatArray {
+
+ private @NonNull float[] mValues;
+ private @IntRange(from = 0) int mSize;
+
+ /**
+ * Creates an empty FloatArray with the default initial capacity.
+ */
+ public FloatArray() {
+ this(10);
+ }
+
+ /**
+ * Creates an empty FloatArray with the specified initial capacity.
+ */
+ public FloatArray(@IntRange(from = 0) int initialCapacity) {
+ if (initialCapacity == 0) {
+ mValues = EmptyArray.FLOAT;
+ } else {
+ mValues = ArrayUtils.newUnpaddedFloatArray(initialCapacity);
+ }
+ mSize = 0;
+ }
+
+ /**
+ * Changes the size of this FloatArray. If this FloatArray is shrinked, the backing array
+ * capacity is unchanged.
+ */
+ public void resize(@IntRange(from = 0) int newSize) {
+ if (newSize > mValues.length) {
+ ensureCapacity(newSize - mSize);
+ }
+ mSize = newSize;
+ }
+
+ /**
+ * Appends the specified value to the end of this array.
+ */
+ public void append(float value) {
+ ensureCapacity(1);
+ mValues[mSize++] = value;
+ }
+
+ /**
+ * Ensures capacity to append at least <code>count</code> values.
+ */
+ private void ensureCapacity(int count) {
+ final int requestedSize = mSize + count;
+ if (requestedSize >= mValues.length) {
+ final int newCapacity = computeNewCapacity(mSize, requestedSize);
+ final float[] newValues = ArrayUtils.newUnpaddedFloatArray(newCapacity);
+ System.arraycopy(mValues, 0, newValues, 0, mSize);
+ mValues = newValues;
+ }
+ }
+
+ /**
+ * Removes all values from this array.
+ */
+ public void clear() {
+ mSize = 0;
+ }
+
+ /**
+ * Removes all values from this array and release the internal array object if it is too
+ * large.
+ */
+ public void clearWithReleasingLargeArray() {
+ clear();
+ if (mValues.length > MAX_CAPACITY_TO_BE_KEPT) {
+ mValues = EmptyArray.FLOAT;
+ }
+ }
+
+ /**
+ * Returns the value at the specified position in this array.
+ */
+ public float get(@IntRange(from = 0) int index) {
+ return mValues[index];
+ }
+
+ /**
+ * Sets the value at the specified position in this array.
+ */
+ public void set(@IntRange(from = 0) int index, float value) {
+ mValues[index] = value;
+ }
+
+ /**
+ * Returns the number of values in this array.
+ */
+ public @IntRange(from = 0) int size() {
+ return mSize;
+ }
+
+ /**
+ * Returns internal raw array.
+ *
+ * Note that this array may have larger size than you requested.
+ * Use size() instead for getting the actual array size.
+ */
+ public @NonNull float[] getRawArray() {
+ return mValues;
+ }
+ }
+}