class Readthis::Entity
An instance of the Entity
class is used to handle `load` and `dump` operations on cached values.
Constants
- COMPRESSED_FLAG
A hexidecimal compression flag. When it is present within the magic bit of an entity that entity is considered compressed.
- DEFAULT_OPTIONS
Unless they are overridden, these are the options used to load and unload every value.
Public Class Methods
Creates a Readthis::Entity
with default options. Each option can be overridden later when entities are being dumped.
Options are sticky, meaning that whatever is used when dumping will automatically be used again when loading, regardless of how current options are set.
@option [Boolean] :compress (false) Enable or disable automatic
compression
@option [Module] :marshal (Marshal) Any module that responds to `dump`
and `load`
@option [Number] :threshold (8k) The size a string must be for
compression
# File lib/readthis/entity.rb, line 35 def initialize(options = {}) @options = DEFAULT_OPTIONS.merge(options) end
Public Instance Methods
Composes a single byte comprised of the chosen serializer and compression options. The byte is formatted as:
| 0000 | 0 | 000 |
Where there are four unused bits, 1 compression bit, and 3 bits for the serializer. This allows up to 8 different serializers for marshaling.
@param [String] value String to prefix with flags @param [Module] marshal The marshal module to be used @param [Boolean] compress Flag determining whether the value is compressed @return [String] The original string with a single byte prefixed
@example Compose an option embedded string
entity.compose(string, Marshal, false) => 0x1 + string entity.compose(string, JSON, true) => 0x10 + string
# File lib/readthis/entity.rb, line 104 def compose(value, marshal, compress) flags = serializers.assoc(marshal) flags |= COMPRESSED_FLAG if compress value.prepend([flags].pack('C')) end
Decompose an option embedded string into marshal, compression and value.
@param [String] string Option embedded string to @return [Array<Module, Boolean, String>] An array comprised of the
marshal, compression flag, and the base string.
# File lib/readthis/entity.rb, line 117 def decompose(string) flags = string[0].unpack('C').first if flags < 16 marshal = serializers.rassoc(flags) compress = (flags & COMPRESSED_FLAG) != 0 [marshal, compress, string[1..-1]] else [@options[:marshal], @options[:compress], string] end end
Output a value prepared for cache storage. Passed options will override whatever has been specified for the instance.
@param [String] value String to dump @option options [Boolean] :compress Enable or disable automatic
compression
@option options [Module] :marshal Any module that responds to `dump` and
`load`
@option options [Number] :threshold The size a string must be for
compression
@return [String] The prepared, possibly compressed, string
@example Dumping a value using defaults
entity.dump(string)
@example Dumping a value with overrides
entity.dump(string, compress: false, marshal: JSON)
# File lib/readthis/entity.rb, line 59 def dump(value, options = {}) compress = with_fallback(options, :compress) marshal = with_fallback(options, :marshal) threshold = with_fallback(options, :threshold) dumped = deflate(marshal.dump(value), compress, threshold) compose(dumped, marshal, compress) end
Parse a dumped value using the embedded options.
@param [String] string Option embedded string to load @return [String] The original dumped string, restored
@example
entity.load(dumped)
# File lib/readthis/entity.rb, line 78 def load(string) marshal, compress, value = decompose(string) marshal.load(inflate(value, compress)) rescue TypeError, NoMethodError string end
Private Instance Methods
# File lib/readthis/entity.rb, line 132 def deflate(value, compress, threshold) if compress && value.bytesize >= threshold Zlib::Deflate.deflate(value) else value end end
# File lib/readthis/entity.rb, line 140 def inflate(value, decompress) if decompress Zlib::Inflate.inflate(value) else value end rescue Zlib::Error value end
# File lib/readthis/entity.rb, line 150 def serializers Readthis.serializers end
# File lib/readthis/entity.rb, line 154 def with_fallback(options, key) options.key?(key) ? options[key] : @options[key] end