jankotek / mapdb

MapDB provides concurrent Maps, Sets and Queues backed by disk storage or off-heap-memory. It is a fast and easy to use embedded Java database engine.
https://mapdb.org
Apache License 2.0
4.87k stars 873 forks source link

When I define a custom Serializer for key, the 'available' parameter in the deserialize method shows up as -1. #1021

Open galfordliu opened 1 year ago

galfordliu commented 1 year ago

When I define a custom KeySerializer, the 'available' parameter in the deserialize method shows up as -1. What could be the cause of this?

When I serialize keys using kryo or Fst, this exception occurs. My custom Serializer is fine because value also uses the same Serializer

However, in the deserialize method, available will be -1, and the cause of the exception cannot be found. I must only use Serializor.Java to serialize keys.

··· public class KryoUtil {

static final KryoTool INSTANCE = newInstance();

public static KryoTool newInstance(){
    return new KryoTool();
}
public static void setInitListener(Consumer<Kryo> initListener) {
    INSTANCE.setInitListener(initListener);
}

public static Kryo getLocalInstance(){
    return INSTANCE.getLocalInstance();
}

public static <T extends Serializable> byte[] serialize(@Nullable T obj) {
   return INSTANCE.serialize(obj);
}

public static @Nullable  <T extends Serializable> T deserialize(byte[] bytes) {
    return INSTANCE.deserialize(bytes);
}

}

···

··· public class DefaultSerializer implements Serializer {

public DefaultSerializer() {
}

@Override
public void serialize(@NotNull DataOutput2 out, @NotNull E value) throws IOException {
    out.write(KryoUtil.serialize(value));
}

@Override
public E deserialize(@NotNull DataInput2 input, int available) throws IOException {
    if (available == 0) {
        return null;
    }
    byte[] buffer = new byte[available];
    input.readFully(buffer);
    return KryoUtil.deserialize(buffer);
}

}

···

TestKey and MapDbTest implements Serializable. Only one field : String name;

DefaultSerializer<TestKey> keySerializer=new DefaultSerializer<>();
DefaultSerializer<MapDbTest> valueSerializer=new DefaultSerializer<>();
Map<TestKey,MapDbTest> test=db.hashMap(mapName,keySerializer,valueSerializer).createOrOpen()
test.put(TestKey.of("1"),new MapDbTest("1"));

Exception in thread "main" java.lang.NegativeArraySizeException, becase the 'available' parameter in the deserialize method shows up as -1.