[英]how bytes are used to store information in protobuf
我试图了解协议缓冲区,这里是示例,我无法理解的是如何在后续消息中使用字节。 我不知道这个数字1 2 3
用于什么。
message Point {
required int32 x = 1;
required int32 y = 2;
optional string label = 3;
}
message Line {
required Point start = 1;
required Point end = 2;
optional string label = 3;
}
message Polyline {
repeated Point point = 1;
optional string label = 2;
}
我在google protobuf中阅读了以下段落,但无法理解此处所说的内容,有人可以帮助我了解如何使用字节存储信息。
每个元素上的“ = 1”,“ = 2”标记标识该字段在二进制编码中使用的唯一“标记”。 标签编号1至15与较高的编号相比,编码所需的字节减少了一个字节,因此,为了进行优化,您可以决定将这些标签用于常用或重复的元素,而将标签16和更高的标签用于较少使用的可选元素。
protobuf消息的一般形式是它是一系列形式的对:
对于您的问题,我们可以在很大程度上忘记有效负载-这与1/2/3和<= 16限制没有关系-所有这些都在字段标题中。 字段标头是“ varint”编码的整数; “ varint”使用最高有效位作为可选的延续位,因此较小的值(<= 127,假定为无符号而不是之字形)需要一个字节进行编码-较大的值需要多个字节。 换句话说,在需要设置连续位(需要至少2个字节)之前,您将获得7个有用的位。
然而! 字段标题本身由两部分组成:
wire-type是前3位,表示有效载荷的基本格式-“长度分隔”,“ 64位”,“ 32位”,“ varint”,“ start-group”,“ end-组”。 这意味着在我们拥有的7个有用位中,只剩下4个; 4位足以编码数字<=16。 这就是为什么建议将最常见的元素的数字<= 16(作为优化)。
在您的问题中,1/2/3是字段号; 在编码时,将其左移3,并由有效载荷的线型组成; 然后将这个组合值进行varint编码。
Protobuf像从id(它们称为标记的= 1,= 2)到实际值的映射一样存储消息。 与将数据更像具有固定偏移量的结构那样传输数据相比,这将能够更轻松地扩展它。 因此,例如,消息Point
看起来会像这样:
1 -> 100,
2 -> 500
然后将其解释为x=100
, y=500
和label=not set
。 在较低的级别上,protobuf以高度紧凑的格式序列化此标签-值映射,该格式除其他外,还使用可变长度编码存储整数。 您引用的段落仅在标记的情况下恰好突出了这一点,如果标记<16,则可以更紧凑地存储,但是对于protobuf定义中的整数值来说,它也是如此。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.