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