1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 package com.google.protobuf; 32 33 import com.google.protobuf.Internal.DoubleList; 34 35 import java.util.Arrays; 36 import java.util.Collection; 37 import java.util.RandomAccess; 38 39 /** 40 * An implementation of {@link DoubleList} on top of a primitive array. 41 * 42 * @author dweis@google.com (Daniel Weis) 43 */ 44 final class DoubleArrayList 45 extends AbstractProtobufList<Double> implements DoubleList, RandomAccess { 46 47 private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList(); 48 static { EMPTY_LIST.makeImmutable()49 EMPTY_LIST.makeImmutable(); 50 } 51 emptyList()52 public static DoubleArrayList emptyList() { 53 return EMPTY_LIST; 54 } 55 56 /** 57 * The backing store for the list. 58 */ 59 private double[] array; 60 61 /** 62 * The size of the list distinct from the length of the array. That is, it is the number of 63 * elements set in the list. 64 */ 65 private int size; 66 67 /** 68 * Constructs a new mutable {@code DoubleArrayList} with default capacity. 69 */ DoubleArrayList()70 DoubleArrayList() { 71 this(new double[DEFAULT_CAPACITY], 0); 72 } 73 74 /** 75 * Constructs a new mutable {@code DoubleArrayList} containing the same elements as {@code other}. 76 */ DoubleArrayList(double[] array, int size)77 private DoubleArrayList(double[] array, int size) { 78 this.array = array; 79 this.size = size; 80 } 81 82 @Override equals(Object o)83 public boolean equals(Object o) { 84 if (this == o) { 85 return true; 86 } 87 if (!(o instanceof DoubleArrayList)) { 88 return super.equals(o); 89 } 90 DoubleArrayList other = (DoubleArrayList) o; 91 if (size != other.size) { 92 return false; 93 } 94 95 final double[] arr = other.array; 96 for (int i = 0; i < size; i++) { 97 if (array[i] != arr[i]) { 98 return false; 99 } 100 } 101 102 return true; 103 } 104 105 @Override hashCode()106 public int hashCode() { 107 int result = 1; 108 for (int i = 0; i < size; i++) { 109 long bits = Double.doubleToLongBits(array[i]); 110 result = (31 * result) + Internal.hashLong(bits); 111 } 112 return result; 113 } 114 115 @Override mutableCopyWithCapacity(int capacity)116 public DoubleList mutableCopyWithCapacity(int capacity) { 117 if (capacity < size) { 118 throw new IllegalArgumentException(); 119 } 120 return new DoubleArrayList(Arrays.copyOf(array, capacity), size); 121 } 122 123 @Override get(int index)124 public Double get(int index) { 125 return getDouble(index); 126 } 127 128 @Override getDouble(int index)129 public double getDouble(int index) { 130 ensureIndexInRange(index); 131 return array[index]; 132 } 133 134 @Override size()135 public int size() { 136 return size; 137 } 138 139 @Override set(int index, Double element)140 public Double set(int index, Double element) { 141 return setDouble(index, element); 142 } 143 144 @Override setDouble(int index, double element)145 public double setDouble(int index, double element) { 146 ensureIsMutable(); 147 ensureIndexInRange(index); 148 double previousValue = array[index]; 149 array[index] = element; 150 return previousValue; 151 } 152 153 @Override add(int index, Double element)154 public void add(int index, Double element) { 155 addDouble(index, element); 156 } 157 158 /** 159 * Like {@link #add(Double)} but more efficient in that it doesn't box the element. 160 */ 161 @Override addDouble(double element)162 public void addDouble(double element) { 163 addDouble(size, element); 164 } 165 166 /** 167 * Like {@link #add(int, Double)} but more efficient in that it doesn't box the element. 168 */ addDouble(int index, double element)169 private void addDouble(int index, double element) { 170 ensureIsMutable(); 171 if (index < 0 || index > size) { 172 throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index)); 173 } 174 175 if (size < array.length) { 176 // Shift everything over to make room 177 System.arraycopy(array, index, array, index + 1, size - index); 178 } else { 179 // Resize to 1.5x the size 180 int length = ((size * 3) / 2) + 1; 181 double[] newArray = new double[length]; 182 183 // Copy the first part directly 184 System.arraycopy(array, 0, newArray, 0, index); 185 186 // Copy the rest shifted over by one to make room 187 System.arraycopy(array, index, newArray, index + 1, size - index); 188 array = newArray; 189 } 190 191 array[index] = element; 192 size++; 193 modCount++; 194 } 195 196 @Override addAll(Collection<? extends Double> collection)197 public boolean addAll(Collection<? extends Double> collection) { 198 ensureIsMutable(); 199 200 if (collection == null) { 201 throw new NullPointerException(); 202 } 203 204 // We specialize when adding another DoubleArrayList to avoid boxing elements. 205 if (!(collection instanceof DoubleArrayList)) { 206 return super.addAll(collection); 207 } 208 209 DoubleArrayList list = (DoubleArrayList) collection; 210 if (list.size == 0) { 211 return false; 212 } 213 214 int overflow = Integer.MAX_VALUE - size; 215 if (overflow < list.size) { 216 // We can't actually represent a list this large. 217 throw new OutOfMemoryError(); 218 } 219 220 int newSize = size + list.size; 221 if (newSize > array.length) { 222 array = Arrays.copyOf(array, newSize); 223 } 224 225 System.arraycopy(list.array, 0, array, size, list.size); 226 size = newSize; 227 modCount++; 228 return true; 229 } 230 231 @Override remove(Object o)232 public boolean remove(Object o) { 233 ensureIsMutable(); 234 for (int i = 0; i < size; i++) { 235 if (o.equals(array[i])) { 236 System.arraycopy(array, i + 1, array, i, size - i); 237 size--; 238 modCount++; 239 return true; 240 } 241 } 242 return false; 243 } 244 245 @Override remove(int index)246 public Double remove(int index) { 247 ensureIsMutable(); 248 ensureIndexInRange(index); 249 double value = array[index]; 250 System.arraycopy(array, index + 1, array, index, size - index); 251 size--; 252 modCount++; 253 return value; 254 } 255 256 /** 257 * Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an 258 * {@link IndexOutOfBoundsException} if it is not. 259 * 260 * @param index the index to verify is in range 261 */ ensureIndexInRange(int index)262 private void ensureIndexInRange(int index) { 263 if (index < 0 || index >= size) { 264 throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index)); 265 } 266 } 267 makeOutOfBoundsExceptionMessage(int index)268 private String makeOutOfBoundsExceptionMessage(int index) { 269 return "Index:" + index + ", Size:" + size; 270 } 271 } 272