Skip to content

Commit

Permalink
apacheGH-41569: [Java] ListViewVector Implementation for UnionListVie…
Browse files Browse the repository at this point in the history
…wReader (apache#43077)

### Rationale for this change

This PR contains the multiple components which are mainly required to add the C Data interface for `ListViewVector`. This PR solves the following major issues associated with this exercise. 

#### What changes are included in this PR?

- [x] apache#41269
- [x] apache#41270

Apart from that, the following features have also been added

- [x] JSON Writer/Reader
- [x] Complex Writer functionality

### Are these changes tested?

Yes

### Are there any user-facing changes?

Yes, we are introducing the usage of `listview` instead of `list`, `startListView` instead of `startList` and `endListView` instead of `endList` for `ListView` related APIs in building the `ListViewVector`. 

* GitHub Issue: apache#41569

Authored-by: Vibhatha Abeykoon <vibhatha@gmail.com>
Signed-off-by: David Li <li.davidm96@gmail.com>
  • Loading branch information
vibhatha authored Aug 1, 2024
1 parent 0dec116 commit d4d92e4
Show file tree
Hide file tree
Showing 25 changed files with 2,513 additions and 566 deletions.
22 changes: 22 additions & 0 deletions java/vector/src/main/codegen/templates/AbstractFieldWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ public void endList() {
throw new IllegalStateException(String.format("You tried to end a list when you are using a ValueWriter of type %s.", this.getClass().getSimpleName()));
}

@Override
public void startListView() {
throw new IllegalStateException(String.format("You tried to start a list view when you are using a ValueWriter of type %s.", this.getClass().getSimpleName()));
}

@Override
public void endListView() {
throw new IllegalStateException(String.format("You tried to end a list view when you are using a ValueWriter of type %s.", this.getClass().getSimpleName()));
}

@Override
public void startMap() {
throw new IllegalStateException(String.format("You tried to start a map when you are using a ValueWriter of type %s.", this.getClass().getSimpleName()));
Expand Down Expand Up @@ -184,6 +194,12 @@ public ListWriter list() {
return null;
}

@Override
public ListWriter listView() {
fail("ListView");
return null;
}

@Override
public MapWriter map() {
fail("Map");
Expand All @@ -202,6 +218,12 @@ public ListWriter list(String name) {
return null;
}

@Override
public ListWriter listView(String name) {
fail("ListView");
return null;
}

@Override
public MapWriter map(String name) {
fail("Map");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,17 @@ public void endList() {
setPosition(idx() + 1);
}

@Override
public void startListView() {
getWriter(MinorType.LISTVIEW).startListView();
}

@Override
public void endListView() {
getWriter(MinorType.LISTVIEW).endListView();
setPosition(idx() + 1);
}

@Override
public void startMap() {
getWriter(MinorType.MAP).startMap();
Expand Down Expand Up @@ -267,6 +278,11 @@ public ListWriter list() {
return getWriter(MinorType.LIST).list();
}
@Override
public ListWriter listView() {
return getWriter(MinorType.LISTVIEW).listView();
}
@Override
public MapWriter map() {
return getWriter(MinorType.LIST).map();
Expand All @@ -287,6 +303,11 @@ public ListWriter list(String name) {
return getWriter(MinorType.STRUCT).list(name);
}
@Override
public ListWriter listView(String name) {
return getWriter(MinorType.STRUCT).listView(name);
}
@Override
public MapWriter map(String name) {
return getWriter(MinorType.STRUCT).map(name);
Expand All @@ -296,6 +317,7 @@ public MapWriter map(String name) {
public MapWriter map(String name, boolean keysSorted) {
return getWriter(MinorType.STRUCT).map(name, keysSorted);
}
<#list vv.types as type><#list type.minor as minor>
<#assign lowerName = minor.class?uncap_first />
<#if lowerName == "int" ><#assign lowerName = "integer" /></#if>
Expand Down
5 changes: 5 additions & 0 deletions java/vector/src/main/codegen/templates/BaseWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public interface StructWriter extends BaseWriter {
void copyReaderToField(String name, FieldReader reader);
StructWriter struct(String name);
ListWriter list(String name);
ListWriter listView(String name);
MapWriter map(String name);
MapWriter map(String name, boolean keysSorted);
void start();
Expand All @@ -71,8 +72,11 @@ public interface StructWriter extends BaseWriter {
public interface ListWriter extends BaseWriter {
void startList();
void endList();
void startListView();
void endListView();
StructWriter struct();
ListWriter list();
ListWriter listView();
MapWriter map();
MapWriter map(boolean keysSorted);
void copyReader(FieldReader reader);
Expand Down Expand Up @@ -106,6 +110,7 @@ public interface ComplexWriter {
void copyReader(FieldReader reader);
StructWriter rootAsStruct();
ListWriter rootAsList();
ListWriter rootAsListView();
MapWriter rootAsMap(boolean keysSorted);

void setPosition(int index);
Expand Down
7 changes: 7 additions & 0 deletions java/vector/src/main/codegen/templates/ComplexCopier.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ private static void writeValue(FieldReader reader, FieldWriter writer) {
switch (mt) {

case LIST:
case LISTVIEW:
case LARGELIST:
case FIXED_SIZE_LIST:
if (reader.isSet()) {
Expand Down Expand Up @@ -158,6 +159,8 @@ private static FieldWriter getStructWriterForReader(FieldReader reader, StructWr
return (FieldWriter) writer.list(name);
case MAP:
return (FieldWriter) writer.map(name);
case LISTVIEW:
return (FieldWriter) writer.listView(name);
default:
throw new UnsupportedOperationException(reader.getMinorType().toString());
}
Expand All @@ -180,6 +183,8 @@ private static FieldWriter getListWriterForReader(FieldReader reader, ListWriter
case MAP:
case NULL:
return (FieldWriter) writer.list();
case LISTVIEW:
return (FieldWriter) writer.listView();
default:
throw new UnsupportedOperationException(reader.getMinorType().toString());
}
Expand All @@ -201,6 +206,8 @@ private static FieldWriter getMapWriterForReader(FieldReader reader, MapWriter w
case LIST:
case NULL:
return (FieldWriter) writer.list();
case LISTVIEW:
return (FieldWriter) writer.listView();
case MAP:
return (FieldWriter) writer.map(false);
default:
Expand Down
21 changes: 21 additions & 0 deletions java/vector/src/main/codegen/templates/DenseUnionWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@ public void endList() {
getListWriter(typeId).endList();
}

@Override
public void startListView() {
byte typeId = data.getTypeId(idx());
getListViewWriter(typeId).startList();
}

@Override
public void endListView() {
byte typeId = data.getTypeId(idx());
getListViewWriter(typeId).endList();
}

private StructWriter getStructWriter(byte typeId) {
StructWriter structWriter = (StructWriter) writers[typeId];
if (structWriter == null) {
Expand All @@ -106,6 +118,15 @@ private ListWriter getListWriter(byte typeId) {
return listWriter;
}

private ListWriter getListViewWriter(byte typeId) {
ListWriter listWriter = (ListWriter) writers[typeId];
if (listWriter == null) {
listWriter = new UnionListViewWriter((ListViewVector) data.getVectorByType(typeId), nullableStructWriterFactory);
writers[typeId] = listWriter;
}
return listWriter;
}

public ListWriter asList(byte typeId) {
data.setTypeId(idx(), typeId);
return getListWriter(typeId);
Expand Down
167 changes: 167 additions & 0 deletions java/vector/src/main/codegen/templates/PromotableViewWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

<@pp.dropOutputFile />
<@pp.changeOutputFile name="/org/apache/arrow/vector/complex/impl/PromotableViewWriter.java" />

<#include "/@includes/license.ftl" />

package org.apache.arrow.vector.complex.impl;

import java.util.Locale;
<#include "/@includes/vv_imports.ftl" />

/**
* This FieldWriter implementation delegates all FieldWriter API calls to an inner FieldWriter. This
* inner field writer can start as a specific type, and this class will promote the writer to a
* UnionWriter if a call is made that the specifically typed writer cannot handle. A new UnionVector
* is created, wrapping the original vector, and replaces the original vector in the parent vector,
* which can be either an AbstractStructVector or a ListViewVector.
*
* <p>The writer used can either be for single elements (struct) or lists.
*/
public class PromotableViewWriter extends PromotableWriter {

public PromotableViewWriter(ValueVector v, FixedSizeListVector fixedListVector) {
super(v, fixedListVector);
}

public PromotableViewWriter(ValueVector v, FixedSizeListVector fixedListVector,
NullableStructWriterFactory nullableStructWriterFactory) {
super(v, fixedListVector, nullableStructWriterFactory);
}

public PromotableViewWriter(ValueVector v, LargeListVector largeListVector) {
super(v, largeListVector);
}

public PromotableViewWriter(ValueVector v, LargeListVector largeListVector,
NullableStructWriterFactory nullableStructWriterFactory) {
super(v, largeListVector, nullableStructWriterFactory);
}

public PromotableViewWriter(ValueVector v, ListVector listVector) {
super(v, listVector);
}

public PromotableViewWriter(ValueVector v, ListVector listVector,
NullableStructWriterFactory nullableStructWriterFactory) {
super(v, listVector, nullableStructWriterFactory);
}

public PromotableViewWriter(ValueVector v, ListViewVector listViewVector,
NullableStructWriterFactory nullableStructWriterFactory) {
super(v, listViewVector, nullableStructWriterFactory);
}

public PromotableViewWriter(ValueVector v, AbstractStructVector parentContainer) {
super(v, parentContainer);
}

public PromotableViewWriter(ValueVector v, AbstractStructVector parentContainer,
NullableStructWriterFactory nullableStructWriterFactory) {
super(v, parentContainer, nullableStructWriterFactory);
}

@Override
protected FieldWriter getWriter(MinorType type, ArrowType arrowType) {
if (state == State.UNION) {
if (requiresArrowType(type)) {
writer = ((UnionWriter) writer).toViewWriter();
((UnionViewWriter) writer).getWriter(type, arrowType);
} else {
writer = ((UnionWriter) writer).toViewWriter();
((UnionViewWriter) writer).getWriter(type);
}
} else if (state == State.UNTYPED) {
if (type == null) {
// ???
return null;
}
if (arrowType == null) {
arrowType = type.getType();
}
FieldType fieldType = new FieldType(addVectorAsNullable, arrowType, null, null);
ValueVector v;
if (listVector != null) {
v = listVector.addOrGetVector(fieldType).getVector();
} else if (fixedListVector != null) {
v = fixedListVector.addOrGetVector(fieldType).getVector();
} else if (listViewVector != null) {
v = listViewVector.addOrGetVector(fieldType).getVector();
} else {
v = largeListVector.addOrGetVector(fieldType).getVector();
}
v.allocateNew();
setWriter(v);
writer.setPosition(position);
} else if (type != this.type) {
promoteToUnion();
if (requiresArrowType(type)) {
writer = ((UnionWriter) writer).toViewWriter();
((UnionViewWriter) writer).getWriter(type, arrowType);
} else {
writer = ((UnionWriter) writer).toViewWriter();
((UnionViewWriter) writer).getWriter(type);
}
}
return writer;
}

@Override
public StructWriter struct() {
return getWriter(MinorType.LISTVIEW).struct();
}

<#list vv.types as type><#list type.minor as minor>
<#assign lowerName = minor.class?uncap_first />
<#if lowerName == "int" ><#assign lowerName = "integer" /></#if>
<#assign upperName = minor.class?upper_case />
<#assign capName = minor.class?cap_first />

@Override
public ${capName}Writer ${lowerName}() {
return getWriter(MinorType.LISTVIEW).${lowerName}();
}

</#list></#list>

@Override
public void allocate() {
getWriter().allocate();
}

@Override
public void clear() {
getWriter().clear();
}

@Override
public Field getField() {
return getWriter().getField();
}

@Override
public int getValueCapacity() {
return getWriter().getValueCapacity();
}

@Override
public void close() throws Exception {
getWriter().close();
}
}
Loading

0 comments on commit d4d92e4

Please sign in to comment.