You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by th...@apache.org on 2022/08/25 09:29:14 UTC

[avro] branch master updated: AVRO-3602 Support Map(with non-String keys) and Set in ReflectDatumReader (#1818)

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

thiru pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/master by this push:
     new f1c04f7e4 AVRO-3602 Support Map(with non-String keys) and Set in ReflectDatumReader (#1818)
f1c04f7e4 is described below

commit f1c04f7e4d664a976e0f525ac1e1726321aa11ad
Author: Yury Bubonv <yb...@gmail.com>
AuthorDate: Thu Aug 25 02:29:07 2022 -0700

    AVRO-3602 Support Map(with non-String keys) and Set in ReflectDatumReader (#1818)
    
    Co-authored-by: Yury Bubnov <yu...@grammarly.com>
---
 .../apache/avro/reflect/ReflectDatumReader.java    |  10 ++
 .../avro/reflect/TestReflectDatumReader.java       | 144 ++++++++++++++++++++-
 2 files changed, 152 insertions(+), 2 deletions(-)

diff --git a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectDatumReader.java b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectDatumReader.java
index 6aecf25cb..ebdca36cc 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectDatumReader.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectDatumReader.java
@@ -21,6 +21,8 @@ import java.io.IOException;
 import java.lang.reflect.Array;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.HashMap;
 import java.util.Collection;
 import java.util.Map;
 
@@ -92,8 +94,16 @@ public class ReflectDatumReader<T> extends SpecificDatumReader<T> {
         ((Collection<?>) old).clear();
         return old;
       }
+
       if (collectionClass.isAssignableFrom(ArrayList.class))
         return new ArrayList<>();
+
+      if (collectionClass.isAssignableFrom(HashSet.class))
+        return new HashSet<>();
+
+      if (collectionClass.isAssignableFrom(HashMap.class))
+        return new HashMap<>();
+
       return SpecificData.newInstance(collectionClass, schema);
     }
 
diff --git a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectDatumReader.java b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectDatumReader.java
index e431f8f55..3b97eab04 100644
--- a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectDatumReader.java
+++ b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflectDatumReader.java
@@ -18,18 +18,22 @@
 
 package org.apache.avro.reflect;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Set;
+import java.util.Map;
 
 import org.apache.avro.io.Decoder;
 import org.apache.avro.io.DecoderFactory;
 import org.apache.avro.io.Encoder;
 import org.apache.avro.io.EncoderFactory;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class TestReflectDatumReader {
 
@@ -78,6 +82,49 @@ public class TestReflectDatumReader {
     assertEquals(pojoWithArray, deserialized);
   }
 
+  @Test
+  public void testRead_PojoWithSet() throws IOException {
+    PojoWithSet pojoWithSet = new PojoWithSet();
+    pojoWithSet.setId(42);
+    Set<Integer> relatedIds = new HashSet<>();
+    relatedIds.add(1);
+    relatedIds.add(2);
+    relatedIds.add(3);
+    pojoWithSet.setRelatedIds(relatedIds);
+
+    byte[] serializedBytes = serializeWithReflectDatumWriter(pojoWithSet, PojoWithSet.class);
+
+    Decoder decoder = DecoderFactory.get().binaryDecoder(serializedBytes, null);
+    ReflectDatumReader<PojoWithSet> reflectDatumReader = new ReflectDatumReader<>(PojoWithSet.class);
+
+    PojoWithSet deserialized = new PojoWithSet();
+    reflectDatumReader.read(deserialized, decoder);
+
+    assertEquals(pojoWithSet, deserialized);
+
+  }
+
+  @Test
+  public void testRead_PojoWithMap() throws IOException {
+    PojoWithMap pojoWithMap = new PojoWithMap();
+    pojoWithMap.setId(42);
+    Map<Integer, Integer> relatedIds = new HashMap<>();
+    relatedIds.put(1, 11);
+    relatedIds.put(2, 22);
+    relatedIds.put(3, 33);
+    pojoWithMap.setRelatedIds(relatedIds);
+
+    byte[] serializedBytes = serializeWithReflectDatumWriter(pojoWithMap, PojoWithMap.class);
+
+    Decoder decoder = DecoderFactory.get().binaryDecoder(serializedBytes, null);
+    ReflectDatumReader<PojoWithMap> reflectDatumReader = new ReflectDatumReader<>(PojoWithMap.class);
+
+    PojoWithMap deserialized = new PojoWithMap();
+    reflectDatumReader.read(deserialized, decoder);
+
+    assertEquals(pojoWithMap, deserialized);
+  }
+
   public static class PojoWithList {
     private int id;
     private List<Integer> relatedIds;
@@ -167,6 +214,99 @@ public class TestReflectDatumReader {
         return false;
       return Arrays.equals(relatedIds, other.relatedIds);
     }
+  }
+
+  public static class PojoWithSet {
+    private int id;
+    private Set<Integer> relatedIds;
+
+    public int getId() {
+      return id;
+    }
+
+    public void setId(int id) {
+      this.id = id;
+    }
+
+    public Set<Integer> getRelatedIds() {
+      return relatedIds;
+    }
+
+    public void setRelatedIds(Set<Integer> relatedIds) {
+      this.relatedIds = relatedIds;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + id;
+      result = prime * result + ((relatedIds == null) ? 0 : relatedIds.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj)
+        return true;
+      if (obj == null)
+        return false;
+      if (getClass() != obj.getClass())
+        return false;
+      PojoWithSet other = (PojoWithSet) obj;
+      if (id != other.id)
+        return false;
+      if (relatedIds == null) {
+        return other.relatedIds == null;
+      } else
+        return relatedIds.equals(other.relatedIds);
+    }
+  }
+
+  public static class PojoWithMap {
+    private int id;
+    private Map<Integer, Integer> relatedIds;
+
+    public int getId() {
+      return id;
+    }
 
+    public void setId(int id) {
+      this.id = id;
+    }
+
+    public Map<Integer, Integer> getRelatedIds() {
+      return relatedIds;
+    }
+
+    public void setRelatedIds(Map<Integer, Integer> relatedIds) {
+      this.relatedIds = relatedIds;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + id;
+      result = prime * result + ((relatedIds == null) ? 0 : relatedIds.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj)
+        return true;
+      if (obj == null)
+        return false;
+      if (getClass() != obj.getClass())
+        return false;
+      PojoWithMap other = (PojoWithMap) obj;
+      if (id != other.id)
+        return false;
+      if (relatedIds == null) {
+        return other.relatedIds == null;
+      } else
+        return relatedIds.equals(other.relatedIds);
+    }
   }
 }