class MemoryCache::MemoryCacheStore

A processor level in memory cache storage. Data is not across multiple processes. Thread-safe

Constants

MEGABYTE

Public Class Methods

new() click to toggle source
# File lib/memory_cache/memory_cache_store.rb, line 7
def initialize
  @data = {}
  @key_access_store = {}
  @lock = Monitor.new
  @cache_size = 0
  @max_size = 25 * MEGABYTE
  @buffer_size = 5 * MEGABYTE
  @max_wait_loop_for_flush = 100
  @max_single_value_limit = 2 * MEGABYTE
end

Public Instance Methods

clear() click to toggle source

flushed the data store

# File lib/memory_cache/memory_cache_store.rb, line 66
def clear
  synchronize_block do
    @data.clear
    @key_access_store.clear
  end
end
delete(key, options = {}) click to toggle source

delete key from store

# File lib/memory_cache/memory_cache_store.rb, line 52
def delete(key, options = {})
  old_key_present = key_exists?(key)
  value = @data[key]
  @data.delete(key)
  @key_access_store.delete(key)
  @cache_size -= compute_value_size(value) if @cache_size > 0 && old_key_present
end
key_exists?(key) click to toggle source
# File lib/memory_cache/memory_cache_store.rb, line 73
def key_exists?(key)
  @data.key?(key)
end
read(key, options = {}) click to toggle source

read a key value from store return value of the key

# File lib/memory_cache/memory_cache_store.rb, line 44
def read(key, options = {})
  synchronize_block do
    set_key_access_strategy(key)
    return @data[key] ? dup_value(@data[key]) : nil
  end
end
synchronize_block(&block) click to toggle source

Synchronize calls to the cache for thread safety

# File lib/memory_cache/memory_cache_store.rb, line 61
def synchronize_block(&block)
  @lock.synchronize(&block)
end
write(key, value, options = {}) click to toggle source

write a key with value return true if success, false if any exception

# File lib/memory_cache/memory_cache_store.rb, line 21
def write(key, value, options = {})
  synchronize_block do
    return false unless can_allocate_value?(value)
    prune_keys(@buffer_size) if is_buffer_limit_reached?

    old_value_present = false

    if key_exists?(key)
      old_value_present = true
      old_value = @data[key]
      old_value_size = compute_value_size(old_value)
    end

    @data[key] = value
    set_key_access_strategy(key)
    @cache_size -= old_value_size if old_value_present
    @cache_size += compute_value_size(value)
    return true
  end
end

Private Instance Methods

available_size() click to toggle source
# File lib/memory_cache/memory_cache_store.rb, line 97
def available_size
  size = @max_size - @cache_size
  size < 0 ? 0 : size
end
can_allocate_value?(value = '') click to toggle source
# File lib/memory_cache/memory_cache_store.rb, line 106
def can_allocate_value?(value = '')
  value.to_s.bytesize < @max_single_value_limit
end
compute_value_size(value = '') click to toggle source
# File lib/memory_cache/memory_cache_store.rb, line 93
def compute_value_size(value = '')
  value.to_s.bytesize
end
dup_value(value) click to toggle source
# File lib/memory_cache/memory_cache_store.rb, line 110
def dup_value(value)
  value.is_a?(String) ? value.dup : value
end
is_buffer_limit_reached?() click to toggle source
# File lib/memory_cache/memory_cache_store.rb, line 102
def is_buffer_limit_reached?
  available_size <= @buffer_size
end
prune_keys(new_allocate_size = 0) click to toggle source
# File lib/memory_cache/memory_cache_store.rb, line 79
def prune_keys(new_allocate_size = 0)
  keys = prune_keys_in_order
  loop_counter = 0
  keys.each do |key|
    delete(key)
    return if available_size > new_allocate_size
    if loop_counter >= @max_wait_loop_for_flush
      clear
      return
    end
    loop_counter += 1
  end
end
prune_keys_in_order() click to toggle source
# File lib/memory_cache/memory_cache_store.rb, line 118
def prune_keys_in_order
  synchronize_block { @key_access_store.keys.sort { |a, b| @key_access_store[a] <=> @key_access_store[b] } }
end
set_key_access_strategy(key) click to toggle source
# File lib/memory_cache/memory_cache_store.rb, line 114
def set_key_access_strategy(key)
  @key_access_store[key] = Time.now.utc.to_i
end