Skip to content

Commit

Permalink
feat(java): support jdk17+ record copy (#1741)
Browse files Browse the repository at this point in the history
## What does this PR do?

This PR supports jdk17+ record copy

## Related issues

#1739 
#1701 

Closes #1740

## Does this PR introduce any user-facing change?

<!--
If any user-facing interface changes, please [open an
issue](https://github.com/apache/fury/issues/new/choose) describing the
need to do so and update the document if necessary.
-->

- [ ] 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.
-->
  • Loading branch information
chaokunyang authored Jul 20, 2024
1 parent 5e0b8a9 commit eee6528
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,14 @@ public void testPrivateRecord(boolean codegen) {
}

private record PrivateRecord(String foo) {}

@Test(dataProvider = "codegen")
public void testCopy(boolean codegen) {
Fury fury = Fury.builder().withCodegen(codegen).build();
fury.register(Foo.class);
fury.register(PrivateRecord.class);
Assert.assertEquals(fury.copy(new PrivateRecord("foo")), new PrivateRecord("foo"));
Foo foo = new Foo(10, "abc", new ArrayList<>(Arrays.asList("a", "b")), 'x');
Assert.assertEquals(fury.copy(foo), foo);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.fury.Fury;
import org.apache.fury.collection.Tuple2;
import org.apache.fury.collection.Tuple3;
Expand All @@ -44,6 +46,7 @@
import org.apache.fury.type.FinalObjectTypeStub;
import org.apache.fury.type.GenericType;
import org.apache.fury.util.record.RecordComponent;
import org.apache.fury.util.record.RecordInfo;
import org.apache.fury.util.record.RecordUtils;

public abstract class AbstractObjectSerializer<T> extends Serializer<T> {
Expand All @@ -52,6 +55,7 @@ public abstract class AbstractObjectSerializer<T> extends Serializer<T> {
protected final boolean isRecord;
protected final MethodHandle constructor;
private InternalFieldInfo[] fieldInfos;
private RecordInfo copyRecordInfo;

public AbstractObjectSerializer(Fury fury, Class<T> type) {
this(
Expand All @@ -78,7 +82,9 @@ public T copy(T originObj) {
if (isRecord) {
Object[] fieldValues = copyFields(originObj);
try {
return (T) constructor.invokeWithArguments(fieldValues);
T t = (T) constructor.invokeWithArguments(fieldValues);
Arrays.fill(copyRecordInfo.getRecordComponents(), null);
return t;
} catch (Throwable e) {
Platform.throwException(e);
}
Expand Down Expand Up @@ -117,7 +123,7 @@ private Object[] copyFields(T originObj) {
fieldValues[i] = fury.copyObject(fieldValue, fieldInfo.classId);
}
}
return fieldValues;
return RecordUtils.remapping(copyRecordInfo, fieldValues);
}

private void copyFields(T originObj, T newObj) {
Expand Down Expand Up @@ -242,6 +248,13 @@ private InternalFieldInfo[] buildFieldsInfo() {
System.arraycopy(infos.f0.f0, 0, fieldInfos, 0, infos.f0.f0.length);
System.arraycopy(infos.f1, 0, fieldInfos, infos.f0.f0.length, infos.f1.length);
System.arraycopy(infos.f2, 0, fieldInfos, fieldInfos.length - infos.f2.length, infos.f2.length);
if (isRecord) {
List<String> fieldNames =
Arrays.stream(fieldInfos)
.map(f -> f.fieldAccessor.getField().getName())
.collect(Collectors.toList());
copyRecordInfo = new RecordInfo(type, fieldNames);
}
return fieldInfos;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,10 @@ public T read(MemoryBuffer buffer) {
if (isRecord) {
Object[] fieldValues = new Object[fieldResolver.getNumFields()];
readFields(buffer, fieldValues);
RecordUtils.remapping(recordInfo, fieldValues);
fieldValues = RecordUtils.remapping(recordInfo, fieldValues);
assert constructor != null;
try {
T t = (T) constructor.invokeWithArguments(recordInfo.getRecordComponents());
T t = (T) constructor.invokeWithArguments(fieldValues);
Arrays.fill(recordInfo.getRecordComponents(), null);
return t;
} catch (Throwable e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ public T read(MemoryBuffer buffer) {
Object[] fieldValues =
new Object[finalFields.length + otherFields.length + containerFields.length];
readFields(buffer, fieldValues);
RecordUtils.remapping(recordInfo, fieldValues);
fieldValues = RecordUtils.remapping(recordInfo, fieldValues);
try {
T t = (T) constructor.invokeWithArguments(recordInfo.getRecordComponents());
T t = (T) constructor.invokeWithArguments(fieldValues);
Arrays.fill(recordInfo.getRecordComponents(), null);
return t;
} catch (Throwable e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,9 @@ static void writeContainerFieldValue(
public T read(MemoryBuffer buffer) {
if (isRecord) {
Object[] fields = readFields(buffer);
RecordUtils.remapping(recordInfo, fields);
fields = RecordUtils.remapping(recordInfo, fields);
try {
T obj = (T) constructor.invokeWithArguments(recordInfo.getRecordComponents());
T obj = (T) constructor.invokeWithArguments(fields);
Arrays.fill(recordInfo.getRecordComponents(), null);
return obj;
} catch (Throwable e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ public static Map<String, Integer> buildFieldToComponentMapping(Class<?> cls) {
return recordComponentsIndex;
}

public static void remapping(RecordInfo recordInfo, Object[] fields) {
public static Object[] remapping(RecordInfo recordInfo, Object[] fields) {
int[] recordComponentsIndex = recordInfo.getRecordComponentsIndex();
Object[] recordComponents = recordInfo.getRecordComponents();
Object[] recordComponentsDefaultValues = recordInfo.getRecordComponentsDefaultValues();
Expand All @@ -291,5 +291,6 @@ public static void remapping(RecordInfo recordInfo, Object[] fields) {
recordComponents[i] = recordComponentsDefaultValues[i];
}
}
return recordComponents;
}
}

0 comments on commit eee6528

Please sign in to comment.