go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/gae/internal/zstd/zstd.go (about) 1 // Copyright 2020 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package zstd holds zstd encoders and decoders used by the GAE library. 16 package zstd 17 18 import ( 19 "github.com/klauspost/compress/zstd" 20 ) 21 22 // Globally shared zstd encoder and decoder. We use only their EncodeAll and 23 // DecodeAll methods which are allowed to be used concurrently. Internally, both 24 // the encode and the decoder have worker pools (limited by GOMAXPROCS) and each 25 // concurrent EncodeAll/DecodeAll call temporary consumes one worker (so overall 26 // we do not run more jobs that we have cores for). 27 var ( 28 zstdEncoder *zstd.Encoder 29 zstdDecoder *zstd.Decoder 30 ) 31 32 func init() { 33 var err error 34 if zstdEncoder, err = zstd.NewWriter(nil); err != nil { 35 panic(err) // this is impossible 36 } 37 if zstdDecoder, err = zstd.NewReader(nil); err != nil { 38 panic(err) // this is impossible 39 } 40 } 41 42 // EncodeAll will encode all input in src and append it to dst. 43 // 44 // This function can be called concurrently, but each call will only run on 45 // a single goroutine. If empty input is given, nothing is returned. Data 46 // compressed with EncodeAll can be decoded via DecodeAll. 47 func EncodeAll(src, dst []byte) []byte { 48 return zstdEncoder.EncodeAll(src, dst) 49 } 50 51 // DecodeAll allows stateless decoding of a blob of bytes. 52 // 53 // Output will be appended to dst, so if the destination size is known you 54 // can pre-allocate the destination slice to avoid allocations. DecodeAll can 55 // be used concurrently. 56 func DecodeAll(input, dst []byte) ([]byte, error) { 57 return zstdDecoder.DecodeAll(input, dst) 58 }