Skip to content

Commit 5b70810

Browse files
authored
fix(java): fix xlang register type by id (#2591)
<!-- **Thanks for contributing to Apache Fory™.** **If this is your first time opening a PR on fory, you can refer to [CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).** Contribution Checklist - The **Apache Fory™** community has requirements on the naming of pr titles. You can also find instructions in [CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md). - Apache Fory™ has a strong focus on performance. If the PR you submit will have an impact on performance, please benchmark it first and provide the benchmark result here. --> ## Why? <!-- Describe the purpose of this PR. --> ## What does this PR do? <!-- Describe the details of this PR. --> ## Related issues <!-- Is there any related issue? If this PR closes them you say say fix/closes: - #xxxx0 - #xxxx1 - Fixes #xxxx2 --> ## Does this PR introduce any user-facing change? <!-- If any user-facing interface changes, please [open an issue](https://github.com/apache/fory/issues/new/choose) describing the need to do so and update the document if necessary. Delete section if not applicable. --> - [ ] Does this PR introduce any public API change? - [ ] Does this PR introduce any binary protocol compatibility change? ## Benchmark <!-- When the PR has an impact on performance (if you don't know whether the PR will have an impact on performance, you can submit the PR first, and if it will have impact on performance, the code reviewer will explain it), be sure to attach a benchmark data here. Delete section if not applicable. -->
1 parent 4b1d113 commit 5b70810

4 files changed

Lines changed: 61 additions & 9 deletions

File tree

java/fory-core/src/main/java/org/apache/fory/resolver/XtypeResolver.java

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import java.util.concurrent.atomic.AtomicInteger;
5050
import java.util.concurrent.atomic.AtomicLong;
5151
import org.apache.fory.Fory;
52+
import org.apache.fory.annotation.Internal;
5253
import org.apache.fory.collection.IdentityMap;
5354
import org.apache.fory.collection.IdentityObjectIntMap;
5455
import org.apache.fory.collection.LongMap;
@@ -139,11 +140,10 @@ public void register(Class<?> type) {
139140
register(type, xtypeIdGenerator++);
140141
}
141142

142-
public void register(Class<?> type, int typeId) {
143+
public void register(Class<?> type, int userTypeId) {
143144
// ClassInfo[] has length of max type id. If the type id is too big, Fory will waste many
144-
// memory.
145-
// We can relax this limit in the future.
146-
Preconditions.checkArgument(typeId < MAX_TYPE_ID, "Too big type id %s", typeId);
145+
// memory. We can relax this limit in the future.
146+
Preconditions.checkArgument(userTypeId < MAX_TYPE_ID, "Too big type id %s", userTypeId);
147147
ClassInfo classInfo = classInfoMap.get(type);
148148
if (type.isArray()) {
149149
buildClassInfo(type);
@@ -165,7 +165,7 @@ public void register(Class<?> type, int typeId) {
165165
type, prevNamespace, prevTypeName));
166166
}
167167
}
168-
int xtypeId = typeId;
168+
int xtypeId = userTypeId;
169169
if (type.isEnum()) {
170170
xtypeId = (xtypeId << 8) + Types.ENUM;
171171
} else {
@@ -175,6 +175,8 @@ public void register(Class<?> type, int typeId) {
175175
} else {
176176
xtypeId = (xtypeId << 8) + Types.EXT;
177177
}
178+
} else {
179+
xtypeId = (xtypeId << 8) + Types.STRUCT;
178180
}
179181
}
180182
register(
@@ -242,6 +244,28 @@ private void register(
242244
xtypeIdToClassMap.put(xtypeId, classInfo);
243245
}
244246

247+
/**
248+
* Register type with given type id and serializer for type in fory type system.
249+
*
250+
* <p>Do not use this method to register custom type in java type system. Use {@link
251+
* #register(Class, String, String)} or {@link #register(Class, int)} instead.
252+
*
253+
* @param type type to register.
254+
* @param serializer serializer to register.
255+
* @param typeId type id to register.
256+
* @throws IllegalArgumentException if type id is too big.
257+
*/
258+
@Internal
259+
public void registerForyType(Class<?> type, Serializer serializer, int typeId) {
260+
Preconditions.checkArgument(typeId < MAX_TYPE_ID, "Too big type id %s", typeId);
261+
register(
262+
type,
263+
serializer,
264+
ReflectionUtils.getPackage(type),
265+
ReflectionUtils.getClassNameWithoutPackage(type),
266+
typeId);
267+
}
268+
245269
private boolean isStructType(Serializer serializer) {
246270
if (serializer instanceof ObjectSerializer || serializer instanceof GeneratedSerializer) {
247271
return true;

java/fory-core/src/test/java/org/apache/fory/CrossLanguageTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,21 @@ public void testSerializeSimpleStruct() throws Exception {
497497
structRoundBack(fory, obj2, "test_serialize_simple_struct");
498498
}
499499

500+
@Test
501+
public void testRegisterById() throws Exception {
502+
Fory fory =
503+
Fory.builder()
504+
.withLanguage(Language.XLANG)
505+
.withRefTracking(true)
506+
.requireClassRegistration(false)
507+
.build();
508+
fory.register(ComplexObject2.class, 100);
509+
ComplexObject2 obj2 = new ComplexObject2();
510+
obj2.f1 = true;
511+
obj2.f2 = new HashMap<>(ImmutableMap.of((byte) -1, 2));
512+
structRoundBack(fory, obj2, "test_register_by_id");
513+
}
514+
500515
public void testSerializeComplexStruct() throws Exception {
501516
Fory fory =
502517
Fory.builder()

java/fory-format/src/main/java/org/apache/fory/format/vectorized/ArrowSerializers.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.apache.fory.memory.MemoryBuffer;
3838
import org.apache.fory.memory.MemoryUtils;
3939
import org.apache.fory.memory.Platform;
40+
import org.apache.fory.resolver.XtypeResolver;
4041
import org.apache.fory.serializer.BufferObject;
4142
import org.apache.fory.serializer.Serializers.CrossLanguageCompatibleSerializer;
4243
import org.apache.fory.type.Types;
@@ -167,10 +168,14 @@ public MemoryBuffer toBuffer() {
167168

168169
public static void registerSerializers(Fory fory) {
169170
if (fory.isCrossLanguage()) {
170-
fory.register(ArrowTable.class, Types.ARROW_TABLE);
171-
fory.register(VectorSchemaRoot.class, Types.ARROW_RECORD_BATCH);
171+
XtypeResolver resolver = fory.getXtypeResolver();
172+
resolver.registerForyType(
173+
ArrowTable.class, new ArrowTableSerializer(fory), Types.ARROW_TABLE);
174+
resolver.registerForyType(
175+
VectorSchemaRoot.class, new VectorSchemaRootSerializer(fory), Types.ARROW_RECORD_BATCH);
176+
} else {
177+
fory.registerSerializer(ArrowTable.class, new ArrowTableSerializer(fory));
178+
fory.registerSerializer(VectorSchemaRoot.class, new VectorSchemaRootSerializer(fory));
172179
}
173-
fory.registerSerializer(ArrowTable.class, new ArrowTableSerializer(fory));
174-
fory.registerSerializer(VectorSchemaRoot.class, new VectorSchemaRootSerializer(fory));
175180
}
176181
}

python/pyfory/tests/test_cross_language.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,14 @@ def test_serialize_simple_struct(data_file_path):
462462
struct_round_back(data_file_path, fory, obj)
463463

464464

465+
@cross_language_test
466+
def test_register_by_id(data_file_path):
467+
fory = pyfory.Fory(language=pyfory.Language.XLANG, ref_tracking=True)
468+
fory.register_type(ComplexObject2, type_id=100)
469+
obj = ComplexObject2(f1=True, f2={-1: 2})
470+
struct_round_back(data_file_path, fory, obj)
471+
472+
465473
class SomeClass:
466474
f1: "SomeClass"
467475
f2: Dict[str, str]

0 commit comments

Comments
 (0)