aboutsummaryrefslogtreecommitdiffstats
path: root/library/go/blockcodecs/blocklz4/lz4.go
blob: bb549b9beb3f5b8ef85af0a7adf5058f5cf88599 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package blocklz4

import (
	"encoding/binary"

	"github.com/pierrec/lz4"

	"a.yandex-team.ru/library/go/blockcodecs"
)

type lz4Codec struct{}

func (l lz4Codec) ID() blockcodecs.CodecID {
	return 6051
}

func (l lz4Codec) Name() string {
	return "lz4-fast14-safe"
}

func (l lz4Codec) DecodedLen(in []byte) (int, error) {
	return blockcodecs.DecodedLen(in)
}

func (l lz4Codec) Encode(dst, src []byte) ([]byte, error) {
	dst = dst[:cap(dst)]

	n := lz4.CompressBlockBound(len(src)) + 8
	if len(dst) < n {
		dst = append(dst, make([]byte, n-len(dst))...)
	}
	binary.LittleEndian.PutUint64(dst, uint64(len(src)))

	m, err := lz4.CompressBlock(src, dst[8:], nil)
	if err != nil {
		return nil, err
	}

	return dst[:8+m], nil
}

func (l lz4Codec) Decode(dst, src []byte) ([]byte, error) {
	n, err := lz4.UncompressBlock(src[8:], dst)
	if err != nil {
		return nil, err
	}
	return dst[:n], nil
}

type lz4HCCodec struct {
	lz4Codec
}

func (l lz4HCCodec) ID() blockcodecs.CodecID {
	return 62852
}

func (l lz4HCCodec) Name() string {
	return "lz4-hc-safe"
}

func (l lz4HCCodec) Encode(dst, src []byte) ([]byte, error) {
	dst = dst[:cap(dst)]

	n := lz4.CompressBlockBound(len(src)) + 8
	if len(dst) < n {
		dst = append(dst, make([]byte, n-len(dst))...)
	}
	binary.LittleEndian.PutUint64(dst, uint64(len(src)))

	m, err := lz4.CompressBlockHC(src, dst[8:], 0)
	if err != nil {
		return nil, err
	}

	return dst[:8+m], nil
}

func init() {
	blockcodecs.Register(lz4Codec{})
	blockcodecs.Register(lz4HCCodec{})
}