mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
feat(util): add compressor for http gzip
Benchmark_Gzip-4 4005 317424 ns/op 855350 B/op 29 allocs/op Signed-off-by: slasher <mcq.sejust@gmail.com>
This commit is contained in:
parent
96a24a26e9
commit
58101cf142
43
util/compressor/compressor.go
Normal file
43
util/compressor/compressor.go
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2023 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package compressor
|
||||
|
||||
const EncodingGzip = "gzip"
|
||||
|
||||
// Compressor bytes compressor.
|
||||
// TODO: add stream Compressor.
|
||||
type Compressor interface {
|
||||
Compress([]byte) ([]byte, error)
|
||||
Decompress([]byte) ([]byte, error)
|
||||
}
|
||||
|
||||
type none struct{}
|
||||
|
||||
func (none) Compress(pb []byte) ([]byte, error) { return pb, nil }
|
||||
func (none) Decompress(cb []byte) ([]byte, error) { return cb, nil }
|
||||
|
||||
var compressors = make(map[string]func() Compressor)
|
||||
|
||||
func init() {
|
||||
compressors[""] = func() Compressor { return none{} }
|
||||
compressors[EncodingGzip] = func() Compressor { return gzipCompressor{} }
|
||||
}
|
||||
|
||||
func New(encoding string) Compressor {
|
||||
if newCompressor, ok := compressors[encoding]; ok {
|
||||
return newCompressor()
|
||||
}
|
||||
return compressors[""]()
|
||||
}
|
||||
39
util/compressor/compressor_test.go
Normal file
39
util/compressor/compressor_test.go
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2023 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package compressor_test
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/cubefs/cubefs/util/compressor"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCompressor_New(t *testing.T) {
|
||||
for _, encoding := range []string{"", "none", "balaa"} {
|
||||
buf := make([]byte, 1024)
|
||||
rand.Read(buf)
|
||||
|
||||
c := compressor.New(encoding)
|
||||
require.NotNil(t, c)
|
||||
cbuf, err := c.Compress(buf)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, buf, cbuf)
|
||||
pbuf, err := c.Decompress(cbuf)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, buf, pbuf)
|
||||
}
|
||||
}
|
||||
52
util/compressor/gzip.go
Normal file
52
util/compressor/gzip.go
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright 2023 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package compressor
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"io"
|
||||
)
|
||||
|
||||
// TODO: reuse bytes.Buffer
|
||||
|
||||
type gzipCompressor struct{}
|
||||
|
||||
func (gzipCompressor) Compress(pb []byte) ([]byte, error) {
|
||||
buffer := new(bytes.Buffer)
|
||||
gw := gzip.NewWriter(buffer)
|
||||
if _, err := gw.Write(pb); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := gw.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
func (gzipCompressor) Decompress(cb []byte) ([]byte, error) {
|
||||
gr, err := gzip.NewReader(bytes.NewBuffer(cb))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buffer := new(bytes.Buffer)
|
||||
if _, err := io.Copy(buffer, gr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := gr.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
47
util/compressor/gzip_test.go
Normal file
47
util/compressor/gzip_test.go
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2023 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package compressor_test
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/cubefs/cubefs/util/compressor"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCompressor_Gzip(t *testing.T) {
|
||||
for range [100]struct{}{} {
|
||||
buf := make([]byte, 1024)
|
||||
rand.Read(buf)
|
||||
c := compressor.New(compressor.EncodingGzip)
|
||||
require.NotNil(t, c)
|
||||
cbuf, err := c.Compress(buf)
|
||||
require.NoError(t, err)
|
||||
pbuf, err := c.Decompress(cbuf)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, buf, pbuf)
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_Gzip(b *testing.B) {
|
||||
buf := make([]byte, 1024)
|
||||
rand.Read(buf)
|
||||
for ii := 0; ii < b.N; ii++ {
|
||||
c := compressor.New(compressor.EncodingGzip)
|
||||
cbuf, _ := c.Compress(buf)
|
||||
c.Decompress(cbuf)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user