C#: Implement transparent compression feature#213
C#: Implement transparent compression feature#213prateek-kumar-improving wants to merge 36 commits intomainfrom
Conversation
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
…rc/ffi.rs Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
…rc/ffi.rs Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Updated submodule from 2ea4018f6 to 0429c1201 to include: - Transparent Compression Feature (#4759) - Go bindings for compression (#5359) This update enables compression functionality in the Rust core. Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
4bb939e to
34ff162
Compare
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
C# documentation is being shifted to |
currantw
left a comment
There was a problem hiding this comment.
Reviewed implementation. Will review tests once addressed.
rust/src/ffi.rs
Outdated
| compression_config: if config.has_compression_config { | ||
| Some(glide_core::compression::CompressionConfig { | ||
| enabled: config.compression_config.enabled, | ||
| min_compression_size: config.compression_config.min_compression_size, | ||
| compression_level: if config.compression_config.compression_level == 0 { | ||
| None | ||
| } else { | ||
| Some(config.compression_config.compression_level) | ||
| }, | ||
| backend: match config.compression_config.backend { | ||
| CompressionBackend::Zstd => { | ||
| glide_core::compression::CompressionBackendType::Zstd | ||
| } | ||
| CompressionBackend::Lz4 => { | ||
| glide_core::compression::CompressionBackendType::Lz4 | ||
| } | ||
| }, | ||
| }) | ||
| } else { | ||
| None | ||
| }, |
There was a problem hiding this comment.
I think this can be simplified quite a bit using then_some (this also removes the unnecessary brackets from the match block):
| compression_config: if config.has_compression_config { | |
| Some(glide_core::compression::CompressionConfig { | |
| enabled: config.compression_config.enabled, | |
| min_compression_size: config.compression_config.min_compression_size, | |
| compression_level: if config.compression_config.compression_level == 0 { | |
| None | |
| } else { | |
| Some(config.compression_config.compression_level) | |
| }, | |
| backend: match config.compression_config.backend { | |
| CompressionBackend::Zstd => { | |
| glide_core::compression::CompressionBackendType::Zstd | |
| } | |
| CompressionBackend::Lz4 => { | |
| glide_core::compression::CompressionBackendType::Lz4 | |
| } | |
| }, | |
| }) | |
| } else { | |
| None | |
| }, | |
| compression_config: config.has_compression_config.then_some( | |
| glide_core::compression::CompressionConfig { | |
| enabled: config.compression_config.enabled, | |
| min_compression_size: config.compression_config.min_compression_size, | |
| compression_level: (config.compression_config.compression_level != 0) | |
| .then_some(config.compression_config.compression_level), | |
| backend: match config.compression_config.backend { | |
| CompressionBackend::Zstd => glide_core::compression::CompressionBackendType::Zstd, | |
| CompressionBackend::Lz4 => glide_core::compression::CompressionBackendType::Lz4, | |
| }, | |
| }, | |
| ), |
There was a problem hiding this comment.
Updated.
| if (minCompressionSize < MinCompressionSizeLimit) | ||
| { | ||
| throw new ArgumentException($"minCompressionSize must be at least {MinCompressionSizeLimit} bytes", nameof(minCompressionSize)); | ||
| } |
There was a problem hiding this comment.
I think ArgumentOutOfRangeException might be better here?
There was a problem hiding this comment.
Updated.
There was a problem hiding this comment.
Are these StackExchange.Redis-compatible types? Otherwise, I think they should just be in sources rather than sources/abstract_APITypes. The distinction between these is certainly not clear, but that is my understanding of the separation!
Moreover, I think we should generally endeavour to have one class (excepting private classes) per file? That seems to be the pattern (loosely followed) in the code base.
See the refactoring PR I just raised along these lines: #246
There was a problem hiding this comment.
Updated.
| /// Enables automatic compression of values before sending to the server | ||
| /// and decompression when receiving from the server. | ||
| /// </summary> | ||
| [StructLayout(LayoutKind.Sequential)] |
There was a problem hiding this comment.
Marshalling related code should be isolated in FFI.structs.cs, not exposed in public APIs. We probably need to split this into two separate classes? See #246
There was a problem hiding this comment.
Updated.
| /// <summary> | ||
| /// Zstandard (zstd) compression backend. | ||
| /// Provides high compression ratios with good performance. | ||
| /// Default compression level: 3 |
There was a problem hiding this comment.
Don't think we need to specify the default compression level here?
There was a problem hiding this comment.
Updated.
| /// <summary> | ||
| /// Statistics structure containing telemetry data from Rust core. | ||
| /// </summary> | ||
| [StructLayout(LayoutKind.Sequential)] |
There was a problem hiding this comment.
As mentioned elsewhere, we need to separate the FFI classes from the API ones.
There was a problem hiding this comment.
Updated.
| public ulong TotalConnections; | ||
| public ulong TotalClients; | ||
| public ulong TotalValuesCompressed; | ||
| public ulong TotalValuesDecompressed; | ||
| public ulong TotalOriginalBytes; | ||
| public ulong TotalBytesCompressed; | ||
| public ulong TotalBytesDecompressed; | ||
| public ulong CompressionSkippedCount; |
There was a problem hiding this comment.
Can these be documented please?
There was a problem hiding this comment.
Updated.
| /// Statistics structure containing telemetry data from Rust core. | ||
| /// </summary> | ||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal struct Statistics |
There was a problem hiding this comment.
Should this be readonly like others in this class? Similarly, should fields also be readonly?
There was a problem hiding this comment.
Updated.
README.md
Outdated
| - **[Cluster Scan](https://github.com/valkey-io/valkey-glide/wiki/General-Concepts#cluster-scan)** – Unified key iteration across shards using a consistent, high-level API | ||
| - **[Batching (Pipeline and Transaction)](https://github.com/valkey-io/valkey-glide/wiki/General-Concepts#batching-pipeline-and-transaction)** – Execute multiple commands efficiently in a single network roundtrip | ||
| - **[OpenTelemetry](https://github.com/valkey-io/valkey-glide/wiki/General-Concepts#opentelemetry)** – Integrated tracing support for enhanced observability | ||
| - **[Transparent Compression](#compression-operations)** – Automatic value compression with Zstd and LZ4 backends to reduce bandwidth and storage |
There was a problem hiding this comment.
Probably also need to update CHANGELOG.md?
There was a problem hiding this comment.
Updated.
README.md
Outdated
| ### Compression Operations | ||
|
|
||
| ```csharp | ||
| // Enable transparent compression with Zstd | ||
| var config = new StandaloneClientConfigurationBuilder() | ||
| .WithAddress("localhost", 6379) | ||
| .WithCompression(CompressionConfig.Zstd()) | ||
| .Build(); | ||
|
|
||
| await using var client = await GlideClient.CreateClient(config); | ||
|
|
||
| // Values are automatically compressed/decompressed | ||
| await client.StringSetAsync("large_data", new string('a', 10000)); | ||
| var retrieved = await client.StringGetAsync("large_data"); | ||
|
|
||
| // Monitor compression statistics | ||
| var stats = BaseClient.GetCompressionStatistics(); | ||
| Console.WriteLine($"Compression ratio: {stats.CompressionRatio:F2}x"); | ||
| Console.WriteLine($"Space saved: {stats.SpaceSavedPercent:F2}%"); | ||
|
|
||
| // Use LZ4 for faster compression | ||
| var lz4Config = new StandaloneClientConfigurationBuilder() | ||
| .WithAddress("localhost", 6379) | ||
| .WithCompression(CompressionConfig.Lz4(compressionLevel: 5, minCompressionSize: 128)) | ||
| .Build(); | ||
| ``` |
There was a problem hiding this comment.
This should be part of valkey-glide-docs instead. Please raise PR for that and link here (as described in other comment).
There was a problem hiding this comment.
Removed readme.md update from this PR. Documentation is not updated for compression feature for now. Will be updated later after all work related to the feature is done.
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
…ics.cs Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
…ture Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Signed-off-by: Prateek Kumar <prateek.kumar@improving.com>
Summary
Implementing C# bindings for the transparent compression feature added in valkey-io/valkey-glide#4759
Issue Link
This pull request is linked to issue: valkey-io/valkey-glide#5120
Related Issue: valkey-io/valkey-glide#5299
Features and Behaviour Changes
Implementation
Rust FFI
C# Public API
C# FFI Internals
Tests
Documentation:
README.md - Added compression documentation and examples
Limitations
This feature is only limited to GET and SET for now.
Testing
All tests passing locally and in CI. Both unit tests and integration tests added.
Checklist
CHANGELOG.md,README.md,DEVELOPER.md, and other documentation files are updated.mainor releasemain, squash otherwise.