4444import org .apache .arrow .vector .Float4Vector ;
4545import org .apache .arrow .vector .Float8Vector ;
4646import org .apache .arrow .vector .IntVector ;
47+ import org .apache .arrow .vector .NullableVarBinaryVector ;
48+ import org .apache .arrow .vector .NullableVarCharVector ;
4749import org .apache .arrow .vector .SmallIntVector ;
4850import org .apache .arrow .vector .TimeMicroVector ;
4951import org .apache .arrow .vector .TimeMilliVector ;
6365import org .apache .arrow .vector .UInt4Vector ;
6466import org .apache .arrow .vector .UInt8Vector ;
6567import org .apache .arrow .vector .ValueVector ;
66- import org .apache .arrow .vector .ValueVector .Mutator ;
6768import org .apache .arrow .vector .VarBinaryVector ;
6869import org .apache .arrow .vector .VarCharVector ;
6970import org .apache .arrow .vector .VectorSchemaRoot ;
71+ import org .apache .arrow .vector .complex .ListVector ;
7072import org .apache .arrow .vector .dictionary .Dictionary ;
7173import org .apache .arrow .vector .dictionary .DictionaryProvider ;
7274import org .apache .arrow .vector .schema .ArrowVectorType ;
8486import com .google .common .base .Objects ;
8587
8688public class JsonFileReader implements AutoCloseable , DictionaryProvider {
87- private final File inputFile ;
8889 private final JsonParser parser ;
8990 private final BufferAllocator allocator ;
9091 private Schema schema ;
@@ -93,7 +94,6 @@ public class JsonFileReader implements AutoCloseable, DictionaryProvider {
9394
9495 public JsonFileReader (File inputFile , BufferAllocator allocator ) throws JsonParseException , IOException {
9596 super ();
96- this .inputFile = inputFile ;
9797 this .allocator = allocator ;
9898 MappingJsonFactory jsonFactory = new MappingJsonFactory ();
9999 this .parser = jsonFactory .createParser (inputFile );
@@ -216,10 +216,9 @@ public VectorSchemaRoot read() throws IOException {
216216 }
217217 }
218218
219- /*
220- * TODO: This method doesn't load some vectors correctly. For instance, it doesn't initialize
221- * `lastSet` in ListVector, VarCharVector, NullableVarBinaryVector A better way of implementing
222- * this function is to use `loadFieldBuffers` methods in FieldVector.
219+ /**
220+ * TODO: A better way of implementing this function is to use `loadFieldBuffers` methods in
221+ * FieldVector to set the inner-vector data as done in `ArrowFileReader`.
223222 */
224223 private void readVector (Field field , FieldVector vector ) throws JsonParseException , IOException {
225224 List <ArrowVectorType > vectorTypes = field .getTypeLayout ().getVectorTypes ();
@@ -234,29 +233,42 @@ private void readVector(Field field, FieldVector vector) throws JsonParseExcepti
234233 if (started && !Objects .equal (field .getName (), name )) {
235234 throw new IllegalArgumentException ("Expected field " + field .getName () + " but got " + name );
236235 }
236+
237+ // Initialize the vector with required capacity
237238 int count = readNextField ("count" , Integer .class );
239+ vector .setInitialCapacity (count );
238240 vector .allocateNew ();
239- vector .getMutator ().setValueCount (count );
241+
242+ // Read inner vectors
240243 for (int v = 0 ; v < vectorTypes .size (); v ++) {
241244 ArrowVectorType vectorType = vectorTypes .get (v );
242- BufferBacked innerVector = fieldInnerVectors .get (v );
245+ ValueVector valueVector = ( ValueVector ) fieldInnerVectors .get (v );
243246 nextFieldIs (vectorType .getName ());
244247 readToken (START_ARRAY );
245- ValueVector valueVector = (ValueVector ) innerVector ;
246-
247248 int innerVectorCount = vectorType .equals (OFFSET ) ? count + 1 : count ;
248- valueVector .setInitialCapacity (innerVectorCount );
249- valueVector .allocateNew ();
250-
251249 for (int i = 0 ; i < innerVectorCount ; i ++) {
252250 parser .nextToken ();
253251 setValueFromParser (valueVector , i );
254252 }
255- Mutator mutator = valueVector .getMutator ();
256- mutator .setValueCount (innerVectorCount );
257253 readToken (END_ARRAY );
258254 }
259- // if children
255+
256+ // Set lastSet before valueCount to prevent setValueCount from filling empty values
257+ switch (vector .getMinorType ()) {
258+ case LIST :
259+ // ListVector starts lastSet from index 0, so lastSet value is always last index written + 1
260+ ((ListVector ) vector ).getMutator ().setLastSet (count );
261+ break ;
262+ case VARBINARY :
263+ ((NullableVarBinaryVector ) vector ).getMutator ().setLastSet (count - 1 );
264+ break ;
265+ case VARCHAR :
266+ ((NullableVarCharVector ) vector ).getMutator ().setLastSet (count - 1 );
267+ break ;
268+ }
269+ vector .getMutator ().setValueCount (count );
270+
271+ // read child vectors, if any
260272 List <Field > fields = field .getChildren ();
261273 if (!fields .isEmpty ()) {
262274 List <FieldVector > vectorChildren = vector .getChildrenFromFields ();
0 commit comments