OpenHFT / Chronicle-Map

Replicate your Key Value Store across your network, with consistency, persistance and performance.
http://chronicle.software/products/chronicle-map/
Apache License 2.0
2.77k stars 469 forks source link

use of ByteBuffer vs Bytes in map #513

Closed edhjer closed 7 months ago

edhjer commented 8 months ago

When upgrading from net.openhft:chronicle-map:3.24ea3 -> net.openhft:chronicle-map:3.24ea4 I noticed an issue reading the values from my ChronicleMap<ByteBuffer,ByteBuffer> instance.

basic repro case below:

ChronicleMap<ByteBuffer, ByteBuffer> map = ChronicleMap
     .of(ByteBuffer.class, ByteBuffer.class)
     .name("my-map")
     .entries(10)
     .averageKeySize(100)
     .averageValue(ByteBuffer.allocate(Long.BYTES * 2))
     .skipCloseOnExitHook(true)
     .putReturnsNull(true)
     .create();
ByteBuffer key = ByteBuffer.wrap("foo".getBytes());
ByteBuffer counter = ByteBuffer.allocateDirect(Long.BYTES);
counter.putLong(0, 1L);
map.put(key, counter);

// using net.openhft:chronicle-map:3.24ea3 --> prints out 1
// using net.openhft:chronicle-map:3.24ea4 --> prints out 72057594037927936
System.out.println(counter.getLong(0)); 

We can see in the newer version the value read from counter is72057594037927936 instead of 1...digging in I came across this change which introduces a call bb.order(ByteOrder.nativeOrder()) that seems to modify the byte order on the buffer - in this case from BIG_ENDIAN -> LITTLE_ENDIAN I believe.

I'm curious if this change in the Chronicle-Bytes library is trying to get us to tweak our use of ChronicleMap, perhaps to use the Bytes object instead of ByteBuffer?

Appreciate any insight or help

Additional notes:

yevgenp commented 8 months ago

Hi @edhjer. Thanks for flagging that. As a workaround you could simply instantiate value as ByteBuffer counter = ByteBuffer.allocateDirect(Long.BYTES).order(ByteOrder.nativeOrder()) Though I agree that it's counterintuitive and seems more like a bug. Thus we will release a new ea version soon that has it fixed.