class Viscacha::Store

Constants

DEFAULT_DIR
DEFAULT_NAME
DEFAULT_SIZE

Attributes

data_store[R]
meta_store[R]

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method
# File lib/viscacha/store.rb, line 12
def initialize(options = {})
  super options
  
  directory = options.fetch(:directory, DEFAULT_DIR)
  name      = options.fetch(:name,      DEFAULT_NAME)
  size      = options.fetch(:size,      DEFAULT_SIZE)

  data_store_options = {
    filename: Pathname.new(directory).join("#{name}-data.lmc").to_s,
    size_mb:  [DEFAULT_SIZE, size].max / 1.megabyte
  }
  meta_store_options = {
    filename: Pathname.new(directory).join("#{name}-meta.lmc").to_s,
    size_mb:  data_store_options[:size_mb]
  }

  @data_store = LocalMemCache.new(data_store_options)
  @meta_store = LocalMemCache.new(meta_store_options)
end

Public Instance Methods

cleanup(options = nil) click to toggle source
# File lib/viscacha/store.rb, line 38
def cleanup(options = nil)
  true
end
clear(options = nil) click to toggle source
# File lib/viscacha/store.rb, line 32
def clear(options = nil)
  data_store.clear
  meta_store.clear
  self
end
decrement(name, amount = 1, options = nil) click to toggle source
# File lib/viscacha/store.rb, line 46
def decrement(name, amount = 1, options = nil)
  raise NotImplementedError.new("#{self.class.name} does not support #{__method__}")
end
delete_matched(matcher, options = nil) click to toggle source
# File lib/viscacha/store.rb, line 50
def delete_matched(matcher, options = nil)
  raise NotImplementedError.new("#{self.class.name} does not support #{__method__}")
end
increment(name, amount = 1, options = nil) click to toggle source
# File lib/viscacha/store.rb, line 42
def increment(name, amount = 1, options = nil)
  raise NotImplementedError.new("#{self.class.name} does not support #{__method__}")
end

Protected Instance Methods

delete_entry(key, options = {}) click to toggle source
# File lib/viscacha/store.rb, line 75
def delete_entry(key, options = {})
  meta = meta_store[key]
  data_store.delete(key)
  meta_store.delete(key)
  !(meta.nil? || meta.empty?)
end
get_free_ratio() click to toggle source
# File lib/viscacha/store.rb, line 106
def get_free_ratio
  1.0 * data_store.shm_status[:free_bytes] / data_store.shm_status[:total_bytes]
end
get_free_space() click to toggle source
# File lib/viscacha/store.rb, line 102
def get_free_space
  data_store.shm_status[:free_bytes]
end
make_space_for(bytes) click to toggle source
# File lib/viscacha/store.rb, line 82
def make_space_for(bytes)
  return true if get_free_space > (bytes * 2)

  keys = []
  meta_store.each_pair do |key,meta|
    keys << [key, meta.unpack('GGNC').first]
  end

  keys.sort_by(&:last).each do |key,_|
    delete_entry(key)
    return true if get_free_space > (bytes * 2) && get_free_ratio > 0.15
  end

  false
end
metadata_pack(entry, used_at = nil) click to toggle source
# File lib/viscacha/store.rb, line 110
def metadata_pack(entry, used_at = nil)
  used_at ||= entry.created_at
  [used_at, entry.created_at, entry.expires_in || 0, entry.compressed? ? 1 : 0].pack('GGNC')
end
metadata_unpack(meta, data) click to toggle source
# File lib/viscacha/store.rb, line 115
def metadata_unpack(meta, data)
  used_at, created_at, expires_in, compressed = meta.unpack('GGNC')

  compressed = (compressed == 1)
  expires_in = nil if expires_in == 0

  ActiveSupport::Cache::Entry.create(data, created_at, compressed: compressed, expires_in: expires_in)
end
read_entry(key, options = {}) click to toggle source
# File lib/viscacha/store.rb, line 59
def read_entry(key, options = {})
  data = data_store[key]
  meta = meta_store[key]
  return nil if data.nil? || meta.nil? || data.empty? || meta.empty?
  entry = metadata_unpack(meta, data)
  touch_entry(entry, key)
  entry
end
touch_entry(entry, key) click to toggle source
# File lib/viscacha/store.rb, line 98
def touch_entry(entry, key)
  meta_store[key] = metadata_pack(entry, Time.now.to_f)
end
write_entry(key, entry, options = {}) click to toggle source
# File lib/viscacha/store.rb, line 68
def write_entry(key, entry, options = {})
  make_space_for(entry.raw_value.bytesize)
  data_store[key] = entry.raw_value
  meta_store[key] = metadata_pack(entry)
  true
end