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