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]