class Garcon::MemStash

In-process cache with least-recently used (LRU) and time-to-live (TTL) expiration semantics. This implementation is thread-safe. It does not use a thread to clean up expired values. Instead, an expiration check is performed:

  1. Every time you retrieve a value, against that value. If the value has expired, it will be removed and ‘nil` will be returned.

  2. Every ‘expire_interval` operations as the cache is used to remove all expired values up to that point.

For manual expiration call {#expire!}.

Constants

DEFAULT_MAX_ENTRIES

The maximum sum total number of elements (cache entries) allowed on the disk tier for the cache. If this target is exceeded, eviction occurs to bring the count within the allowed target. The default value is 100. A setting of 0 means that no eviction of the cache’s entries takes place (infinite size is allowed), and consequently can cause the node to run out of disk space.

DEFAULT_TTI_SECONDS

The maximum number of seconds an element can exist in the cache without being accessed. The element expires at this limit and will no longer be returned from the cache. The default value is 3600, or 1 hour. Setting a TTI value of 0 means no TTI eviction takes place (infinite lifetime).

DEFAULT_TTL_SECONDS

The maximum number of seconds an element can exist in the cache regardless of use. The element expires at this limit and will no longer be returned from the cache. The default value is 3600, or 1 hour. Setting A TTL value of 0 means no TTL eviction takes place (infinite lifetime).

Attributes

expires_at[R]
stats[R]

@!attribute [r] :stats

@return [CacheStats] The Cache statistics.
tti[R]

@!attribute [r] :tti (DEFAULT_TTI_SECONDS)

@return [Integer] The time to idle for an element before it expires.
ttl[R]

@!attribute [r] :ttl (DEFAULT_TTL_SECONDS)

@return [Integer] The time to live for an element before it expires.
value[R]

Public Class Methods

new(opts = {}) click to toggle source

Initializes the cache.

@param [Hash] opts

The options to configure the cache.

@option opts [Integer] :max_entries

Maximum number of elements in the cache.

@option opts [Numeric] :ttl

Maximum time, in seconds, for a value to stay in the cache.

@option opts [Numeric] :tti

Maximum time, in seconds, for a value to stay in the cache without
being accessed.

@option opts [Integer] :interval

Number of cache operations between calls to {#expire!}.
# File lib/garcon/utility/memstash.rb, line 96
def initialize(opts = {})
  @max_entries = opts.fetch(:max_entries, DEFAULT_MAX_ENTRIES)
  @ttl_seconds = opts.fetch(:ttl_seconds, DEFAULT_TTL_SECONDS)
  @tti_seconds = opts.fetch(:ttl_seconds, DEFAULT_TTI_SECONDS)
  @interval    = opts.fetch(:interval, 100)
  @operations  = 0
  @monitor     = Monitor.new
  @stash       = {}
  @expires_at  = {}
end

Public Instance Methods

[](key) click to toggle source

Retrieves a value from the cache.

@param [Object] key

The key to look up.

@return [Object, nil]

The value at the key, when present, or `nil`.
# File lib/garcon/utility/memstash.rb, line 152
def [](key)
  @monitor.synchronize do
    _, value = get(key)
    value
  end
end
Also aliased as: get
[]=(key, val) click to toggle source

Stores a value in the cache.

@param [Object] key

The key to store.

@param val [Object]

The value to store.

@return [Object, nil]

The value at the key.
# File lib/garcon/utility/memstash.rb, line 171
def []=(key, val)
  @monitor.synchronize do
    expire!
    store(key, val)
  end
end
Also aliased as: set
clear() click to toggle source

Clears the cache.

@return [self]

# File lib/garcon/utility/memstash.rb, line 213
def clear
  @monitor.synchronize do
    @stash.clear
    @expires_at.clear
    self
  end
end
count() click to toggle source

Returns the number of elements in the cache.

@note

Calls to {#empty?} do not count against `expire_interval`. Therefore,
the number of elements is that prior to any expiration.

@return [Integer]

Number of elements in the cache.
# File lib/garcon/utility/memstash.rb, line 230
def count
  @monitor.synchronize { @stash.count }
end
Also aliased as: size, length
delete(key) click to toggle source

Removes a value from the cache.

@param [Object] key

The key to remove.

@return [Object, nil]

The value at the key, when present, or `nil`.
# File lib/garcon/utility/memstash.rb, line 187
def delete(key)
  @monitor.synchronize do
    entry = @stash.delete(key)
    if entry
      @expires_at.delete(entry)
      entry.value
    else
      nil
    end
  end
end
each(&block) click to toggle source

Allows iteration over the items in the cache. Enumeration is stable: it is not affected by changes to the cache, including value expiration. Expired values are removed first.

@note

The returned values could have expired by the time the client code gets
to accessing them.

@note

Because of its stability, this operation is very expensive. Use with
caution.

@yield [Array<key, value>]

Key/value pairs, when a block is provided.

@return [Enumerator, Array<key, value>]

An Enumerator, when no block is provided, or array of key/value pairs.
# File lib/garcon/utility/memstash.rb, line 254
def each(&block)
  @monitor.synchronize do
    expire!
    @stash.map { |key, entry| [key, entry.value] }.each(&block)
  end
end
empty?() click to toggle source

Checks whether the cache is empty.

@note calls to {#empty?} do not count against ‘expire_interval`.

@return [Boolean]

# File lib/garcon/utility/memstash.rb, line 205
def empty?
  @monitor.synchronize { count == 0 }
end
expire!() click to toggle source

Removes expired values from the cache.

@return [self]

# File lib/garcon/utility/memstash.rb, line 265
def expire!
  @monitor.synchronize do
    check_expired(Time.now.to_f)
    self
  end
end
fetch(key) { || ... } click to toggle source

Retrieves a value from the cache, if available and not expired, or yields to a block that calculates the value to be stored in the cache.

@param [Object] key

The key to look up or store at.

@yield yields when the value is not present.

@yieldreturn [Object]

The value to store in the cache.

@return [Object]

The value at the key.
# File lib/garcon/utility/memstash.rb, line 137
def fetch(key)
  @monitor.synchronize do
    found, value = get(key)
    found ? value : store(key, yield)
  end
end
get(key)
Alias for: []
inspect() click to toggle source

Returns information about the number of objects in the cache, its maximum size and TTL.

@return [String]

# File lib/garcon/utility/memstash.rb, line 285
def inspect
  @monitor.synchronize do
    "<#{self.class.name} count=#{count} max_entries=#{@max_entries} " \
    "ttl=#{@ttl_seconds}>"
  end
end
keys() click to toggle source

Return all keys in the store as an array.

@return [Array<String, Symbol>] all the keys in store

# File lib/garcon/utility/memstash.rb, line 276
def keys
  @monitor.synchronize { @stash.keys }
end
length()
Alias for: count
load(data) click to toggle source

Loads a hash of data into the stash.

@param [Hash] data

Hash of data with either String or Symbol keys.

@return nothing.

# File lib/garcon/utility/memstash.rb, line 114
def load(data)
  @monitor.synchronize do
    data.each do |key, value|
      expire!
      store(key, val)
    end
  end
end
set(key, val)
Alias for: []=
size()
Alias for: count