mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-22 16:36:27 +01:00
271 lines
4.2 KiB
Go
271 lines
4.2 KiB
Go
|
package varint
|
||
|
|
||
|
const maxUint64 = uint64(1<<64 - 1)
|
||
|
|
||
|
// MaxLenN is the maximum length of a varint-encoded N-bit integer.
|
||
|
const (
|
||
|
MaxLen8 = 2
|
||
|
MaxLen16 = 3
|
||
|
MaxLen32 = 5
|
||
|
MaxLen64 = 10
|
||
|
)
|
||
|
|
||
|
// MaxValN is the maximum varint-encoded integer that fits in N bytes.
|
||
|
const (
|
||
|
MaxVal9 = maxUint64 >> (1 + iota*7)
|
||
|
MaxVal8
|
||
|
MaxVal7
|
||
|
MaxVal6
|
||
|
MaxVal5
|
||
|
MaxVal4
|
||
|
MaxVal3
|
||
|
MaxVal2
|
||
|
MaxVal1
|
||
|
)
|
||
|
|
||
|
// UvarintSize returns the number of bytes necessary to encode a given uint.
|
||
|
func UvarintSize(x uint64) int {
|
||
|
if x <= MaxVal4 {
|
||
|
if x <= MaxVal1 {
|
||
|
return 1
|
||
|
} else if x <= MaxVal2 {
|
||
|
return 2
|
||
|
} else if x <= MaxVal3 {
|
||
|
return 3
|
||
|
}
|
||
|
return 4
|
||
|
}
|
||
|
if x <= MaxVal5 {
|
||
|
return 5
|
||
|
} else if x <= MaxVal6 {
|
||
|
return 6
|
||
|
} else if x <= MaxVal7 {
|
||
|
return 7
|
||
|
} else if x <= MaxVal8 {
|
||
|
return 8
|
||
|
} else if x <= MaxVal9 {
|
||
|
return 9
|
||
|
}
|
||
|
return 10
|
||
|
}
|
||
|
|
||
|
// Uvarint decodes a uint64 from buf and returns that value and the
|
||
|
// number of bytes read (> 0). If an error occurred, the value is 0
|
||
|
// and the number of bytes n is <= 0 meaning:
|
||
|
//
|
||
|
// n == 0: buf too small
|
||
|
// n < 0: value larger than 64 bits (overflow)
|
||
|
// and -n is the number of bytes read
|
||
|
//
|
||
|
func Uvarint(buf []byte) (uint64, int) {
|
||
|
// Fully unrolled implementation of binary.Uvarint.
|
||
|
//
|
||
|
// It will also eliminate bound checks for buffers larger than 9 bytes.
|
||
|
sz := len(buf)
|
||
|
if sz == 0 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
const (
|
||
|
step = 7
|
||
|
bit = 1 << 7
|
||
|
mask = bit - 1
|
||
|
)
|
||
|
if sz >= 10 { // no bound checks
|
||
|
// i == 0
|
||
|
b := buf[0]
|
||
|
if b < bit {
|
||
|
return uint64(b), 1
|
||
|
}
|
||
|
x := uint64(b & mask)
|
||
|
var s uint = step
|
||
|
|
||
|
// i == 1
|
||
|
b = buf[1]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 2
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 2
|
||
|
b = buf[2]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 3
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 3
|
||
|
b = buf[3]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 4
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 4
|
||
|
b = buf[4]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 5
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 5
|
||
|
b = buf[5]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 6
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 6
|
||
|
b = buf[6]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 7
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 7
|
||
|
b = buf[7]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 8
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 8
|
||
|
b = buf[8]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 9
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 9
|
||
|
b = buf[9]
|
||
|
if b < bit {
|
||
|
if b > 1 {
|
||
|
return 0, -10 // overflow
|
||
|
}
|
||
|
return x | uint64(b)<<s, 10
|
||
|
} else if sz == 10 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
for j, b := range buf[10:] {
|
||
|
if b < bit {
|
||
|
return 0, -(11 + j)
|
||
|
}
|
||
|
}
|
||
|
return 0, 0
|
||
|
}
|
||
|
|
||
|
// i == 0
|
||
|
b := buf[0]
|
||
|
if b < bit {
|
||
|
return uint64(b), 1
|
||
|
} else if sz == 1 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
x := uint64(b & mask)
|
||
|
var s uint = step
|
||
|
|
||
|
// i == 1
|
||
|
b = buf[1]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 2
|
||
|
} else if sz == 2 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 2
|
||
|
b = buf[2]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 3
|
||
|
} else if sz == 3 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 3
|
||
|
b = buf[3]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 4
|
||
|
} else if sz == 4 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 4
|
||
|
b = buf[4]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 5
|
||
|
} else if sz == 5 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 5
|
||
|
b = buf[5]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 6
|
||
|
} else if sz == 6 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 6
|
||
|
b = buf[6]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 7
|
||
|
} else if sz == 7 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 7
|
||
|
b = buf[7]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 8
|
||
|
} else if sz == 8 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 8
|
||
|
b = buf[8]
|
||
|
if b < bit {
|
||
|
return x | uint64(b)<<s, 9
|
||
|
} else if sz == 9 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
x |= uint64(b&mask) << s
|
||
|
s += step
|
||
|
|
||
|
// i == 9
|
||
|
b = buf[9]
|
||
|
if b < bit {
|
||
|
if b > 1 {
|
||
|
return 0, -10 // overflow
|
||
|
}
|
||
|
return x | uint64(b)<<s, 10
|
||
|
} else if sz == 10 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
for j, b := range buf[10:] {
|
||
|
if b < bit {
|
||
|
return 0, -(11 + j)
|
||
|
}
|
||
|
}
|
||
|
return 0, 0
|
||
|
}
|