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