CavalliumDBEngine/src/main/java/it/cavallium/dbengine/database/serialization/SerializerFixedBinaryLength.java

153 lines
5.5 KiB
Java
Raw Normal View History

2021-02-02 19:40:37 +01:00
package it.cavallium.dbengine.database.serialization;
2021-09-17 16:56:28 +02:00
import io.net5.buffer.api.Buffer;
import io.net5.buffer.api.BufferAllocator;
import io.net5.buffer.api.Send;
2021-08-29 23:18:03 +02:00
import it.cavallium.dbengine.database.LLUtils;
import java.nio.charset.StandardCharsets;
2021-09-22 18:33:28 +02:00
import java.util.Objects;
2021-02-02 19:40:37 +01:00
import org.jetbrains.annotations.NotNull;
2021-09-22 18:33:28 +02:00
import org.jetbrains.annotations.Nullable;
2021-02-02 19:40:37 +01:00
2021-02-03 14:37:02 +01:00
@SuppressWarnings("unused")
2021-09-01 00:01:56 +02:00
public interface SerializerFixedBinaryLength<A> extends Serializer<A> {
2021-02-02 19:40:37 +01:00
int getSerializedBinaryLength();
2021-09-01 00:01:56 +02:00
static SerializerFixedBinaryLength<Send<Buffer>> noop(int length) {
2021-02-02 19:40:37 +01:00
return new SerializerFixedBinaryLength<>() {
@Override
public @NotNull DeserializationResult<Send<Buffer>> deserialize(@NotNull Send<Buffer> serialized) {
2021-09-22 18:33:28 +02:00
Objects.requireNonNull(serialized);
2021-08-29 23:18:03 +02:00
try (var buf = serialized.receive()) {
if (buf.readableBytes() != getSerializedBinaryLength()) {
throw new IllegalArgumentException(
"Fixed serializer with " + getSerializedBinaryLength() + " bytes has tried to deserialize an element with "
2021-08-29 23:18:03 +02:00
+ buf.readableBytes() + " bytes instead");
}
2021-09-01 00:01:56 +02:00
var readableBytes = buf.readableBytes();
return new DeserializationResult<>(buf.send(), readableBytes);
}
2021-02-02 19:40:37 +01:00
}
@Override
2021-08-29 23:18:03 +02:00
public @NotNull Send<Buffer> serialize(@NotNull Send<Buffer> deserialized) {
try (Buffer buf = deserialized.receive()) {
if (buf.readableBytes() != getSerializedBinaryLength()) {
throw new IllegalArgumentException(
"Fixed serializer with " + getSerializedBinaryLength() + " bytes has tried to serialize an element with "
+ buf.readableBytes() + " bytes instead");
}
return buf.send();
}
2021-02-02 19:40:37 +01:00
}
@Override
public int getSerializedBinaryLength() {
return length;
}
};
}
2021-09-01 00:01:56 +02:00
static SerializerFixedBinaryLength<String> utf8(BufferAllocator allocator, int length) {
2021-02-02 19:40:37 +01:00
return new SerializerFixedBinaryLength<>() {
@Override
public @NotNull DeserializationResult<String> deserialize(@NotNull Send<Buffer> serializedToReceive)
2021-09-01 00:01:56 +02:00
throws SerializationException {
2021-08-29 23:18:03 +02:00
try (var serialized = serializedToReceive.receive()) {
if (serialized.readableBytes() != getSerializedBinaryLength()) {
throw new SerializationException(
"Fixed serializer with " + getSerializedBinaryLength() + " bytes has tried to deserialize an element with "
+ serialized.readableBytes() + " bytes instead");
}
2021-08-29 23:18:03 +02:00
var readerOffset = serialized.readerOffset();
2021-09-01 00:01:56 +02:00
return new DeserializationResult<>(LLUtils.deserializeString(serialized.send(),
2021-09-02 17:15:40 +02:00
readerOffset, length, StandardCharsets.UTF_8), length);
}
2021-02-02 19:40:37 +01:00
}
@Override
2021-08-29 23:18:03 +02:00
public @NotNull Send<Buffer> serialize(@NotNull String deserialized) throws SerializationException {
// UTF-8 uses max. 3 bytes per char, so calculate the worst case.
2021-08-29 23:18:03 +02:00
try (Buffer buf = allocator.allocate(LLUtils.utf8MaxBytes(deserialized))) {
2021-09-02 17:15:40 +02:00
assert buf.isAccessible();
var bytes = deserialized.getBytes(StandardCharsets.UTF_8);
buf.ensureWritable(bytes.length);
buf.writeBytes(bytes);
if (buf.readableBytes() != getSerializedBinaryLength()) {
2021-05-02 19:18:15 +02:00
throw new SerializationException("Fixed serializer with " + getSerializedBinaryLength()
+ " bytes has tried to serialize an element with "
+ buf.readableBytes() + " bytes instead");
}
2021-09-02 17:15:40 +02:00
assert buf.isAccessible();
2021-08-29 23:18:03 +02:00
return buf.send();
}
}
@Override
public int getSerializedBinaryLength() {
return length;
}
};
}
2021-09-01 00:01:56 +02:00
static SerializerFixedBinaryLength<Integer> intSerializer(BufferAllocator allocator) {
return new SerializerFixedBinaryLength<>() {
@Override
public @NotNull DeserializationResult<Integer> deserialize(@NotNull Send<Buffer> serializedToReceive) {
2021-09-22 18:33:28 +02:00
Objects.requireNonNull(serializedToReceive);
2021-08-29 23:18:03 +02:00
try (var serialized = serializedToReceive.receive()) {
if (serialized.readableBytes() != getSerializedBinaryLength()) {
throw new IllegalArgumentException(
"Fixed serializer with " + getSerializedBinaryLength() + " bytes has tried to deserialize an element with "
+ serialized.readableBytes() + " bytes instead");
}
2021-09-02 17:15:40 +02:00
return new DeserializationResult<>(serialized.readInt(), Integer.BYTES);
}
}
@Override
2021-08-29 23:18:03 +02:00
public @NotNull Send<Buffer> serialize(@NotNull Integer deserialized) {
try (Buffer buf = allocator.allocate(Integer.BYTES)) {
return buf.writeInt(deserialized).send();
}
2021-02-02 19:40:37 +01:00
}
@Override
public int getSerializedBinaryLength() {
return Integer.BYTES;
}
};
}
2021-09-01 00:01:56 +02:00
static SerializerFixedBinaryLength<Long> longSerializer(BufferAllocator allocator) {
2021-02-02 19:40:37 +01:00
return new SerializerFixedBinaryLength<>() {
@Override
public @NotNull DeserializationResult<Long> deserialize(@NotNull Send<Buffer> serializedToReceive) {
2021-09-22 18:33:28 +02:00
Objects.requireNonNull(serializedToReceive);
2021-08-29 23:18:03 +02:00
try (var serialized = serializedToReceive.receive()) {
if (serialized.readableBytes() != getSerializedBinaryLength()) {
throw new IllegalArgumentException(
"Fixed serializer with " + getSerializedBinaryLength() + " bytes has tried to deserialize an element with "
+ serialized.readableBytes() + " bytes instead");
}
2021-09-01 00:01:56 +02:00
var readableBytes = serialized.readableBytes();
2021-09-02 17:15:40 +02:00
return new DeserializationResult<>(serialized.readLong(), Long.BYTES);
}
2021-02-02 19:40:37 +01:00
}
@Override
2021-08-29 23:18:03 +02:00
public @NotNull Send<Buffer> serialize(@NotNull Long deserialized) {
try (Buffer buf = allocator.allocate(Long.BYTES)) {
return buf.writeLong(deserialized).send();
}
2021-02-02 19:40:37 +01:00
}
@Override
public int getSerializedBinaryLength() {
return Long.BYTES;
}
};
}
}