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

[Java] Add string serializer #90

Merged
merged 3 commits into from
May 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions java/fury-core/src/main/java/io/fury/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ public class Config implements Serializable {
private final Language language;
private final boolean referenceTracking;
private final boolean basicTypesReferenceIgnored;
private final boolean stringReferenceIgnored;
private final boolean compressNumber;
private final boolean compressString;
private final boolean secureModeEnabled;
private final boolean classRegistrationRequired;
private transient int configHash;
Expand All @@ -60,7 +62,9 @@ public class Config implements Serializable {
language = builder.language;
referenceTracking = builder.referenceTracking;
basicTypesReferenceIgnored = !referenceTracking || builder.basicTypesReferenceIgnored;
stringReferenceIgnored = !referenceTracking || builder.stringReferenceIgnored;
compressNumber = builder.compressNumber;
compressString = builder.compressString;
secureModeEnabled = builder.secureModeEnabled;
classRegistrationRequired = builder.requireClassRegistration;
}
Expand All @@ -77,10 +81,18 @@ public boolean isBasicTypesReferenceIgnored() {
return basicTypesReferenceIgnored;
}

public boolean isStringReferenceIgnored() {
return stringReferenceIgnored;
}

public boolean compressNumber() {
return compressNumber;
}

public boolean compressString() {
return compressString;
}

public boolean isClassRegistrationRequired() {
return classRegistrationRequired;
}
Expand Down
27 changes: 25 additions & 2 deletions java/fury-core/src/main/java/io/fury/Fury.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import io.fury.serializer.OpaqueObjects;
import io.fury.serializer.Serializer;
import io.fury.serializer.SerializerFactory;
import io.fury.serializer.StringSerializer;
import io.fury.type.Generics;
import io.fury.type.Type;
import io.fury.util.LoggerFactory;
Expand Down Expand Up @@ -88,6 +89,7 @@ public final class Fury {

private final MemoryBuffer buffer;
private final List<Object> nativeObjects;
private final StringSerializer stringSerializer;
private final Language language;
private final boolean compressNumber;
private final Generics generics;
Expand Down Expand Up @@ -117,6 +119,7 @@ private Fury(FuryBuilder builder, ClassLoader classLoader) {
buffer = MemoryUtils.buffer(32);
nativeObjects = new ArrayList<>();
generics = new Generics(this);
stringSerializer = new StringSerializer(this);
LOG.info("Created new fury {}", this);
}

Expand Down Expand Up @@ -462,7 +465,8 @@ private void writeData(MemoryBuffer buffer, ClassInfo classInfo, Object obj) {
buffer.writeDouble((Double) obj);
break;
case ClassResolver.STRING_CLASS_ID:
throw new UnsupportedOperationException();
stringSerializer.writeJavaString(buffer, (String) obj);
break;
// TODO(add fastpath for other types)
default:
depth++;
Expand Down Expand Up @@ -683,7 +687,7 @@ private Object readData(MemoryBuffer buffer, ClassInfo classInfo) {
case ClassResolver.DOUBLE_CLASS_ID:
return buffer.readDouble();
case ClassResolver.STRING_CLASS_ID:
throw new UnsupportedOperationException();
return stringSerializer.readJavaString(buffer);
// TODO(add fastpath for other types)
default:
depth++;
Expand Down Expand Up @@ -855,6 +859,10 @@ public boolean trackingReference() {
return referenceTracking;
}

public boolean isStringReferenceIgnored() {
return config.isStringReferenceIgnored();
}

public boolean isBasicTypesReferenceIgnored() {
return config.isBasicTypesReferenceIgnored();
}
Expand All @@ -863,6 +871,10 @@ public Config getConfig() {
return config;
}

public boolean compressString() {
return config.compressString();
}

public boolean compressNumber() {
return compressNumber;
}
Expand Down Expand Up @@ -897,6 +909,7 @@ public static final class FuryBuilder {
boolean timeReferenceIgnored = true;
ClassLoader classLoader;
boolean compressNumber = false;
boolean compressString = true;
boolean secureModeEnabled = true;
boolean requireClassRegistration = true;

Expand All @@ -917,12 +930,22 @@ public FuryBuilder ignoreBasicTypesReference(boolean ignoreBasicTypesReference)
return this;
}

public FuryBuilder ignoreStringReference(boolean ignoreStringReference) {
this.stringReferenceIgnored = ignoreStringReference;
return this;
}

/** Use variable length encoding for int/long. */
public FuryBuilder withNumberCompressed(boolean compressNumber) {
this.compressNumber = compressNumber;
return this;
}

public FuryBuilder withStringCompressed(boolean compressString) {
this.compressString = compressString;
return this;
}

public FuryBuilder withClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import io.fury.serializer.Serializer;
import io.fury.serializer.SerializerFactory;
import io.fury.serializer.Serializers;
import io.fury.serializer.StringSerializer;
import io.fury.type.TypeUtils;
import io.fury.util.Functions;
import io.fury.util.LoggerFactory;
Expand Down Expand Up @@ -219,6 +220,8 @@ private void addDefaultSerializers() {
addDefaultSerializer(Long.class, new Serializers.LongSerializer(fury, Long.class));
addDefaultSerializer(Float.class, new Serializers.FloatSerializer(fury, Float.class));
addDefaultSerializer(Double.class, new Serializers.DoubleSerializer(fury, Double.class));
addDefaultSerializer(String.class, new StringSerializer(fury));
addDefaultSerializer(String[].class, new Serializers.StringArraySerializer(fury));
addDefaultSerializer(Class.class, new Serializers.ClassSerializer(fury));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,78 @@ public Double read(MemoryBuffer buffer) {
}
}

public static final class StringArraySerializer extends Serializer<String[]> {
private final StringSerializer stringSerializer;

public StringArraySerializer(Fury fury) {
super(fury, String[].class);
stringSerializer = new StringSerializer(fury);
}

@Override
public short getCrossLanguageTypeId() {
return (short) -Type.FURY_STRING_ARRAY.getId();
}

@Override
public void write(MemoryBuffer buffer, String[] value) {
int len = value.length;
buffer.writeInt(len);
for (String elem : value) {
// TODO reference support
if (elem != null) {
buffer.writeByte(Fury.REF_VALUE_FLAG);
stringSerializer.writeJavaString(buffer, elem);
} else {
buffer.writeByte(Fury.NULL_FLAG);
}
}
}

@Override
public String[] read(MemoryBuffer buffer) {
int numElements = buffer.readInt();
String[] value = new String[numElements];
fury.getReferenceResolver().reference(value);
for (int i = 0; i < numElements; i++) {
if (buffer.readByte() == Fury.REF_VALUE_FLAG) {
value[i] = stringSerializer.readJavaString(buffer);
} else {
value[i] = null;
}
}
return value;
}

@Override
public void crossLanguageWrite(MemoryBuffer buffer, String[] value) {
int len = value.length;
buffer.writeInt(len);
for (String elem : value) {
if (elem != null) {
buffer.writeByte(Fury.REF_VALUE_FLAG);
stringSerializer.writeUTF8String(buffer, elem);
} else {
buffer.writeByte(Fury.NULL_FLAG);
}
}
}

@Override
public String[] crossLanguageRead(MemoryBuffer buffer) {
int numElements = buffer.readInt();
String[] value = new String[numElements];
for (int i = 0; i < numElements; i++) {
if (buffer.readByte() == Fury.REF_VALUE_FLAG) {
value[i] = stringSerializer.readUTF8String(buffer);
} else {
value[i] = null;
}
}
return value;
}
}

public static final class ClassSerializer extends Serializer<Class> {
private static final byte USE_CLASS_ID = 0;
private static final byte USE_CLASSNAME = 1;
Expand Down
Loading