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

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


The following commit(s) were added to refs/heads/main by this push:
     new bfa6dea4 feat(java): support jdk9+ java.util.ImmutableCollections copy 
(#1800)
bfa6dea4 is described below

commit bfa6dea4bd76a49d7091a4a9766ed8dc33155858
Author: zhaommmmomo <[email protected]>
AuthorDate: Thu Aug 15 19:13:54 2024 +0800

    feat(java): support jdk9+ java.util.ImmutableCollections copy (#1800)
    
    ## What does this PR do?
    support jdk9+ java.util.ImmutableCollections copy
    
    ## Related issues
    https://github.com/apache/fury/issues/1679
    
    
    ## Does this PR introduce any user-facing change?
    - [ ] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
    
    
    ## Benchmark
---
 .../collection/AbstractMapSerializer.java          | 24 +++++++++
 .../collection/ImmutableCollectionSerializers.java | 63 ++++++++++++++++++----
 .../fury/serializer/collection/MapSerializers.java | 12 ++++-
 3 files changed, 87 insertions(+), 12 deletions(-)

diff --git 
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractMapSerializer.java
 
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractMapSerializer.java
index 89049441..4b0a8ba0 100644
--- 
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractMapSerializer.java
+++ 
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractMapSerializer.java
@@ -463,6 +463,30 @@ public abstract class AbstractMapSerializer<T> extends 
Serializer<T> {
     }
   }
 
+  protected <K, V> void copyEntry(Map<K, V> originMap, Object[] elements) {
+    ClassResolver classResolver = fury.getClassResolver();
+    int index = 0;
+    for (Entry<K, V> entry : originMap.entrySet()) {
+      K key = entry.getKey();
+      if (key != null) {
+        ClassInfo classInfo = classResolver.getClassInfo(key.getClass(), 
keyClassInfoWriteCache);
+        if (!classInfo.getSerializer().isImmutable()) {
+          key = fury.copyObject(key, classInfo.getClassId());
+        }
+      }
+      V value = entry.getValue();
+      if (value != null) {
+        ClassInfo classInfo =
+            classResolver.getClassInfo(value.getClass(), 
valueClassInfoWriteCache);
+        if (!classInfo.getSerializer().isImmutable()) {
+          value = fury.copyObject(value, classInfo.getClassId());
+        }
+      }
+      elements[index++] = key;
+      elements[index++] = value;
+    }
+  }
+
   @SuppressWarnings("unchecked")
   protected final void readElements(MemoryBuffer buffer, int size, Map map) {
     Serializer keySerializer = this.keySerializer;
diff --git 
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/ImmutableCollectionSerializers.java
 
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/ImmutableCollectionSerializers.java
index 4a69a25c..ae31d90b 100644
--- 
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/ImmutableCollectionSerializers.java
+++ 
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/ImmutableCollectionSerializers.java
@@ -118,6 +118,23 @@ public class ImmutableCollectionSerializers {
       }
     }
 
+    @Override
+    public Collection copy(Collection originCollection) {
+      if (Platform.JAVA_VERSION <= 8) {
+        throw new UnsupportedOperationException(
+            String.format(
+                "Only support jdk9+ java.util.ImmutableCollections deep copy. 
%s",
+                originCollection.getClass()));
+      }
+      Object[] elements = new Object[originCollection.size()];
+      copyElements(originCollection, elements);
+      try {
+        return (List) listFactory.invoke(elements);
+      } catch (Throwable e) {
+        throw new RuntimeException(e);
+      }
+    }
+
     @Override
     public Collection onCollectionRead(Collection collection) {
       if (Platform.JAVA_VERSION > 8) {
@@ -150,6 +167,23 @@ public class ImmutableCollectionSerializers {
       }
     }
 
+    @Override
+    public Collection copy(Collection originCollection) {
+      if (Platform.JAVA_VERSION <= 8) {
+        throw new UnsupportedOperationException(
+            String.format(
+                "Only support jdk9+ java.util.ImmutableCollections deep copy. 
%s",
+                originCollection.getClass()));
+      }
+      Object[] elements = new Object[originCollection.size()];
+      copyElements(originCollection, elements);
+      try {
+        return (Set) setFactory.invoke(elements);
+      } catch (Throwable e) {
+        throw new RuntimeException(e);
+      }
+    }
+
     @Override
     public Collection onCollectionRead(Collection collection) {
       if (Platform.JAVA_VERSION > 8) {
@@ -183,18 +217,25 @@ public class ImmutableCollectionSerializers {
     }
 
     @Override
-    public Map newMap(Map map) {
-      int numElements = map.size();
-      if (Platform.JAVA_VERSION > 8) {
-        return new JDKImmutableMapContainer(numElements);
-      } else {
-        return new HashMap(numElements);
+    public Map copy(Map originMap) {
+      if (Platform.JAVA_VERSION <= 8) {
+        throw new UnsupportedOperationException(
+            String.format(
+                "Only support jdk9+ java.util.ImmutableCollections deep copy. 
%s",
+                originMap.getClass()));
+      }
+      int size = originMap.size();
+      Object[] elements = new Object[size * 2];
+      copyEntry(originMap, elements);
+      try {
+        if (size == 1) {
+          return (Map) map1Factory.invoke(elements[0], elements[1]);
+        } else {
+          return (Map) mapNFactory.invoke(elements);
+        }
+      } catch (Throwable e) {
+        throw new RuntimeException(e);
       }
-    }
-
-    @Override
-    public Map onMapCopy(Map map) {
-      return onMapRead(map);
     }
 
     @Override
diff --git 
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/MapSerializers.java
 
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/MapSerializers.java
index be4abfcb..a9f6a626 100644
--- 
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/MapSerializers.java
+++ 
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/MapSerializers.java
@@ -37,6 +37,7 @@ import org.apache.fury.config.Language;
 import org.apache.fury.memory.MemoryBuffer;
 import org.apache.fury.memory.Platform;
 import org.apache.fury.reflect.ReflectionUtils;
+import org.apache.fury.resolver.ClassInfo;
 import org.apache.fury.resolver.ClassResolver;
 import org.apache.fury.serializer.ReplaceResolveSerializer;
 import org.apache.fury.serializer.Serializer;
@@ -398,8 +399,17 @@ public class MapSerializers {
 
     @Override
     protected <K, V> void copyEntry(Map<K, V> originMap, Map<K, V> newMap) {
+      ClassResolver classResolver = fury.getClassResolver();
       for (Entry<K, V> entry : originMap.entrySet()) {
-        newMap.put(entry.getKey(), fury.copyObject(entry.getValue()));
+        V value = entry.getValue();
+        if (value != null) {
+          ClassInfo classInfo =
+              classResolver.getClassInfo(value.getClass(), 
valueClassInfoWriteCache);
+          if (!classInfo.getSerializer().isImmutable()) {
+            value = fury.copyObject(value, classInfo.getClassId());
+          }
+        }
+        newMap.put(entry.getKey(), value);
       }
     }
   }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to