一味宠爱|Google Protocol Buffers 序列化原理( 二 )
ZigZag encoding
通过上面的示例 , 我们可以发现 , 负数由于最高位是符号位 , 肯定是 1 , 对于负数来说并不能起到压缩效果 , 针对这种情况 ProtoBuffer 提供了有符号整型(sint32 和 sint64) 。
这种类型怎么序列化呢?负数最高位符号位一定是 1 , 比如我们可以将符号位移到最低位 。 负数在计算机中是补码存储的 , 越接近 0 的负数 , 高位 1 越多 , 由于是补码取过反 , 我们是不是可以再取反下 , 将 1 转换成 0 。
下面来看 sint32 公式(64 位的将 31 换成 63)
(n << 1) ^ (n >> 31)
- n<<1: 相当于将最低位空出来 。
- n>>31: 带符号移位 , 正数就是 32 个 0 , 负数就是 32 个 1 。
- 异或:相当于把符号位移到低位 , 并对负数做个取反 。
03
—
字符串
定义如下结构:
message Test2 {optional string b = 1;}给 b 赋值 "java" 输出的字节数组如下:[10, 4, 106, 97, 118, 97]第一个字节标记类型和序号 , 大家可以自己推算 。 第二个字节是长度 , 也是用压缩整形序列化 , 后面 4 个字节对应 “java” 这 4 个字符的 ASCII 码 。04
—
嵌套类型
如下 Test3 中包含 Test1 数据
message Test3 {optional Test1 c = 1;}Test1 中的 a 赋值 128 , 将 Test3 序列化输出如下:[10, 3, 8, -128, 1]- 10:0000 1010 对应的是 c 字符的位置和序号
- 3:接下来内容大小 , 3 个字节
- 8, -128, 1:对应的是 Test1 的数据
—
数组
repeated 是表示字段可以重复 。
message Test4 {repeated int32 d = 1;}这里给 d 添加 2 个值 “1” 和 “128” , 输出如下:[8, 1, 8, -128, 1]- 8, 1:这里表示 1
- 8, -128, 1:这里表示 128
这里在序列化的时候 , ProtoBuffer 并不保证数组的元素一定是连续存储 , 有可能中间序列化的有别的元素 。
对于基本类型来说数组可以压缩 , 省略掉每个元素都要标记 T。 配置了压缩之后 , 数组就是连续存储 。
message Test4 {repeated int32 d = 1 [packed=true];}同样的 “1” 和 “128” 输出如下:[10, 3, 1, -128, 1]- 10:field_number=1, wire_type=2 , 不定长 。
- 3:长度 , 接下来 3 个字节存放数据 。
- 1:0000 0001 , 高位是 0 说明是一个完整的数据 , 就是我们第一数据 1 。
- -128 , 1:对应的是第二个数据 128
—
Map
Map 的序列化方式跟数组是差不多的 , 我们可以认为一个 key-value 是一个 item , 其实就相当于一个 item 数组 。
定义如下结构
message Test5 {map e = 1;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 一味宠爱|最全盘点卡中国脖子的35项技术,折射中国工业水平的真实现状
- 金在中|4岁遭抛弃,被养父家8个姐姐宠爱,红遍亚洲后亲生父母上门认亲
- T恤|集万千宠爱于一身的T恤,不仅百搭还时髦,难怪这么受欢迎
- 德国天然宠粮Real Nature浩瀚母公司Fressnapf(宠爱碗)最全剖析
- 一味宠爱|上海:打造“四全”在线教育的“上海模式”
- 一味宠爱|2020开学季之手机CPU性能天梯图、拍照天梯图(0903)
- 一味宠爱|Springboot整合K8s读取ConfigMap刷新配置
- 一味宠爱|骗走十亿,“世联通证”究竟什么来头?,100多万人上当
- 一味宠爱|德国专家:中方顶级芯片若自研成功,美将无法对中国技术封锁
- 一味宠爱|微信撤回消息为何还要提示对方?腾讯解答真相
