Ram Karumuri
Ram Karumuri

Reputation: 13

Using chronicle map and byte[] or byte buffer

I am trying to create a Chronicle map with a Long key and a variable sized byte[], a serialized Java BitSet to be precise. I can create a map at using Values interface, but the size of the array in it is fixed.

So, I am looking to use byte[] or Bytebuffer since they are dynamically sized, thus saving memory. Is this a supported use case? Is there an example of using chronicle map with byte[] or ByteBuffer value classes? The following code fails

ChronicleMap<Long, ByteBuffer> map = ChronicleMap
    .of(Long.class, ByteBuffer.class)
    .name("shard_map")
    .averageValueSize(1000)
    .entries(1_000_000)
    .create();

ByteBuffer ts2 = ByteBuffer.allocateDirect(10);
ts2.putInt(10);
map.put(1L, ts2);
System.out.println(map.get(1L).getInt());

with the error:

Exception in thread "main" java.nio.BufferUnderflowException
    at java.nio.Buffer.nextGetIndex(Buffer.java:506)
    at java.nio.HeapByteBuffer.getInt(HeapByteBuffer.java:361)

I have tried creating the value object with Values.newHeapInstance, but that fails with the error:

Exception in thread "main" java.lang.IllegalArgumentException: class java.nio.ByteBuffer is not an interface nor a generated class native or heap class
    at net.openhft.chronicle.values.ValueModel.notValueInterfaceOfImpl(ValueModel.java:68)
    at net.openhft.chronicle.values.ValueModel.lambda$acquire$0(ValueModel.java:64)
    at net.openhft.chronicle.values.ValueModel.doSomethingForInterfaceOr(ValueModel.java:85)
    at net.openhft.chronicle.values.ValueModel.acquire(ValueModel.java:63)
    at net.openhft.chronicle.values.Values.heapClassFor(Values.java:68)
    at net.openhft.chronicle.values.Values.newHeapInstance(Values.java:37)

The documentation says that byte[] and ByteBuffer are supported out of the box, but I couldn't find a working example for it, so decided to ask here.

Upvotes: 1

Views: 1053

Answers (1)

leventov
leventov

Reputation: 15263

Your test works on my machine (ends without error), but prints unexpected output "0". That's because you forgot to call ts2.flip(), the code should look like:

ts2.putInt(10);
ts2.flip();
map.put(1L, ts2);

With this change, the snippet prints "10".

Out of the box, Chronicle Map serializes ByteBuffer's contents between ByteBuffer's position and limit. You could override this in your custom serializer, and write the whole buffer.

BTW, in your case I don't recommend to use small direct buffer just to put a value into Chronicle Map (ts2). Use an ordinary heap buffer for this.

Upvotes: 1

Related Questions