当前位置:网站首页>VLQ的介绍
VLQ的介绍
2022-07-19 05:08:00 【JYCJ_】
本文来介绍一下VLQ(variable-length quantity)
用变长字节数组来对整形进行编码,极大提高存储效率。
其实,这样的优点也被应用到了protobuf中,所以才有较高的序列化效率。
具体实现代码如下:
package vlq
import (
"math"
"math/bits"
)
// DecodeVarint takes a variable length VLQ based integer and
// decodes it into a 32 bit integer.
func DecodeVarint(input []byte) (uint32, error) {
const lastBitSet = 0x80 // 1000 0000
var d uint32
var bitPos int
for i := len(input) - 1; i >= 0; i-- {
n := uint8(input[i])
// Process the first 7 bits and ignore the 8th.
for checkBit := 0; checkBit < 7; checkBit++ {
// Rotate the last bit off and move it to the back.
// Before: 0000 0001
// After: 1000 0000
n = bits.RotateLeft8(n, -1)
// Calculate based on only those 1 bits that were rotated.
// Convert the bitPos to base 10.
if n >= lastBitSet {
switch {
case bitPos == 0:
d++
default:
base10 := math.Pow(2, float64(bitPos))
d += uint32(base10)
}
}
// Move the bit position.
bitPos++
}
}
return d, nil
}
// EncodeVarint takes a 32 bit integer and encodes it into
// a variable length VLQ based integer.
func EncodeVarint(n uint32) []byte {
const maxBytes = 4
const eightBitSet = 0x80 // 1000 0000
const lastBitSet = 0x80000000 // 1000 0000 0000 0000
encoded := make([]byte, maxBytes)
for bytePos := maxBytes - 1; bytePos >= 0; bytePos-- {
var d uint8
// Process the next 7 bits.
for checkBit := 0; checkBit < 7; checkBit++ {
// Rotate the last bit off and move it to the back.
// Before: 0000 0000 0000 0001
// After: 1000 0000 0000 0000
n = bits.RotateLeft32(n, -1)
// Calculate based on only those 1 bits that were
// rotated. Convert the bit position to base 10.
if n >= lastBitSet {
switch {
case checkBit == 0:
d++
default:
base10 := math.Pow(2, float64(checkBit))
d += uint8(base10)
}
}
}
// These values need the 8th bit to be set as 1.
if bytePos < 3 {
d += eightBitSet
}
// Store the value in reserve order.
encoded[bytePos] = d
}
// Remove leading zero values by finding values that only
// have their eight bit set.
for bytePos, b := range encoded {
if b == eightBitSet {
continue
}
encoded = encoded[bytePos:]
break
}
return encoded
}
在此抛砖引玉,有兴趣的同学,可以自行研究。
边栏推荐
猜你喜欢
Navicat如何修改语言(中文or英文)?
104 polkadot substrate : 许可网络
10e Polkadot substrate: configure contract tray
慧眼识花草微信小程序源码/植物辨别微信小程序源码
Wordpress固定链接怎么设置伪静态
10A Polkadot substrate: node index
10I polkadot substrate : 连接本地平行链
106 polkadot substrate : 无叉升级
Using NVM use, exit status 1 and exit status 145 are garbled
无需编程,通过配置零代码生成CRUD RESTful API
随机推荐
mysql密码忘了,怎么办?
在线支付,出款和收款
102 polkadot substrate : 存在证明
ES6语法(let、const、var 的区别、解构赋值、箭头函数、剩余参数、Array 的扩展方法)
Generate multiple databases at the same time based on multiple data sources and zero code, add, delete, modify and check restful API interfaces - mysql, PostgreSQL, Oracle, Microsoft SQL Server
基于多数据源零代码同时生成多个数据库CRUD增删改查RESTful API接口——MySql,PostgreSql,Oracle,Microsoft SQL Server
WordPress函数大全,学会了你就可以做主题了
106 polkadot substrate : 无叉升级
上传本地jar包到线上私服
无需编程,基于微软mssql数据库零代码生成CRUD增删改查RESTful API接口
函数内部的this指向/改变函数内部 this 指向
102 Polkadot substrate: proof of existence
函数的定义方式和调用
Golang:容易误解的一些操作
聚合支付滿足各行業接入多種支付通道
如何开通企业付款到零钱|红包功能
WordPress控制文章评论最少字数和最大字数
ThinkPHP5 验证码
微信公众号、微信支付开发
插补搜寻法和二分查找法 哪个效率更好?