GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing arrow.apache.org — ValueVector - arrow-java 19.0.0 documentation ValueVector¶
There are concrete subclasses of It is important that vector is allocated before attempting to read or write,
Vector Life Cycle¶As discussed above, each vector goes through several steps in its life cycle, and each step is triggered by a vector operation. In particular, we have the following vector operations: 1. Vector creation: we create a new vector object by, for example, the vector constructor.
The following code creates a new RootAllocator allocator = new RootAllocator(Long.MAX_VALUE); ... IntVector vector = new IntVector("int vector", allocator); By now, a vector object is created. However, no underlying memory has been allocated, so we need the following step. 2. Vector allocation: in this step, we allocate memory for the vector. For most vectors, we
have two options: 1) if we know the maximum vector capacity, we can specify it by calling the
vector.allocateNew(10); 3. Vector mutation: now we can populate the vector with values we desire. For all vectors, we can populate
vector values through vector writers (An example will be given in the next section). For primitive types,
we can also mutate the vector by the set methods. There are two classes of set methods: 1) if we can
be sure the vector has enough capacity, we can call the vector.set(/*index*/5, /*value*/25); 4. Set value count: for this step, we set the value count of the vector by calling the
vector.setValueCount(10); After this step, the vector enters an immutable state. In other words, we should no longer mutate it. (Unless we reuse the vector by allocating it again. This will be discussed shortly.) 5. Vector access: it is time to access vector values. Similarly, we have two options to access values: 1) get methods and 2) vector reader. Vector reader works for all types of vectors, while get methods are only available for primitive vectors. A concrete example for vector reader will be given in the next section. Below is an example of vector access by get method: int value = vector.get(5); // value == 25 6. Vector clear: when we are done with the vector, we should clear it to release its memory. This is done by
calling the vector.close(); Some points to note about the steps above:
VarCharVector vector = new VarCharVector("vector", allocator); vector.allocateNew(); vector.setSafe(0, "zero"); vector.setSafe(1, "one"); ... vector.setSafe(9, "nine"); Then we set the value at position 5 again: vector.setSafe(5, "5"); After that, the values at positions 6, 7, 8, and 9 of the vector will become invalid. Building ValueVector¶Note that the current implementation doesn’t enforce the rule that Arrow objects are immutable.
For example, the code below shows how to build a try (BufferAllocator allocator = new RootAllocator(Long.MAX_VALUE); BigIntVector vector = new BigIntVector("vector", allocator)) { vector.allocateNew(8); vector.set(0, 1); vector.set(1, 2); vector.set(2, 3); vector.setNull(3); vector.set(4, 5); vector.set(5, 6); vector.set(6, 7); vector.set(7, 8); vector.setValueCount(8); // this will finalizes the vector by convention. ... } The Here is how to build a vector using writer try (BigIntVector vector = new BigIntVector("vector", allocator); BigIntWriter writer = new BigIntWriterImpl(vector)) { writer.setPosition(0); writer.writeBigInt(1); writer.setPosition(1); writer.writeBigInt(2); writer.setPosition(2); writer.writeBigInt(3); // writer.setPosition(3) is not called which means the fourth value is null. writer.setPosition(4); writer.writeBigInt(5); writer.setPosition(5); writer.writeBigInt(6); writer.setPosition(6); writer.writeBigInt(7); writer.setPosition(7); writer.writeBigInt(8); } There are get API and concrete subclasses of // access via get API for (int i = 0; i < vector.getValueCount(); i++) { if (!vector.isNull(i)) { System.out.println(vector.get(i)); } } // access via reader BigIntReader reader = vector.getReader(); for (int i = 0; i < vector.getValueCount(); i++) { reader.setPosition(i); if (reader.isSet()) { System.out.println(reader.readLong()); } } Building ListVector¶A For example, the code below shows how to build a try (BufferAllocator allocator = new RootAllocator(Long.MAX_VALUE); ListVector listVector = ListVector.empty("vector", allocator)) { UnionListWriter writer = listVector.getWriter(); for (int i = 0; i < 10; i++) { writer.startList(); writer.setPosition(i); for (int j = 0; j < 5; j++) { writer.writeInt(j * i); } writer.setValueCount(5); writer.endList(); } listVector.setValueCount(10); }
// access via get API for (int i = 0; i < listVector.getValueCount(); i++) { if (!listVector.isNull(i)) { ArrayList<Integer> elements = (ArrayList<Integer>) listVector.getObject(i); for (Integer element : elements) { System.out.println(element); } } } // access via reader UnionListReader reader = listVector.getReader(); for (int i = 0; i < listVector.getValueCount(); i++) { reader.setPosition(i); while (reader.next()) { IntReader intReader = reader.reader(); if (intReader.isSet()) { System.out.println(intReader.readInteger()); } } } Dictionary Encoding¶Dictionary encoding is a form of compression where values of one type are replaced by values of a smaller type: an array of ints replacing an array of strings is a common example. The mapping between the original values and the replacements is held in a ‘dictionary’. Since the dictionary needs only one copy of each of the longer values, the combination of the dictionary and the array of smaller values may use less memory. The more repetitive the original data, the greater the savings. A There are a few steps involved in the encoding process:
The encoded values will be integers. Depending on how many unique values you have, you can use Another critical attribute in This result will be a new vector (for example, an // 1. create a vector for the un-encoded data and populate it VarCharVector unencoded = new VarCharVector("unencoded", allocator); // now put some data in it before continuing // 2. create a vector to hold the dictionary and populate it VarCharVector dictionaryVector = new VarCharVector("dictionary", allocator); // 3. create a dictionary object Dictionary dictionary = new Dictionary(dictionaryVector, new DictionaryEncoding(1L, false, null)); // 4. create a dictionary encoder DictionaryEncoder encoder = new DictionaryEncoder.encode(dictionary, allocator); // 5. encode the data IntVector encoded = (IntVector) encoder.encode(unencoded); // 6. re-create an un-encoded version from the encoded vector VarCharVector decoded = (VarCharVector) encoder.decode(encoded); One thing we haven’t discussed is how to create the dictionary vector from the original un-encoded values. That is left to the library user since a custom method will likely be more efficient than a general utility. Since the dictionary vector is just a normal vector, you can populate its values with the standard APIs. Finally, you can package a number of dictionaries together, which is useful if you’re working with a DictionaryProvider.MapDictionaryProvider provider = new DictionaryProvider.MapDictionaryProvider(); provider.put(dictionary); The This is where the
// create the encoded vector, the Dictionary and DictionaryProvider as discussed above // Create a VectorSchemaRoot with one encoded vector VectorSchemaRoot vsr = new VectorSchemaRoot(List.of(encoded)); // now we want to decode our vector, so we retrieve its dictionary from the provider Field f = vsr.getField(encoded.getName()); DictionaryEncoding encoding = f.getDictionary(); Dictionary dictionary = provider.lookup(encoding.getId()); As you can see, a Slicing¶Similar with C++ implementation, it is possible to make zero-copy slices of vectors to obtain a vector
referring to some logical sub-sequence of the data through IntVector vector = new IntVector("intVector", allocator); for (int i = 0; i < 10; i++) { vector.setSafe(i, i); } vector.setValueCount(10); TransferPair tp = vector.getTransferPair(allocator); tp.splitAndTransfer(0, 5); IntVector sliced = (IntVector) tp.getTo(); // In this case, the vector values are [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] and the sliceVector values are [0, 1, 2, 3, 4]. |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |