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