Module: VibeZstd::ThreadLocal
- Defined in:
- lib/vibe_zstd.rb
Overview
Thread-local context pooling for high-performance reuse Ideal for Rails/Puma applications where threads are reused across requests
Example usage:
# In Rails model with encrypted attributes
class User < ApplicationRecord
encrypts :email
encrypts :preferences, dict: JSON_DICT
end
# Instead of:
VibeZstd.decompress(data, dict: dict) # Creates new DCtx each time
# Use:
VibeZstd::ThreadLocal.decompress(data, dict: dict) # Reuses DCtx per thread
Memory footprint: ~128KB per DCtx × unique dictionaries × threads Example: 3 dicts × 5 Puma threads = 1.9MB total
Storage: uses Thread#thread_variable_get/set (true thread-local) so that fiber-based servers (Falcon, async) share one pool per OS thread rather than allocating a fresh pool for every fiber.
Note: Only supports per-operation parameters (level, dict, pledged_size, initial_capacity) Does NOT support context-level settings (nb_workers, checksum_flag, etc.)
Class Method Summary collapse
-
.clear_thread_cache! ⇒ Object
Clear all thread-local context pools for the current thread Useful for testing or explicit memory management.
-
.compress(data, level: nil, dict: nil, pledged_size: nil) ⇒ String
Compress data using thread-local context pool Contexts are keyed by dictionary ID for automatic isolation.
-
.decompress(data, dict: nil, initial_capacity: nil, max_decompressed_size: nil) ⇒ String
Decompress data using thread-local context pool Contexts are keyed by dictionary ID for automatic isolation.
-
.thread_cache_stats ⇒ Hash
Get statistics about the current thread’s context pools.
Class Method Details
.clear_thread_cache! ⇒ Object
Clear all thread-local context pools for the current thread Useful for testing or explicit memory management
167 168 169 170 171 |
# File 'lib/vibe_zstd.rb', line 167 def self.clear_thread_cache! Thread.current.thread_variable_set(:vibe_zstd_cctx_pool, {}) Thread.current.thread_variable_set(:vibe_zstd_dctx_pool, {}) nil end |
.compress(data, level: nil, dict: nil, pledged_size: nil) ⇒ String
Compress data using thread-local context pool Contexts are keyed by dictionary ID for automatic isolation
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/vibe_zstd.rb', line 121 def self.compress(data, level: nil, dict: nil, pledged_size: nil) # Key by dictionary ID, or :default if no dict key = dict ? dict.dict_id : :default # Get or create thread-local context pool (true thread-local, not fiber-local) pool = Thread.current.thread_variable_get(:vibe_zstd_cctx_pool) || {} cctx = pool[key] ||= VibeZstd::CCtx.new Thread.current.thread_variable_set(:vibe_zstd_cctx_pool, pool) # Build options hash = {} [:level] = level if level [:dict] = dict if dict [:pledged_size] = pledged_size if pledged_size cctx.compress(data, **) end |
.decompress(data, dict: nil, initial_capacity: nil, max_decompressed_size: nil) ⇒ String
Decompress data using thread-local context pool Contexts are keyed by dictionary ID for automatic isolation
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/vibe_zstd.rb', line 147 def self.decompress(data, dict: nil, initial_capacity: nil, max_decompressed_size: nil) key = dict ? dict.dict_id : :default # Get or create thread-local context pool (true thread-local, not fiber-local) pool = Thread.current.thread_variable_get(:vibe_zstd_dctx_pool) || {} dctx = pool[key] ||= VibeZstd::DCtx.new Thread.current.thread_variable_set(:vibe_zstd_dctx_pool, pool) # Build options hash = {} [:dict] = dict if dict [:initial_capacity] = initial_capacity if initial_capacity [:max_decompressed_size] = max_decompressed_size if max_decompressed_size # C code will validate dict matches frame requirements dctx.decompress(data, **) end |
.thread_cache_stats ⇒ Hash
Get statistics about the current thread’s context pools
175 176 177 178 179 180 181 182 183 184 |
# File 'lib/vibe_zstd.rb', line 175 def self.thread_cache_stats cctx_pool = Thread.current.thread_variable_get(:vibe_zstd_cctx_pool) dctx_pool = Thread.current.thread_variable_get(:vibe_zstd_dctx_pool) { compression_contexts: cctx_pool&.size || 0, decompression_contexts: dctx_pool&.size || 0, compression_keys: cctx_pool&.keys || [], decompression_keys: dctx_pool&.keys || [] } end |