package org.gbif.nub.mapdb;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.pool.KryoFactory;
import com.esotericsoftware.kryo.pool.KryoPool;
import org.apache.commons.lang3.NotImplementedException;
import org.jetbrains.annotations.NotNull;
import org.mapdb.DataIO;
import org.mapdb.DataInput2;
import org.mapdb.DataOutput2;
import org.mapdb.serializer.GroupSerializerObjectArray;
/**
* A mapDB serializer that uses kryo under the hood to quickly serialize objects into the mapdb data output/input.
* @param <T> the class to serialize
*/
public class MapDbObjectSerializer<T> extends GroupSerializerObjectArray<T> {
private final KryoPool pool;
private final int bufferSize;
private final Class<T> clazz;
public MapDbObjectSerializer(Class<T> clazz, KryoFactory kryoFactory) {
this(clazz, new KryoPool.Builder(kryoFactory).softReferences().build(), 256);
}
public MapDbObjectSerializer(Class<T> clazz, KryoPool pool, int bufferSize) {
this.pool = pool;
this.clazz = clazz;
this.bufferSize = bufferSize;
}
@Override
public void serialize(@NotNull DataOutput2 out, @NotNull T value) throws IOException {
Kryo kryo = pool.borrow();
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(bufferSize);
Output output = new Output(buffer, bufferSize);
kryo.writeObject(output, value);
output.close();
byte[] bytes = buffer.toByteArray();
DataIO.packInt(out, bytes.length);
out.write(bytes);
} finally {
pool.release(kryo);
}
}
@Override
public T deserialize(@NotNull DataInput2 in, int available) throws IOException {
if(available==0) return null;
Kryo kryo = pool.borrow();
try {
int size = DataIO.unpackInt(in);
byte[] ret = new byte[size];
in.readFully(ret);
return kryo.readObject(new Input(ret), clazz);
} finally {
pool.release(kryo);
}
}
@Override
public boolean isTrusted() {
return true;
}
@Override
public int compare(T first, T second) {
throw new NotImplementedException("compare should not be needed for our mapdb use");
}
}