]>
Commit | Line | Data |
---|---|---|
1d09f67e TL |
1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
3 | * contributor license agreements. See the NOTICE file distributed with | |
4 | * this work for additional information regarding copyright ownership. | |
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
6 | * (the "License"); you may not use this file except in compliance with | |
7 | * the License. You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | */ | |
17 | ||
18 | package org.apache.arrow.vector; | |
19 | ||
20 | import static org.apache.arrow.vector.NullCheckingForGet.NULL_CHECKING_ENABLED; | |
21 | ||
22 | import org.apache.arrow.memory.ArrowBuf; | |
23 | import org.apache.arrow.memory.BufferAllocator; | |
24 | import org.apache.arrow.vector.complex.impl.UInt1ReaderImpl; | |
25 | import org.apache.arrow.vector.complex.reader.FieldReader; | |
26 | import org.apache.arrow.vector.holders.NullableUInt1Holder; | |
27 | import org.apache.arrow.vector.holders.UInt1Holder; | |
28 | import org.apache.arrow.vector.types.Types.MinorType; | |
29 | import org.apache.arrow.vector.types.pojo.Field; | |
30 | import org.apache.arrow.vector.types.pojo.FieldType; | |
31 | import org.apache.arrow.vector.util.TransferPair; | |
32 | import org.apache.arrow.vector.util.ValueVectorUtility; | |
33 | ||
34 | /** | |
35 | * UInt1Vector implements a fixed width (1 bytes) vector of | |
36 | * integer values which could be null. A validity buffer (bit vector) is | |
37 | * maintained to track which elements in the vector are null. | |
38 | */ | |
39 | public final class UInt1Vector extends BaseFixedWidthVector implements BaseIntVector { | |
40 | /** | |
41 | * The mask to use when promoting the unsigned byte value to an integer. | |
42 | */ | |
43 | public static final int PROMOTION_MASK = 0xFF; | |
44 | ||
45 | /** | |
46 | * The maximum 8-bit unsigned integer. | |
47 | */ | |
48 | public static final byte MAX_UINT1 = (byte) 0XFF; | |
49 | ||
50 | public static final byte TYPE_WIDTH = 1; | |
51 | private final FieldReader reader; | |
52 | ||
53 | public UInt1Vector(String name, BufferAllocator allocator) { | |
54 | this(name, FieldType.nullable(MinorType.UINT1.getType()), allocator); | |
55 | } | |
56 | ||
57 | public UInt1Vector(String name, FieldType fieldType, BufferAllocator allocator) { | |
58 | this(new Field(name, fieldType, null), allocator); | |
59 | } | |
60 | ||
61 | public UInt1Vector(Field field, BufferAllocator allocator) { | |
62 | super(field, allocator, TYPE_WIDTH); | |
63 | reader = new UInt1ReaderImpl(UInt1Vector.this); | |
64 | } | |
65 | ||
66 | @Override | |
67 | public FieldReader getReader() { | |
68 | return reader; | |
69 | } | |
70 | ||
71 | @Override | |
72 | public MinorType getMinorType() { | |
73 | return MinorType.UINT1; | |
74 | } | |
75 | ||
76 | ||
77 | /*----------------------------------------------------------------* | |
78 | | | | |
79 | | vector value retrieval methods | | |
80 | | | | |
81 | *----------------------------------------------------------------*/ | |
82 | /** | |
83 | * Given a data buffer, get the value stored at a particular position | |
84 | * in the vector. | |
85 | * | |
86 | * <p>To avoid overflow, the returned type is one step up from the signed | |
87 | * type. | |
88 | * | |
89 | * <p>This method is mainly meant for integration tests. | |
90 | * | |
91 | * @param buffer data buffer | |
92 | * @param index position of the element. | |
93 | * @return value stored at the index. | |
94 | */ | |
95 | public static short getNoOverflow(final ArrowBuf buffer, final int index) { | |
96 | byte b = buffer.getByte(index * TYPE_WIDTH); | |
97 | return (short) (PROMOTION_MASK & b); | |
98 | } | |
99 | ||
100 | ||
101 | /** | |
102 | * Get the element at the given index from the vector. | |
103 | * | |
104 | * @param index position of element | |
105 | * @return element at given index | |
106 | */ | |
107 | public byte get(int index) throws IllegalStateException { | |
108 | if (NULL_CHECKING_ENABLED && isSet(index) == 0) { | |
109 | throw new IllegalStateException("Value at index is null"); | |
110 | } | |
111 | return valueBuffer.getByte(index * TYPE_WIDTH); | |
112 | } | |
113 | ||
114 | /** | |
115 | * Get the element at the given index from the vector and | |
116 | * sets the state in holder. If element at given index | |
117 | * is null, holder.isSet will be zero. | |
118 | * | |
119 | * @param index position of element | |
120 | */ | |
121 | public void get(int index, NullableUInt1Holder holder) { | |
122 | if (isSet(index) == 0) { | |
123 | holder.isSet = 0; | |
124 | return; | |
125 | } | |
126 | holder.isSet = 1; | |
127 | holder.value = valueBuffer.getByte(index * TYPE_WIDTH); | |
128 | } | |
129 | ||
130 | /** | |
131 | * Same as {@link #get(int)}. | |
132 | * | |
133 | * @param index position of element | |
134 | * @return element at given index | |
135 | */ | |
136 | public Byte getObject(int index) { | |
137 | if (isSet(index) == 0) { | |
138 | return null; | |
139 | } else { | |
140 | return valueBuffer.getByte(index * TYPE_WIDTH); | |
141 | } | |
142 | } | |
143 | ||
144 | /** | |
145 | * Returns the value stored at index without the potential for overflow. | |
146 | * | |
147 | * @param index position of element | |
148 | * @return element at given index | |
149 | */ | |
150 | public Short getObjectNoOverflow(int index) { | |
151 | if (isSet(index) == 0) { | |
152 | return null; | |
153 | } else { | |
154 | return getNoOverflow(valueBuffer, index); | |
155 | } | |
156 | } | |
157 | ||
158 | ||
159 | /*----------------------------------------------------------------* | |
160 | | | | |
161 | | vector value setter methods | | |
162 | | | | |
163 | *----------------------------------------------------------------*/ | |
164 | ||
165 | ||
166 | private void setValue(int index, int value) { | |
167 | valueBuffer.setByte(index * TYPE_WIDTH, value); | |
168 | } | |
169 | ||
170 | private void setValue(int index, byte value) { | |
171 | valueBuffer.setByte(index * TYPE_WIDTH, value); | |
172 | } | |
173 | ||
174 | /** | |
175 | * Set the element at the given index to the given value. | |
176 | * | |
177 | * @param index position of element | |
178 | * @param value value of element | |
179 | */ | |
180 | public void set(int index, int value) { | |
181 | BitVectorHelper.setBit(validityBuffer, index); | |
182 | setValue(index, value); | |
183 | } | |
184 | ||
185 | /** | |
186 | * Set the element at the given index to the given value. | |
187 | * | |
188 | * @param index position of element | |
189 | * @param value value of element | |
190 | */ | |
191 | public void set(int index, byte value) { | |
192 | BitVectorHelper.setBit(validityBuffer, index); | |
193 | setValue(index, value); | |
194 | } | |
195 | ||
196 | /** | |
197 | * Set the element at the given index to the value set in data holder. | |
198 | * If the value in holder is not indicated as set, element in the | |
199 | * at the given index will be null. | |
200 | * | |
201 | * @param index position of element | |
202 | * @param holder nullable data holder for value of element | |
203 | */ | |
204 | public void set(int index, NullableUInt1Holder holder) throws IllegalArgumentException { | |
205 | if (holder.isSet < 0) { | |
206 | throw new IllegalArgumentException(); | |
207 | } else if (holder.isSet > 0) { | |
208 | BitVectorHelper.setBit(validityBuffer, index); | |
209 | setValue(index, holder.value); | |
210 | } else { | |
211 | BitVectorHelper.unsetBit(validityBuffer, index); | |
212 | } | |
213 | } | |
214 | ||
215 | /** | |
216 | * Set the element at the given index to the value set in data holder. | |
217 | * | |
218 | * @param index position of element | |
219 | * @param holder data holder for value of element | |
220 | */ | |
221 | public void set(int index, UInt1Holder holder) { | |
222 | BitVectorHelper.setBit(validityBuffer, index); | |
223 | setValue(index, holder.value); | |
224 | } | |
225 | ||
226 | /** | |
227 | * Same as {@link #set(int, int)} except that it handles the | |
228 | * case when index is greater than or equal to existing | |
229 | * value capacity {@link #getValueCapacity()}. | |
230 | * | |
231 | * @param index position of element | |
232 | * @param value value of element | |
233 | */ | |
234 | public void setSafe(int index, int value) { | |
235 | handleSafe(index); | |
236 | set(index, value); | |
237 | } | |
238 | ||
239 | /** | |
240 | * Same as {@link #set(int, byte)} except that it handles the | |
241 | * case when index is greater than or equal to existing | |
242 | * value capacity {@link #getValueCapacity()}. | |
243 | * | |
244 | * @param index position of element | |
245 | * @param value value of element | |
246 | */ | |
247 | public void setSafe(int index, byte value) { | |
248 | handleSafe(index); | |
249 | set(index, value); | |
250 | } | |
251 | ||
252 | /** | |
253 | * Same as {@link #set(int, NullableUInt1Holder)} except that it handles the | |
254 | * case when index is greater than or equal to existing | |
255 | * value capacity {@link #getValueCapacity()}. | |
256 | * | |
257 | * @param index position of element | |
258 | * @param holder nullable data holder for value of element | |
259 | */ | |
260 | public void setSafe(int index, NullableUInt1Holder holder) throws IllegalArgumentException { | |
261 | handleSafe(index); | |
262 | set(index, holder); | |
263 | } | |
264 | ||
265 | /** | |
266 | * Same as {@link #set(int, UInt1Holder)} except that it handles the | |
267 | * case when index is greater than or equal to existing | |
268 | * value capacity {@link #getValueCapacity()}. | |
269 | * | |
270 | * @param index position of element | |
271 | * @param holder data holder for value of element | |
272 | */ | |
273 | public void setSafe(int index, UInt1Holder holder) { | |
274 | handleSafe(index); | |
275 | set(index, holder); | |
276 | } | |
277 | ||
278 | /** | |
279 | * Sets the value at index to value isSet > 0, otherwise sets the index position | |
280 | * to invalid/null. | |
281 | */ | |
282 | public void set(int index, int isSet, byte value) { | |
283 | if (isSet > 0) { | |
284 | set(index, value); | |
285 | } else { | |
286 | BitVectorHelper.unsetBit(validityBuffer, index); | |
287 | } | |
288 | } | |
289 | ||
290 | /** | |
291 | * Same as {@link #set(int, int, byte)} but will reallocate the buffer if index | |
292 | * is larger than current capacity. | |
293 | */ | |
294 | public void setSafe(int index, int isSet, byte value) { | |
295 | handleSafe(index); | |
296 | set(index, isSet, value); | |
297 | } | |
298 | ||
299 | ||
300 | /*----------------------------------------------------------------* | |
301 | | | | |
302 | | vector transfer | | |
303 | | | | |
304 | *----------------------------------------------------------------*/ | |
305 | ||
306 | ||
307 | @Override | |
308 | public TransferPair getTransferPair(String ref, BufferAllocator allocator) { | |
309 | return new TransferImpl(ref, allocator); | |
310 | } | |
311 | ||
312 | @Override | |
313 | public TransferPair makeTransferPair(ValueVector to) { | |
314 | return new TransferImpl((UInt1Vector) to); | |
315 | } | |
316 | ||
317 | @Override | |
318 | public void setWithPossibleTruncate(int index, long value) { | |
319 | this.setSafe(index, (int) value); | |
320 | } | |
321 | ||
322 | @Override | |
323 | public void setUnsafeWithPossibleTruncate(int index, long value) { | |
324 | this.set(index, (int) value); | |
325 | } | |
326 | ||
327 | @Override | |
328 | public long getValueAsLong(int index) { | |
329 | return this.get(index) & PROMOTION_MASK; | |
330 | } | |
331 | ||
332 | @Override | |
333 | public String toString() { | |
334 | return ValueVectorUtility.getToString(this, 0, getValueCount(), (v, i) -> v.getObjectNoOverflow(i)); | |
335 | } | |
336 | ||
337 | private class TransferImpl implements TransferPair { | |
338 | UInt1Vector to; | |
339 | ||
340 | public TransferImpl(String ref, BufferAllocator allocator) { | |
341 | to = new UInt1Vector(ref, field.getFieldType(), allocator); | |
342 | } | |
343 | ||
344 | public TransferImpl(UInt1Vector to) { | |
345 | this.to = to; | |
346 | } | |
347 | ||
348 | @Override | |
349 | public UInt1Vector getTo() { | |
350 | return to; | |
351 | } | |
352 | ||
353 | @Override | |
354 | public void transfer() { | |
355 | transferTo(to); | |
356 | } | |
357 | ||
358 | @Override | |
359 | public void splitAndTransfer(int startIndex, int length) { | |
360 | splitAndTransferTo(startIndex, length, to); | |
361 | } | |
362 | ||
363 | @Override | |
364 | public void copyValueSafe(int fromIndex, int toIndex) { | |
365 | to.copyFromSafe(fromIndex, toIndex, UInt1Vector.this); | |
366 | } | |
367 | } | |
368 | } |