• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 com.android.car.internal.util;
18 
19 import static com.android.car.internal.common.CommonConstants.EMPTY_INT_ARRAY;
20 
21 import com.android.internal.util.Preconditions;
22 
23 import java.util.Arrays;
24 
25 // Copy of frameworks/base/core/java/android/util/IntArray.java
26 /**
27  * Implements a growing array of int primitives.
28  */
29 public class IntArray implements Cloneable {
30     private static final int MIN_CAPACITY_INCREMENT = 12;
31 
32     private int[] mValues;
33     private int mSize;
34 
IntArray(int[] array, int size)35     private  IntArray(int[] array, int size) {
36         mValues = array;
37         mSize = Preconditions.checkArgumentInRange(size, 0, array.length, "size");
38     }
39 
40     /**
41      * Creates an empty IntArray with the default initial capacity.
42      */
IntArray()43     public IntArray() {
44         this(10);
45     }
46 
47     /**
48      * Creates an empty IntArray with the specified initial capacity.
49      */
IntArray(int initialCapacity)50     public IntArray(int initialCapacity) {
51         if (initialCapacity == 0) {
52             mValues = EMPTY_INT_ARRAY;
53         } else {
54             mValues = new int[initialCapacity];
55         }
56         mSize = 0;
57     }
58 
59     /**
60      * Creates an IntArray wrapping the given primitive int array.
61      */
wrap(int[] array)62     public static IntArray wrap(int[] array) {
63         return new IntArray(array, array.length);
64     }
65 
66     /**
67      * Creates an IntArray from the given primitive int array, copying it.
68      */
fromArray(int[] array, int size)69     public static IntArray fromArray(int[] array, int size) {
70         return wrap(Arrays.copyOf(array, size));
71     }
72 
73     /**
74      * Changes the size of this IntArray. If this IntArray is shrinked, the backing array capacity
75      * is unchanged. If the new size is larger than backing array capacity, a new backing array is
76      * created from the current content of this IntArray padded with 0s.
77      */
resize(int newSize)78     public void resize(int newSize) {
79         Preconditions.checkArgumentNonnegative(newSize);
80         if (newSize <= mValues.length) {
81             Arrays.fill(mValues, newSize, mValues.length, 0);
82         } else {
83             ensureCapacity(newSize - mSize);
84         }
85         mSize = newSize;
86     }
87 
88     /**
89      * Appends the specified value to the end of this array.
90      */
add(int value)91     public void add(int value) {
92         add(mSize, value);
93     }
94 
95     /**
96      * Inserts a value at the specified position in this array. If the specified index is equal to
97      * the length of the array, the value is added at the end.
98      *
99      * @throws IndexOutOfBoundsException when index &lt; 0 || index &gt; size()
100      */
add(int index, int value)101     public void add(int index, int value) {
102         ensureCapacity(1);
103         int rightSegment = mSize - index;
104         mSize++;
105         ArrayUtils.checkBounds(mSize, index);
106 
107         if (rightSegment != 0) {
108             // Move by 1 all values from the right of 'index'
109             System.arraycopy(mValues, index, mValues, index + 1, rightSegment);
110         }
111 
112         mValues[index] = value;
113     }
114 
115     /**
116      * Searches the array for the specified value using the binary search algorithm. The array must
117      * be sorted (as by the {@link Arrays#sort(int[], int, int)} method) prior to making this call.
118      * If it is not sorted, the results are undefined. If the range contains multiple elements with
119      * the specified value, there is no guarantee which one will be found.
120      *
121      * @param value The value to search for.
122      * @return index of the search key, if it is contained in the array; otherwise, <i>(-(insertion
123      *         point) - 1)</i>. The insertion point is defined as the point at which the key would
124      *         be inserted into the array: the index of the first element greater than the key, or
125      *         {@link #size()} if all elements in the array are less than the specified key.
126      *         Note that this guarantees that the return value will be >= 0 if and only if the key
127      *         is found.
128      */
binarySearch(int value)129     public int binarySearch(int value) {
130         return Arrays.binarySearch(mValues, value);
131     }
132 
133     /**
134      * Adds the values in the specified array to this array.
135      */
addAll(IntArray values)136     public void addAll(IntArray values) {
137         final int count = values.mSize;
138         ensureCapacity(count);
139 
140         System.arraycopy(values.mValues, 0, mValues, mSize, count);
141         mSize += count;
142     }
143 
144     /**
145      * Adds the values in the specified array to this array.
146      */
addAll(int[] values)147     public void addAll(int[] values) {
148         final int count = values.length;
149         ensureCapacity(count);
150 
151         System.arraycopy(values, 0, mValues, mSize, count);
152         mSize += count;
153     }
154 
155     /**
156      * Ensures capacity to append at least <code>count</code> values.
157      */
ensureCapacity(int count)158     private void ensureCapacity(int count) {
159         final int currentSize = mSize;
160         final int minCapacity = currentSize + count;
161         if (minCapacity >= mValues.length) {
162             final int targetCap = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2)
163                     ? MIN_CAPACITY_INCREMENT : currentSize >> 1);
164             final int newCapacity = targetCap > minCapacity ? targetCap : minCapacity;
165             final int[] newValues = new int[newCapacity];
166             System.arraycopy(mValues, 0, newValues, 0, currentSize);
167             mValues = newValues;
168         }
169     }
170 
171     /**
172      * Removes all values from this array.
173      */
clear()174     public void clear() {
175         mSize = 0;
176     }
177 
178     @Override
clone()179     public IntArray clone() throws CloneNotSupportedException {
180         final IntArray clone = (IntArray) super.clone();
181         clone.mValues = mValues.clone();
182         return clone;
183     }
184 
185     /**
186      * Returns the value at the specified position in this array.
187      */
get(int index)188     public int get(int index) {
189         ArrayUtils.checkBounds(mSize, index);
190         return mValues[index];
191     }
192 
193     /**
194      * Sets the value at the specified position in this array.
195      */
set(int index, int value)196     public void set(int index, int value) {
197         ArrayUtils.checkBounds(mSize, index);
198         mValues[index] = value;
199     }
200 
201     /**
202      * Returns the index of the first occurrence of the specified value in this
203      * array, or -1 if this array does not contain the value.
204      */
indexOf(int value)205     public int indexOf(int value) {
206         final int n = mSize;
207         for (int i = 0; i < n; i++) {
208             if (mValues[i] == value) {
209                 return i;
210             }
211         }
212         return -1;
213     }
214 
215     /**
216      * Removes the value at the specified index from this array.
217      */
remove(int index)218     public void remove(int index) {
219         ArrayUtils.checkBounds(mSize, index);
220         System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1);
221         mSize--;
222     }
223 
224     /**
225      * Returns the number of values in this array.
226      */
size()227     public int size() {
228         return mSize;
229     }
230 
231     /**
232      * Returns a new array with the contents of this IntArray.
233      */
toArray()234     public int[] toArray() {
235         return Arrays.copyOf(mValues, mSize);
236     }
237 }
238