This is an automated email from the ASF dual-hosted git repository.

lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 8068554a5d GH-43512: [Java] ListViewVector Visitor-based component 
Integration (#43513)
8068554a5d is described below

commit 8068554a5d18129121f824978c7ee4a9c430640b
Author: Vibhatha Lakmal Abeykoon <[email protected]>
AuthorDate: Fri Aug 2 06:34:34 2024 +0530

    GH-43512: [Java] ListViewVector Visitor-based component Integration (#43513)
    
    ### Rationale for this change
    
    This PR integrates the core visitor-based components to ListViewVector.
    
    ### What changes are included in this PR?
    
    This PR includes the addition of `RangeEqualsVisitor`, `TypeEqualsVisitor` 
and necessary test cases.
    
    ### Are these changes tested?
    
    Yes
    
    ### Are there any user-facing changes?
    
    No
    * GitHub Issue: #43512
    
    Authored-by: Vibhatha Abeykoon <[email protected]>
    Signed-off-by: David Li <[email protected]>
---
 .../arrow/vector/compare/RangeEqualsVisitor.java   |  57 ++++++++++++
 .../arrow/vector/compare/TypeEqualsVisitor.java    |   6 ++
 .../apache/arrow/vector/compare/VectorVisitor.java |   5 ++
 .../arrow/vector/complex/ListViewVector.java       |   2 +-
 .../org/apache/arrow/vector/TestValueVector.java   |  60 +++++++++++++
 .../vector/compare/TestRangeEqualsVisitor.java     | 100 +++++++++++++++++++++
 .../vector/compare/TestTypeEqualsVisitor.java      |  17 ++++
 7 files changed, 246 insertions(+), 1 deletion(-)

diff --git 
a/java/vector/src/main/java/org/apache/arrow/vector/compare/RangeEqualsVisitor.java
 
b/java/vector/src/main/java/org/apache/arrow/vector/compare/RangeEqualsVisitor.java
index 3050649737..fbc28a3609 100644
--- 
a/java/vector/src/main/java/org/apache/arrow/vector/compare/RangeEqualsVisitor.java
+++ 
b/java/vector/src/main/java/org/apache/arrow/vector/compare/RangeEqualsVisitor.java
@@ -32,10 +32,12 @@ import org.apache.arrow.vector.ExtensionTypeVector;
 import org.apache.arrow.vector.NullVector;
 import org.apache.arrow.vector.ValueVector;
 import org.apache.arrow.vector.complex.BaseRepeatedValueVector;
+import org.apache.arrow.vector.complex.BaseRepeatedValueViewVector;
 import org.apache.arrow.vector.complex.DenseUnionVector;
 import org.apache.arrow.vector.complex.FixedSizeListVector;
 import org.apache.arrow.vector.complex.LargeListVector;
 import org.apache.arrow.vector.complex.ListVector;
+import org.apache.arrow.vector.complex.ListViewVector;
 import org.apache.arrow.vector.complex.NonNullableStructVector;
 import org.apache.arrow.vector.complex.UnionVector;
 
@@ -234,6 +236,14 @@ public class RangeEqualsVisitor implements 
VectorVisitor<Boolean, Range> {
     return underlyingVisitor.rangeEquals(range);
   }
 
+  @Override
+  public Boolean visit(ListViewVector left, Range range) {
+    if (!validate(left)) {
+      return false;
+    }
+    return compareListViewVectors(range);
+  }
+
   protected RangeEqualsVisitor createInnerVisitor(
       ValueVector leftInner,
       ValueVector rightInner,
@@ -702,4 +712,51 @@ public class RangeEqualsVisitor implements 
VectorVisitor<Boolean, Range> {
     }
     return true;
   }
+
+  protected boolean compareListViewVectors(Range range) {
+    ListViewVector leftVector = (ListViewVector) left;
+    ListViewVector rightVector = (ListViewVector) right;
+
+    RangeEqualsVisitor innerVisitor =
+        createInnerVisitor(
+            leftVector.getDataVector(), rightVector.getDataVector(), /*type 
comparator*/ null);
+    Range innerRange = new Range();
+
+    for (int i = 0; i < range.getLength(); i++) {
+      int leftIndex = range.getLeftStart() + i;
+      int rightIndex = range.getRightStart() + i;
+
+      boolean isNull = leftVector.isNull(leftIndex);
+      if (isNull != rightVector.isNull(rightIndex)) {
+        return false;
+      }
+
+      int offsetWidth = BaseRepeatedValueViewVector.OFFSET_WIDTH;
+      int sizeWidth = BaseRepeatedValueViewVector.SIZE_WIDTH;
+
+      if (!isNull) {
+        final int startIndexLeft =
+            leftVector.getOffsetBuffer().getInt((long) leftIndex * 
offsetWidth);
+        final int leftSize = leftVector.getSizeBuffer().getInt((long) 
leftIndex * sizeWidth);
+
+        final int startIndexRight =
+            rightVector.getOffsetBuffer().getInt((long) rightIndex * 
offsetWidth);
+        final int rightSize = rightVector.getSizeBuffer().getInt((long) 
rightIndex * sizeWidth);
+
+        if (leftSize != rightSize) {
+          return false;
+        }
+
+        innerRange =
+            innerRange
+                .setRightStart(startIndexRight)
+                .setLeftStart(startIndexLeft)
+                .setLength(leftSize);
+        if (!innerVisitor.rangeEquals(innerRange)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
 }
diff --git 
a/java/vector/src/main/java/org/apache/arrow/vector/compare/TypeEqualsVisitor.java
 
b/java/vector/src/main/java/org/apache/arrow/vector/compare/TypeEqualsVisitor.java
index 15cc2c31b8..6e15d6a83e 100644
--- 
a/java/vector/src/main/java/org/apache/arrow/vector/compare/TypeEqualsVisitor.java
+++ 
b/java/vector/src/main/java/org/apache/arrow/vector/compare/TypeEqualsVisitor.java
@@ -29,6 +29,7 @@ import org.apache.arrow.vector.complex.DenseUnionVector;
 import org.apache.arrow.vector.complex.FixedSizeListVector;
 import org.apache.arrow.vector.complex.LargeListVector;
 import org.apache.arrow.vector.complex.ListVector;
+import org.apache.arrow.vector.complex.ListViewVector;
 import org.apache.arrow.vector.complex.NonNullableStructVector;
 import org.apache.arrow.vector.complex.UnionVector;
 import org.apache.arrow.vector.types.pojo.Field;
@@ -124,6 +125,11 @@ public class TypeEqualsVisitor implements 
VectorVisitor<Boolean, Void> {
     return compareField(left.getField(), right.getField());
   }
 
+  @Override
+  public Boolean visit(ListViewVector left, Void value) {
+    return compareField(left.getField(), right.getField());
+  }
+
   private boolean compareField(Field leftField, Field rightField) {
 
     if (leftField == rightField) {
diff --git 
a/java/vector/src/main/java/org/apache/arrow/vector/compare/VectorVisitor.java 
b/java/vector/src/main/java/org/apache/arrow/vector/compare/VectorVisitor.java
index 870f015862..c912359d4a 100644
--- 
a/java/vector/src/main/java/org/apache/arrow/vector/compare/VectorVisitor.java
+++ 
b/java/vector/src/main/java/org/apache/arrow/vector/compare/VectorVisitor.java
@@ -26,6 +26,7 @@ import org.apache.arrow.vector.complex.DenseUnionVector;
 import org.apache.arrow.vector.complex.FixedSizeListVector;
 import org.apache.arrow.vector.complex.LargeListVector;
 import org.apache.arrow.vector.complex.ListVector;
+import org.apache.arrow.vector.complex.ListViewVector;
 import org.apache.arrow.vector.complex.NonNullableStructVector;
 import org.apache.arrow.vector.complex.UnionVector;
 
@@ -60,4 +61,8 @@ public interface VectorVisitor<OUT, IN> {
   OUT visit(NullVector left, IN value);
 
   OUT visit(ExtensionTypeVector<?> left, IN value);
+
+  default OUT visit(ListViewVector left, IN value) {
+    throw new UnsupportedOperationException("VectorVisitor for ListViewVector 
is not supported.");
+  }
 }
diff --git 
a/java/vector/src/main/java/org/apache/arrow/vector/complex/ListViewVector.java 
b/java/vector/src/main/java/org/apache/arrow/vector/complex/ListViewVector.java
index d719c9b1a9..6ced66d81e 100644
--- 
a/java/vector/src/main/java/org/apache/arrow/vector/complex/ListViewVector.java
+++ 
b/java/vector/src/main/java/org/apache/arrow/vector/complex/ListViewVector.java
@@ -341,7 +341,7 @@ public class ListViewVector extends 
BaseRepeatedValueViewVector
 
   @Override
   public <OUT, IN> OUT accept(VectorVisitor<OUT, IN> visitor, IN value) {
-    throw new UnsupportedOperationException("ListViewVector does not support 
visitor pattern.");
+    return visitor.visit(this, value);
   }
 
   @Override
diff --git 
a/java/vector/src/test/java/org/apache/arrow/vector/TestValueVector.java 
b/java/vector/src/test/java/org/apache/arrow/vector/TestValueVector.java
index 376ad3ec75..4dd55afdb8 100644
--- a/java/vector/src/test/java/org/apache/arrow/vector/TestValueVector.java
+++ b/java/vector/src/test/java/org/apache/arrow/vector/TestValueVector.java
@@ -2882,6 +2882,34 @@ public class TestValueVector {
     }
   }
 
+  @Test
+  public void testListViewVectorEqualsWithNull() {
+    try (final ListViewVector vector1 = ListViewVector.empty("listview", 
allocator);
+        final ListViewVector vector2 = ListViewVector.empty("listview", 
allocator); ) {
+
+      UnionListViewWriter writer1 = vector1.getWriter();
+      writer1.allocate();
+
+      // set some values
+      writeListViewVector(writer1, new int[] {1, 2});
+      writeListViewVector(writer1, new int[] {3, 4});
+      writeListViewVector(writer1, new int[] {});
+      writer1.setValueCount(3);
+
+      UnionListViewWriter writer2 = vector2.getWriter();
+      writer2.allocate();
+
+      // set some values
+      writeListViewVector(writer2, new int[] {1, 2});
+      writeListViewVector(writer2, new int[] {3, 4});
+      writer2.setValueCount(3);
+
+      VectorEqualsVisitor visitor = new VectorEqualsVisitor();
+
+      assertFalse(visitor.vectorEquals(vector1, vector2));
+    }
+  }
+
   @Test
   public void testListVectorEquals() {
     try (final ListVector vector1 = ListVector.empty("list", allocator);
@@ -2914,6 +2942,38 @@ public class TestValueVector {
     }
   }
 
+  @Test
+  public void testListViewVectorEquals() {
+    try (final ListViewVector vector1 = ListViewVector.empty("listview", 
allocator);
+        final ListViewVector vector2 = ListViewVector.empty("listview", 
allocator); ) {
+
+      UnionListViewWriter writer1 = vector1.getWriter();
+      writer1.allocate();
+
+      // set some values
+      writeListViewVector(writer1, new int[] {1, 2});
+      writeListViewVector(writer1, new int[] {3, 4});
+      writeListViewVector(writer1, new int[] {5, 6});
+      writer1.setValueCount(3);
+
+      UnionListViewWriter writer2 = vector2.getWriter();
+      writer2.allocate();
+
+      // set some values
+      writeListViewVector(writer2, new int[] {1, 2});
+      writeListViewVector(writer2, new int[] {3, 4});
+      writer2.setValueCount(2);
+
+      VectorEqualsVisitor visitor = new VectorEqualsVisitor();
+      assertFalse(visitor.vectorEquals(vector1, vector2));
+
+      writeListViewVector(writer2, new int[] {5, 6});
+      writer2.setValueCount(3);
+
+      assertTrue(visitor.vectorEquals(vector1, vector2));
+    }
+  }
+
   @Test
   public void testListVectorSetNull() {
     try (final ListVector vector = ListVector.empty("list", allocator)) {
diff --git 
a/java/vector/src/test/java/org/apache/arrow/vector/compare/TestRangeEqualsVisitor.java
 
b/java/vector/src/test/java/org/apache/arrow/vector/compare/TestRangeEqualsVisitor.java
index bab8c737f6..7e91b76043 100644
--- 
a/java/vector/src/test/java/org/apache/arrow/vector/compare/TestRangeEqualsVisitor.java
+++ 
b/java/vector/src/test/java/org/apache/arrow/vector/compare/TestRangeEqualsVisitor.java
@@ -37,10 +37,12 @@ import 
org.apache.arrow.vector.compare.util.ValueEpsilonEqualizers;
 import org.apache.arrow.vector.complex.DenseUnionVector;
 import org.apache.arrow.vector.complex.FixedSizeListVector;
 import org.apache.arrow.vector.complex.ListVector;
+import org.apache.arrow.vector.complex.ListViewVector;
 import org.apache.arrow.vector.complex.StructVector;
 import org.apache.arrow.vector.complex.UnionVector;
 import org.apache.arrow.vector.complex.impl.NullableStructWriter;
 import org.apache.arrow.vector.complex.impl.UnionFixedSizeListWriter;
+import org.apache.arrow.vector.complex.impl.UnionListViewWriter;
 import org.apache.arrow.vector.complex.impl.UnionListWriter;
 import org.apache.arrow.vector.holders.NullableBigIntHolder;
 import org.apache.arrow.vector.holders.NullableFloat4Holder;
@@ -201,6 +203,24 @@ public class TestRangeEqualsVisitor {
     }
   }
 
+  @Test
+  public void testListViewVectorWithDifferentChild() {
+    try (final ListViewVector vector1 = ListViewVector.empty("listview", 
allocator);
+        final ListViewVector vector2 = ListViewVector.empty("listview", 
allocator); ) {
+
+      vector1.allocateNew();
+      vector1.initializeChildrenFromFields(
+          Arrays.asList(Field.nullable("child", new ArrowType.Int(32, true))));
+
+      vector2.allocateNew();
+      vector2.initializeChildrenFromFields(
+          Arrays.asList(Field.nullable("child", new ArrowType.Int(64, true))));
+
+      RangeEqualsVisitor visitor = new RangeEqualsVisitor(vector1, vector2);
+      assertFalse(visitor.rangeEquals(new Range(0, 0, 0)));
+    }
+  }
+
   @Test
   public void testListVectorRangeEquals() {
     try (final ListVector vector1 = ListVector.empty("list", allocator);
@@ -233,6 +253,38 @@ public class TestRangeEqualsVisitor {
     }
   }
 
+  @Test
+  public void testListViewVectorRangeEquals() {
+    try (final ListViewVector vector1 = ListViewVector.empty("listview", 
allocator);
+        final ListViewVector vector2 = ListViewVector.empty("listview", 
allocator); ) {
+
+      UnionListViewWriter writer1 = vector1.getWriter();
+      writer1.allocate();
+
+      // set some values
+      writeListViewVector(writer1, new int[] {1, 2});
+      writeListViewVector(writer1, new int[] {3, 4});
+      writeListViewVector(writer1, new int[] {5, 6});
+      writeListViewVector(writer1, new int[] {7, 8});
+      writeListViewVector(writer1, new int[] {9, 10});
+      writer1.setValueCount(5);
+
+      UnionListViewWriter writer2 = vector2.getWriter();
+      writer2.allocate();
+
+      // set some values
+      writeListViewVector(writer2, new int[] {0, 0});
+      writeListViewVector(writer2, new int[] {3, 4});
+      writeListViewVector(writer2, new int[] {5, 6});
+      writeListViewVector(writer2, new int[] {7, 8});
+      writeListViewVector(writer2, new int[] {0, 0});
+      writer2.setValueCount(5);
+
+      RangeEqualsVisitor visitor = new RangeEqualsVisitor(vector1, vector2);
+      assertTrue(visitor.rangeEquals(new Range(1, 1, 3)));
+    }
+  }
+
   @Test
   public void testBitVectorRangeEquals() {
     try (final BitVector vector1 = new BitVector("v1", allocator);
@@ -819,6 +871,38 @@ public class TestRangeEqualsVisitor {
     }
   }
 
+  @Test
+  public void testListViewVectorApproxEquals() {
+    try (final ListViewVector right = ListViewVector.empty("listview", 
allocator);
+        final ListViewVector left1 = ListViewVector.empty("listview", 
allocator);
+        final ListViewVector left2 = ListViewVector.empty("listview", 
allocator); ) {
+
+      final float epsilon = 1.0E-6f;
+
+      UnionListViewWriter rightWriter = right.getWriter();
+      rightWriter.allocate();
+      writeListViewVector(rightWriter, new double[] {1, 2});
+      writeListViewVector(rightWriter, new double[] {1.01, 2.02});
+      rightWriter.setValueCount(2);
+
+      UnionListViewWriter leftWriter1 = left1.getWriter();
+      leftWriter1.allocate();
+      writeListViewVector(leftWriter1, new double[] {1, 2});
+      writeListViewVector(leftWriter1, new double[] {1.01 + epsilon / 2, 2.02 
- epsilon / 2});
+      leftWriter1.setValueCount(2);
+
+      UnionListViewWriter leftWriter2 = left2.getWriter();
+      leftWriter2.allocate();
+      writeListViewVector(leftWriter2, new double[] {1, 2});
+      writeListViewVector(leftWriter2, new double[] {1.01 + epsilon * 2, 2.02 
- epsilon * 2});
+      leftWriter2.setValueCount(2);
+
+      Range range = new Range(0, 0, right.getValueCount());
+      assertTrue(new ApproxEqualsVisitor(left1, right, epsilon, 
epsilon).rangeEquals(range));
+      assertFalse(new ApproxEqualsVisitor(left2, right, epsilon, 
epsilon).rangeEquals(range));
+    }
+  }
+
   private void writeStructVector(NullableStructWriter writer, int value1, long 
value2) {
     writer.start();
     writer.integer("f0").writeInt(value1);
@@ -841,6 +925,14 @@ public class TestRangeEqualsVisitor {
     writer.endList();
   }
 
+  private void writeListViewVector(UnionListViewWriter writer, int[] values) {
+    writer.startListView();
+    for (int v : values) {
+      writer.integer().writeInt(v);
+    }
+    writer.endListView();
+  }
+
   private void writeFixedSizeListVector(UnionFixedSizeListWriter writer, int[] 
values) {
     writer.startList();
     for (int v : values) {
@@ -856,4 +948,12 @@ public class TestRangeEqualsVisitor {
     }
     writer.endList();
   }
+
+  private void writeListViewVector(UnionListViewWriter writer, double[] 
values) {
+    writer.startListView();
+    for (double v : values) {
+      writer.float8().writeFloat8(v);
+    }
+    writer.endListView();
+  }
 }
diff --git 
a/java/vector/src/test/java/org/apache/arrow/vector/compare/TestTypeEqualsVisitor.java
 
b/java/vector/src/test/java/org/apache/arrow/vector/compare/TestTypeEqualsVisitor.java
index 4cd3603e20..d65096205f 100644
--- 
a/java/vector/src/test/java/org/apache/arrow/vector/compare/TestTypeEqualsVisitor.java
+++ 
b/java/vector/src/test/java/org/apache/arrow/vector/compare/TestTypeEqualsVisitor.java
@@ -33,6 +33,7 @@ import org.apache.arrow.vector.ViewVarBinaryVector;
 import org.apache.arrow.vector.ViewVarCharVector;
 import org.apache.arrow.vector.complex.DenseUnionVector;
 import org.apache.arrow.vector.complex.ListVector;
+import org.apache.arrow.vector.complex.ListViewVector;
 import org.apache.arrow.vector.complex.StructVector;
 import org.apache.arrow.vector.complex.UnionVector;
 import org.apache.arrow.vector.types.Types;
@@ -104,6 +105,22 @@ public class TestTypeEqualsVisitor {
     }
   }
 
+  @Test
+  public void testListViewTypeEquals() {
+    try (final ListViewVector right = ListViewVector.empty("listview", 
allocator);
+        final ListViewVector left1 = ListViewVector.empty("listview", 
allocator);
+        final ListViewVector left2 = ListViewVector.empty("listview", 
allocator)) {
+
+      right.addOrGetVector(FieldType.nullable(new ArrowType.Utf8()));
+      left1.addOrGetVector(FieldType.nullable(new ArrowType.Utf8()));
+      left2.addOrGetVector(FieldType.nullable(new 
ArrowType.FixedSizeBinary(2)));
+
+      TypeEqualsVisitor visitor = new TypeEqualsVisitor(right);
+      assertTrue(visitor.equals(left1));
+      assertFalse(visitor.equals(left2));
+    }
+  }
+
   @Test
   public void testStructTypeEquals() {
     try (final StructVector right = StructVector.empty("struct", allocator);

Reply via email to