Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(java): Type annotation hints for serialization(WIP) #2036

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Prev Previous commit
Next Next commit
mvn spotless
hening committed Feb 7, 2025
commit 6df98e9edbb0f3cd623ec2205b84aa8ad749f550
46 changes: 46 additions & 0 deletions java/fury-core/src/main/java/org/apache/fury/Fury.java
Original file line number Diff line number Diff line change
@@ -462,6 +462,29 @@ public <T> void writeRef(MemoryBuffer buffer, T obj, Serializer<T> serializer) {
}
}

public <T> void writeRefNullable(
MemoryBuffer buffer, T obj, Serializer<T> serializer, boolean nullable) {
if (serializer.needToWriteRef()) {
if (!refResolver.writeRefOrNull(buffer, obj)) {
depth++;
serializer.write(buffer, obj);
depth--;
}
} else {
if (nullable) {
if (obj == null) {
buffer.writeByte(Fury.NULL_FLAG);
return;
} else {
buffer.writeByte(Fury.NOT_NULL_VALUE_FLAG);
}
}
depth++;
serializer.write(buffer, obj);
depth--;
}
}

/** Write object class and data without tracking ref. */
public void writeNullable(MemoryBuffer buffer, Object obj) {
if (obj == null) {
@@ -961,6 +984,29 @@ public <T> T readRef(MemoryBuffer buffer, Serializer<T> serializer) {
}
}

@SuppressWarnings("unchecked")
public <T> T readRefNullable(MemoryBuffer buffer, Serializer<T> serializer, boolean nullable) {
if (serializer.needToWriteRef()) {
T obj;
int nextReadRefId = refResolver.tryPreserveRefId(buffer);
if (nextReadRefId >= NOT_NULL_VALUE_FLAG) {
obj = serializer.read(buffer);
refResolver.setReadObject(nextReadRefId, obj);
return obj;
} else {
return (T) refResolver.getReadObject();
}
} else {
if (nullable) {
byte headFlag = buffer.readByte();
if (headFlag == Fury.NULL_FLAG) {
return null;
}
}
return serializer.read(buffer);
}
}

/** Deserialize not-null and non-reference object from <code>buffer</code>. */
public Object readNonRef(MemoryBuffer buffer) {
return readDataInternal(buffer, classResolver.readClassInfo(buffer));
Original file line number Diff line number Diff line change
@@ -141,7 +141,8 @@ private void readAndWriteFieldValue(
} else {
ClassInfo classInfo = fieldInfo.getClassInfo(classId);
Serializer<Object> serializer = classInfo.getSerializer();
fury.writeRef(buffer, fieldValue, serializer);
fury.writeRefNullable(
buffer, fieldValue, serializer, fieldInfo.getFuryFieldAnnotationInfo().nullable);
}
}
}
@@ -181,7 +182,8 @@ private void writeFieldValue(
buffer.writeFloat64((Double) fieldValue);
return;
case ClassResolver.STRING_CLASS_ID:
fury.writeJavaStringRef(buffer, (String) fieldValue);
fury.writeJavaStringRef(
buffer, (String) fieldValue, fieldInfo.getFuryFieldAnnotationInfo().nullable);
break;
case ClassResolver.NO_CLASS_ID: // SEPARATE_TYPES_HASH
writeSeparateFieldValue(fieldInfo, buffer, fieldValue);
@@ -190,7 +192,8 @@ private void writeFieldValue(
{
ClassInfo classInfo = fieldInfo.getClassInfo(classId);
Serializer<Object> serializer = classInfo.getSerializer();
fury.writeRef(buffer, fieldValue, serializer);
fury.writeRefNullable(
buffer, fieldValue, serializer, fieldInfo.getFuryFieldAnnotationInfo().nullable);
}
}
}
@@ -580,7 +583,10 @@ private void readAndSetFieldValue(
} else {
ClassInfo classInfo = fieldInfo.getClassInfo(classId);
Serializer<Object> serializer = classInfo.getSerializer();
fieldAccessor.putObject(targetObject, fury.readRef(buffer, serializer));
fieldAccessor.putObject(
targetObject,
fury.readRefNullable(
buffer, serializer, fieldInfo.getFuryFieldAnnotationInfo().nullable));
}
}
}
@@ -610,14 +616,15 @@ private Object readFieldValue(FieldResolver.FieldInfo fieldInfo, MemoryBuffer bu
case ClassResolver.PRIMITIVE_DOUBLE_CLASS_ID:
return buffer.readFloat64();
case ClassResolver.STRING_CLASS_ID:
return fury.readJavaStringRef(buffer);
return fury.readJavaStringRef(buffer, fieldInfo.getFuryFieldAnnotationInfo().nullable);
case ClassResolver.NO_CLASS_ID:
return fieldResolver.readObjectField(buffer, fieldInfo);
default:
{
ClassInfo classInfo = fieldInfo.getClassInfo(classId);
Serializer<Object> serializer = classInfo.getSerializer();
return fury.readRef(buffer, serializer);
return fury.readRefNullable(
buffer, serializer, fieldInfo.getFuryFieldAnnotationInfo().nullable);
}
}
}

Unchanged files with check annotations Beta

name: Rust CI
strategy:
matrix:
os: [ubuntu-latest, macos-13, macos-14] # macos-13: x86, macos-14: arm64

Check warning on line 188 in .github/workflows/ci.yml

GitHub Actions / 🍏 YAML

188:49 [comments] too few spaces before comment
runs-on: ${{ matrix.os }}
timeout-minutes: 45
steps:
name: C++ CI
strategy:
matrix:
os: [ubuntu-latest, macos-13, macos-14, windows-2022] # macos-13: x86, macos-14: arm64

Check warning on line 204 in .github/workflows/ci.yml

GitHub Actions / 🍏 YAML

204:63 [comments] too few spaces before comment
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
if: github.repository == 'apache/fury'
environment:
name: pypi
url: https://pypi.org/project/pyfury

Check warning on line 32 in .github/workflows/release.yaml

GitHub Actions / 🍏 YAML

32:63 [comments] too few spaces before comment
strategy:
matrix:
python-version: [3.8, 3.9, 3.10.12, 3.11, 3.12]