java如何使用编年史映射在随机索引上使用get/set序列化/反序列化long[]值?
我不熟悉编年史地图。我正在尝试使用历史记录映射对堆外映射进行建模,其中键是一个短基元,值是一个长基元数组。已知给定映射的长数组值的最大大小。但是,我将有多个这种类型的映射,每个映射对于长数组值可能有不同的最大大小。我的问题涉及密钥和值的序列化/反序列化
通过阅读文档,我了解到对于键,我可以使用值类型ShortValue并重用该接口实现的实例。关于这个值,我发现这个页面讨论的是DataAccess and SizedReader,它给出了byte[]的一个例子,但我不确定如何将它适应于长[]。我还有一个额外的要求,就是我需要在长数组中的任意索引处获取和设置值,而无需每次完全序列化/反序列化整个值
因此,我的问题是:在构建映射时,如何对值类型进行建模?如果每个映射的最大大小已知,并且我需要能够读取和写入随机索引,而无需每次序列化/反序列化整个值负载,那么对于长[]数组,我需要什么序列化/反序列化代码?理想情况下,长[]将直接编码/解码到堆外或从堆外进行编码/解码,而无需进行堆内到字节[]的中间转换,并且历史记录映射代码也不会在运行时分配。多谢各位
# 1 楼答案
首先,我建议使用某种
LongList
接口抽象,而不是long[]
,这样可以更容易地处理大小变化,提供可选的flyweight实现,等等如果只想读/写大型列表中的单个元素,应该使用advanced contexts API:
注:
writeLock()
,否则在调用context.entry()
方法时会自动获取readLock(),以后将无法将read lock升级为write lock。请仔细阅读^{RandomDataInput
,但您可以确定(它在Data.bytes()
javadoc中指定)它实际上是^{RandomDataInput
和RandomDataOutput
的组合)李>SizedReader
和SizedWriter
(或DataAccess
)。请注意,使用了“字节/元素联合大小”技术,与^{LongListMarshaller
基于该示例类李>单元素读取的实现类似
# 2 楼答案
回答额外问题:
使用
DataAccess
而不是SizedWriter
可以在Map.put(key, value)
上创建一个值较小的数据副本。然而,如果在您的用例中putOneValue()
(如上面的例子)是主要的查询类型,那么它不会有太大的区别。如果Map.put(key, value)
(和replace()
等,即任何“全值写入”操作)很重要,那么仍然可以为LongList
实现DataAccess
。它看起来是这样的:为了提高效率,方法} 、^{} and ^{} 和Custom serialization checklist
size()
和writeTo()
是关键。但是正确地实现所有其他方法(我在这里没有写)也很重要。非常仔细地阅读DataAccess
、Data
和StatefulCopyable
javadocs,也要非常注意教程中的Understanding ^{跨进程是安全的,请注意,接口名为InterProcessReadWriteUpdateLock
将一个键的值存储一次,之后不更改值的大小(也不删除键),不会导致外部碎片。更改值的大小或删除键可能会导致外部碎片^{} 配置允许在外部和内部碎片之间进行交易。区块越大,外部碎片越少,但内部碎片越多。如果您的值明显大于页面大小(4KB),那么您可以设置非常大的块大小,并且仍然有页面大小限制的内部碎片,因为Chronicle Map能够利用Linux中的延迟页面分配功能