From f13e9c10a408e8309740f167669c7ce1fc768bc2 Mon Sep 17 00:00:00 2001 From: Srigovind Nayak <5201843+konidev20@users.noreply.github.com> Date: Tue, 1 Apr 2025 00:51:12 +0530 Subject: [PATCH] Add support for additional compression levels `fastest` and `better` (#5321) * repository: expose addtional compression levels * adding better and fastest compression levels for zstd * repository: add changelog entry for issue-4728 * chore: fix golint issues * chore: sort compression modes in the help text * updating review comments --- changelog/unreleased/issue-4728 | 7 +++++++ cmd/restic/global.go | 2 +- internal/repository/repository.go | 26 ++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 changelog/unreleased/issue-4728 diff --git a/changelog/unreleased/issue-4728 b/changelog/unreleased/issue-4728 new file mode 100644 index 000000000..e0149e675 --- /dev/null +++ b/changelog/unreleased/issue-4728 @@ -0,0 +1,7 @@ +Enhancement: Added support for zstd compression levels `fastest` and `better` + +Restic now supports the zstd compression modes `fastest` and `better`. Set the +environment variable `RESTIC_COMPRESSION` to `fastest` or `better` to use these +compression levels. This can also be set with the `--compression` flag. + +https://github.com/restic/restic/issues/4728 diff --git a/cmd/restic/global.go b/cmd/restic/global.go index 7dafa6f96..6e58a0d73 100644 --- a/cmd/restic/global.go +++ b/cmd/restic/global.go @@ -114,7 +114,7 @@ func (opts *GlobalOptions) AddFlags(f *pflag.FlagSet) { f.BoolVar(&opts.InsecureNoPassword, "insecure-no-password", false, "use an empty password for the repository, must be passed to every restic command (insecure)") f.BoolVar(&opts.InsecureTLS, "insecure-tls", false, "skip TLS certificate verification when connecting to the repository (insecure)") f.BoolVar(&opts.CleanupCache, "cleanup-cache", false, "auto remove old cache directories") - f.Var(&opts.Compression, "compression", "compression mode (only available for repository format version 2), one of (auto|off|max) (default: $RESTIC_COMPRESSION)") + f.Var(&opts.Compression, "compression", "compression mode (only available for repository format version 2), one of (auto|off|fastest|better|max) (default: $RESTIC_COMPRESSION)") f.BoolVar(&opts.NoExtraVerify, "no-extra-verify", false, "skip additional verification of data before upload (see documentation)") f.IntVar(&opts.Limits.UploadKb, "limit-upload", 0, "limits uploads to a maximum `rate` in KiB/s. (default: unlimited)") f.IntVar(&opts.Limits.DownloadKb, "limit-download", 0, "limits downloads to a maximum `rate` in KiB/s. (default: unlimited)") diff --git a/internal/repository/repository.go b/internal/repository/repository.go index 066ba5ed5..fb718e9f9 100644 --- a/internal/repository/repository.go +++ b/internal/repository/repository.go @@ -73,7 +73,9 @@ const ( CompressionAuto CompressionMode = 0 CompressionOff CompressionMode = 1 CompressionMax CompressionMode = 2 - CompressionInvalid CompressionMode = 3 + CompressionFastest CompressionMode = 3 + CompressionBetter CompressionMode = 4 + CompressionInvalid CompressionMode = 5 ) // Set implements the method needed for pflag command flag parsing. @@ -85,9 +87,13 @@ func (c *CompressionMode) Set(s string) error { *c = CompressionOff case "max": *c = CompressionMax + case "fastest": + *c = CompressionFastest + case "better": + *c = CompressionBetter default: *c = CompressionInvalid - return fmt.Errorf("invalid compression mode %q, must be one of (auto|off|max)", s) + return fmt.Errorf("invalid compression mode %q, must be one of (auto|off|fastest|better|max)", s) } return nil @@ -101,6 +107,10 @@ func (c *CompressionMode) String() string { return "off" case CompressionMax: return "max" + case CompressionFastest: + return "fastest" + case CompressionBetter: + return "better" default: return "invalid" } @@ -305,9 +315,17 @@ func (r *Repository) loadBlob(ctx context.Context, blobs []restic.PackedBlob, bu func (r *Repository) getZstdEncoder() *zstd.Encoder { r.allocEnc.Do(func() { - level := zstd.SpeedDefault - if r.opts.Compression == CompressionMax { + + var level zstd.EncoderLevel + switch r.opts.Compression { + case CompressionFastest: + level = zstd.SpeedFastest + case CompressionBetter: + level = zstd.SpeedBetterCompression + case CompressionMax: level = zstd.SpeedBestCompression + default: + level = zstd.SpeedDefault } opts := []zstd.EOption{