Skip to content

Commit

Permalink
feat(java): support jdk9+ java.util.ImmutableCollections copy (#1800)
Browse files Browse the repository at this point in the history
## What does this PR do?
support jdk9+ java.util.ImmutableCollections copy

## Related 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
  • Loading branch information
zhaommmmomo authored Aug 15, 2024
1 parent 9a39cb3 commit bfa6dea
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,30 @@ protected <K, V> void copyEntry(Map<K, V> originMap, Builder<K, V> builder) {
}
}

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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@ public Collection newCollection(MemoryBuffer buffer) {
}
}

@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) {
Expand Down Expand Up @@ -150,6 +167,23 @@ public Collection newCollection(MemoryBuffer buffer) {
}
}

@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) {
Expand Down Expand Up @@ -183,18 +217,25 @@ public Map newMap(MemoryBuffer buffer) {
}

@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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
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;
Expand Down Expand Up @@ -398,8 +399,17 @@ public Map<String, T> read(MemoryBuffer buffer) {

@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);
}
}
}
Expand Down

0 comments on commit bfa6dea

Please sign in to comment.