blob: 9b0489ca5c6ed8054e0e9728ffdfa0f8e1878b72 [file] [log] [blame]
Alan Viverettef0aed092013-11-06 15:33:03 -08001/*
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
17package android.util;
18
19import com.android.internal.util.ArrayUtils;
Hugo Benichi112962a2017-03-27 13:45:23 +090020import com.android.internal.util.Preconditions;
21import java.util.Arrays;
Adam Lesinski776abc22014-03-07 11:30:59 -050022import libcore.util.EmptyArray;
Alan Viverettef0aed092013-11-06 15:33:03 -080023
24/**
25 * Implements a growing array of long primitives.
26 *
27 * @hide
28 */
29public class LongArray implements Cloneable {
30 private static final int MIN_CAPACITY_INCREMENT = 12;
31
32 private long[] mValues;
33 private int mSize;
34
Hugo Benichi112962a2017-03-27 13:45:23 +090035 private LongArray(long[] array, int size) {
36 mValues = array;
37 mSize = Preconditions.checkArgumentInRange(size, 0, array.length, "size");
38 }
39
Alan Viverettef0aed092013-11-06 15:33:03 -080040 /**
41 * Creates an empty LongArray with the default initial capacity.
42 */
43 public LongArray() {
44 this(10);
45 }
46
47 /**
48 * Creates an empty LongArray with the specified initial capacity.
49 */
50 public LongArray(int initialCapacity) {
51 if (initialCapacity == 0) {
Adam Lesinski776abc22014-03-07 11:30:59 -050052 mValues = EmptyArray.LONG;
Alan Viverettef0aed092013-11-06 15:33:03 -080053 } else {
Adam Lesinski776abc22014-03-07 11:30:59 -050054 mValues = ArrayUtils.newUnpaddedLongArray(initialCapacity);
Alan Viverettef0aed092013-11-06 15:33:03 -080055 }
56 mSize = 0;
57 }
58
59 /**
Hugo Benichi112962a2017-03-27 13:45:23 +090060 * Creates an LongArray wrapping the given primitive long array.
61 */
62 public static LongArray wrap(long[] array) {
63 return new LongArray(array, array.length);
64 }
65
66 /**
67 * Creates an LongArray from the given primitive long array, copying it.
68 */
69 public static LongArray fromArray(long[] array, int size) {
70 return wrap(Arrays.copyOf(array, size));
71 }
72
73 /**
74 * Changes the size of this LongArray. If this LongArray 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 LongArray padded with 0s.
77 */
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 /**
Alan Viverettef0aed092013-11-06 15:33:03 -080089 * Appends the specified value to the end of this array.
90 */
91 public void add(long value) {
92 add(mSize, value);
93 }
94
95 /**
Hugo Benichi112962a2017-03-27 13:45:23 +090096 * 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.
Alan Viverettef0aed092013-11-06 15:33:03 -080098 *
99 * @throws IndexOutOfBoundsException when index &lt; 0 || index &gt; size()
100 */
101 public void add(int index, long value) {
Alan Viverettef0aed092013-11-06 15:33:03 -0800102 ensureCapacity(1);
Hugo Benichi112962a2017-03-27 13:45:23 +0900103 int rightSegment = mSize - index;
104 mSize++;
105 checkBounds(index);
Alan Viverettef0aed092013-11-06 15:33:03 -0800106
Hugo Benichi112962a2017-03-27 13:45:23 +0900107 if (rightSegment != 0) {
108 // Move by 1 all values from the right of 'index'
109 System.arraycopy(mValues, index, mValues, index + 1, rightSegment);
Alan Viverettef0aed092013-11-06 15:33:03 -0800110 }
111
112 mValues[index] = value;
Alan Viverettef0aed092013-11-06 15:33:03 -0800113 }
114
115 /**
116 * Adds the values in the specified array to this array.
117 */
118 public void addAll(LongArray values) {
119 final int count = values.mSize;
120 ensureCapacity(count);
121
Alan Viverettedb24d142013-11-27 17:38:24 -0800122 System.arraycopy(values.mValues, 0, mValues, mSize, count);
Alan Viverettef0aed092013-11-06 15:33:03 -0800123 mSize += count;
124 }
125
126 /**
127 * Ensures capacity to append at least <code>count</code> values.
128 */
129 private void ensureCapacity(int count) {
130 final int currentSize = mSize;
131 final int minCapacity = currentSize + count;
132 if (minCapacity >= mValues.length) {
133 final int targetCap = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2) ?
134 MIN_CAPACITY_INCREMENT : currentSize >> 1);
135 final int newCapacity = targetCap > minCapacity ? targetCap : minCapacity;
Adam Lesinski776abc22014-03-07 11:30:59 -0500136 final long[] newValues = ArrayUtils.newUnpaddedLongArray(newCapacity);
Alan Viverettef0aed092013-11-06 15:33:03 -0800137 System.arraycopy(mValues, 0, newValues, 0, currentSize);
138 mValues = newValues;
139 }
140 }
141
142 /**
143 * Removes all values from this array.
144 */
145 public void clear() {
146 mSize = 0;
147 }
148
149 @Override
Alan Viverettef0aed092013-11-06 15:33:03 -0800150 public LongArray clone() {
151 LongArray clone = null;
152 try {
153 clone = (LongArray) super.clone();
154 clone.mValues = mValues.clone();
155 } catch (CloneNotSupportedException cnse) {
156 /* ignore */
157 }
158 return clone;
159 }
160
161 /**
162 * Returns the value at the specified position in this array.
163 */
164 public long get(int index) {
Hugo Benichi112962a2017-03-27 13:45:23 +0900165 checkBounds(index);
Alan Viverettef0aed092013-11-06 15:33:03 -0800166 return mValues[index];
167 }
168
169 /**
Hugo Benichi112962a2017-03-27 13:45:23 +0900170 * Sets the value at the specified position in this array.
171 */
172 public void set(int index, long value) {
173 checkBounds(index);
174 mValues[index] = value;
175 }
176
177 /**
Alan Viverettef0aed092013-11-06 15:33:03 -0800178 * Returns the index of the first occurrence of the specified value in this
179 * array, or -1 if this array does not contain the value.
180 */
181 public int indexOf(long value) {
182 final int n = mSize;
183 for (int i = 0; i < n; i++) {
184 if (mValues[i] == value) {
185 return i;
186 }
187 }
188 return -1;
189 }
190
191 /**
192 * Removes the value at the specified index from this array.
193 */
194 public void remove(int index) {
Hugo Benichi112962a2017-03-27 13:45:23 +0900195 checkBounds(index);
Svetoslav8e3feb12014-02-24 13:46:47 -0800196 System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1);
197 mSize--;
Alan Viverettef0aed092013-11-06 15:33:03 -0800198 }
199
200 /**
201 * Returns the number of values in this array.
202 */
203 public int size() {
204 return mSize;
205 }
Hugo Benichi112962a2017-03-27 13:45:23 +0900206
207 /**
208 * Returns a new array with the contents of this LongArray.
209 */
210 public long[] toArray() {
211 return Arrays.copyOf(mValues, mSize);
212 }
213
214 private void checkBounds(int index) {
215 if (index < 0 || mSize <= index) {
216 throw new ArrayIndexOutOfBoundsException(mSize, index);
217 }
218 }
Alan Viverettef0aed092013-11-06 15:33:03 -0800219}