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 com.android.internal.util.ArrayUtils;
20 import libcore.util.EmptyArray;
21 
22 /**
23  * Implements a growing array of long primitives.
24  *
25  * @hide
26  */
27 public class LongArray implements Cloneable {
28     private static final int MIN_CAPACITY_INCREMENT = 12;
29 
30     private long[] mValues;
31     private int mSize;
32 
33     /**
34      * Creates an empty LongArray with the default initial capacity.
35      */
LongArray()36     public LongArray() {
37         this(10);
38     }
39 
40     /**
41      * Creates an empty LongArray with the specified initial capacity.
42      */
LongArray(int initialCapacity)43     public LongArray(int initialCapacity) {
44         if (initialCapacity == 0) {
45             mValues = EmptyArray.LONG;
46         } else {
47             mValues = ArrayUtils.newUnpaddedLongArray(initialCapacity);
48         }
49         mSize = 0;
50     }
51 
52     /**
53      * Appends the specified value to the end of this array.
54      */
add(long value)55     public void add(long value) {
56         add(mSize, value);
57     }
58 
59     /**
60      * Inserts a value at the specified position in this array.
61      *
62      * @throws IndexOutOfBoundsException when index < 0 || index > size()
63      */
add(int index, long value)64     public void add(int index, long value) {
65         if (index < 0 || index > mSize) {
66             throw new IndexOutOfBoundsException();
67         }
68 
69         ensureCapacity(1);
70 
71         if (mSize - index != 0) {
72             System.arraycopy(mValues, index, mValues, index + 1, mSize - index);
73         }
74 
75         mValues[index] = value;
76         mSize++;
77     }
78 
79     /**
80      * Adds the values in the specified array to this array.
81      */
addAll(LongArray values)82     public void addAll(LongArray values) {
83         final int count = values.mSize;
84         ensureCapacity(count);
85 
86         System.arraycopy(values.mValues, 0, mValues, mSize, count);
87         mSize += count;
88     }
89 
90     /**
91      * Ensures capacity to append at least <code>count</code> values.
92      */
ensureCapacity(int count)93     private void ensureCapacity(int count) {
94         final int currentSize = mSize;
95         final int minCapacity = currentSize + count;
96         if (minCapacity >= mValues.length) {
97             final int targetCap = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2) ?
98                     MIN_CAPACITY_INCREMENT : currentSize >> 1);
99             final int newCapacity = targetCap > minCapacity ? targetCap : minCapacity;
100             final long[] newValues = ArrayUtils.newUnpaddedLongArray(newCapacity);
101             System.arraycopy(mValues, 0, newValues, 0, currentSize);
102             mValues = newValues;
103         }
104     }
105 
106     /**
107      * Removes all values from this array.
108      */
clear()109     public void clear() {
110         mSize = 0;
111     }
112 
113     @Override
clone()114     public LongArray clone() {
115         LongArray clone = null;
116         try {
117             clone = (LongArray) super.clone();
118             clone.mValues = mValues.clone();
119         } catch (CloneNotSupportedException cnse) {
120             /* ignore */
121         }
122         return clone;
123     }
124 
125     /**
126      * Returns the value at the specified position in this array.
127      */
get(int index)128     public long get(int index) {
129         if (index >= mSize) {
130             throw new ArrayIndexOutOfBoundsException(mSize, index);
131         }
132         return mValues[index];
133     }
134 
135     /**
136      * Returns the index of the first occurrence of the specified value in this
137      * array, or -1 if this array does not contain the value.
138      */
indexOf(long value)139     public int indexOf(long value) {
140         final int n = mSize;
141         for (int i = 0; i < n; i++) {
142             if (mValues[i] == value) {
143                 return i;
144             }
145         }
146         return -1;
147     }
148 
149     /**
150      * Removes the value at the specified index from this array.
151      */
remove(int index)152     public void remove(int index) {
153         if (index >= mSize) {
154             throw new ArrayIndexOutOfBoundsException(mSize, index);
155         }
156         System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1);
157         mSize--;
158     }
159 
160     /**
161      * Returns the number of values in this array.
162      */
size()163     public int size() {
164         return mSize;
165     }
166 }
167