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