| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 package com.google.protobuf; | 31 package com.google.protobuf; |
| 32 | 32 |
| 33 import com.google.protobuf.Internal.DoubleList; | 33 import com.google.protobuf.Internal.DoubleList; |
| 34 | 34 |
| 35 import java.util.Arrays; | 35 import java.util.Arrays; |
| 36 import java.util.Collection; | 36 import java.util.Collection; |
| 37 import java.util.RandomAccess; | 37 import java.util.RandomAccess; |
| 38 | 38 |
| 39 /** | 39 /** |
| 40 * An implementation of {@link DoubleList} on top of a primitive array. | 40 * An implementation of {@link DoubleList} on top of a primitive array. |
| 41 * | 41 * |
| 42 * @author dweis@google.com (Daniel Weis) | 42 * @author dweis@google.com (Daniel Weis) |
| 43 */ | 43 */ |
| 44 final class DoubleArrayList | 44 final class DoubleArrayList |
| 45 extends AbstractProtobufList<Double> implements DoubleList, RandomAccess { | 45 extends AbstractProtobufList<Double> |
| 46 | 46 implements DoubleList, RandomAccess { |
| 47 |
| 47 private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList(); | 48 private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList(); |
| 48 static { | 49 static { |
| 49 EMPTY_LIST.makeImmutable(); | 50 EMPTY_LIST.makeImmutable(); |
| 50 } | 51 } |
| 51 | 52 |
| 52 public static DoubleArrayList emptyList() { | 53 public static DoubleArrayList emptyList() { |
| 53 return EMPTY_LIST; | 54 return EMPTY_LIST; |
| 54 } | 55 } |
| 55 | 56 |
| 56 /** | 57 /** |
| 57 * The backing store for the list. | 58 * The backing store for the list. |
| 58 */ | 59 */ |
| 59 private double[] array; | 60 private double[] array; |
| 60 | 61 |
| 61 /** | 62 /** |
| 62 * The size of the list distinct from the length of the array. That is, it is
the number of | 63 * 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 * elements set in the list. |
| 64 */ | 65 */ |
| 65 private int size; | 66 private int size; |
| 66 | 67 |
| 67 /** | 68 /** |
| 68 * Constructs a new mutable {@code DoubleArrayList} with default capacity. | 69 * Constructs a new mutable {@code DoubleArrayList} with default capacity. |
| 69 */ | 70 */ |
| 70 DoubleArrayList() { | 71 DoubleArrayList() { |
| 71 this(new double[DEFAULT_CAPACITY], 0); | 72 this(new double[DEFAULT_CAPACITY], 0); |
| 72 } | 73 } |
| 73 | 74 |
| 74 /** | 75 /** |
| 75 * Constructs a new mutable {@code DoubleArrayList} containing the same elemen
ts as {@code other}. | 76 * Constructs a new mutable {@code DoubleArrayList} |
| 77 * containing the same elements as {@code other}. |
| 76 */ | 78 */ |
| 77 private DoubleArrayList(double[] array, int size) { | 79 private DoubleArrayList(double[] other, int size) { |
| 78 this.array = array; | 80 array = other; |
| 79 this.size = size; | 81 this.size = size; |
| 80 } | 82 } |
| 81 | 83 |
| 82 @Override | 84 @Override |
| 83 public boolean equals(Object o) { | 85 public boolean equals(Object o) { |
| 84 if (this == o) { | 86 if (this == o) { |
| 85 return true; | 87 return true; |
| 86 } | 88 } |
| 87 if (!(o instanceof DoubleArrayList)) { | 89 if (!(o instanceof DoubleArrayList)) { |
| 88 return super.equals(o); | 90 return super.equals(o); |
| 89 } | 91 } |
| 90 DoubleArrayList other = (DoubleArrayList) o; | 92 DoubleArrayList other = (DoubleArrayList) o; |
| 91 if (size != other.size) { | 93 if (size != other.size) { |
| 92 return false; | 94 return false; |
| 93 } | 95 } |
| 94 | 96 |
| 95 final double[] arr = other.array; | 97 final double[] arr = other.array; |
| 96 for (int i = 0; i < size; i++) { | 98 for (int i = 0; i < size; i++) { |
| 97 if (array[i] != arr[i]) { | 99 if (array[i] != arr[i]) { |
| 98 return false; | 100 return false; |
| 99 } | 101 } |
| 100 } | 102 } |
| 101 | 103 |
| 102 return true; | 104 return true; |
| 103 } | 105 } |
| 104 | 106 |
| 105 @Override | 107 @Override |
| 106 public int hashCode() { | 108 public int hashCode() { |
| 107 int result = 1; | 109 int result = 1; |
| 108 for (int i = 0; i < size; i++) { | 110 for (int i = 0; i < size; i++) { |
| 109 long bits = Double.doubleToLongBits(array[i]); | 111 long bits = Double.doubleToLongBits(array[i]); |
| 110 result = (31 * result) + Internal.hashLong(bits); | 112 result = (31 * result) + Internal.hashLong(bits); |
| 111 } | 113 } |
| 112 return result; | 114 return result; |
| 113 } | 115 } |
| 114 | 116 |
| 115 @Override | 117 @Override |
| 116 public DoubleList mutableCopyWithCapacity(int capacity) { | 118 public DoubleList mutableCopyWithCapacity(int capacity) { |
| 117 if (capacity < size) { | 119 if (capacity < size) { |
| 118 throw new IllegalArgumentException(); | 120 throw new IllegalArgumentException(); |
| 119 } | 121 } |
| 120 return new DoubleArrayList(Arrays.copyOf(array, capacity), size); | 122 return new DoubleArrayList(Arrays.copyOf(array, capacity), size); |
| 121 } | 123 } |
| 122 | 124 |
| 123 @Override | 125 @Override |
| 124 public Double get(int index) { | 126 public Double get(int index) { |
| 125 return getDouble(index); | 127 return getDouble(index); |
| 126 } | 128 } |
| 127 | 129 |
| 128 @Override | 130 @Override |
| 129 public double getDouble(int index) { | 131 public double getDouble(int index) { |
| 130 ensureIndexInRange(index); | 132 ensureIndexInRange(index); |
| 131 return array[index]; | 133 return array[index]; |
| 132 } | 134 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 } | 166 } |
| 165 | 167 |
| 166 /** | 168 /** |
| 167 * Like {@link #add(int, Double)} but more efficient in that it doesn't box th
e element. | 169 * Like {@link #add(int, Double)} but more efficient in that it doesn't box th
e element. |
| 168 */ | 170 */ |
| 169 private void addDouble(int index, double element) { | 171 private void addDouble(int index, double element) { |
| 170 ensureIsMutable(); | 172 ensureIsMutable(); |
| 171 if (index < 0 || index > size) { | 173 if (index < 0 || index > size) { |
| 172 throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index)
); | 174 throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index)
); |
| 173 } | 175 } |
| 174 | 176 |
| 175 if (size < array.length) { | 177 if (size < array.length) { |
| 176 // Shift everything over to make room | 178 // Shift everything over to make room |
| 177 System.arraycopy(array, index, array, index + 1, size - index); | 179 System.arraycopy(array, index, array, index + 1, size - index); |
| 178 } else { | 180 } else { |
| 179 // Resize to 1.5x the size | 181 // Resize to 1.5x the size |
| 180 int length = ((size * 3) / 2) + 1; | 182 int length = ((size * 3) / 2) + 1; |
| 181 double[] newArray = new double[length]; | 183 double[] newArray = new double[length]; |
| 182 | 184 |
| 183 // Copy the first part directly | 185 // Copy the first part directly |
| 184 System.arraycopy(array, 0, newArray, 0, index); | 186 System.arraycopy(array, 0, newArray, 0, index); |
| 185 | 187 |
| 186 // Copy the rest shifted over by one to make room | 188 // Copy the rest shifted over by one to make room |
| 187 System.arraycopy(array, index, newArray, index + 1, size - index); | 189 System.arraycopy(array, index, newArray, index + 1, size - index); |
| 188 array = newArray; | 190 array = newArray; |
| 189 } | 191 } |
| 190 | 192 |
| 191 array[index] = element; | 193 array[index] = element; |
| 192 size++; | 194 size++; |
| 193 modCount++; | 195 modCount++; |
| 194 } | 196 } |
| 195 | 197 |
| 196 @Override | 198 @Override |
| 197 public boolean addAll(Collection<? extends Double> collection) { | 199 public boolean addAll(Collection<? extends Double> collection) { |
| 198 ensureIsMutable(); | 200 ensureIsMutable(); |
| 199 | 201 |
| 200 if (collection == null) { | 202 if (collection == null) { |
| 201 throw new NullPointerException(); | 203 throw new NullPointerException(); |
| 202 } | 204 } |
| 203 | 205 |
| 204 // We specialize when adding another DoubleArrayList to avoid boxing element
s. | 206 // We specialize when adding another DoubleArrayList to avoid boxing element
s. |
| 205 if (!(collection instanceof DoubleArrayList)) { | 207 if (!(collection instanceof DoubleArrayList)) { |
| 206 return super.addAll(collection); | 208 return super.addAll(collection); |
| 207 } | 209 } |
| 208 | 210 |
| 209 DoubleArrayList list = (DoubleArrayList) collection; | 211 DoubleArrayList list = (DoubleArrayList) collection; |
| 210 if (list.size == 0) { | 212 if (list.size == 0) { |
| 211 return false; | 213 return false; |
| 212 } | 214 } |
| 213 | 215 |
| 214 int overflow = Integer.MAX_VALUE - size; | 216 int overflow = Integer.MAX_VALUE - size; |
| 215 if (overflow < list.size) { | 217 if (overflow < list.size) { |
| 216 // We can't actually represent a list this large. | 218 // We can't actually represent a list this large. |
| 217 throw new OutOfMemoryError(); | 219 throw new OutOfMemoryError(); |
| 218 } | 220 } |
| 219 | 221 |
| 220 int newSize = size + list.size; | 222 int newSize = size + list.size; |
| 221 if (newSize > array.length) { | 223 if (newSize > array.length) { |
| 222 array = Arrays.copyOf(array, newSize); | 224 array = Arrays.copyOf(array, newSize); |
| 223 } | 225 } |
| 224 | 226 |
| 225 System.arraycopy(list.array, 0, array, size, list.size); | 227 System.arraycopy(list.array, 0, array, size, list.size); |
| 226 size = newSize; | 228 size = newSize; |
| 227 modCount++; | 229 modCount++; |
| 228 return true; | 230 return true; |
| 229 } | 231 } |
| 230 | 232 |
| 231 @Override | 233 @Override |
| 232 public boolean remove(Object o) { | 234 public boolean remove(Object o) { |
| 233 ensureIsMutable(); | 235 ensureIsMutable(); |
| 234 for (int i = 0; i < size; i++) { | 236 for (int i = 0; i < size; i++) { |
| 235 if (o.equals(array[i])) { | 237 if (o.equals(array[i])) { |
| 236 System.arraycopy(array, i + 1, array, i, size - i); | 238 System.arraycopy(array, i + 1, array, i, size - i); |
| 237 size--; | 239 size--; |
| 238 modCount++; | 240 modCount++; |
| 239 return true; | 241 return true; |
| 240 } | 242 } |
| 241 } | 243 } |
| 242 return false; | 244 return false; |
| 243 } | 245 } |
| 244 | 246 |
| 245 @Override | 247 @Override |
| 246 public Double remove(int index) { | 248 public Double remove(int index) { |
| 247 ensureIsMutable(); | 249 ensureIsMutable(); |
| 248 ensureIndexInRange(index); | 250 ensureIndexInRange(index); |
| 249 double value = array[index]; | 251 double value = array[index]; |
| 250 System.arraycopy(array, index + 1, array, index, size - index); | 252 System.arraycopy(array, index + 1, array, index, size - index); |
| 251 size--; | 253 size--; |
| 252 modCount++; | 254 modCount++; |
| 253 return value; | 255 return value; |
| 254 } | 256 } |
| 255 | 257 |
| 256 /** | 258 /** |
| 257 * Ensures that the provided {@code index} is within the range of {@code [0, s
ize]}. Throws an | 259 * Ensures that the provided {@code index} is within the range of {@code [0, s
ize]}. Throws an |
| 258 * {@link IndexOutOfBoundsException} if it is not. | 260 * {@link IndexOutOfBoundsException} if it is not. |
| 259 * | 261 * |
| 260 * @param index the index to verify is in range | 262 * @param index the index to verify is in range |
| 261 */ | 263 */ |
| 262 private void ensureIndexInRange(int index) { | 264 private void ensureIndexInRange(int index) { |
| 263 if (index < 0 || index >= size) { | 265 if (index < 0 || index >= size) { |
| 264 throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index)
); | 266 throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index)
); |
| 265 } | 267 } |
| 266 } | 268 } |
| 267 | 269 |
| 268 private String makeOutOfBoundsExceptionMessage(int index) { | 270 private String makeOutOfBoundsExceptionMessage(int index) { |
| 269 return "Index:" + index + ", Size:" + size; | 271 return "Index:" + index + ", Size:" + size; |
| 270 } | 272 } |
| 271 } | 273 } |
| OLD | NEW |