1

我正在尝试使用 Long 键和可变大小的 byte[] 创建一个 Chronicle 映射,准确地说是一个序列化的 Java BitSet。我可以使用 Values 接口创建地图,但其中的数组大小是固定的。

因此,我希望使用 byte[] 或 Bytebuffer,因为它们是动态调整大小的,因此可以节省内存。这是受支持的用例吗?是否有使用带有 byte[] 或 ByteBuffer 值类的编年史地图的示例?以下代码失败

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());

出现错误:

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

我尝试使用 Values.newHeapInstance 创建值对象,但失败并出现错误:

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)

文档说 byte[] 和 ByteBuffer 支持开箱即用,但我找不到它的工作示例,所以决定在这里询问。

4

1 回答 1

1

您的测试在我的机器上工作(没有错误结束),但打印出意外的输出“0”。那是因为你忘了打电话ts2.flip(),代码应该是这样的:

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

通过此更改,代码段将打印“10”。

开箱即用,Chronicle Map 在 ByteBuffer 的位置和限制之间序列化 ByteBuffer 的内容。您可以在自定义序列化程序中覆盖它,并写入整个缓冲区。

顺便说一句,在您的情况下,我不建议使用小型直接缓冲区来将值放入 Chronicle Map (ts2)。为此使用普通的堆缓冲区。

于 2017-04-04T23:16:06.903 回答