| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- //go:build !appengine && !noasm && gc
- // +build !appengine,!noasm,gc
- package s2
- import (
- "sync"
- "github.com/klauspost/compress/internal/race"
- )
- const hasAmd64Asm = true
- var encPools [4]sync.Pool
- // encodeBlock encodes a non-empty src to a guaranteed-large-enough dst. It
- // assumes that the varint-encoded length of the decompressed bytes has already
- // been written.
- //
- // It also assumes that:
- //
- // len(dst) >= MaxEncodedLen(len(src)) &&
- // minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize
- func encodeBlock(dst, src []byte) (d int) {
- race.ReadSlice(src)
- race.WriteSlice(dst)
- const (
- // Use 12 bit table when less than...
- limit12B = 16 << 10
- // Use 10 bit table when less than...
- limit10B = 4 << 10
- // Use 8 bit table when less than...
- limit8B = 512
- )
- if len(src) >= 4<<20 {
- const sz, pool = 65536, 0
- tmp, ok := encPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encPools[pool].Put(tmp)
- return encodeBlockAsm(dst, src, tmp)
- }
- if len(src) >= limit12B {
- const sz, pool = 65536, 0
- tmp, ok := encPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encPools[pool].Put(tmp)
- return encodeBlockAsm4MB(dst, src, tmp)
- }
- if len(src) >= limit10B {
- const sz, pool = 16384, 1
- tmp, ok := encPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encPools[pool].Put(tmp)
- return encodeBlockAsm12B(dst, src, tmp)
- }
- if len(src) >= limit8B {
- const sz, pool = 4096, 2
- tmp, ok := encPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encPools[pool].Put(tmp)
- return encodeBlockAsm10B(dst, src, tmp)
- }
- if len(src) < minNonLiteralBlockSize {
- return 0
- }
- const sz, pool = 1024, 3
- tmp, ok := encPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encPools[pool].Put(tmp)
- return encodeBlockAsm8B(dst, src, tmp)
- }
- var encBetterPools [5]sync.Pool
- // encodeBlockBetter encodes a non-empty src to a guaranteed-large-enough dst. It
- // assumes that the varint-encoded length of the decompressed bytes has already
- // been written.
- //
- // It also assumes that:
- //
- // len(dst) >= MaxEncodedLen(len(src)) &&
- // minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize
- func encodeBlockBetter(dst, src []byte) (d int) {
- race.ReadSlice(src)
- race.WriteSlice(dst)
- const (
- // Use 12 bit table when less than...
- limit12B = 16 << 10
- // Use 10 bit table when less than...
- limit10B = 4 << 10
- // Use 8 bit table when less than...
- limit8B = 512
- )
- if len(src) > 4<<20 {
- const sz, pool = 589824, 0
- tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encBetterPools[pool].Put(tmp)
- return encodeBetterBlockAsm(dst, src, tmp)
- }
- if len(src) >= limit12B {
- const sz, pool = 589824, 0
- tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encBetterPools[pool].Put(tmp)
- return encodeBetterBlockAsm4MB(dst, src, tmp)
- }
- if len(src) >= limit10B {
- const sz, pool = 81920, 0
- tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encBetterPools[pool].Put(tmp)
- return encodeBetterBlockAsm12B(dst, src, tmp)
- }
- if len(src) >= limit8B {
- const sz, pool = 20480, 1
- tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encBetterPools[pool].Put(tmp)
- return encodeBetterBlockAsm10B(dst, src, tmp)
- }
- if len(src) < minNonLiteralBlockSize {
- return 0
- }
- const sz, pool = 5120, 2
- tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encBetterPools[pool].Put(tmp)
- return encodeBetterBlockAsm8B(dst, src, tmp)
- }
- // encodeBlockSnappy encodes a non-empty src to a guaranteed-large-enough dst. It
- // assumes that the varint-encoded length of the decompressed bytes has already
- // been written.
- //
- // It also assumes that:
- //
- // len(dst) >= MaxEncodedLen(len(src)) &&
- // minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize
- func encodeBlockSnappy(dst, src []byte) (d int) {
- race.ReadSlice(src)
- race.WriteSlice(dst)
- const (
- // Use 12 bit table when less than...
- limit12B = 16 << 10
- // Use 10 bit table when less than...
- limit10B = 4 << 10
- // Use 8 bit table when less than...
- limit8B = 512
- )
- if len(src) > 65536 {
- const sz, pool = 65536, 0
- tmp, ok := encPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encPools[pool].Put(tmp)
- return encodeSnappyBlockAsm(dst, src, tmp)
- }
- if len(src) >= limit12B {
- const sz, pool = 65536, 0
- tmp, ok := encPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encPools[pool].Put(tmp)
- return encodeSnappyBlockAsm64K(dst, src, tmp)
- }
- if len(src) >= limit10B {
- const sz, pool = 16384, 1
- tmp, ok := encPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encPools[pool].Put(tmp)
- return encodeSnappyBlockAsm12B(dst, src, tmp)
- }
- if len(src) >= limit8B {
- const sz, pool = 4096, 2
- tmp, ok := encPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encPools[pool].Put(tmp)
- return encodeSnappyBlockAsm10B(dst, src, tmp)
- }
- if len(src) < minNonLiteralBlockSize {
- return 0
- }
- const sz, pool = 1024, 3
- tmp, ok := encPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encPools[pool].Put(tmp)
- return encodeSnappyBlockAsm8B(dst, src, tmp)
- }
- // encodeBlockSnappy encodes a non-empty src to a guaranteed-large-enough dst. It
- // assumes that the varint-encoded length of the decompressed bytes has already
- // been written.
- //
- // It also assumes that:
- //
- // len(dst) >= MaxEncodedLen(len(src)) &&
- // minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize
- func encodeBlockBetterSnappy(dst, src []byte) (d int) {
- race.ReadSlice(src)
- race.WriteSlice(dst)
- const (
- // Use 12 bit table when less than...
- limit12B = 16 << 10
- // Use 10 bit table when less than...
- limit10B = 4 << 10
- // Use 8 bit table when less than...
- limit8B = 512
- )
- if len(src) > 65536 {
- const sz, pool = 589824, 0
- tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encBetterPools[pool].Put(tmp)
- return encodeSnappyBetterBlockAsm(dst, src, tmp)
- }
- if len(src) >= limit12B {
- const sz, pool = 294912, 4
- tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encBetterPools[pool].Put(tmp)
- return encodeSnappyBetterBlockAsm64K(dst, src, tmp)
- }
- if len(src) >= limit10B {
- const sz, pool = 81920, 0
- tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encBetterPools[pool].Put(tmp)
- return encodeSnappyBetterBlockAsm12B(dst, src, tmp)
- }
- if len(src) >= limit8B {
- const sz, pool = 20480, 1
- tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encBetterPools[pool].Put(tmp)
- return encodeSnappyBetterBlockAsm10B(dst, src, tmp)
- }
- if len(src) < minNonLiteralBlockSize {
- return 0
- }
- const sz, pool = 5120, 2
- tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
- if !ok {
- tmp = &[sz]byte{}
- }
- race.WriteSlice(tmp[:])
- defer encBetterPools[pool].Put(tmp)
- return encodeSnappyBetterBlockAsm8B(dst, src, tmp)
- }
|