You've already forked postgres_exporter
mirror of
https://github.com/prometheus-community/postgres_exporter.git
synced 2025-08-09 15:42:47 +03:00
This commit implements a massive refactor of the repository, and moves the build system over to use Mage (magefile.org) which should allow seamless building across multiple platforms.
248 lines
5.0 KiB
Go
248 lines
5.0 KiB
Go
package rardecode
|
|
|
|
const (
|
|
mainSize = 299
|
|
offsetSize = 60
|
|
lowOffsetSize = 17
|
|
lengthSize = 28
|
|
tableSize = mainSize + offsetSize + lowOffsetSize + lengthSize
|
|
)
|
|
|
|
var (
|
|
lengthBase = [28]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20,
|
|
24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224}
|
|
lengthExtraBits = [28]uint{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2,
|
|
2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}
|
|
|
|
offsetBase = [60]int{0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96,
|
|
128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096,
|
|
6144, 8192, 12288, 16384, 24576, 32768, 49152, 65536, 98304,
|
|
131072, 196608, 262144, 327680, 393216, 458752, 524288,
|
|
589824, 655360, 720896, 786432, 851968, 917504, 983040,
|
|
1048576, 1310720, 1572864, 1835008, 2097152, 2359296, 2621440,
|
|
2883584, 3145728, 3407872, 3670016, 3932160}
|
|
offsetExtraBits = [60]uint{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
|
|
6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
|
|
15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
|
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18}
|
|
|
|
shortOffsetBase = [8]int{0, 4, 8, 16, 32, 64, 128, 192}
|
|
shortOffsetExtraBits = [8]uint{2, 2, 3, 4, 5, 6, 6, 6}
|
|
)
|
|
|
|
type lz29Decoder struct {
|
|
codeLength [tableSize]byte
|
|
|
|
mainDecoder huffmanDecoder
|
|
offsetDecoder huffmanDecoder
|
|
lowOffsetDecoder huffmanDecoder
|
|
lengthDecoder huffmanDecoder
|
|
|
|
offset [4]int // history of previous offsets
|
|
length int // previous length
|
|
lowOffset int
|
|
lowOffsetRepeats int
|
|
|
|
br *rarBitReader
|
|
}
|
|
|
|
func (d *lz29Decoder) reset() {
|
|
for i := range d.offset {
|
|
d.offset[i] = 0
|
|
}
|
|
d.length = 0
|
|
for i := range d.codeLength {
|
|
d.codeLength[i] = 0
|
|
}
|
|
}
|
|
|
|
func (d *lz29Decoder) init(br *rarBitReader) error {
|
|
d.br = br
|
|
d.lowOffset = 0
|
|
d.lowOffsetRepeats = 0
|
|
|
|
n, err := d.br.readBits(1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
addOld := n > 0
|
|
|
|
cl := d.codeLength[:]
|
|
if err = readCodeLengthTable(d.br, cl, addOld); err != nil {
|
|
return err
|
|
}
|
|
|
|
d.mainDecoder.init(cl[:mainSize])
|
|
cl = cl[mainSize:]
|
|
d.offsetDecoder.init(cl[:offsetSize])
|
|
cl = cl[offsetSize:]
|
|
d.lowOffsetDecoder.init(cl[:lowOffsetSize])
|
|
cl = cl[lowOffsetSize:]
|
|
d.lengthDecoder.init(cl)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *lz29Decoder) readFilterData() (b []byte, err error) {
|
|
flags, err := d.br.ReadByte()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
n := (int(flags) & 7) + 1
|
|
switch n {
|
|
case 7:
|
|
n, err = d.br.readBits(8)
|
|
n += 7
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
case 8:
|
|
n, err = d.br.readBits(16)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
buf := make([]byte, n+1)
|
|
buf[0] = flags
|
|
err = d.br.readFull(buf[1:])
|
|
|
|
return buf, err
|
|
}
|
|
|
|
func (d *lz29Decoder) readEndOfBlock() error {
|
|
n, err := d.br.readBits(1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if n > 0 {
|
|
return endOfBlock
|
|
}
|
|
n, err = d.br.readBits(1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if n > 0 {
|
|
return endOfBlockAndFile
|
|
}
|
|
return endOfFile
|
|
}
|
|
|
|
func (d *lz29Decoder) decode(win *window) ([]byte, error) {
|
|
sym, err := d.mainDecoder.readSym(d.br)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
switch {
|
|
case sym < 256:
|
|
// literal
|
|
win.writeByte(byte(sym))
|
|
return nil, nil
|
|
case sym == 256:
|
|
return nil, d.readEndOfBlock()
|
|
case sym == 257:
|
|
return d.readFilterData()
|
|
case sym == 258:
|
|
// use previous offset and length
|
|
case sym < 263:
|
|
i := sym - 259
|
|
offset := d.offset[i]
|
|
copy(d.offset[1:i+1], d.offset[:i])
|
|
d.offset[0] = offset
|
|
|
|
i, err := d.lengthDecoder.readSym(d.br)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
d.length = lengthBase[i] + 2
|
|
bits := lengthExtraBits[i]
|
|
if bits > 0 {
|
|
n, err := d.br.readBits(bits)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
d.length += n
|
|
}
|
|
case sym < 271:
|
|
i := sym - 263
|
|
copy(d.offset[1:], d.offset[:])
|
|
offset := shortOffsetBase[i] + 1
|
|
bits := shortOffsetExtraBits[i]
|
|
if bits > 0 {
|
|
n, err := d.br.readBits(bits)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
offset += n
|
|
}
|
|
d.offset[0] = offset
|
|
|
|
d.length = 2
|
|
default:
|
|
i := sym - 271
|
|
d.length = lengthBase[i] + 3
|
|
bits := lengthExtraBits[i]
|
|
if bits > 0 {
|
|
n, err := d.br.readBits(bits)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
d.length += n
|
|
}
|
|
|
|
i, err = d.offsetDecoder.readSym(d.br)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
offset := offsetBase[i] + 1
|
|
bits = offsetExtraBits[i]
|
|
|
|
switch {
|
|
case bits >= 4:
|
|
if bits > 4 {
|
|
n, err := d.br.readBits(bits - 4)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
offset += n << 4
|
|
}
|
|
|
|
if d.lowOffsetRepeats > 0 {
|
|
d.lowOffsetRepeats--
|
|
offset += d.lowOffset
|
|
} else {
|
|
n, err := d.lowOffsetDecoder.readSym(d.br)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if n == 16 {
|
|
d.lowOffsetRepeats = 15
|
|
offset += d.lowOffset
|
|
} else {
|
|
offset += n
|
|
d.lowOffset = n
|
|
}
|
|
}
|
|
case bits > 0:
|
|
n, err := d.br.readBits(bits)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
offset += n
|
|
}
|
|
|
|
if offset >= 0x2000 {
|
|
d.length++
|
|
if offset >= 0x40000 {
|
|
d.length++
|
|
}
|
|
}
|
|
copy(d.offset[1:], d.offset[:])
|
|
d.offset[0] = offset
|
|
}
|
|
win.copyBytes(d.length, d.offset[0])
|
|
return nil, nil
|
|
}
|