From 7db00263edcb5040725031ce259a2c0e67435be8 Mon Sep 17 00:00:00 2001 From: pandalee99 <1162953505@qq.com> Date: Mon, 11 Sep 2023 16:20:11 +0800 Subject: [PATCH 01/14] Optimize StringBuilder/StringBuffer serialization --- .../java/io/fury/serializer/Serializers.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index bcf55fd27b..8ddc7713cf 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -420,12 +420,21 @@ public StringBuilderSerializer(Fury fury) { @Override public void write(MemoryBuffer buffer, StringBuilder value) { - stringSerializer.writeJavaString(buffer, value.toString()); + int length = value.length(); + buffer.writeInt(length); + for (int i = 0; i < length; i++) { + buffer.writeChar(value.charAt(i)); + } } @Override public StringBuilder read(MemoryBuffer buffer) { - return new StringBuilder(stringSerializer.readJavaString(buffer)); + int length = buffer.readInt(); + StringBuilder stringBuilder = new StringBuilder(length); + for (int i = 0; i < length; i++) { + stringBuilder.append(buffer.readChar()); + } + return stringBuilder; } } @@ -444,7 +453,11 @@ public short getXtypeId() { @Override public void write(MemoryBuffer buffer, StringBuffer value) { - stringSerializer.writeJavaString(buffer, value.toString()); + int length = value.length(); + buffer.writeInt(length); + for (int i = 0; i < length; i++) { + buffer.writeChar(value.charAt(i)); + } } @Override @@ -454,7 +467,12 @@ public void xwrite(MemoryBuffer buffer, StringBuffer value) { @Override public StringBuffer read(MemoryBuffer buffer) { - return new StringBuffer(stringSerializer.readJavaString(buffer)); + int length = buffer.readInt(); + StringBuffer stringBuffer = new StringBuffer(length); + for (int i = 0; i < length; i++) { + stringBuffer.append(buffer.readChar()); + } + return stringBuffer; } @Override From de3ff1a615af1f6af7def63ff2dcff24969da2da Mon Sep 17 00:00:00 2001 From: pandalee99 <1162953505@qq.com> Date: Mon, 18 Sep 2023 10:48:54 +0800 Subject: [PATCH 02/14] try to optimize StringBuilder --- .../java/io/fury/serializer/Serializers.java | 13 +- .../io/fury/serializer/StringSerializer.java | 114 +++++++++++++++++- 2 files changed, 115 insertions(+), 12 deletions(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index 8ddc7713cf..b8a6f90e60 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -420,21 +420,12 @@ public StringBuilderSerializer(Fury fury) { @Override public void write(MemoryBuffer buffer, StringBuilder value) { - int length = value.length(); - buffer.writeInt(length); - for (int i = 0; i < length; i++) { - buffer.writeChar(value.charAt(i)); - } + stringSerializer.writeJavaStringBuilder(buffer, value); } @Override public StringBuilder read(MemoryBuffer buffer) { - int length = buffer.readInt(); - StringBuilder stringBuilder = new StringBuilder(length); - for (int i = 0; i < length; i++) { - stringBuilder.append(buffer.readChar()); - } - return stringBuilder; + return stringSerializer.readJavaStringBuilder(buffer); } } diff --git a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java index 4b72b5f16a..3ebe31b141 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java +++ b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java @@ -299,7 +299,6 @@ public void writeJavaString(MemoryBuffer buffer, String value) { } } } - public static boolean isAscii(char[] chars) { int numChars = chars.length; int vectorizedLen = numChars >> 2; @@ -705,4 +704,117 @@ public String readUTF8String(MemoryBuffer buffer) { return new String(tmpArray, 0, numBytes, StandardCharsets.UTF_8); } } + + public void writeJavaStringBuilder(MemoryBuffer buffer, StringBuilder value) { + if (isJDK8StringBuilder()) { + writeJDK8StringBuilder(buffer, value); + } else { + writeJDK9PlusStringBuilder(buffer, value); + } + } + + private void writeJDK8StringBuilder(MemoryBuffer buffer, StringBuilder value) { + int length = value.length(); + buffer.writePositiveVarInt(length); + buffer.ensure(buffer.writerIndex() + length); + byte[] targetArray = buffer.getHeapMemory(); + int writerIndex = buffer.writerIndex(); + if (targetArray != null) { + int arrIndex = buffer.unsafeHeapWriterIndex(); + for (int i = 0; i < length; i++) { + targetArray[arrIndex + i] = (byte) value.charAt(i); + } + buffer.unsafeWriterIndex(writerIndex + length); + } else { + for (int i = 0; i < length; i++) { + buffer.unsafePut(writerIndex++, (byte) value.charAt(i)); + } + buffer.unsafeWriterIndex(writerIndex); + } + } + + private void writeJDK9PlusStringBuilder(MemoryBuffer buffer, StringBuilder value) { + byte[] bytes = getJDK9PlusInternalByteArray(value); + int bytesLen = bytes.length; + buffer.ensure(buffer.writerIndex() + 9 + bytesLen); + byte[] targetArray = buffer.getHeapMemory(); + if (targetArray != null) { + int targetIndex = buffer.unsafeHeapWriterIndex(); + int arrIndex = targetIndex; + targetArray[arrIndex++] = 0; + arrIndex += MemoryUtils.writePositiveVarInt(targetArray, arrIndex, bytesLen); + System.arraycopy(bytes, 0, targetArray, arrIndex, bytesLen); + buffer.unsafeWriterIndex(buffer.writerIndex() + arrIndex - targetIndex + bytesLen); + } else { + buffer.unsafePut(buffer.writerIndex(), (byte) 0); + buffer.unsafePutPositiveVarInt(buffer.writerIndex() + 1, bytesLen); + long offHeapAddress = buffer.getUnsafeAddress(); + Platform.copyMemory(bytes, Platform.BYTE_ARRAY_OFFSET, null, offHeapAddress + buffer.writerIndex() + 9, + bytesLen); + buffer.unsafeWriterIndex(buffer.writerIndex() + 9 + bytesLen); + } + } + + private byte[] getJDK9PlusInternalByteArray(StringBuilder sb) { + try { + Field valueField = StringBuilder.class.getDeclaredField("value"); + valueField.setAccessible(true); + char[] charArray = (char[]) valueField.get(sb); + byte[] byteArray = new byte[charArray.length * 2]; + for (int i = 0, j = 0; i < charArray.length; i++) { + char ch = charArray[i]; + byteArray[j++] = (byte) (ch >> 8); + byteArray[j++] = (byte) ch; + } + return byteArray; + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public StringBuilder readJavaStringBuilder(MemoryBuffer buffer) { + if (isJDK8StringBuilder()) { + return readJDK8StringBuilder(buffer); + } else { + return readJDK9PlusStringBuilder(buffer); + } + } + + private StringBuilder readJDK8StringBuilder(MemoryBuffer buffer) { + int length = buffer.readPositiveVarInt(); + StringBuilder sb = new StringBuilder(length); + byte[] targetArray = buffer.getHeapMemory(); + if (targetArray != null) { + int arrIndex = buffer.readerIndex(); + for (int i = 0; i < length; i++) { + sb.append((char) (targetArray[arrIndex++] & 0xFF)); + } + buffer.readerIndex(arrIndex); + } else { + for (int i = 0; i < length; i++) { + sb.append((char) (buffer.readByte() & 0xFF)); + } + } + return sb; + } + + private StringBuilder readJDK9PlusStringBuilder(MemoryBuffer buffer) { + int length = buffer.readInt(); + byte[] bytes = new byte[length]; + buffer.readBytes(bytes); + return new StringBuilder(new String(bytes, StandardCharsets.UTF_8)); + } + + public boolean isJDK8StringBuilder() { + String version = System.getProperty("java.version"); + if (version.startsWith("1.")) { + version = version.substring(2, 3); + } else { + int dot = version.indexOf("."); + if (dot != -1) { + version = version.substring(0, dot); + } + } + return Integer.parseInt(version) == 8; + } } From 5d439c204a661659f5f54f33e46f26587d4f9b32 Mon Sep 17 00:00:00 2001 From: pankoli Date: Fri, 22 Sep 2023 10:55:07 +0800 Subject: [PATCH 03/14] first to Check code Style --- .../java/io/fury/serializer/Serializers.java | 62 ++++++++++++++++--- .../io/fury/serializer/StringSerializer.java | 54 +++++++--------- 2 files changed, 79 insertions(+), 37 deletions(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index b8a6f90e60..4466d3ce63 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -19,11 +19,14 @@ import com.google.common.base.Preconditions; import com.google.common.primitives.Primitives; import io.fury.Fury; +import io.fury.collection.Tuple2; import io.fury.memory.MemoryBuffer; import io.fury.resolver.ClassResolver; import io.fury.type.Type; import io.fury.util.Platform; import io.fury.util.Utils; +import io.fury.util.function.Functions; +import io.fury.util.function.ToByteFunction; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; @@ -37,6 +40,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import java.util.regex.Pattern; /** @@ -410,22 +414,66 @@ public Double read(MemoryBuffer buffer) { } } - public static final class StringBuilderSerializer extends Serializer { - private final StringSerializer stringSerializer; + static Tuple2 builderCache; + + private static synchronized Tuple2 getBuilderFunc() { + if (builderCache == null) { + Function getValue = + (Function) Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getValue"); + if (Platform.JAVA_VERSION > 8) { + ToByteFunction getCoder = + (ToByteFunction) + Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getCoder"); + builderCache = Tuple2.of(getCoder, getValue); + } else { + builderCache = Tuple2.of(null, getValue); + } + } + return builderCache; + } - public StringBuilderSerializer(Fury fury) { - super(fury, StringBuilder.class); + public abstract static class AbstractStringBuilderSerializer extends Serializer { + protected final ToByteFunction getCoder; + protected final Function getValue; + protected final StringSerializer stringSerializer; + + public AbstractStringBuilderSerializer(Fury fury, Class type) { + super(fury, type); + Tuple2 builderFunc = getBuilderFunc(); + getCoder = builderFunc.f0; + getValue = builderFunc.f1; stringSerializer = new StringSerializer(fury); } @Override - public void write(MemoryBuffer buffer, StringBuilder value) { - stringSerializer.writeJavaStringBuilder(buffer, value); + public void write(MemoryBuffer buffer, T value) { + if (Platform.JAVA_VERSION > 8) { + byte coder = getCoder.applyAsByte(value); + byte[] v = (byte[]) getValue.apply(value); + buffer.writeByte(coder); + buffer.writePositiveVarInt(v.length); + buffer.writeBytes(v, 0, v.length); + } else { + char[] v = (char[]) getValue.apply(value); + if (StringSerializer.isAscii(v)) { + stringSerializer.writeJDK8Ascii(buffer, v); + } else { + stringSerializer.writeJDK8UTF16(buffer, v); + } + } + } + } + + public static final class StringBuilderSerializer + extends AbstractStringBuilderSerializer { + + public StringBuilderSerializer(Fury fury) { + super(fury, StringBuilder.class); } @Override public StringBuilder read(MemoryBuffer buffer) { - return stringSerializer.readJavaStringBuilder(buffer); + return new StringBuilder(stringSerializer.readJavaString(buffer)); } } diff --git a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java index 3ebe31b141..bca0c750bd 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java +++ b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java @@ -299,6 +299,7 @@ public void writeJavaString(MemoryBuffer buffer, String value) { } } } + public static boolean isAscii(char[] chars) { int numChars = chars.length; int vectorizedLen = numChars >> 2; @@ -706,7 +707,7 @@ public String readUTF8String(MemoryBuffer buffer) { } public void writeJavaStringBuilder(MemoryBuffer buffer, StringBuilder value) { - if (isJDK8StringBuilder()) { + if (Platform.JAVA_VERSION <= 8) { writeJDK8StringBuilder(buffer, value); } else { writeJDK9PlusStringBuilder(buffer, value); @@ -734,8 +735,14 @@ private void writeJDK8StringBuilder(MemoryBuffer buffer, StringBuilder value) { } private void writeJDK9PlusStringBuilder(MemoryBuffer buffer, StringBuilder value) { - byte[] bytes = getJDK9PlusInternalByteArray(value); - int bytesLen = bytes.length; + byte[] bytes = null; + if (value != null) { + bytes = getJDK9PlusInternalByteArray(value); + } + int bytesLen = 0; + if (bytes != null) { + bytesLen = bytes.length; + } buffer.ensure(buffer.writerIndex() + 9 + bytesLen); byte[] targetArray = buffer.getHeapMemory(); if (targetArray != null) { @@ -743,37 +750,36 @@ private void writeJDK9PlusStringBuilder(MemoryBuffer buffer, StringBuilder value int arrIndex = targetIndex; targetArray[arrIndex++] = 0; arrIndex += MemoryUtils.writePositiveVarInt(targetArray, arrIndex, bytesLen); - System.arraycopy(bytes, 0, targetArray, arrIndex, bytesLen); + if (bytes != null) { + System.arraycopy(bytes, 0, targetArray, arrIndex, bytesLen); + } buffer.unsafeWriterIndex(buffer.writerIndex() + arrIndex - targetIndex + bytesLen); } else { buffer.unsafePut(buffer.writerIndex(), (byte) 0); buffer.unsafePutPositiveVarInt(buffer.writerIndex() + 1, bytesLen); long offHeapAddress = buffer.getUnsafeAddress(); - Platform.copyMemory(bytes, Platform.BYTE_ARRAY_OFFSET, null, offHeapAddress + buffer.writerIndex() + 9, - bytesLen); + Platform.copyMemory( + bytes, + Platform.BYTE_ARRAY_OFFSET, + null, + offHeapAddress + buffer.writerIndex() + 9, + bytesLen); buffer.unsafeWriterIndex(buffer.writerIndex() + 9 + bytesLen); } } private byte[] getJDK9PlusInternalByteArray(StringBuilder sb) { try { - Field valueField = StringBuilder.class.getDeclaredField("value"); + Field valueField = sb.getClass().getSuperclass().getDeclaredField("value"); valueField.setAccessible(true); - char[] charArray = (char[]) valueField.get(sb); - byte[] byteArray = new byte[charArray.length * 2]; - for (int i = 0, j = 0; i < charArray.length; i++) { - char ch = charArray[i]; - byteArray[j++] = (byte) (ch >> 8); - byteArray[j++] = (byte) ch; - } - return byteArray; + return (byte[]) valueField.get(sb); } catch (NoSuchFieldException | IllegalAccessException e) { throw new RuntimeException(e); } } public StringBuilder readJavaStringBuilder(MemoryBuffer buffer) { - if (isJDK8StringBuilder()) { + if (Platform.JAVA_VERSION <= 8) { return readJDK8StringBuilder(buffer); } else { return readJDK9PlusStringBuilder(buffer); @@ -799,22 +805,10 @@ private StringBuilder readJDK8StringBuilder(MemoryBuffer buffer) { } private StringBuilder readJDK9PlusStringBuilder(MemoryBuffer buffer) { - int length = buffer.readInt(); + byte coder = buffer.readByte(); + int length = buffer.readPositiveVarInt(); byte[] bytes = new byte[length]; buffer.readBytes(bytes); return new StringBuilder(new String(bytes, StandardCharsets.UTF_8)); } - - public boolean isJDK8StringBuilder() { - String version = System.getProperty("java.version"); - if (version.startsWith("1.")) { - version = version.substring(2, 3); - } else { - int dot = version.indexOf("."); - if (dot != -1) { - version = version.substring(0, dot); - } - } - return Integer.parseInt(version) == 8; - } } From e05a2549eb2c89990d697b3aef9abb98fd42fff7 Mon Sep 17 00:00:00 2001 From: pandalee99 <1162953505@qq.com> Date: Fri, 22 Sep 2023 11:45:34 +0800 Subject: [PATCH 04/14] hidden --- .../java/io/fury/serializer/Serializers.java | 123 +++++++++------- .../io/fury/serializer/StringSerializer.java | 132 +++++++++--------- 2 files changed, 139 insertions(+), 116 deletions(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index 4466d3ce63..4e0029bbd9 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -29,6 +29,7 @@ import io.fury.util.function.ToByteFunction; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; @@ -414,61 +415,83 @@ public Double read(MemoryBuffer buffer) { } } - static Tuple2 builderCache; - - private static synchronized Tuple2 getBuilderFunc() { - if (builderCache == null) { - Function getValue = - (Function) Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getValue"); - if (Platform.JAVA_VERSION > 8) { - ToByteFunction getCoder = - (ToByteFunction) - Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getCoder"); - builderCache = Tuple2.of(getCoder, getValue); - } else { - builderCache = Tuple2.of(null, getValue); - } - } - return builderCache; - } + static Tuple2 builderCache; - public abstract static class AbstractStringBuilderSerializer extends Serializer { - protected final ToByteFunction getCoder; - protected final Function getValue; - protected final StringSerializer stringSerializer; - - public AbstractStringBuilderSerializer(Fury fury, Class type) { - super(fury, type); - Tuple2 builderFunc = getBuilderFunc(); - getCoder = builderFunc.f0; - getValue = builderFunc.f1; - stringSerializer = new StringSerializer(fury); - } + private static synchronized Tuple2 getBuilderFunc() { + if (builderCache == null) { + Function getValue = + (Function) Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getValue"); + if (Platform.JAVA_VERSION > 8) { + ToByteFunction getCoder = + (ToByteFunction) + Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getCoder"); + builderCache = Tuple2.of(getCoder, getValue); + } else { + builderCache = Tuple2.of(null, getValue); + } + } + return builderCache; + } - @Override - public void write(MemoryBuffer buffer, T value) { - if (Platform.JAVA_VERSION > 8) { - byte coder = getCoder.applyAsByte(value); - byte[] v = (byte[]) getValue.apply(value); - buffer.writeByte(coder); - buffer.writePositiveVarInt(v.length); - buffer.writeBytes(v, 0, v.length); - } else { - char[] v = (char[]) getValue.apply(value); - if (StringSerializer.isAscii(v)) { - stringSerializer.writeJDK8Ascii(buffer, v); - } else { - stringSerializer.writeJDK8UTF16(buffer, v); + public abstract static class AbstractStringBuilderSerializer extends Serializer { + protected final ToByteFunction getCoder; + protected final Function getValue; + protected final StringSerializer stringSerializer; + + public AbstractStringBuilderSerializer(Fury fury, Class type) { + super(fury, type); + Tuple2 builderFunc = getBuilderFunc(); + getCoder = builderFunc.f0; + getValue = builderFunc.f1; + stringSerializer = new StringSerializer(fury); + } + + @Override + public void write(MemoryBuffer buffer, T value) { + if (Platform.JAVA_VERSION > 8) { + byte[] v = new byte[0]; + byte coder = getCoder.applyAsByte(value); + try { + Method getValueMethod = StringBuilder.class.getSuperclass().getDeclaredMethod("getVCoder"); + getValueMethod.setAccessible(true); + Object valueArray = getValueMethod.invoke(value); + v = (byte[]) valueArray; + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + if (v.length==0){return;} + buffer.writeByte(coder); + buffer.writePositiveVarInt(v.length); + buffer.writeBytes(v, 0, v.length); + } else { + char[] v = new char[0]; + try { + StringBuilder sb = (StringBuilder) value; + int len = sb.length(); + v = new char[len]; + Method getCharsMethod = StringBuilder.class.getSuperclass().getDeclaredMethod("getChars", int.class, int.class, char[].class, int.class); + getCharsMethod.setAccessible(true); + getCharsMethod.invoke(sb, 0, len, v, 0); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + if (v.length == 0) { + return; + } + if (StringSerializer.isAscii(v)) { + stringSerializer.writeJDK8Ascii(buffer, v); + } else { + stringSerializer.writeJDK8UTF16(buffer, v); + } + } + } } - } - } - } - public static final class StringBuilderSerializer - extends AbstractStringBuilderSerializer { + public static final class StringBuilderSerializer + extends AbstractStringBuilderSerializer { - public StringBuilderSerializer(Fury fury) { - super(fury, StringBuilder.class); + public StringBuilderSerializer(Fury fury) { + super(fury, StringBuilder.class); } @Override diff --git a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java index bca0c750bd..e110baa3c7 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java +++ b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java @@ -734,81 +734,81 @@ private void writeJDK8StringBuilder(MemoryBuffer buffer, StringBuilder value) { } } - private void writeJDK9PlusStringBuilder(MemoryBuffer buffer, StringBuilder value) { - byte[] bytes = null; - if (value != null) { - bytes = getJDK9PlusInternalByteArray(value); - } - int bytesLen = 0; - if (bytes != null) { - bytesLen = bytes.length; - } - buffer.ensure(buffer.writerIndex() + 9 + bytesLen); - byte[] targetArray = buffer.getHeapMemory(); - if (targetArray != null) { - int targetIndex = buffer.unsafeHeapWriterIndex(); - int arrIndex = targetIndex; - targetArray[arrIndex++] = 0; - arrIndex += MemoryUtils.writePositiveVarInt(targetArray, arrIndex, bytesLen); + private void writeJDK9PlusStringBuilder(MemoryBuffer buffer, StringBuilder value) { + byte[] bytes = null; + if (value != null) { + bytes = getJDK9PlusInternalByteArray(value); + } + int bytesLen = 0; if (bytes != null) { - System.arraycopy(bytes, 0, targetArray, arrIndex, bytesLen); + bytesLen = bytes.length; + } + buffer.ensure(buffer.writerIndex() + 9 + bytesLen); + byte[] targetArray = buffer.getHeapMemory(); + if (targetArray != null) { + int targetIndex = buffer.unsafeHeapWriterIndex(); + int arrIndex = targetIndex; + targetArray[arrIndex++] = 0; + arrIndex += MemoryUtils.writePositiveVarInt(targetArray, arrIndex, bytesLen); + if (bytes != null) { + System.arraycopy(bytes, 0, targetArray, arrIndex, bytesLen); + } + buffer.unsafeWriterIndex(buffer.writerIndex() + arrIndex - targetIndex + bytesLen); + } else { + buffer.unsafePut(buffer.writerIndex(), (byte) 0); + buffer.unsafePutPositiveVarInt(buffer.writerIndex() + 1, bytesLen); + long offHeapAddress = buffer.getUnsafeAddress(); + Platform.copyMemory( + bytes, + Platform.BYTE_ARRAY_OFFSET, + null, + offHeapAddress + buffer.writerIndex() + 9, + bytesLen); + buffer.unsafeWriterIndex(buffer.writerIndex() + 9 + bytesLen); } - buffer.unsafeWriterIndex(buffer.writerIndex() + arrIndex - targetIndex + bytesLen); - } else { - buffer.unsafePut(buffer.writerIndex(), (byte) 0); - buffer.unsafePutPositiveVarInt(buffer.writerIndex() + 1, bytesLen); - long offHeapAddress = buffer.getUnsafeAddress(); - Platform.copyMemory( - bytes, - Platform.BYTE_ARRAY_OFFSET, - null, - offHeapAddress + buffer.writerIndex() + 9, - bytesLen); - buffer.unsafeWriterIndex(buffer.writerIndex() + 9 + bytesLen); } - } - private byte[] getJDK9PlusInternalByteArray(StringBuilder sb) { - try { - Field valueField = sb.getClass().getSuperclass().getDeclaredField("value"); - valueField.setAccessible(true); - return (byte[]) valueField.get(sb); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); + private byte[] getJDK9PlusInternalByteArray(StringBuilder sb) { + try { + Field valueField = sb.getClass().getSuperclass().getDeclaredField("value"); + valueField.setAccessible(true); + return (byte[]) valueField.get(sb); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } } - } - public StringBuilder readJavaStringBuilder(MemoryBuffer buffer) { - if (Platform.JAVA_VERSION <= 8) { - return readJDK8StringBuilder(buffer); - } else { - return readJDK9PlusStringBuilder(buffer); + public StringBuilder readJavaStringBuilder(MemoryBuffer buffer) { + if (Platform.JAVA_VERSION <= 8) { + return readJDK8StringBuilder(buffer); + } else { + return readJDK9PlusStringBuilder(buffer); + } } - } - private StringBuilder readJDK8StringBuilder(MemoryBuffer buffer) { - int length = buffer.readPositiveVarInt(); - StringBuilder sb = new StringBuilder(length); - byte[] targetArray = buffer.getHeapMemory(); - if (targetArray != null) { - int arrIndex = buffer.readerIndex(); - for (int i = 0; i < length; i++) { - sb.append((char) (targetArray[arrIndex++] & 0xFF)); - } - buffer.readerIndex(arrIndex); - } else { - for (int i = 0; i < length; i++) { - sb.append((char) (buffer.readByte() & 0xFF)); + private StringBuilder readJDK8StringBuilder(MemoryBuffer buffer) { + int length = buffer.readPositiveVarInt(); + StringBuilder sb = new StringBuilder(length); + byte[] targetArray = buffer.getHeapMemory(); + if (targetArray != null) { + int arrIndex = buffer.readerIndex(); + for (int i = 0; i < length; i++) { + sb.append((char) (targetArray[arrIndex++] & 0xFF)); + } + buffer.readerIndex(arrIndex); + } else { + for (int i = 0; i < length; i++) { + sb.append((char) (buffer.readByte() & 0xFF)); + } } + return sb; } - return sb; - } - private StringBuilder readJDK9PlusStringBuilder(MemoryBuffer buffer) { - byte coder = buffer.readByte(); - int length = buffer.readPositiveVarInt(); - byte[] bytes = new byte[length]; - buffer.readBytes(bytes); - return new StringBuilder(new String(bytes, StandardCharsets.UTF_8)); + private StringBuilder readJDK9PlusStringBuilder(MemoryBuffer buffer) { + byte coder = buffer.readByte(); + int length = buffer.readPositiveVarInt(); + byte[] bytes = new byte[length]; + buffer.readBytes(bytes); + return new StringBuilder(new String(bytes, StandardCharsets.UTF_8)); + } } -} From 01c999ffcd92b134c970b299339db6f1310de697 Mon Sep 17 00:00:00 2001 From: pandalee99 <1162953505@qq.com> Date: Fri, 22 Sep 2023 11:46:57 +0800 Subject: [PATCH 05/14] hidden --- .../java/io/fury/serializer/Serializers.java | 77 ------------------- .../io/fury/serializer/StringSerializer.java | 76 ------------------ 2 files changed, 153 deletions(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index 4e0029bbd9..27eee0c12f 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -415,84 +415,7 @@ public Double read(MemoryBuffer buffer) { } } - static Tuple2 builderCache; - - private static synchronized Tuple2 getBuilderFunc() { - if (builderCache == null) { - Function getValue = - (Function) Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getValue"); - if (Platform.JAVA_VERSION > 8) { - ToByteFunction getCoder = - (ToByteFunction) - Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getCoder"); - builderCache = Tuple2.of(getCoder, getValue); - } else { - builderCache = Tuple2.of(null, getValue); - } - } - return builderCache; - } - - public abstract static class AbstractStringBuilderSerializer extends Serializer { - protected final ToByteFunction getCoder; - protected final Function getValue; - protected final StringSerializer stringSerializer; - - public AbstractStringBuilderSerializer(Fury fury, Class type) { - super(fury, type); - Tuple2 builderFunc = getBuilderFunc(); - getCoder = builderFunc.f0; - getValue = builderFunc.f1; - stringSerializer = new StringSerializer(fury); - } - - @Override - public void write(MemoryBuffer buffer, T value) { - if (Platform.JAVA_VERSION > 8) { - byte[] v = new byte[0]; - byte coder = getCoder.applyAsByte(value); - try { - Method getValueMethod = StringBuilder.class.getSuperclass().getDeclaredMethod("getVCoder"); - getValueMethod.setAccessible(true); - Object valueArray = getValueMethod.invoke(value); - v = (byte[]) valueArray; - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - } - if (v.length==0){return;} - buffer.writeByte(coder); - buffer.writePositiveVarInt(v.length); - buffer.writeBytes(v, 0, v.length); - } else { - char[] v = new char[0]; - try { - StringBuilder sb = (StringBuilder) value; - int len = sb.length(); - v = new char[len]; - Method getCharsMethod = StringBuilder.class.getSuperclass().getDeclaredMethod("getChars", int.class, int.class, char[].class, int.class); - getCharsMethod.setAccessible(true); - getCharsMethod.invoke(sb, 0, len, v, 0); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - } - if (v.length == 0) { - return; - } - if (StringSerializer.isAscii(v)) { - stringSerializer.writeJDK8Ascii(buffer, v); - } else { - stringSerializer.writeJDK8UTF16(buffer, v); - } - } - } - } - public static final class StringBuilderSerializer - extends AbstractStringBuilderSerializer { - - public StringBuilderSerializer(Fury fury) { - super(fury, StringBuilder.class); - } @Override public StringBuilder read(MemoryBuffer buffer) { diff --git a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java index e110baa3c7..30598610ef 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java +++ b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java @@ -734,81 +734,5 @@ private void writeJDK8StringBuilder(MemoryBuffer buffer, StringBuilder value) { } } - private void writeJDK9PlusStringBuilder(MemoryBuffer buffer, StringBuilder value) { - byte[] bytes = null; - if (value != null) { - bytes = getJDK9PlusInternalByteArray(value); - } - int bytesLen = 0; - if (bytes != null) { - bytesLen = bytes.length; - } - buffer.ensure(buffer.writerIndex() + 9 + bytesLen); - byte[] targetArray = buffer.getHeapMemory(); - if (targetArray != null) { - int targetIndex = buffer.unsafeHeapWriterIndex(); - int arrIndex = targetIndex; - targetArray[arrIndex++] = 0; - arrIndex += MemoryUtils.writePositiveVarInt(targetArray, arrIndex, bytesLen); - if (bytes != null) { - System.arraycopy(bytes, 0, targetArray, arrIndex, bytesLen); - } - buffer.unsafeWriterIndex(buffer.writerIndex() + arrIndex - targetIndex + bytesLen); - } else { - buffer.unsafePut(buffer.writerIndex(), (byte) 0); - buffer.unsafePutPositiveVarInt(buffer.writerIndex() + 1, bytesLen); - long offHeapAddress = buffer.getUnsafeAddress(); - Platform.copyMemory( - bytes, - Platform.BYTE_ARRAY_OFFSET, - null, - offHeapAddress + buffer.writerIndex() + 9, - bytesLen); - buffer.unsafeWriterIndex(buffer.writerIndex() + 9 + bytesLen); - } - } - - private byte[] getJDK9PlusInternalByteArray(StringBuilder sb) { - try { - Field valueField = sb.getClass().getSuperclass().getDeclaredField("value"); - valueField.setAccessible(true); - return (byte[]) valueField.get(sb); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - public StringBuilder readJavaStringBuilder(MemoryBuffer buffer) { - if (Platform.JAVA_VERSION <= 8) { - return readJDK8StringBuilder(buffer); - } else { - return readJDK9PlusStringBuilder(buffer); - } - } - private StringBuilder readJDK8StringBuilder(MemoryBuffer buffer) { - int length = buffer.readPositiveVarInt(); - StringBuilder sb = new StringBuilder(length); - byte[] targetArray = buffer.getHeapMemory(); - if (targetArray != null) { - int arrIndex = buffer.readerIndex(); - for (int i = 0; i < length; i++) { - sb.append((char) (targetArray[arrIndex++] & 0xFF)); - } - buffer.readerIndex(arrIndex); - } else { - for (int i = 0; i < length; i++) { - sb.append((char) (buffer.readByte() & 0xFF)); - } - } - return sb; - } - - private StringBuilder readJDK9PlusStringBuilder(MemoryBuffer buffer) { - byte coder = buffer.readByte(); - int length = buffer.readPositiveVarInt(); - byte[] bytes = new byte[length]; - buffer.readBytes(bytes); - return new StringBuilder(new String(bytes, StandardCharsets.UTF_8)); - } } From c649a2558648a1feeec87ef6aff849ca2f0ba0f4 Mon Sep 17 00:00:00 2001 From: pandalee99 <1162953505@qq.com> Date: Fri, 22 Sep 2023 11:48:08 +0800 Subject: [PATCH 06/14] bug fix and check code style --- .../java/io/fury/serializer/Serializers.java | 83 +++++++++++++++++++ .../io/fury/serializer/StringSerializer.java | 76 +++++++++++++++++ 2 files changed, 159 insertions(+) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index 27eee0c12f..e2dc1c31e4 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -415,7 +415,90 @@ public Double read(MemoryBuffer buffer) { } } + static Tuple2 builderCache; + + private static synchronized Tuple2 getBuilderFunc() { + if (builderCache == null) { + Function getValue = + (Function) Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getValue"); + if (Platform.JAVA_VERSION > 8) { + ToByteFunction getCoder = + (ToByteFunction) + Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getCoder"); + builderCache = Tuple2.of(getCoder, getValue); + } else { + builderCache = Tuple2.of(null, getValue); + } + } + return builderCache; + } + + public abstract static class AbstractStringBuilderSerializer extends Serializer { + protected final ToByteFunction getCoder; + protected final Function getValue; + protected final StringSerializer stringSerializer; + + public AbstractStringBuilderSerializer(Fury fury, Class type) { + super(fury, type); + Tuple2 builderFunc = getBuilderFunc(); + getCoder = builderFunc.f0; + getValue = builderFunc.f1; + stringSerializer = new StringSerializer(fury); + } + @Override + public void write(MemoryBuffer buffer, T value) { + if (Platform.JAVA_VERSION > 8) { + byte[] v = new byte[0]; + byte coder = getCoder.applyAsByte(value); + try { + Method getValueMethod = + StringBuilder.class.getSuperclass().getDeclaredMethod("getVCoder"); + getValueMethod.setAccessible(true); + Object valueArray = getValueMethod.invoke(value); + v = (byte[]) valueArray; + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + if (v.length == 0) { + return; + } + buffer.writeByte(coder); + buffer.writePositiveVarInt(v.length); + buffer.writeBytes(v, 0, v.length); + } else { + char[] v = new char[0]; + try { + StringBuilder sb = (StringBuilder) value; + int len = sb.length(); + v = new char[len]; + Method getCharsMethod = + StringBuilder.class + .getSuperclass() + .getDeclaredMethod("getChars", int.class, int.class, char[].class, int.class); + getCharsMethod.setAccessible(true); + getCharsMethod.invoke(sb, 0, len, v, 0); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + if (v.length == 0) { + return; + } + if (StringSerializer.isAscii(v)) { + stringSerializer.writeJDK8Ascii(buffer, v); + } else { + stringSerializer.writeJDK8UTF16(buffer, v); + } + } + } + } + + public static final class StringBuilderSerializer + extends AbstractStringBuilderSerializer { + + public StringBuilderSerializer(Fury fury) { + super(fury, StringBuilder.class); + } @Override public StringBuilder read(MemoryBuffer buffer) { diff --git a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java index 30598610ef..bca0c750bd 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java +++ b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java @@ -734,5 +734,81 @@ private void writeJDK8StringBuilder(MemoryBuffer buffer, StringBuilder value) { } } + private void writeJDK9PlusStringBuilder(MemoryBuffer buffer, StringBuilder value) { + byte[] bytes = null; + if (value != null) { + bytes = getJDK9PlusInternalByteArray(value); + } + int bytesLen = 0; + if (bytes != null) { + bytesLen = bytes.length; + } + buffer.ensure(buffer.writerIndex() + 9 + bytesLen); + byte[] targetArray = buffer.getHeapMemory(); + if (targetArray != null) { + int targetIndex = buffer.unsafeHeapWriterIndex(); + int arrIndex = targetIndex; + targetArray[arrIndex++] = 0; + arrIndex += MemoryUtils.writePositiveVarInt(targetArray, arrIndex, bytesLen); + if (bytes != null) { + System.arraycopy(bytes, 0, targetArray, arrIndex, bytesLen); + } + buffer.unsafeWriterIndex(buffer.writerIndex() + arrIndex - targetIndex + bytesLen); + } else { + buffer.unsafePut(buffer.writerIndex(), (byte) 0); + buffer.unsafePutPositiveVarInt(buffer.writerIndex() + 1, bytesLen); + long offHeapAddress = buffer.getUnsafeAddress(); + Platform.copyMemory( + bytes, + Platform.BYTE_ARRAY_OFFSET, + null, + offHeapAddress + buffer.writerIndex() + 9, + bytesLen); + buffer.unsafeWriterIndex(buffer.writerIndex() + 9 + bytesLen); + } + } + + private byte[] getJDK9PlusInternalByteArray(StringBuilder sb) { + try { + Field valueField = sb.getClass().getSuperclass().getDeclaredField("value"); + valueField.setAccessible(true); + return (byte[]) valueField.get(sb); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + public StringBuilder readJavaStringBuilder(MemoryBuffer buffer) { + if (Platform.JAVA_VERSION <= 8) { + return readJDK8StringBuilder(buffer); + } else { + return readJDK9PlusStringBuilder(buffer); + } + } + + private StringBuilder readJDK8StringBuilder(MemoryBuffer buffer) { + int length = buffer.readPositiveVarInt(); + StringBuilder sb = new StringBuilder(length); + byte[] targetArray = buffer.getHeapMemory(); + if (targetArray != null) { + int arrIndex = buffer.readerIndex(); + for (int i = 0; i < length; i++) { + sb.append((char) (targetArray[arrIndex++] & 0xFF)); + } + buffer.readerIndex(arrIndex); + } else { + for (int i = 0; i < length; i++) { + sb.append((char) (buffer.readByte() & 0xFF)); + } + } + return sb; + } + + private StringBuilder readJDK9PlusStringBuilder(MemoryBuffer buffer) { + byte coder = buffer.readByte(); + int length = buffer.readPositiveVarInt(); + byte[] bytes = new byte[length]; + buffer.readBytes(bytes); + return new StringBuilder(new String(bytes, StandardCharsets.UTF_8)); } +} From 03650a8d6429ae00aac1c7362a7eb4d9d3b6424c Mon Sep 17 00:00:00 2001 From: pandalee99 <1162953505@qq.com> Date: Mon, 25 Sep 2023 11:39:35 +0800 Subject: [PATCH 07/14] delete excess code and add buffers to try testing --- .../java/io/fury/serializer/Serializers.java | 106 +++++++++++------- .../io/fury/serializer/StringSerializer.java | 106 ------------------ 2 files changed, 64 insertions(+), 148 deletions(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index e2dc1c31e4..8ee967bf86 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -449,23 +449,10 @@ public AbstractStringBuilderSerializer(Fury fury, Class type) { @Override public void write(MemoryBuffer buffer, T value) { if (Platform.JAVA_VERSION > 8) { - byte[] v = new byte[0]; byte coder = getCoder.applyAsByte(value); - try { - Method getValueMethod = - StringBuilder.class.getSuperclass().getDeclaredMethod("getVCoder"); - getValueMethod.setAccessible(true); - Object valueArray = getValueMethod.invoke(value); - v = (byte[]) valueArray; - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - } - if (v.length == 0) { - return; - } + byte[] v = (byte[]) getValue.apply(value); buffer.writeByte(coder); - buffer.writePositiveVarInt(v.length); - buffer.writeBytes(v, 0, v.length); + buffer.writeBytesWithSizeEmbedded(v); } else { char[] v = new char[0]; try { @@ -506,46 +493,81 @@ public StringBuilder read(MemoryBuffer buffer) { } } - public static final class StringBufferSerializer extends Serializer { - private final StringSerializer stringSerializer; + static Tuple2 bufferCache; - public StringBufferSerializer(Fury fury) { - super(fury, StringBuffer.class); - stringSerializer = new StringSerializer(fury); + private static synchronized Tuple2 getBufferFunc() { + if (bufferCache == null) { + Function getValue = + (Function) Functions.makeGetterFunction(StringBuffer.class.getSuperclass(), "getValue"); + if (Platform.JAVA_VERSION > 8) { + ToByteFunction getCoder = + (ToByteFunction) + Functions.makeGetterFunction(StringBuffer.class.getSuperclass(), "getCoder"); + bufferCache = Tuple2.of(getCoder, getValue); + } else { + bufferCache = Tuple2.of(null, getValue); + } } + return bufferCache; + } - @Override - public short getXtypeId() { - return (short) -Type.STRING.getId(); + public abstract static class AbstractStringBufferSerializer extends Serializer { + protected final ToByteFunction getCoder; + protected final Function getValue; + protected final StringSerializer stringSerializer; + + public AbstractStringBufferSerializer(Fury fury, Class type) { + super(fury, type); + Tuple2 bufferFunc = getBufferFunc(); + getCoder = bufferFunc.f0; + getValue = bufferFunc.f1; + stringSerializer = new StringSerializer(fury); } @Override - public void write(MemoryBuffer buffer, StringBuffer value) { - int length = value.length(); - buffer.writeInt(length); - for (int i = 0; i < length; i++) { - buffer.writeChar(value.charAt(i)); + public void write(MemoryBuffer buffer, T value) { + if (Platform.JAVA_VERSION > 8) { + byte coder = getCoder.applyAsByte(value); + byte[] v = (byte[]) getValue.apply(value); + buffer.writeByte(coder); + buffer.writeBytesWithSizeEmbedded(v); + } else { + char[] v = new char[0]; + try { + StringBuffer sb = (StringBuffer) value; + int len = sb.length(); + v = new char[len]; + Method getCharsMethod = + StringBuffer.class + .getSuperclass() + .getDeclaredMethod("getChars", int.class, int.class, char[].class, int.class); + getCharsMethod.setAccessible(true); + getCharsMethod.invoke(sb, 0, len, v, 0); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + if (v.length == 0) { + return; + } + if (StringSerializer.isAscii(v)) { + stringSerializer.writeJDK8Ascii(buffer, v); + } else { + stringSerializer.writeJDK8UTF16(buffer, v); + } } } + } - @Override - public void xwrite(MemoryBuffer buffer, StringBuffer value) { - stringSerializer.writeUTF8String(buffer, value.toString()); - } + public static final class StringBufferSerializer + extends AbstractStringBufferSerializer { - @Override - public StringBuffer read(MemoryBuffer buffer) { - int length = buffer.readInt(); - StringBuffer stringBuffer = new StringBuffer(length); - for (int i = 0; i < length; i++) { - stringBuffer.append(buffer.readChar()); - } - return stringBuffer; + public StringBufferSerializer(Fury fury) { + super(fury, StringBuffer.class); } @Override - public StringBuffer xread(MemoryBuffer buffer) { - return new StringBuffer(stringSerializer.readUTF8String(buffer)); + public StringBuffer read(MemoryBuffer buffer) { + return new StringBuffer(stringSerializer.readJavaString(buffer)); } } diff --git a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java index bca0c750bd..4b72b5f16a 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java +++ b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java @@ -705,110 +705,4 @@ public String readUTF8String(MemoryBuffer buffer) { return new String(tmpArray, 0, numBytes, StandardCharsets.UTF_8); } } - - public void writeJavaStringBuilder(MemoryBuffer buffer, StringBuilder value) { - if (Platform.JAVA_VERSION <= 8) { - writeJDK8StringBuilder(buffer, value); - } else { - writeJDK9PlusStringBuilder(buffer, value); - } - } - - private void writeJDK8StringBuilder(MemoryBuffer buffer, StringBuilder value) { - int length = value.length(); - buffer.writePositiveVarInt(length); - buffer.ensure(buffer.writerIndex() + length); - byte[] targetArray = buffer.getHeapMemory(); - int writerIndex = buffer.writerIndex(); - if (targetArray != null) { - int arrIndex = buffer.unsafeHeapWriterIndex(); - for (int i = 0; i < length; i++) { - targetArray[arrIndex + i] = (byte) value.charAt(i); - } - buffer.unsafeWriterIndex(writerIndex + length); - } else { - for (int i = 0; i < length; i++) { - buffer.unsafePut(writerIndex++, (byte) value.charAt(i)); - } - buffer.unsafeWriterIndex(writerIndex); - } - } - - private void writeJDK9PlusStringBuilder(MemoryBuffer buffer, StringBuilder value) { - byte[] bytes = null; - if (value != null) { - bytes = getJDK9PlusInternalByteArray(value); - } - int bytesLen = 0; - if (bytes != null) { - bytesLen = bytes.length; - } - buffer.ensure(buffer.writerIndex() + 9 + bytesLen); - byte[] targetArray = buffer.getHeapMemory(); - if (targetArray != null) { - int targetIndex = buffer.unsafeHeapWriterIndex(); - int arrIndex = targetIndex; - targetArray[arrIndex++] = 0; - arrIndex += MemoryUtils.writePositiveVarInt(targetArray, arrIndex, bytesLen); - if (bytes != null) { - System.arraycopy(bytes, 0, targetArray, arrIndex, bytesLen); - } - buffer.unsafeWriterIndex(buffer.writerIndex() + arrIndex - targetIndex + bytesLen); - } else { - buffer.unsafePut(buffer.writerIndex(), (byte) 0); - buffer.unsafePutPositiveVarInt(buffer.writerIndex() + 1, bytesLen); - long offHeapAddress = buffer.getUnsafeAddress(); - Platform.copyMemory( - bytes, - Platform.BYTE_ARRAY_OFFSET, - null, - offHeapAddress + buffer.writerIndex() + 9, - bytesLen); - buffer.unsafeWriterIndex(buffer.writerIndex() + 9 + bytesLen); - } - } - - private byte[] getJDK9PlusInternalByteArray(StringBuilder sb) { - try { - Field valueField = sb.getClass().getSuperclass().getDeclaredField("value"); - valueField.setAccessible(true); - return (byte[]) valueField.get(sb); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - public StringBuilder readJavaStringBuilder(MemoryBuffer buffer) { - if (Platform.JAVA_VERSION <= 8) { - return readJDK8StringBuilder(buffer); - } else { - return readJDK9PlusStringBuilder(buffer); - } - } - - private StringBuilder readJDK8StringBuilder(MemoryBuffer buffer) { - int length = buffer.readPositiveVarInt(); - StringBuilder sb = new StringBuilder(length); - byte[] targetArray = buffer.getHeapMemory(); - if (targetArray != null) { - int arrIndex = buffer.readerIndex(); - for (int i = 0; i < length; i++) { - sb.append((char) (targetArray[arrIndex++] & 0xFF)); - } - buffer.readerIndex(arrIndex); - } else { - for (int i = 0; i < length; i++) { - sb.append((char) (buffer.readByte() & 0xFF)); - } - } - return sb; - } - - private StringBuilder readJDK9PlusStringBuilder(MemoryBuffer buffer) { - byte coder = buffer.readByte(); - int length = buffer.readPositiveVarInt(); - byte[] bytes = new byte[length]; - buffer.readBytes(bytes); - return new StringBuilder(new String(bytes, StandardCharsets.UTF_8)); - } } From a27933b2b5990c0b202dad17fa985de02e5c2faa Mon Sep 17 00:00:00 2001 From: pandalee99 <1162953505@qq.com> Date: Mon, 25 Sep 2023 16:28:18 +0800 Subject: [PATCH 08/14] fix --- .../java/io/fury/serializer/Serializers.java | 86 +------------------ 1 file changed, 2 insertions(+), 84 deletions(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index 8ee967bf86..30904aa62f 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -29,7 +29,6 @@ import io.fury.util.function.ToByteFunction; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; @@ -454,23 +453,7 @@ public void write(MemoryBuffer buffer, T value) { buffer.writeByte(coder); buffer.writeBytesWithSizeEmbedded(v); } else { - char[] v = new char[0]; - try { - StringBuilder sb = (StringBuilder) value; - int len = sb.length(); - v = new char[len]; - Method getCharsMethod = - StringBuilder.class - .getSuperclass() - .getDeclaredMethod("getChars", int.class, int.class, char[].class, int.class); - getCharsMethod.setAccessible(true); - getCharsMethod.invoke(sb, 0, len, v, 0); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - } - if (v.length == 0) { - return; - } + char[] v = (char[]) getValue.apply(value); if (StringSerializer.isAscii(v)) { stringSerializer.writeJDK8Ascii(buffer, v); } else { @@ -493,73 +476,8 @@ public StringBuilder read(MemoryBuffer buffer) { } } - static Tuple2 bufferCache; - - private static synchronized Tuple2 getBufferFunc() { - if (bufferCache == null) { - Function getValue = - (Function) Functions.makeGetterFunction(StringBuffer.class.getSuperclass(), "getValue"); - if (Platform.JAVA_VERSION > 8) { - ToByteFunction getCoder = - (ToByteFunction) - Functions.makeGetterFunction(StringBuffer.class.getSuperclass(), "getCoder"); - bufferCache = Tuple2.of(getCoder, getValue); - } else { - bufferCache = Tuple2.of(null, getValue); - } - } - return bufferCache; - } - - public abstract static class AbstractStringBufferSerializer extends Serializer { - protected final ToByteFunction getCoder; - protected final Function getValue; - protected final StringSerializer stringSerializer; - - public AbstractStringBufferSerializer(Fury fury, Class type) { - super(fury, type); - Tuple2 bufferFunc = getBufferFunc(); - getCoder = bufferFunc.f0; - getValue = bufferFunc.f1; - stringSerializer = new StringSerializer(fury); - } - - @Override - public void write(MemoryBuffer buffer, T value) { - if (Platform.JAVA_VERSION > 8) { - byte coder = getCoder.applyAsByte(value); - byte[] v = (byte[]) getValue.apply(value); - buffer.writeByte(coder); - buffer.writeBytesWithSizeEmbedded(v); - } else { - char[] v = new char[0]; - try { - StringBuffer sb = (StringBuffer) value; - int len = sb.length(); - v = new char[len]; - Method getCharsMethod = - StringBuffer.class - .getSuperclass() - .getDeclaredMethod("getChars", int.class, int.class, char[].class, int.class); - getCharsMethod.setAccessible(true); - getCharsMethod.invoke(sb, 0, len, v, 0); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - } - if (v.length == 0) { - return; - } - if (StringSerializer.isAscii(v)) { - stringSerializer.writeJDK8Ascii(buffer, v); - } else { - stringSerializer.writeJDK8UTF16(buffer, v); - } - } - } - } - public static final class StringBufferSerializer - extends AbstractStringBufferSerializer { + extends AbstractStringBuilderSerializer { public StringBufferSerializer(Fury fury) { super(fury, StringBuffer.class); From 7a0d636d84147ee661d97f92fb26dc663a1be7e9 Mon Sep 17 00:00:00 2001 From: pandalee99 <1162953505@qq.com> Date: Tue, 26 Sep 2023 10:41:45 +0800 Subject: [PATCH 09/14] try to fix problem --- .../main/java/io/fury/serializer/Serializers.java | 7 ++++--- .../java/io/fury/serializer/StringSerializer.java | 14 ++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index 30904aa62f..2d876f6227 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -432,7 +432,8 @@ private static synchronized Tuple2 getBuilderFunc() { return builderCache; } - public abstract static class AbstractStringBuilderSerializer extends Serializer { + public abstract static class AbstractStringBuilderSerializer + extends Serializer { protected final ToByteFunction getCoder; protected final Function getValue; protected final StringSerializer stringSerializer; @@ -455,9 +456,9 @@ public void write(MemoryBuffer buffer, T value) { } else { char[] v = (char[]) getValue.apply(value); if (StringSerializer.isAscii(v)) { - stringSerializer.writeJDK8Ascii(buffer, v); + stringSerializer.writeJDK8Ascii(buffer, v, v.length); } else { - stringSerializer.writeJDK8UTF16(buffer, v); + stringSerializer.writeJDK8UTF16(buffer, v, v.length); } } } diff --git a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java index 4b72b5f16a..ae2ba13185 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java +++ b/java/fury-core/src/main/java/io/fury/serializer/StringSerializer.java @@ -156,9 +156,9 @@ public Expression writeStringExpr(Expression strSerializer, Expression buffer, E public void writeJava8StringCompressed(MemoryBuffer buffer, String value) { final char[] chars = (char[]) Platform.getObject(value, STRING_VALUE_FIELD_OFFSET); if (isAscii(chars)) { - writeJDK8Ascii(buffer, chars); + writeJDK8Ascii(buffer, chars, chars.length); } else { - writeJDK8UTF16(buffer, chars); + writeJDK8UTF16(buffer, chars, chars.length); } } @@ -289,9 +289,9 @@ public void writeJavaString(MemoryBuffer buffer, String value) { final char[] chars = (char[]) Platform.getObject(value, STRING_VALUE_FIELD_OFFSET); if (compressString) { if (isAscii(chars)) { - writeJDK8Ascii(buffer, chars); + writeJDK8Ascii(buffer, chars, chars.length); } else { - writeJDK8UTF16(buffer, chars); + writeJDK8UTF16(buffer, chars, chars.length); } } else { int numBytes = MathUtils.doubleExact(value.length()); @@ -382,8 +382,7 @@ public static void writeJDK11String(MemoryBuffer buffer, String value) { buffer.unsafeWriterIndex(writerIndex); } - public void writeJDK8Ascii(MemoryBuffer buffer, char[] chars) { - final int strLen = chars.length; + public void writeJDK8Ascii(MemoryBuffer buffer, char[] chars, final int strLen) { int writerIndex = buffer.writerIndex(); // The `ensure` ensure next operations are safe without bound checks, // and inner heap buffer doesn't change. @@ -413,8 +412,7 @@ public void writeJDK8Ascii(MemoryBuffer buffer, char[] chars) { } } - public void writeJDK8UTF16(MemoryBuffer buffer, char[] chars) { - int strLen = chars.length; + public void writeJDK8UTF16(MemoryBuffer buffer, char[] chars, int strLen) { int numBytes = MathUtils.doubleExact(strLen); if (Platform.IS_LITTLE_ENDIAN) { buffer.writeByte(UTF16); From 81ffa5b2647a06a30648118faffb5a7e3ad4b4bd Mon Sep 17 00:00:00 2001 From: pandalee99 <1162953505@qq.com> Date: Tue, 26 Sep 2023 15:30:11 +0800 Subject: [PATCH 10/14] fix function --- .../java/io/fury/serializer/Serializers.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index 2d876f6227..3700c74ace 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -26,9 +26,9 @@ import io.fury.util.Platform; import io.fury.util.Utils; import io.fury.util.function.Functions; -import io.fury.util.function.ToByteFunction; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; @@ -414,15 +414,23 @@ public Double read(MemoryBuffer buffer) { } } - static Tuple2 builderCache; + static Tuple2 builderCache; - private static synchronized Tuple2 getBuilderFunc() { + private static synchronized Tuple2 getBuilderFunc() { if (builderCache == null) { Function getValue = (Function) Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getValue"); if (Platform.JAVA_VERSION > 8) { - ToByteFunction getCoder = - (ToByteFunction) + Method getCoderMethod; + try { + getCoderMethod = StringBuilder.class.getSuperclass().getDeclaredMethod("getCoder"); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + // ToIntFunction o = (ToIntFunction) + // makeGetterFunction(lookup, lookup.unreflect(getCoder), int.class); + Function getCoder = + (Function) Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getCoder"); builderCache = Tuple2.of(getCoder, getValue); } else { @@ -434,13 +442,13 @@ private static synchronized Tuple2 getBuilderFunc() { public abstract static class AbstractStringBuilderSerializer extends Serializer { - protected final ToByteFunction getCoder; + protected final Function getCoder; protected final Function getValue; protected final StringSerializer stringSerializer; public AbstractStringBuilderSerializer(Fury fury, Class type) { super(fury, type); - Tuple2 builderFunc = getBuilderFunc(); + Tuple2 builderFunc = getBuilderFunc(); getCoder = builderFunc.f0; getValue = builderFunc.f1; stringSerializer = new StringSerializer(fury); @@ -449,7 +457,7 @@ public AbstractStringBuilderSerializer(Fury fury, Class type) { @Override public void write(MemoryBuffer buffer, T value) { if (Platform.JAVA_VERSION > 8) { - byte coder = getCoder.applyAsByte(value); + byte coder = (byte) getCoder.apply(value); byte[] v = (byte[]) getValue.apply(value); buffer.writeByte(coder); buffer.writeBytesWithSizeEmbedded(v); From dfa77c0bff8cad4c98a721a67533f7d089bd7f40 Mon Sep 17 00:00:00 2001 From: pandalee99 <1162953505@qq.com> Date: Tue, 26 Sep 2023 19:33:11 +0800 Subject: [PATCH 11/14] code fix --- .../java/io/fury/serializer/Serializers.java | 34 +++++++++++-------- .../java/io/fury/util/function/Functions.java | 13 +++++++ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index 3700c74ace..effadf0eed 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -16,6 +16,8 @@ package io.fury.serializer; +import static io.fury.util.function.Functions.makeGetterFunction; + import com.google.common.base.Preconditions; import com.google.common.primitives.Primitives; import io.fury.Fury; @@ -25,7 +27,6 @@ import io.fury.type.Type; import io.fury.util.Platform; import io.fury.util.Utils; -import io.fury.util.function.Functions; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -41,6 +42,7 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; +import java.util.function.ToIntFunction; import java.util.regex.Pattern; /** @@ -414,25 +416,22 @@ public Double read(MemoryBuffer buffer) { } } - static Tuple2 builderCache; + static Tuple2 builderCache; - private static synchronized Tuple2 getBuilderFunc() { + private static synchronized Tuple2 getBuilderFunc() { if (builderCache == null) { Function getValue = - (Function) Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getValue"); + (Function) makeGetterFunction(StringBuilder.class.getSuperclass(), "getValue"); if (Platform.JAVA_VERSION > 8) { - Method getCoderMethod; try { - getCoderMethod = StringBuilder.class.getSuperclass().getDeclaredMethod("getCoder"); + Method getCoderMethod = StringBuilder.class.getSuperclass().getDeclaredMethod("getCoder"); + ToIntFunction getCoder = + (ToIntFunction) makeGetterFunction(getCoderMethod, int.class); + builderCache = Tuple2.of(getCoder, getValue); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } - // ToIntFunction o = (ToIntFunction) - // makeGetterFunction(lookup, lookup.unreflect(getCoder), int.class); - Function getCoder = - (Function) - Functions.makeGetterFunction(StringBuilder.class.getSuperclass(), "getCoder"); - builderCache = Tuple2.of(getCoder, getValue); + } else { builderCache = Tuple2.of(null, getValue); } @@ -442,22 +441,27 @@ private static synchronized Tuple2 getBuilderFunc() { public abstract static class AbstractStringBuilderSerializer extends Serializer { - protected final Function getCoder; + protected final ToIntFunction getCoder; protected final Function getValue; protected final StringSerializer stringSerializer; public AbstractStringBuilderSerializer(Fury fury, Class type) { super(fury, type); - Tuple2 builderFunc = getBuilderFunc(); + Tuple2 builderFunc = getBuilderFunc(); getCoder = builderFunc.f0; getValue = builderFunc.f1; stringSerializer = new StringSerializer(fury); } + @Override + public short getXtypeId() { + return (short) -Type.STRING.getId(); + } + @Override public void write(MemoryBuffer buffer, T value) { if (Platform.JAVA_VERSION > 8) { - byte coder = (byte) getCoder.apply(value); + int coder = getCoder.applyAsInt(value); byte[] v = (byte[]) getValue.apply(value); buffer.writeByte(coder); buffer.writeBytesWithSizeEmbedded(v); diff --git a/java/fury-core/src/main/java/io/fury/util/function/Functions.java b/java/fury-core/src/main/java/io/fury/util/function/Functions.java index 5cf2f84f62..00d06c5413 100644 --- a/java/fury-core/src/main/java/io/fury/util/function/Functions.java +++ b/java/fury-core/src/main/java/io/fury/util/function/Functions.java @@ -87,6 +87,19 @@ public static Object makeGetterFunction(Method method) { } } + public static Object makeGetterFunction(Method method, Class returnType) { + MethodHandles.Lookup lookup = _JDKAccess._trustedLookup(method.getDeclaringClass()); + try { + // Why `lookup.findGetter` doesn't work? + // MethodHandle handle = lookup.findGetter(field.getDeclaringClass(), field.getName(), + // field.getType()); + MethodHandle handle = lookup.unreflect(method); + return _JDKAccess.makeGetterFunction(lookup, handle, returnType); + } catch (IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + public static Tuple2, String> getterMethodInfo(Class type) { return _JDKAccess.getterMethodInfo(type); } From 0b250660468bc2dfa4f17e8d8a248a4f86fd6426 Mon Sep 17 00:00:00 2001 From: pandalee99 <1162953505@qq.com> Date: Wed, 27 Sep 2023 10:35:19 +0800 Subject: [PATCH 12/14] code fix again --- .../java/io/fury/serializer/Serializers.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index effadf0eed..bac8cfd04b 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -453,6 +453,11 @@ public AbstractStringBuilderSerializer(Fury fury, Class type) { stringSerializer = new StringSerializer(fury); } + @Override + public void xwrite(MemoryBuffer buffer, T value) { + stringSerializer.writeUTF8String(buffer, value.toString()); + } + @Override public short getXtypeId() { return (short) -Type.STRING.getId(); @@ -464,7 +469,15 @@ public void write(MemoryBuffer buffer, T value) { int coder = getCoder.applyAsInt(value); byte[] v = (byte[]) getValue.apply(value); buffer.writeByte(coder); - buffer.writeBytesWithSizeEmbedded(v); + if (coder == 0) { + buffer.writePrimitiveArrayWithSizeEmbedded(v, Platform.BYTE_ARRAY_OFFSET, value.length()); + } else { + if (coder != 1) { + throw new UnsupportedOperationException("Unsupported coder " + coder); + } + buffer.writePrimitiveArrayWithSizeEmbedded( + v, Platform.BYTE_ARRAY_OFFSET, value.length() << 1); + } } else { char[] v = (char[]) getValue.apply(value); if (StringSerializer.isAscii(v)) { @@ -487,6 +500,11 @@ public StringBuilderSerializer(Fury fury) { public StringBuilder read(MemoryBuffer buffer) { return new StringBuilder(stringSerializer.readJavaString(buffer)); } + + @Override + public StringBuilder xread(MemoryBuffer buffer) { + return new StringBuilder(stringSerializer.readUTF8String(buffer)); + } } public static final class StringBufferSerializer @@ -500,6 +518,11 @@ public StringBufferSerializer(Fury fury) { public StringBuffer read(MemoryBuffer buffer) { return new StringBuffer(stringSerializer.readJavaString(buffer)); } + + @Override + public StringBuffer xread(MemoryBuffer buffer) { + return new StringBuffer(stringSerializer.readUTF8String(buffer)); + } } public static final class EnumSerializer extends Serializer { From 7e71c9660a2a7e362b183ba57ef201e40efd679a Mon Sep 17 00:00:00 2001 From: PAN <46820719+pandalee99@users.noreply.github.com> Date: Wed, 27 Sep 2023 11:26:52 +0800 Subject: [PATCH 13/14] Update java/fury-core/src/main/java/io/fury/serializer/Serializers.java commit Co-authored-by: Shawn --- .../fury-core/src/main/java/io/fury/serializer/Serializers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index bac8cfd04b..de9cc4127d 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -481,7 +481,7 @@ public void write(MemoryBuffer buffer, T value) { } else { char[] v = (char[]) getValue.apply(value); if (StringSerializer.isAscii(v)) { - stringSerializer.writeJDK8Ascii(buffer, v, v.length); + stringSerializer.writeJDK8Ascii(buffer, v, value.length()); } else { stringSerializer.writeJDK8UTF16(buffer, v, v.length); } From 9c24186ab974a13c969872263563e2ed25ca0120 Mon Sep 17 00:00:00 2001 From: PAN <46820719+pandalee99@users.noreply.github.com> Date: Wed, 27 Sep 2023 11:27:08 +0800 Subject: [PATCH 14/14] Update java/fury-core/src/main/java/io/fury/serializer/Serializers.java commit Co-authored-by: Shawn --- .../fury-core/src/main/java/io/fury/serializer/Serializers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java index de9cc4127d..34ef9c2f73 100644 --- a/java/fury-core/src/main/java/io/fury/serializer/Serializers.java +++ b/java/fury-core/src/main/java/io/fury/serializer/Serializers.java @@ -483,7 +483,7 @@ public void write(MemoryBuffer buffer, T value) { if (StringSerializer.isAscii(v)) { stringSerializer.writeJDK8Ascii(buffer, v, value.length()); } else { - stringSerializer.writeJDK8UTF16(buffer, v, v.length); + stringSerializer.writeJDK8UTF16(buffer, v, value.length()); } } }