-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
backend/compress: add zstd compression #8756
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
b920257
to
cb92bc7
Compare
Added support for reading and writing zstd-compressed archives in seekable format using "github.com/klauspost/compress/zstd" and "github.com/SaveTheRbtz/zstd-seekable-format-go/pkg". Bumped Go version from 1.24.0 to 1.24.4 due to requirements of "github.com/SaveTheRbtz/zstd-seekable-format-go/pkg".
cb92bc7
to
f2b7e5b
Compare
Great idea to introduce this modern compression algorithm. My question is why you limit compression levels to just 4 options? I think it would be much more useful to support all standard levels 1 to 19. I do not see any reason why to use only 4 arbitrary selected levels. Or is it something enforced by zstd golang implementation? For example myself I often use level 17 for online backup software as its speed on my computer nicely matches my max Internet uplink speed. I do not see why to remove option for fine tuning like this when it is available. |
The // EncoderLevel predefines encoder compression levels.
// Only use the constants made available, since the actual mapping
// of these values are very likely to change and your compression could change
// unpredictably when upgrading the library.
type EncoderLevel int
const (
speedNotSet EncoderLevel = iota
// SpeedFastest will choose the fastest reasonable compression.
// This is roughly equivalent to the fastest Zstandard mode.
SpeedFastest
// SpeedDefault is the default "pretty fast" compression option.
// This is roughly equivalent to the default Zstandard mode (level 3).
SpeedDefault
// SpeedBetterCompression will yield better compression than the default.
// Currently it is about zstd level 7-8 with ~ 2x-3x the default CPU usage.
// By using this, notice that CPU usage may go up in the future.
SpeedBetterCompression
// SpeedBestCompression will choose the best available compression option.
// This will offer the best compression no matter the CPU cost.
SpeedBestCompression
// speedLast should be kept as the last actual compression option.
// The is not for external usage, but is used to keep track of the valid options.
speedLast
) The // EncoderLevelFromZstd will return an encoder level that closest matches the compression
// ratio of a specific zstd compression level.
// Many input values will provide the same compression level.
func EncoderLevelFromZstd(level int) EncoderLevel {
switch {
case level < 3:
return SpeedFastest
case level >= 3 && level < 6:
return SpeedDefault
case level >= 6 && level < 10:
return SpeedBetterCompression
default:
return SpeedBestCompression
}
} |
Thank you for clarification. More granular levels would be nice but definitely are not critical. zstd with only 4 levels will make day and night difference compared to gzip anyway. |
576abc0
to
3edb8cc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a useful feature - thank you :-)
All those switch statements
switch {
case Gzip:
case Zstd:
default:
}
Have made the code rather untidy though.
What do you think about factoring it into two implementations, defined by an interface. You can then separate the implementations into zstd.go and gzip.go (say)
That should restore a bit of sanity to the code.
c043dd6
to
43b69ba
Compare
@ncw Thanks for the suggestion! I've refactored the compression handling - almost everything has been moved behind an interface, with separate implementations in |
43b69ba
to
ca6d6f7
Compare
- Replaced switch-based handling with interface-driven design - Added separate implementations: gzip_handler.go, zstd_handler.go, uncompressed_handler.go and unknown_handler.go
ca6d6f7
to
1a93d65
Compare
The refactor looks great - thank you :-) Can you add another target to https://github.com/rclone/rclone/blob/master/fstest/test_all/config.yaml
And then check the integration tests all pass with Once we merge that will go into the integration tester and be run once per day. Would it be possible to lose some dependencies? I think github.com/SaveTheRbtz/zstd-seekable-format-go uses go.uber.org/atomic which can be done in stdlib now I think and go.uber.org/zap - would it be possible to use the stdlib log/slog? That will integrate with rclone's logging system. I will try to give the code another review in a day or two. |
…import, fix metadata, update deps - Add "TestCompressZstd" target in "fstest/test_all/config.yaml" - Refactor metadata handling - Fix metadata size reference in Zstd compression handler - Update package import from "github.com/SaveTheRbtz/zstd-seekable-format-go/pkg@v0.8.0" to "github.com/a1ex3/zstd-seekable-format-go/pkg@v0.10.0" - Lower minimal Go version from 1.24.4 to 1.24.0
@ncw Added a target in
I decided to fork github.com/SaveTheRbtz/zstd-seekable-format-go and removed logging, since it was mostly needed for debugging the library itself.
Now rclone uses github.com/a1ex3/zstd-seekable-format-go/pkg. Additionally, fixed discovered issues with |
Hi @A1ex3 sorry for the delay in looking at this. Your changes are great thank you :-) We ran the integration tests one last time locally and the bisync tests are failing - which they weren't for you earlier. Can you help? Thanks Nick |
Hi @ncw, |
Is this likely to get merged imminently? I could really do with this feature. |
What is the purpose of this change?
Added support for reading and writing seekable Zstd-compressed archives using github.com/klauspost/compress/zstd and github.com/SaveTheRbtz/zstd-seekable-format-go/pkg (ZSTD seekable compression format implementation in Go).
Updated
Go
version from 1.24.0 to 1.24.4 to meet the requirements ofgithub.com/SaveTheRbtz/zstd-seekable-format-go/pkg
.Checklist