简体   繁体   English

Scodec:将vectorOfN与vlong字段一起使用

[英]Scodec: Using vectorOfN with a vlong field

I am playing around with the Bitcoin blockchain to learn Scala and some useful libraries. 我在玩比特币区块链学习Scala和一些有用的库。 Currently I am trying to decode and encode Blocks with SCodec and my problem is that the vectorOfN function takes its size as an Int. 目前,我正在尝试使用SCodec解码和编码块,而我的问题是vectorOfN函数将其大小视为Int。 How can I use a long field for the size while still preserving the full value range . 如何在保留整个值范围的同时使用长字段表示大小。 In other words is there a vectorOfLongN function? 换句话说,是否有vectorOfLongN函数?

This is my code which would compile fine if I were using vintL instead of vlongL: 这是我的代码,如果我使用vintL而不是vlongL可以很好地编译:

object Block {
  implicit val codec: Codec[Block] = {
    ("header" | Codec[BlockHeader]) ::
    (("numTx" | vlongL) >>:~
      { numTx => ("transactions" | vectorOfN(provide(numTx), Codec[Transaction]) ).hlist })
  }.as[Block]
}

You may assume that appropriate Codecs for the Blockheader and the Transactions are implemented. 您可以假定已为Blockheader和事务实现了适当的编解码器。 Actually, vlong is used as a simplification for this question, because Bitcoin uses its own codec for variable sized ints. 实际上,vlong可以简化该问题,因为比特币将自己的编解码器用于可变大小的整数。

I'm not a scodec specialist but my common sense suggests that this is not possible because Scala's Vector being a subtype of GenSeqLike is limited to have length of type Int and apply that accepts Int index as its argument. 我不是scodec专家,但我的常识表明这是不可能的,因为Scala的VectorGenSeqLike的子类型,限于具有Int类型的length ,并且apply接受Int索引作为其参数。 And AFAIU this limitation comes from the underlying JVM platform where you can't have an array of size more than Integer.MAX_VALUE ie around 2^31 (see also "Criticism of Java" wiki ). 而且AFAIU这个限制来自底层的JVM平台,在该平台上,数组的大小不能超过Integer.MAX_VALUE即大约2 ^ 31(另请参见“ Java的批判”维基 )。 And although Vector theoretically could have work this limitation around, it was not done. 并且尽管Vector理论上可以解决此限制,但是并没有做到。 So it makes no sense for vectorOfN to support Long size as well. 因此, vectorOfN不能支持Long size。

In other words, if you want something like this, you probably should start from creating your own Vector-like class that does support Long indices working around JVM limitations. 换句话说,如果您想要这样的东西,您可能应该从创建自己的类似Vector的类开始,该类确实支持围绕JVM限制的Long索引。

You may want to take a look at scodec-stream , which comes in handy when all of your data is not available immediately or does not fit into memory. 您可能想看一下scodec-stream ,当所有数据都不立即可用或不适合内存时,它会派上用场。

Basically, you would use your usual codecs.X and turn it into a StreamDecoder via scodec.stream.decode.many(normal_codec) . 基本上,您将使用常规的codecs.X并通过scodec.stream.decode.many(normal_codec)将其转换为StreamDecoder This way you can work with the data through scodec without the need to load it into memory entirely. 这样,您可以通过scodec数据,而无需将其完全加载到内存中。

A StreamDecoder then offers methods like decodeInputStream along scodec's usual decode . 一个StreamDecoder然后提供类似的方法decodeInputStream沿scodec's通常的decode

(I used it a while ago in a slightly different context – parsing data sent by a client to a server – but it looks like it would apply here as well). (前一阵子我在一个稍有不同的上下文中使用了它-解析客户端发送到服务器的数据-但看起来它也适用于此)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM