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