我正在玩比特币区块链,学习Scala和一些有用的库。目前,我正试图用SCodec对块进行解码和编码,我的问题是vectorOfN函数将其大小作为Int。如何使用长字段作为大小,同时仍然保持的全部值范围。换句话说,是否有一个vectorOfLongN函数?
这是我的代码,如果我使用的是vintL而不是vlongL,它会编译得很好:
object Block {
implicit val codec: Codec[Block] = {
("header" | Codec[BlockHeader]) ::
(("numTx" | vlongL) >>:~
{ numTx => ("transactions" | vectorOfN(provide(numTx), Codec[Transaction]) ).hlist })
}.as[Block]
}您可以假设为Blockheader和事务实现了适当的编解码器。实际上,vlong是用来简化这个问题的,因为比特币对可变大小的ints使用了自己的编解码器。
发布于 2017-12-11 03:41:13
我不是记分专家,但我的常识表明,这是不可能的,因为Scala的Vector是GenSeqLike的一个子类型,仅限于有length类型的Int和接受Int索引作为其论点的apply。AFAIU的这种限制来自底层JVM平台,在该平台中,不能有比Integer.MAX_VALUE更大的数组,即大约2^31 (也请参见“Java批评”维基)。虽然理论上Vector可以解决这一限制,但它并没有完成。因此,vectorOfN也支持Long大小是没有意义的。
换句话说,如果您想要这样的东西,您可能应该从创建您自己的类似向量的类开始,该类确实支持针对JVM限制的Long索引。
发布于 2017-12-11 11:50:17
您可能想看看记分-流,当您的所有数据都无法立即可用或内存中不合适时,它就会派上用场。
基本上,您可以使用通常的codecs.X并通过scodec.stream.decode.many(normal_codec)将其转换为StreamDecoder。这样,您就可以通过scodec处理数据,而无需将其完全加载到内存中。
然后,StreamDecoder提供了像decodeInputStream这样的scodec's普通decode的方法。
(不久前,我在稍微不同的上下文中使用了它--解析客户端发送到服务器的数据--但它看起来也适用于这里)。
https://stackoverflow.com/questions/47738319
复制相似问题