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> 46 implements DoubleList, RandomAccess { 47 48 private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList(); 49 static { EMPTY_LIST.makeImmutable()50 EMPTY_LIST.makeImmutable(); 51 } 52 emptyList()53 public static DoubleArrayList emptyList() { 54 return EMPTY_LIST; 55 } 56 57 /** 58 * The backing store for the list. 59 */ 60 private double[] array; 61 62 /** 63 * The size of the list distinct from the length of the array. That is, it is the number of 64 * elements set in the list. 65 */ 66 private int size; 67 68 /** 69 * Constructs a new mutable {@code DoubleArrayList} with default capacity. 70 */ DoubleArrayList()71 DoubleArrayList() { 72 this(new double[DEFAULT_CAPACITY], 0); 73 } 74 75 /** 76 * Constructs a new mutable {@code DoubleArrayList} 77 * containing the same elements as {@code other}. 78 */ DoubleArrayList(double[] other, int size)79 private DoubleArrayList(double[] other, int size) { 80 array = other; 81 this.size = size; 82 } 83 84 @Override equals(Object o)85 public boolean equals(Object o) { 86 if (this == o) { 87 return true; 88 } 89 if (!(o instanceof DoubleArrayList)) { 90 return super.equals(o); 91 } 92 DoubleArrayList other = (DoubleArrayList) o; 93 if (size != other.size) { 94 return false; 95 } 96 97 final double[] arr = other.array; 98 for (int i = 0; i < size; i++) { 99 if (array[i] != arr[i]) { 100 return false; 101 } 102 } 103 104 return true; 105 } 106 107 @Override hashCode()108 public int hashCode() { 109 int result = 1; 110 for (int i = 0; i < size; i++) { 111 long bits = Double.doubleToLongBits(array[i]); 112 result = (31 * result) + Internal.hashLong(bits); 113 } 114 return result; 115 } 116 117 @Override mutableCopyWithCapacity(int capacity)118 public DoubleList mutableCopyWithCapacity(int capacity) { 119 if (capacity < size) { 120 throw new IllegalArgumentException(); 121 } 122 return new DoubleArrayList(Arrays.copyOf(array, capacity), size); 123 } 124 125 @Override get(int index)126 public Double get(int index) { 127 return getDouble(index); 128 } 129 130 @Override getDouble(int index)131 public double getDouble(int index) { 132 ensureIndexInRange(index); 133 return array[index]; 134 } 135 136 @Override size()137 public int size() { 138 return size; 139 } 140 141 @Override set(int index, Double element)142 public Double set(int index, Double element) { 143 return setDouble(index, element); 144 } 145 146 @Override setDouble(int index, double element)147 public double setDouble(int index, double element) { 148 ensureIsMutable(); 149 ensureIndexInRange(index); 150 double previousValue = array[index]; 151 array[index] = element; 152 return previousValue; 153 } 154 155 @Override add(int index, Double element)156 public void add(int index, Double element) { 157 addDouble(index, element); 158 } 159 160 /** 161 * Like {@link #add(Double)} but more efficient in that it doesn't box the element. 162 */ 163 @Override addDouble(double element)164 public void addDouble(double element) { 165 addDouble(size, element); 166 } 167 168 /** 169 * Like {@link #add(int, Double)} but more efficient in that it doesn't box the element. 170 */ addDouble(int index, double element)171 private void addDouble(int index, double element) { 172 ensureIsMutable(); 173 if (index < 0 || index > size) { 174 throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index)); 175 } 176 177 if (size < array.length) { 178 // Shift everything over to make room 179 System.arraycopy(array, index, array, index + 1, size - index); 180 } else { 181 // Resize to 1.5x the size 182 int length = ((size * 3) / 2) + 1; 183 double[] newArray = new double[length]; 184 185 // Copy the first part directly 186 System.arraycopy(array, 0, newArray, 0, index); 187 188 // Copy the rest shifted over by one to make room 189 System.arraycopy(array, index, newArray, index + 1, size - index); 190 array = newArray; 191 } 192 193 array[index] = element; 194 size++; 195 modCount++; 196 } 197 198 @Override addAll(Collection<? extends Double> collection)199 public boolean addAll(Collection<? extends Double> collection) { 200 ensureIsMutable(); 201 202 if (collection == null) { 203 throw new NullPointerException(); 204 } 205 206 // We specialize when adding another DoubleArrayList to avoid boxing elements. 207 if (!(collection instanceof DoubleArrayList)) { 208 return super.addAll(collection); 209 } 210 211 DoubleArrayList list = (DoubleArrayList) collection; 212 if (list.size == 0) { 213 return false; 214 } 215 216 int overflow = Integer.MAX_VALUE - size; 217 if (overflow < list.size) { 218 // We can't actually represent a list this large. 219 throw new OutOfMemoryError(); 220 } 221 222 int newSize = size + list.size; 223 if (newSize > array.length) { 224 array = Arrays.copyOf(array, newSize); 225 } 226 227 System.arraycopy(list.array, 0, array, size, list.size); 228 size = newSize; 229 modCount++; 230 return true; 231 } 232 233 @Override remove(Object o)234 public boolean remove(Object o) { 235 ensureIsMutable(); 236 for (int i = 0; i < size; i++) { 237 if (o.equals(array[i])) { 238 System.arraycopy(array, i + 1, array, i, size - i); 239 size--; 240 modCount++; 241 return true; 242 } 243 } 244 return false; 245 } 246 247 @Override remove(int index)248 public Double remove(int index) { 249 ensureIsMutable(); 250 ensureIndexInRange(index); 251 double value = array[index]; 252 System.arraycopy(array, index + 1, array, index, size - index); 253 size--; 254 modCount++; 255 return value; 256 } 257 258 /** 259 * Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an 260 * {@link IndexOutOfBoundsException} if it is not. 261 * 262 * @param index the index to verify is in range 263 */ ensureIndexInRange(int index)264 private void ensureIndexInRange(int index) { 265 if (index < 0 || index >= size) { 266 throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index)); 267 } 268 } 269 makeOutOfBoundsExceptionMessage(int index)270 private String makeOutOfBoundsExceptionMessage(int index) { 271 return "Index:" + index + ", Size:" + size; 272 } 273 } 274