Avoid allocating a byte array in writeUTF and readUTF

This commit is contained in:
Andrea Cavalli 2022-02-09 20:02:23 +01:00
parent 46e7abfd8c
commit 2c11b13b7a
3 changed files with 24 additions and 14 deletions

View File

@ -120,11 +120,8 @@ public class BufferDataInputOwned implements SafeCloseable, BufferDataInput {
@Override
public String readUTF() {
if (buf == null) throw new IndexOutOfBoundsException();
var len = buf.readUnsignedShort();
byte[] bytes = new byte[len];
buf.copyInto(buf.readerOffset(), bytes, 0, len);
buf.readerOffset(buf.readerOffset() + len);
return new String(bytes, StandardCharsets.UTF_8);
int len = buf.readUnsignedShort();
return buf.readCharSequence(len, StandardCharsets.UTF_8).toString();
}
@Override

View File

@ -1,10 +1,16 @@
package it.cavallium.dbengine.database.serialization;
import io.net5.buffer.api.Buffer;
import io.net5.buffer.api.ReadableComponent;
import io.net5.buffer.api.ReadableComponentProcessor;
import io.net5.buffer.api.Send;
import io.net5.buffer.api.adaptor.ByteBufAdaptor;
import it.cavallium.dbengine.database.SafeCloseable;
import java.io.DataInput;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -120,11 +126,8 @@ public class BufferDataInputShared implements BufferDataInput {
@Override
public String readUTF() {
if (buf == null) throw new IndexOutOfBoundsException();
var len = buf.readUnsignedShort();
byte[] bytes = new byte[len];
buf.copyInto(buf.readerOffset(), bytes, 0, len);
buf.readerOffset(buf.readerOffset() + len);
return new String(bytes, StandardCharsets.UTF_8);
int len = buf.readUnsignedShort();
return buf.readCharSequence(len, StandardCharsets.UTF_8).toString();
}
public int getReadBytesCount() {

View File

@ -97,9 +97,19 @@ public class BufferDataOutput implements DataOutput {
@Override
public void writeUTF(@NotNull String s) {
var bytes = s.getBytes(StandardCharsets.UTF_8);
buf.ensureWritable(Short.BYTES + Byte.BYTES * bytes.length);
buf.writeUnsignedShort(bytes.length);
buf.writeBytes(bytes);
int sizeShortOffset = buf.writerOffset();
int stringOffset = sizeShortOffset + Short.BYTES;
buf.writerOffset(stringOffset);
buf.writeCharSequence(s, StandardCharsets.UTF_8);
int endOffset = buf.writerOffset();
int stringSize = endOffset - stringOffset;
buf.writerOffset(sizeShortOffset);
buf.writeUnsignedShort(stringSize);
if (stringSize > (1 << 16) - 1) {
buf.writerOffset(sizeShortOffset);
throw new IndexOutOfBoundsException("String too large: " + stringSize);
} else {
buf.writerOffset(endOffset);
}
}
}