Class: Dalli::Protocol::ValueCompressor

Inherits:
Object
  • Object
show all
Defined in:
lib/dalli/protocol/value_compressor.rb

Overview

Dalli::Protocol::ValueCompressor compartmentalizes the logic for managing compression and decompression of stored values. It manages interpreting relevant options from both client and request, determining whether to compress/decompress on store/retrieve, and processes bitflags as necessary.

Constant Summary collapse

DEFAULTS =
{
  compress: true,
  compressor: ::Dalli::Compressor,
  # min byte size to attempt compression
  compression_min_size: 4 * 1024 # 4K
}.freeze
OPTIONS =
DEFAULTS.keys.freeze
FLAG_COMPRESSED =

www.hjp.at/zettel/m/memcached_flags.rxml Looks like most clients use bit 1 to indicate gzip compression.

0x2

Instance Method Summary collapse

Constructor Details

#initialize(client_options) ⇒ ValueCompressor

Returns a new instance of ValueCompressor.



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/dalli/protocol/value_compressor.rb', line 27

def initialize(client_options)
  # Support the deprecated compression option, but don't allow it to override
  # an explicit compress
  # Remove this with 4.0
  if client_options.key?(:compression) && !client_options.key?(:compress)
    Dalli.logger.warn "DEPRECATED: Dalli's :compression option is now just 'compress: true'.  " \
                      'Please update your configuration.'
    client_options[:compress] = client_options.delete(:compression)
  end

  @compression_options =
    DEFAULTS.merge(client_options.select { |k, _| OPTIONS.include?(k) })
end

Instance Method Details

#compress_by_default?Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/dalli/protocol/value_compressor.rb', line 60

def compress_by_default?
  @compression_options[:compress]
end

#compress_value?(value, req_options) ⇒ Boolean

Checks whether we should apply compression when serializing a value based on the specified options. Returns false unless the value is greater than the minimum compression size. Otherwise returns based on a method-level option if specified, falling back to the server default.

Returns:

  • (Boolean)


77
78
79
80
81
82
# File 'lib/dalli/protocol/value_compressor.rb', line 77

def compress_value?(value, req_options)
  return false unless value.bytesize >= compression_min_size
  return compress_by_default? unless req_options && !req_options[:compress].nil?

  req_options[:compress]
end

#compression_min_sizeObject



68
69
70
# File 'lib/dalli/protocol/value_compressor.rb', line 68

def compression_min_size
  @compression_options[:compression_min_size]
end

#compressorObject



64
65
66
# File 'lib/dalli/protocol/value_compressor.rb', line 64

def compressor
  @compression_options[:compressor]
end

#retrieve(value, bitflags) ⇒ Object



49
50
51
52
53
54
55
56
57
58
# File 'lib/dalli/protocol/value_compressor.rb', line 49

def retrieve(value, bitflags)
  compressed = (bitflags & FLAG_COMPRESSED) != 0
  compressed ? compressor.decompress(value) : value

# TODO: We likely want to move this rescue into the Dalli::Compressor / Dalli::GzipCompressor
# itself, since not all compressors necessarily use Zlib.  For now keep it here, so the behavior
# of custom compressors doesn't change.
rescue Zlib::Error
  raise UnmarshalError, "Unable to uncompress value: #{$ERROR_INFO.message}"
end

#store(value, req_options, bitflags) ⇒ Object



41
42
43
44
45
46
47
# File 'lib/dalli/protocol/value_compressor.rb', line 41

def store(value, req_options, bitflags)
  do_compress = compress_value?(value, req_options)
  store_value = do_compress ? compressor.compress(value) : value
  bitflags |= FLAG_COMPRESSED if do_compress

  [store_value, bitflags]
end