class DeviceDetector::MemoryCache

Constants

DEFAULT_MAX_KEYS
STORES_NIL_VALUE

Attributes

data[R]
lock[R]
max_keys[R]

Public Class Methods

new(config) click to toggle source
# File lib/device_detector/memory_cache.rb, line 11
def initialize(config)
  @data = {}
  @max_keys = config[:max_cache_keys] || DEFAULT_MAX_KEYS
  @lock = Mutex.new
end

Public Instance Methods

get(key) click to toggle source
# File lib/device_detector/memory_cache.rb, line 27
def get(key)
  value, _hit = get_hit(key)
  value
end
get_or_set(key, value = nil) { || ... } click to toggle source
# File lib/device_detector/memory_cache.rb, line 32
def get_or_set(key, value = nil)
  string_key = String(key)

  result, hit = get_hit(string_key)
  return result if hit

  value = yield if block_given?
  set(string_key, value)
end
set(key, value) click to toggle source
# File lib/device_detector/memory_cache.rb, line 17
def set(key, value)
  lock.synchronize do
    purge_cache
    # convert nil values into symbol so we know a value is present
    cache_value = value.nil? ? STORES_NIL_VALUE : value
    data[String(key)] = cache_value
    value
  end
end

Private Instance Methods

get_hit(key) click to toggle source
# File lib/device_detector/memory_cache.rb, line 44
def get_hit(key)
  value = data[String(key)]
  is_hit = !value.nil? || value == STORES_NIL_VALUE
  value = nil if value == STORES_NIL_VALUE
  [value, is_hit]
end
purge_cache() click to toggle source
# File lib/device_detector/memory_cache.rb, line 51
def purge_cache
  key_size = data.size

  return if key_size < max_keys

  # always remove about 1/3 of keys to reduce garbage collecting
  amount_of_keys = key_size / 3

  data.keys.first(amount_of_keys).each { |key| data.delete(key) }
end