diff --git a/java/fury-core/src/main/java/io/fury/serializer/CollectionSerializers.java b/java/fury-core/src/main/java/io/fury/serializer/CollectionSerializers.java index 0b2c7b7e49..82c082cec1 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/CollectionSerializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/CollectionSerializers.java @@ -16,10 +16,7 @@ package io.fury.serializer; -import static io.fury.type.TypeUtils.getRawType; - import com.google.common.base.Preconditions; -import com.google.common.reflect.TypeToken; import io.fury.Fury; import io.fury.annotation.CodegenInvoke; import io.fury.config.Language; @@ -31,7 +28,6 @@ import io.fury.resolver.RefResolver; import io.fury.type.GenericType; import io.fury.type.Type; -import io.fury.type.TypeUtils; import io.fury.util.Platform; import io.fury.util.ReflectionUtils; import java.lang.reflect.Constructor; @@ -85,46 +81,34 @@ public static class Flags { public static int NOT_SAME_TYPE = 0b1000; } + /** Serializer for {@link Collection}. All collection serializer should extend this class. */ public static class CollectionSerializer extends Serializer { private Constructor constructor; private final boolean supportCodegenHook; // TODO remove elemSerializer, support generics in CompatibleSerializer. private Serializer elemSerializer; protected final ClassInfoHolder elementClassInfoHolder; - // support subclass whose element type are instantiated already, such as - // `Subclass extends ArrayList`. - // nested generics such as `Subclass extends ArrayList>` can only be passed by - // `pushGenerics` instead of set element serializers. - private final GenericType collectionGenericType; + // For subclass whose element type are instantiated already, such as + // `Subclass extends ArrayList`. If declared `Collection` doesn't specify + // instantiated element type, then the serialization will need to write this element + // type. Although we can extract this generics when creating the serializer, + // we can't do it when jit `Serializer` for some class which contains one of such collection + // field. So we will write this extra element class to keep protocol consistency between + // interpreter and jit mode although it seems unnecessary. + // With elements header, we can write this element class only once, the cost won't be too much. public CollectionSerializer(Fury fury, Class cls) { - this(fury, cls, !ReflectionUtils.isDynamicGeneratedCLass(cls), true); + this(fury, cls, !ReflectionUtils.isDynamicGeneratedCLass(cls)); } - public CollectionSerializer( - Fury fury, Class cls, boolean supportCodegenHook, boolean inferGenerics) { + public CollectionSerializer(Fury fury, Class cls, boolean supportCodegenHook) { super(fury, cls); this.supportCodegenHook = supportCodegenHook; elementClassInfoHolder = fury.getClassResolver().nilClassInfoHolder(); - if (inferGenerics) { - TypeToken elementType = TypeUtils.getElementType(TypeToken.of(cls)); - if (getRawType(elementType) != Object.class) { - collectionGenericType = - fury.getClassResolver() - .buildGenericType(TypeUtils.collectionOf(elementType).getType()); - } else { - collectionGenericType = null; - } - } else { - collectionGenericType = null; - } } private GenericType getElementGenericType(Fury fury) { GenericType genericType = fury.getGenerics().nextGenericType(); - if (genericType == null || genericType.getTypeParametersCount() < 1) { - genericType = collectionGenericType; - } GenericType elemGenericType = null; if (genericType != null) { elemGenericType = genericType.getTypeParameter0(); @@ -735,7 +719,7 @@ public void xreadElements( public static final class ArrayListSerializer extends CollectionSerializer { public ArrayListSerializer(Fury fury) { - super(fury, ArrayList.class, true, false); + super(fury, ArrayList.class, true); } @Override @@ -755,7 +739,7 @@ public static final class ArraysAsListSerializer extends CollectionSerializer
  • > cls) { - super(fury, cls, false, false); + super(fury, cls, false); try { Field arrayField = Class.forName("java.util.Arrays$ArrayList").getDeclaredField("a"); arrayFieldOffset = ReflectionUtils.getFieldOffset(arrayField); @@ -806,7 +790,7 @@ public List xread(MemoryBuffer buffer) { public static final class HashSetSerializer extends CollectionSerializer { public HashSetSerializer(Fury fury) { - super(fury, HashSet.class, true, false); + super(fury, HashSet.class, true); } @Override @@ -824,7 +808,7 @@ public HashSet newCollection(MemoryBuffer buffer, int numElements) { public static final class LinkedHashSetSerializer extends CollectionSerializer { public LinkedHashSetSerializer(Fury fury) { - super(fury, LinkedHashSet.class, true, false); + super(fury, LinkedHashSet.class, true); } @Override @@ -844,7 +828,7 @@ public static class SortedSetSerializer extends CollectionS private Constructor constructor; public SortedSetSerializer(Fury fury, Class cls) { - super(fury, cls, true, false); + super(fury, cls, true); if (cls != TreeSet.class) { try { this.constructor = cls.getConstructor(Comparator.class); @@ -889,7 +873,7 @@ public T newCollection(MemoryBuffer buffer, int numElements) { public static final class EmptyListSerializer extends CollectionSerializer> { public EmptyListSerializer(Fury fury, Class> cls) { - super(fury, cls, false, false); + super(fury, cls, false); } @Override @@ -921,7 +905,7 @@ public List xread(MemoryBuffer buffer) { public static final class EmptySetSerializer extends CollectionSerializer> { public EmptySetSerializer(Fury fury, Class> cls) { - super(fury, cls, false, false); + super(fury, cls, false); } @Override @@ -953,7 +937,7 @@ public Set xread(MemoryBuffer buffer) { public static final class EmptySortedSetSerializer extends CollectionSerializer> { public EmptySortedSetSerializer(Fury fury, Class> cls) { - super(fury, cls, false, false); + super(fury, cls, false); } @Override @@ -969,7 +953,7 @@ public static final class CollectionsSingletonListSerializer extends CollectionSerializer> { public CollectionsSingletonListSerializer(Fury fury, Class> cls) { - super(fury, cls, false, false); + super(fury, cls, false); } @Override @@ -1003,7 +987,7 @@ public List xread(MemoryBuffer buffer) { public static final class CollectionsSingletonSetSerializer extends CollectionSerializer> { public CollectionsSingletonSetSerializer(Fury fury, Class> cls) { - super(fury, cls, false, false); + super(fury, cls, false); } @Override @@ -1053,7 +1037,7 @@ public ConcurrentSkipListSet newCollection(MemoryBuffer buffer, int numElements) public static final class VectorSerializer extends CollectionSerializer { public VectorSerializer(Fury fury, Class cls) { - super(fury, cls, true, false); + super(fury, cls, true); } @Override @@ -1067,7 +1051,7 @@ public Vector newCollection(MemoryBuffer buffer, int numElements) { public static final class ArrayDequeSerializer extends CollectionSerializer { public ArrayDequeSerializer(Fury fury, Class cls) { - super(fury, cls, true, false); + super(fury, cls, true); } @Override @@ -1082,7 +1066,7 @@ public static class EnumSetSerializer extends CollectionSerializer { public EnumSetSerializer(Fury fury, Class type) { // getElementType(EnumSet.class) will be `E` without Enum as bound. // so no need to infer generics in init. - super(fury, type, false, false); + super(fury, type, false); } @Override @@ -1139,7 +1123,7 @@ public BitSet read(MemoryBuffer buffer) { public static class PriorityQueueSerializer extends CollectionSerializer { public PriorityQueueSerializer(Fury fury, Class cls) { - super(fury, cls, true, false); + super(fury, cls, true); } public void writeHeader(MemoryBuffer buffer, PriorityQueue value) { @@ -1165,7 +1149,7 @@ public static final class DefaultJavaCollectionSerializer private Serializer dataSerializer; public DefaultJavaCollectionSerializer(Fury fury, Class cls) { - super(fury, cls, false, false); + super(fury, cls, false); Preconditions.checkArgument( fury.getLanguage() == Language.JAVA, "Python default collection serializer should use " + CollectionSerializer.class); @@ -1196,7 +1180,7 @@ public static final class JDKCompatibleCollectionSerializer cls) { - super(fury, cls, false, false); + super(fury, cls, false); // Collection which defined `writeReplace` may use this serializer, so check replace/resolve // is necessary. Class serializerType = @@ -1227,7 +1211,7 @@ public static void registerDefaultSerializers(Fury fury) { Class arrayAsListClass = Arrays.asList(1, 2).getClass(); fury.registerSerializer(arrayAsListClass, new ArraysAsListSerializer(fury, arrayAsListClass)); fury.registerSerializer( - LinkedList.class, new CollectionSerializer(fury, LinkedList.class, true, false)); + LinkedList.class, new CollectionSerializer(fury, LinkedList.class, true)); fury.registerSerializer(HashSet.class, new HashSetSerializer(fury)); fury.registerSerializer(LinkedHashSet.class, new LinkedHashSetSerializer(fury)); fury.registerSerializer(TreeSet.class, new SortedSetSerializer<>(fury, TreeSet.class)); diff --git a/java/fury-core/src/main/java/io/fury/serializer/GuavaSerializers.java b/java/fury-core/src/main/java/io/fury/serializer/GuavaSerializers.java index b68ca9327e..16987a2d4c 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/GuavaSerializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/GuavaSerializers.java @@ -50,7 +50,7 @@ public class GuavaSerializers { abstract static class GuavaCollectionSerializer extends CollectionSerializer { public GuavaCollectionSerializer(Fury fury, Class cls) { - super(fury, cls, true, false); + super(fury, cls, true); fury.getClassResolver().setSerializer(cls, this); } @@ -183,7 +183,7 @@ public static final class ImmutableSortedSetSerializer { public ImmutableSortedSetSerializer(Fury fury, Class cls) { - super(fury, cls, false, false); + super(fury, cls, false); fury.getClassResolver().setSerializer(cls, this); } @@ -211,7 +211,7 @@ public T onCollectionRead(Collection collection) { abstract static class GuavaMapSerializer extends MapSerializer { public GuavaMapSerializer(Fury fury, Class cls) { - super(fury, cls, true, false); + super(fury, cls, true); fury.getClassResolver().setSerializer(cls, this); } diff --git a/java/fury-core/src/main/java/io/fury/serializer/ImmutableCollectionSerializers.java b/java/fury-core/src/main/java/io/fury/serializer/ImmutableCollectionSerializers.java index 9168243e92..fab4e8cac6 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/ImmutableCollectionSerializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/ImmutableCollectionSerializers.java @@ -105,7 +105,7 @@ class MapNStub {} public static class ImmutableListSerializer extends CollectionSerializers.CollectionSerializer { public ImmutableListSerializer(Fury fury, Class cls) { - super(fury, cls, true, false); + super(fury, cls, true); } @Override @@ -136,7 +136,7 @@ public Collection onCollectionRead(Collection collection) { public static class ImmutableSetSerializer extends CollectionSerializers.CollectionSerializer { public ImmutableSetSerializer(Fury fury, Class cls) { - super(fury, cls, true, false); + super(fury, cls, true); } @Override @@ -167,7 +167,7 @@ public Collection onCollectionRead(Collection collection) { public static class ImmutableMapSerializer extends MapSerializers.MapSerializer { public ImmutableMapSerializer(Fury fury, Class cls) { - super(fury, cls, true, false); + super(fury, cls, true); } @Override diff --git a/java/fury-core/src/main/java/io/fury/serializer/MapSerializers.java b/java/fury-core/src/main/java/io/fury/serializer/MapSerializers.java index c5becea06e..74daa604a7 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/MapSerializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/MapSerializers.java @@ -17,7 +17,6 @@ package io.fury.serializer; import static io.fury.type.TypeUtils.MAP_TYPE; -import static io.fury.type.TypeUtils.getRawType; import com.google.common.base.Preconditions; import com.google.common.reflect.TypeToken; @@ -74,20 +73,21 @@ public static class MapSerializer extends Serializer { // T>` private final IdentityMap> partialGenericKVTypeMap; - // support subclass whose kv types are instantiated already, such as - // `Subclass implements Map`. - // nested generics such as `Subclass extends HashMap>` can only be passed - // by - // `pushGenerics` instead of set value serializers. - private final GenericType mapGenericType; private final GenericType objType = fury.getClassResolver().buildGenericType(Object.class); + // For subclass whose kv type are instantiated already, such as + // `Subclass implements Map`. If declared `Map` doesn't specify + // instantiated kv type, then the serialization will need to write those kv + // types. Although we can extract this generics when creating the serializer, + // we can't do it when jit `Serializer` for some class which contains one of such map + // field. So we will write those extra kv classes to keep protocol consistency between + // interpreter and jit mode although it seems unnecessary. + // With kv header in future, we can write this kv classes only once, the cost won't be too much. public MapSerializer(Fury fury, Class cls) { - this(fury, cls, !ReflectionUtils.isDynamicGeneratedCLass(cls), true); + this(fury, cls, !ReflectionUtils.isDynamicGeneratedCLass(cls)); } - public MapSerializer( - Fury fury, Class cls, boolean supportCodegenHook, boolean inferGenerics) { + public MapSerializer(Fury fury, Class cls, boolean supportCodegenHook) { super(fury, cls); this.supportCodegenHook = supportCodegenHook; keyClassInfoWriteCache = fury.getClassResolver().nilClassInfoHolder(); @@ -95,19 +95,6 @@ public MapSerializer( valueClassInfoWriteCache = fury.getClassResolver().nilClassInfoHolder(); valueClassInfoReadCache = fury.getClassResolver().nilClassInfoHolder(); partialGenericKVTypeMap = new IdentityMap<>(); - if (inferGenerics) { - Tuple2, TypeToken> kvTypes = - TypeUtils.getMapKeyValueType(TypeToken.of(cls)); - if (getRawType(kvTypes.f0) != Object.class || getRawType(kvTypes.f1) != Object.class) { - mapGenericType = - fury.getClassResolver() - .buildGenericType(TypeUtils.mapOf(kvTypes.f0, kvTypes.f1).getType()); - } else { - mapGenericType = null; - } - } else { - mapGenericType = null; - } } /** @@ -202,9 +189,6 @@ private void javaWriteWithKVSerializers( private void genericJavaWrite(Fury fury, MemoryBuffer buffer, T map) { Generics generics = fury.getGenerics(); GenericType genericType = generics.nextGenericType(); - if (genericType == null) { - genericType = mapGenericType; - } if (genericType == null) { generalJavaWrite(fury, buffer, map); } else { @@ -496,9 +480,6 @@ protected final void readElements(MemoryBuffer buffer, int size, Map map) { private void genericJavaRead(Fury fury, MemoryBuffer buffer, Map map, int size) { Generics generics = fury.getGenerics(); GenericType genericType = generics.nextGenericType(); - if (genericType == null) { - genericType = mapGenericType; - } if (genericType == null) { generalJavaRead(fury, buffer, map, size); } else { @@ -801,7 +782,7 @@ private Object readJavaRefOptimized( public static final class HashMapSerializer extends MapSerializer { public HashMapSerializer(Fury fury) { - super(fury, HashMap.class, true, false); + super(fury, HashMap.class, true); } @Override @@ -819,7 +800,7 @@ public HashMap newMap(MemoryBuffer buffer, int size) { public static final class LinkedHashMapSerializer extends MapSerializer { public LinkedHashMapSerializer(Fury fury) { - super(fury, LinkedHashMap.class, true, false); + super(fury, LinkedHashMap.class, true); } @Override @@ -837,7 +818,7 @@ public LinkedHashMap newMap(MemoryBuffer buffer, int size) { public static final class LazyMapSerializer extends MapSerializer { public LazyMapSerializer(Fury fury) { - super(fury, LazyMap.class, true, false); + super(fury, LazyMap.class, true); } @Override @@ -856,7 +837,7 @@ public LazyMap newMap(MemoryBuffer buffer, int size) { public static class SortedMapSerializer extends MapSerializer { public SortedMapSerializer(Fury fury, Class cls) { - super(fury, cls, true, false); + super(fury, cls, true); if (cls != TreeMap.class) { try { this.constructor = cls.getConstructor(Comparator.class); @@ -896,7 +877,7 @@ public Map newMap(MemoryBuffer buffer, int numElements) { public static final class EmptyMapSerializer extends MapSerializer> { public EmptyMapSerializer(Fury fury, Class> cls) { - super(fury, cls, false, false); + super(fury, cls, false); } @Override @@ -927,7 +908,7 @@ public void xwrite(MemoryBuffer buffer, Map value) { public static final class EmptySortedMapSerializer extends MapSerializer> { public EmptySortedMapSerializer(Fury fury, Class> cls) { - super(fury, cls, false, false); + super(fury, cls, false); } @Override @@ -942,7 +923,7 @@ public void write(MemoryBuffer buffer, SortedMap value) {} public static final class SingletonMapSerializer extends MapSerializer> { public SingletonMapSerializer(Fury fury, Class> cls) { - super(fury, cls, false, false); + super(fury, cls, false); } @Override @@ -984,7 +965,7 @@ public void xwrite(MemoryBuffer buffer, Map value) { public static final class ConcurrentHashMapSerializer extends MapSerializer { public ConcurrentHashMapSerializer(Fury fury, Class type) { - super(fury, type, true, false); + super(fury, type, true); } @Override @@ -1027,7 +1008,7 @@ public static class EnumMapSerializer extends MapSerializer { public EnumMapSerializer(Fury fury, Class cls) { // getMapKeyValueType(EnumMap.class) will be `K, V` without Enum as key bound. // so no need to infer key generics in init. - super(fury, cls, true, false); + super(fury, cls, true); Field field = ReflectionUtils.getDeclaredField(EnumMap.class, "keyType"); keyTypeFieldOffset = ReflectionUtils.getFieldOffset(field); } @@ -1054,7 +1035,7 @@ public static final class DefaultJavaMapSerializer extends MapSer private Serializer dataSerializer; public DefaultJavaMapSerializer(Fury fury, Class cls) { - super(fury, cls, false, false); + super(fury, cls, false); Preconditions.checkArgument( fury.getLanguage() == Language.JAVA, "Python default map serializer should use " + MapSerializer.class); @@ -1084,7 +1065,7 @@ public static class JDKCompatibleMapSerializer extends MapSeriali private final Serializer serializer; public JDKCompatibleMapSerializer(Fury fury, Class cls) { - super(fury, cls, false, false); + super(fury, cls, false); // Map which defined `writeReplace` may use this serializer, so check replace/resolve // is necessary. Class serializerType = diff --git a/java/fury-core/src/main/java/io/fury/serializer/SynchronizedSerializers.java b/java/fury-core/src/main/java/io/fury/serializer/SynchronizedSerializers.java index 94794e780a..cf6b5bdf24 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/SynchronizedSerializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/SynchronizedSerializers.java @@ -78,7 +78,7 @@ public static final class SynchronizedCollectionSerializer private final long offset; public SynchronizedCollectionSerializer(Fury fury, Class cls, Function factory, long offset) { - super(fury, cls, false, false); + super(fury, cls, false); this.factory = factory; this.offset = offset; } @@ -104,7 +104,7 @@ public static final class SynchronizedMapSerializer extends MapSerializer { private final long offset; public SynchronizedMapSerializer(Fury fury, Class cls, Function factory, long offset) { - super(fury, cls, false, false); + super(fury, cls, false); this.factory = factory; this.offset = offset; } diff --git a/java/fury-core/src/main/java/io/fury/serializer/UnmodifiableSerializers.java b/java/fury-core/src/main/java/io/fury/serializer/UnmodifiableSerializers.java index 7cd628c81d..a427471171 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/UnmodifiableSerializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/UnmodifiableSerializers.java @@ -74,7 +74,7 @@ public static final class UnmodifiableCollectionSerializer private final long offset; public UnmodifiableCollectionSerializer(Fury fury, Class cls, Function factory, long offset) { - super(fury, cls, false, false); + super(fury, cls, false); this.factory = factory; this.offset = offset; } @@ -98,7 +98,7 @@ public static final class UnmodifiableMapSerializer extends MapSerializers.MapSe private final long offset; public UnmodifiableMapSerializer(Fury fury, Class cls, Function factory, long offset) { - super(fury, cls, false, false); + super(fury, cls, false); this.factory = factory; this.offset = offset; } diff --git a/java/fury-core/src/test/java/io/fury/serializer/CollectionSerializersTest.java b/java/fury-core/src/test/java/io/fury/serializer/CollectionSerializersTest.java index 50bf0d6628..8458edfcaa 100644 --- a/java/fury-core/src/test/java/io/fury/serializer/CollectionSerializersTest.java +++ b/java/fury-core/src/test/java/io/fury/serializer/CollectionSerializersTest.java @@ -485,7 +485,7 @@ public void testJavaSerialization() { public static class SubListSerializer extends CollectionSerializers.CollectionSerializer { public SubListSerializer(Fury fury, Class cls) { - super(fury, cls, true, false); + super(fury, cls, true); } @Override