1

我正在玩比特币区块链来学习 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 和 Transactions 实现了适当的编解码器。实际上,vlong 被用来简化这个问题,因为比特币使用自己的编解码器来处理可变大小的整数。

4

2 回答 2

0

我不是 scodec 专家,但我的常识表明这是不可能的,因为 Scala 的Vector子类型GenSeqLike仅限于具有length类型Int并且apply接受Int索引作为其参数。而 AFAIU 这种限制来自底层 JVM 平台,在该平台上,数组的大小不能超过Integer.MAX_VALUE2^31 左右(另请参见“Java 批评”维基)。虽然Vector理论上可以解决这个限制,但它没有完成。因此,vectorOfN支持Long大小也没有任何意义。

换句话说,如果您想要这样的东西,您可能应该从创建自己的类 Vector 类开始,该类确实支持Long围绕 JVM 限制工作的索引。

于 2017-12-11T03:41:13.583 回答
0

您可能想查看scodec-stream,当您的所有数据无法立即使用或无法放入内存时,它会派上用场。

基本上,你会使用你常用的codecs.X并将其变成StreamDecodervia scodec.stream.decode.many(normal_codec)。通过这种方式,您可以处理数据,scodec而无需将其完全加载到内存中。

A StreamDecoderthen 提供与decodeInputStream通常scodec's一样的方法decode

(我不久前在稍微不同的上下文中使用过它——解析客户端发送到服务器的数据——但它看起来也适用于这里)。

于 2017-12-11T11:50:17.870 回答