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-02-11 01:09:15 +01:00
|
|
|
import java.io.IOError;
|
2021-02-02 19:40:37 +01:00
|
|
|
import java.io.IOException;
|
|
|
|
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
|
|
|
import org.warp.commonutils.error.IndexOutOfBoundsException;
|
|
|
|
|
2021-09-02 17:15:40 +02:00
|
|
|
public class CodecSerializer<A> implements Serializer<A> {
|
2021-02-02 19:40:37 +01:00
|
|
|
|
|
|
|
private final Codecs<A> deserializationCodecs;
|
|
|
|
private final Codec<A> serializationCodec;
|
|
|
|
private final int serializationCodecId;
|
|
|
|
private final boolean microCodecs;
|
2021-10-19 00:22:05 +02:00
|
|
|
private final int serializedSizeHint;
|
2021-02-02 19:40:37 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param microCodecs if true, allow only codecs with a value from 0 to 255 to save disk space
|
2021-10-19 00:22:05 +02:00
|
|
|
* @param serializedSizeHint suggested default buffer size, -1 if unknown
|
2021-02-02 19:40:37 +01:00
|
|
|
*/
|
2021-05-03 21:41:51 +02:00
|
|
|
public CodecSerializer(
|
|
|
|
Codecs<A> deserializationCodecs,
|
2021-02-02 19:40:37 +01:00
|
|
|
Codec<A> serializationCodec,
|
|
|
|
int serializationCodecId,
|
2021-10-19 00:22:05 +02:00
|
|
|
boolean microCodecs,
|
|
|
|
int serializedSizeHint) {
|
2021-02-02 19:40:37 +01:00
|
|
|
this.deserializationCodecs = deserializationCodecs;
|
|
|
|
this.serializationCodec = serializationCodec;
|
|
|
|
this.serializationCodecId = serializationCodecId;
|
|
|
|
this.microCodecs = microCodecs;
|
|
|
|
if (microCodecs && (serializationCodecId > 255 || serializationCodecId < 0)) {
|
|
|
|
throw new IndexOutOfBoundsException(serializationCodecId, 0, 255);
|
|
|
|
}
|
2021-10-19 00:22:05 +02:00
|
|
|
if (serializedSizeHint != -1) {
|
|
|
|
this.serializedSizeHint = (microCodecs ? Byte.BYTES : Integer.BYTES) + serializedSizeHint;
|
|
|
|
} else {
|
|
|
|
this.serializedSizeHint = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getSerializedSizeHint() {
|
|
|
|
return serializedSizeHint;
|
2021-02-02 19:40:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-10-19 00:22:05 +02:00
|
|
|
public @NotNull A deserialize(@NotNull Buffer serializedBuf) throws SerializationException {
|
|
|
|
try {
|
|
|
|
var is = new BufferDataInputShared(serializedBuf);
|
2021-02-02 19:40:37 +01:00
|
|
|
int codecId;
|
|
|
|
if (microCodecs) {
|
|
|
|
codecId = is.readUnsignedByte();
|
|
|
|
} else {
|
|
|
|
codecId = is.readInt();
|
|
|
|
}
|
|
|
|
var serializer = deserializationCodecs.getCodec(codecId);
|
2021-10-19 00:22:05 +02:00
|
|
|
return serializer.deserialize(is);
|
2021-02-02 19:40:37 +01:00
|
|
|
} catch (IOException ex) {
|
|
|
|
// This shouldn't happen
|
2021-02-11 01:09:15 +01:00
|
|
|
throw new IOError(ex);
|
2021-02-02 19:40:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2021-10-19 00:22:05 +02:00
|
|
|
public void serialize(@NotNull A deserialized, Buffer output) throws SerializationException {
|
|
|
|
try {
|
|
|
|
var os = new BufferDataOutput(output);
|
2021-02-02 19:40:37 +01:00
|
|
|
if (microCodecs) {
|
|
|
|
os.writeByte(serializationCodecId);
|
|
|
|
} else {
|
|
|
|
os.writeInt(serializationCodecId);
|
|
|
|
}
|
|
|
|
serializationCodec.serialize(os, deserialized);
|
|
|
|
} catch (IOException ex) {
|
|
|
|
// This shouldn't happen
|
2021-02-11 01:09:15 +01:00
|
|
|
throw new IOError(ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-03 19:09:06 +02:00
|
|
|
@SuppressWarnings("unused")
|
2021-02-11 01:09:15 +01:00
|
|
|
public int getCodecHeadersBytes() {
|
|
|
|
if (microCodecs) {
|
|
|
|
return Byte.BYTES;
|
|
|
|
} else {
|
|
|
|
return Integer.BYTES;
|
2021-02-02 19:40:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|