Skip to content

Commit

Permalink
compression: add support for the zstd algorithm
Browse files Browse the repository at this point in the history
zstd is a compression algorithm that has a very fast decoder, while
providing also good compression ratios.  The fast decoder makes it
suitable for container images, as decompressing the tarballs is a very
expensive operation.  This is a first step at supporting zstd as we We
don't yet generate zstd layers.

In my testing, copying the Fedora image from a local dir: repository,
the wall clock time passed from ~8s with gzip compression to ~4.5s
with zstd.

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Jun 7, 2019
1 parent 476d0be commit 13a8e74
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 0 deletions.
10 changes: 10 additions & 0 deletions pkg/archive/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"sync"
"syscall"

"github.com/DataDog/zstd"
"github.com/containers/storage/pkg/fileutils"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/ioutils"
Expand Down Expand Up @@ -98,6 +99,8 @@ const (
Gzip
// Xz is xz compression algorithm.
Xz
// Zstd is zstd compression algorithm.
Zstd
)

const (
Expand Down Expand Up @@ -141,6 +144,7 @@ func DetectCompression(source []byte) Compression {
Bzip2: {0x42, 0x5A, 0x68},
Gzip: {0x1F, 0x8B, 0x08},
Xz: {0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00},
Zstd: {0x25, 0xb5, 0x2f, 0xfd},
} {
if len(source) < len(m) {
logrus.Debug("Len too short")
Expand Down Expand Up @@ -200,6 +204,8 @@ func DecompressStream(archive io.Reader) (io.ReadCloser, error) {
<-chdone
return readBufWrapper.Close()
}), nil
case Zstd:
return zstd.NewReader(buf), nil
default:
return nil, fmt.Errorf("Unsupported compression format %s", (&compression).Extension())
}
Expand All @@ -217,6 +223,8 @@ func CompressStream(dest io.Writer, compression Compression) (io.WriteCloser, er
gzWriter := gzip.NewWriter(dest)
writeBufWrapper := p.NewWriteCloserWrapper(buf, gzWriter)
return writeBufWrapper, nil
case Zstd:
return zstd.NewWriter(dest), nil
case Bzip2, Xz:
// archive/bzip2 does not support writing, and there is no xz support at all
// However, this is not a problem as docker only currently generates gzipped tars
Expand Down Expand Up @@ -324,6 +332,8 @@ func (compression *Compression) Extension() string {
return "tar.gz"
case Xz:
return "tar.xz"
case Zstd:
return "tar.zst"
}
return ""
}
Expand Down
1 change: 1 addition & 0 deletions vendor.conf
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6
golang.org/x/sys 07c182904dbd53199946ba614a412c61d3c548f5
gotest.tools master
github.com/google/go-cmp master
github.com/DataDog/zstd master

0 comments on commit 13a8e74

Please sign in to comment.