Class: Readthis::Entity

Inherits:
Object
  • Object
show all
Defined in:
lib/readthis/entity.rb

Overview

An instance of the Entity class is used to handle `load` and `dump` operations on cached values.

Constant Summary collapse

DEFAULT_OPTIONS =

Unless they are overridden, these are the options used to load and unload every value.

{
  compress: false,
  marshal: Marshal,
  threshold: 8 * 1024
}.freeze
COMPRESSED_FLAG =

A hexidecimal compression flag. When it is present within the magic bit of an entity that entity is considered compressed.

0x8

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Entity

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.

Parameters:

  • [Boolean] (Hash)

    a customizable set of options

  • [Module] (Hash)

    a customizable set of options

  • [Number] (Hash)

    a customizable set of options


35
36
37
# File 'lib/readthis/entity.rb', line 35

def initialize(options = {})
  @options = DEFAULT_OPTIONS.merge(options)
end

Instance Method Details

#compose(value, marshal, compress) ⇒ String

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.

Examples:

Compose an option embedded string


entity.compose(string, Marshal, false) => 0x1  + string
entity.compose(string, JSON, true) => 0x10 + string

Parameters:

  • value (String)

    String to prefix with flags

  • marshal (Module)

    The marshal module to be used

  • compress (Boolean)

    Flag determining whether the value is compressed

Returns:

  • (String)

    The original string with a single byte prefixed


104
105
106
107
108
109
# 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(string) ⇒ Array<Module, Boolean, String>

Decompose an option embedded string into marshal, compression and value.

Parameters:

  • string (String)

    Option embedded string to

Returns:

  • (Array<Module, Boolean, String>)

    An array comprised of the marshal, compression flag, and the base string.


117
118
119
120
121
122
123
124
125
126
127
128
# 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

#dump(value, options = {}) ⇒ String

Output a value prepared for cache storage. Passed options will override whatever has been specified for the instance.

Examples:

Dumping a value using defaults


entity.dump(string)

Dumping a value with overrides


entity.dump(string, compress: false, marshal: JSON)

Parameters:

  • value (String)

    String to dump

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :compress (Boolean)

    Enable or disable automatic compression

  • :marshal (Module)

    Any module that responds to `dump` and `load`

  • :threshold (Number)

    The size a string must be for compression

Returns:

  • (String)

    The prepared, possibly compressed, string


59
60
61
62
63
64
65
66
67
# 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

#load(string) ⇒ String

Parse a dumped value using the embedded options.

Examples:


entity.load(dumped)

Parameters:

  • string (String)

    Option embedded string to load

Returns:

  • (String)

    The original dumped string, restored


78
79
80
81
82
83
84
# 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