1f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka/*
2f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * Copyright (C) 2017 The Android Open Source Project
3f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka *
4f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * Licensed under the Apache License, Version 2.0 (the "License");
5f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * you may not use this file except in compliance with the License.
6f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * You may obtain a copy of the License at
7f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka *
8f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka *      http://www.apache.org/licenses/LICENSE-2.0
9f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka *
10f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * Unless required by applicable law or agreed to in writing, software
11f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * distributed under the License is distributed on an "AS IS" BASIS,
12f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * See the License for the specific language governing permissions and
14f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * limitations under the License.
15f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka */
16f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
17f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonakapackage android.text;
18f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
19f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonakaimport android.annotation.IntRange;
20f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonakaimport android.annotation.NonNull;
21f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
22f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonakaimport com.android.internal.util.ArrayUtils;
23f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
24f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonakaimport libcore.util.EmptyArray;
25f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
26f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka/**
27f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * Implements a growing array of int primitives.
28f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka *
29f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * These arrays are NOT thread safe.
30f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka *
31f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka * @hide
32f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka */
33f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonakapublic final class AutoGrowArray {
34f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    private static final int MIN_CAPACITY_INCREMENT = 12;
35f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    private static final int MAX_CAPACITY_TO_BE_KEPT = 10000;
36f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
37f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    /**
38f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka     * Returns next capacity size.
39f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka     *
40f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka     * The returned capacity is larger than requested capacity.
41f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka     */
42f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    private static int computeNewCapacity(int currentSize, int requested) {
43f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        final int targetCapacity = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2)
44f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                ?  MIN_CAPACITY_INCREMENT : currentSize >> 1);
45f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        return targetCapacity > requested ? targetCapacity : requested;
46f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    }
47f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
48f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    /**
49f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka     * An auto growing byte array.
50f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka     */
51f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    public static class ByteArray {
52f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
53f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        private @NonNull byte[] mValues;
54f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        private @IntRange(from = 0) int mSize;
55f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
56f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
57f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Creates an empty ByteArray with the default initial capacity.
58f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
59f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public ByteArray() {
60f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            this(10);
61f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
62f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
63f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
64f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Creates an empty ByteArray with the specified initial capacity.
65f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
66f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public ByteArray(@IntRange(from = 0) int initialCapacity) {
67f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (initialCapacity == 0) {
68f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = EmptyArray.BYTE;
69f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            } else {
70f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = ArrayUtils.newUnpaddedByteArray(initialCapacity);
71f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
72f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mSize = 0;
73f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
74f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
75f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
76f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Changes the size of this ByteArray. If this ByteArray is shrinked, the backing array
77f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * capacity is unchanged.
78f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
79f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void resize(@IntRange(from = 0) int newSize) {
80f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (newSize > mValues.length) {
81f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                ensureCapacity(newSize - mSize);
82f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
83f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mSize = newSize;
84f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
85f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
86f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
87f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Appends the specified value to the end of this array.
88f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
89f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void append(byte value) {
90f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            ensureCapacity(1);
91f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mValues[mSize++] = value;
92f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
93f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
94f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
95f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Ensures capacity to append at least <code>count</code> values.
96f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
97f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        private void ensureCapacity(@IntRange int count) {
98f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            final int requestedSize = mSize + count;
99f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (requestedSize >= mValues.length) {
100f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                final int newCapacity = computeNewCapacity(mSize, requestedSize);
101f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                final byte[] newValues = ArrayUtils.newUnpaddedByteArray(newCapacity);
102f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                System.arraycopy(mValues, 0, newValues, 0, mSize);
103f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = newValues;
104f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
105f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
106f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
107f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
108f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Removes all values from this array.
109f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
110f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void clear() {
111f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mSize = 0;
112f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
113f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
114f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
115f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Removes all values from this array and release the internal array object if it is too
116f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * large.
117f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
118f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void clearWithReleasingLargeArray() {
119f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            clear();
120f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (mValues.length > MAX_CAPACITY_TO_BE_KEPT) {
121f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = EmptyArray.BYTE;
122f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
123f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
124f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
125f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
126f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Returns the value at the specified position in this array.
127f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
128f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public byte get(@IntRange(from = 0) int index) {
129f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            return mValues[index];
130f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
131f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
132f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
133f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Sets the value at the specified position in this array.
134f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
135f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void set(@IntRange(from = 0) int index, byte value) {
136f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mValues[index] = value;
137f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
138f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
139f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
140f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Returns the number of values in this array.
141f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
142f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public @IntRange(from = 0) int size() {
143f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            return mSize;
144f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
145f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
146f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
147f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Returns internal raw array.
148f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         *
149f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Note that this array may have larger size than you requested.
150f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Use size() instead for getting the actual array size.
151f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
152f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public @NonNull byte[] getRawArray() {
153f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            return mValues;
154f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
155f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    }
156f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
157f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    /**
158f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka     * An auto growing int array.
159f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka     */
160f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    public static class IntArray {
161f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
162f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        private @NonNull int[] mValues;
163f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        private @IntRange(from = 0) int mSize;
164f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
165f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
166f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Creates an empty IntArray with the default initial capacity.
167f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
168f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public IntArray() {
169f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            this(10);
170f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
171f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
172f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
173f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Creates an empty IntArray with the specified initial capacity.
174f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
175f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public IntArray(@IntRange(from = 0) int initialCapacity) {
176f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (initialCapacity == 0) {
177f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = EmptyArray.INT;
178f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            } else {
179f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = ArrayUtils.newUnpaddedIntArray(initialCapacity);
180f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
181f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mSize = 0;
182f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
183f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
184f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
185f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Changes the size of this IntArray. If this IntArray is shrinked, the backing array
186f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * capacity is unchanged.
187f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
188f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void resize(@IntRange(from = 0) int newSize) {
189f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (newSize > mValues.length) {
190f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                ensureCapacity(newSize - mSize);
191f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
192f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mSize = newSize;
193f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
194f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
195f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
196f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Appends the specified value to the end of this array.
197f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
198f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void append(int value) {
199f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            ensureCapacity(1);
200f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mValues[mSize++] = value;
201f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
202f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
203f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
204f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Ensures capacity to append at least <code>count</code> values.
205f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
206f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        private void ensureCapacity(@IntRange(from = 0) int count) {
207f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            final int requestedSize = mSize + count;
208f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (requestedSize >= mValues.length) {
209f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                final int newCapacity = computeNewCapacity(mSize, requestedSize);
210f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                final int[] newValues = ArrayUtils.newUnpaddedIntArray(newCapacity);
211f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                System.arraycopy(mValues, 0, newValues, 0, mSize);
212f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = newValues;
213f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
214f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
215f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
216f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
217f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Removes all values from this array.
218f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
219f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void clear() {
220f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mSize = 0;
221f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
222f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
223f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
224f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Removes all values from this array and release the internal array object if it is too
225f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * large.
226f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
227f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void clearWithReleasingLargeArray() {
228f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            clear();
229f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (mValues.length > MAX_CAPACITY_TO_BE_KEPT) {
230f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = EmptyArray.INT;
231f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
232f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
233f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
234f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
235f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Returns the value at the specified position in this array.
236f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
237f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public int get(@IntRange(from = 0) int index) {
238f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            return mValues[index];
239f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
240f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
241f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
242f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Sets the value at the specified position in this array.
243f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
244f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void set(@IntRange(from = 0) int index, int value) {
245f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mValues[index] = value;
246f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
247f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
248f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
249f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Returns the number of values in this array.
250f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
251f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public @IntRange(from = 0) int size() {
252f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            return mSize;
253f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
254f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
255f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
256f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Returns internal raw array.
257f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         *
258f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Note that this array may have larger size than you requested.
259f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Use size() instead for getting the actual array size.
260f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
261f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public @NonNull int[] getRawArray() {
262f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            return mValues;
263f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
264f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    }
265f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
266f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    /**
267f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka     * An auto growing float array.
268f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka     */
269f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    public static class FloatArray {
270f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
271f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        private @NonNull float[] mValues;
272f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        private @IntRange(from = 0) int mSize;
273f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
274f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
275f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Creates an empty FloatArray with the default initial capacity.
276f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
277f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public FloatArray() {
278f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            this(10);
279f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
280f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
281f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
282f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Creates an empty FloatArray with the specified initial capacity.
283f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
284f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public FloatArray(@IntRange(from = 0) int initialCapacity) {
285f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (initialCapacity == 0) {
286f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = EmptyArray.FLOAT;
287f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            } else {
288f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = ArrayUtils.newUnpaddedFloatArray(initialCapacity);
289f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
290f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mSize = 0;
291f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
292f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
293f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
294f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Changes the size of this FloatArray. If this FloatArray is shrinked, the backing array
295f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * capacity is unchanged.
296f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
297f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void resize(@IntRange(from = 0) int newSize) {
298f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (newSize > mValues.length) {
299f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                ensureCapacity(newSize - mSize);
300f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
301f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mSize = newSize;
302f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
303f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
304f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
305f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Appends the specified value to the end of this array.
306f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
307f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void append(float value) {
308f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            ensureCapacity(1);
309f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mValues[mSize++] = value;
310f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
311f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
312f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
313f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Ensures capacity to append at least <code>count</code> values.
314f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
315f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        private void ensureCapacity(int count) {
316f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            final int requestedSize = mSize + count;
317f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (requestedSize >= mValues.length) {
318f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                final int newCapacity = computeNewCapacity(mSize, requestedSize);
319f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                final float[] newValues = ArrayUtils.newUnpaddedFloatArray(newCapacity);
320f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                System.arraycopy(mValues, 0, newValues, 0, mSize);
321f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = newValues;
322f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
323f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
324f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
325f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
326f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Removes all values from this array.
327f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
328f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void clear() {
329f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mSize = 0;
330f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
331f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
332f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
333f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Removes all values from this array and release the internal array object if it is too
334f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * large.
335f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
336f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void clearWithReleasingLargeArray() {
337f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            clear();
338f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            if (mValues.length > MAX_CAPACITY_TO_BE_KEPT) {
339f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka                mValues = EmptyArray.FLOAT;
340f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            }
341f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
342f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
343f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
344f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Returns the value at the specified position in this array.
345f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
346f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public float get(@IntRange(from = 0) int index) {
347f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            return mValues[index];
348f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
349f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
350f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
351f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Sets the value at the specified position in this array.
352f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
353f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public void set(@IntRange(from = 0) int index, float value) {
354f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            mValues[index] = value;
355f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
356f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
357f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
358f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Returns the number of values in this array.
359f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
360f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public @IntRange(from = 0) int size() {
361f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            return mSize;
362f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
363f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka
364f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        /**
365f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Returns internal raw array.
366f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         *
367f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Note that this array may have larger size than you requested.
368f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         * Use size() instead for getting the actual array size.
369f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka         */
370f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        public @NonNull float[] getRawArray() {
371f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka            return mValues;
372f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka        }
373f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka    }
374f1644f735de3a940d429c42ec920348e96a4d14eSeigo Nonaka}
375