Class: ActiveSupport::Cache::TokyoStore

Inherits:
Store
  • Object
show all
Defined in:
lib/cache/tokyo_store.rb

Overview

A cache store implementation which stores data in Tokyo Cabinet

Special features:

  • Substring match

  • Clustering and load balancing. TODO

  • Time-based expiry support. TODO (Lua)

  • Per-request in memory cache for all communication with the Tokyo server(s).

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*store) ⇒ TokyoStore

Creates a new TokyoStore object, with the given tyrant server addresses. Each address is either a host name, or a host-with-port string in the form of “host_name:port”. For example:

ActiveSupport::Cache::TokyoStore.new("localhost", "server-downstairs.localnetwork:8229")

If no addresses are specified, then TokyoStore will connect to localhost port 1978 (the default tyrant port).



42
43
44
45
46
47
48
49
50
# File 'lib/cache/tokyo_store.rb', line 42

def initialize(*store)
  if store.first.respond_to?(:get)
    @data = store.first
  else
    @data = self.class.build_tokyo(*store)
  end

  extend Strategy::LocalCache
end

Class Method Details

.build_tokyo(*store) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/cache/tokyo_store.rb', line 15

def self.build_tokyo(*store)
  store = store.flatten
  options = store.extract_options!
  #TODO: multiple instances
  store = store.empty? ? ["localhost", 1978]  : store[0].split(":")

  #TODO: Auto choice between tyrant ffi x tyrant pure ruby x cabinet C
  # Tyrant FFI
  Rufus::Tokyo::Tyrant.new(store[0], store[1].to_i)

  # Cabinet C
  #hdb = HDB.new
  # if !hdb.open(store[0], HDB::OWRITER | HDB::OCREAT)
  #   ecode = hdb.ecode
  #   STDERR.printf("open error: %s\n", hdb.errmsg(ecode))
  # end
  # hdb
end

Instance Method Details

#clearObject



117
118
119
# File 'lib/cache/tokyo_store.rb', line 117

def clear
  @data.clear
end

#decrement(key, amount = 1) ⇒ Object

:nodoc:



107
108
109
110
# File 'lib/cache/tokyo_store.rb', line 107

def decrement(key, amount = 1) # :nodoc:
  # @data.incr(key, -amount)
  increment(key, -amount)
end

#delete(key, options = nil) ⇒ Object

:nodoc:



91
92
93
94
# File 'lib/cache/tokyo_store.rb', line 91

def delete(key, options = nil) # :nodoc:
  super
  @data.delete(key) #= nil #, expires_in(options))
end

#delete_matched(matcher, options = nil) ⇒ Object

:nodoc:



112
113
114
115
# File 'lib/cache/tokyo_store.rb', line 112

def delete_matched(matcher, options = nil) # :nodoc:
  super
  @data.delete_keys_with_prefix(matcher)
end

#exist?(key, options = nil) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


96
97
98
99
# File 'lib/cache/tokyo_store.rb', line 96

def exist?(key, options = nil) # :nodoc:
  # Local cache is checked first?
 !read(key, options).nil?
end

#increment(key, amount = 1) ⇒ Object

:nodoc:



101
102
103
104
105
# File 'lib/cache/tokyo_store.rb', line 101

def increment(key, amount = 1) # :nodoc:
  #NATIVE breaks...rufus integer prob?
  # @data.incr(key, amount)
  @data[key] = (@data[key].to_i + amount).to_s
end

#read(key, options = nil) ⇒ Object

:nodoc:



58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/cache/tokyo_store.rb', line 58

def read(key, options = nil) # :nodoc:
  # TODO: benchmark [key] vs .get(key)
  super
  return nil unless val = @data[key]
  val = Marshal.load(val) unless raw?(options)
  val
  # if str = @data.get(key)
  #   Marshal.load str
  #   else
  #   STDERR.printf("get error: %s\n", @data.errmsg(@data.ecode))
  #   end
  # logger.error("TokyoError (#{e}): #{e.message}")
  # nil
end

#read_multi(*keys) ⇒ Object

Reads multiple keys from the cache.



53
54
55
56
# File 'lib/cache/tokyo_store.rb', line 53

def read_multi(*keys)
  #keys.inject({ }){ |h,k| h.merge({ k => read(k)}) }
  @data.lget(keys).inject({ }) { |h, k| h.merge({ k[0] => Marshal.load(k[1])})} #
end

#statsObject



121
122
123
# File 'lib/cache/tokyo_store.rb', line 121

def stats
  @data.stat
end

#write(key, value, options = nil) ⇒ Object

Writes a value to the cache.

Possible options:

  • :unless_exist - set to true if you don’t want to update the cache if the key is already set.



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/cache/tokyo_store.rb', line 78

def write(key, value, options = nil)
  super
  method = options && options[:unless_exist] ? :add : :set
  # will break the connection if you send it an integer
  # in raw mode, so we convert it to a string to be sure it continues working.
  value = raw?(options) ? value.to_s : Marshal.dump(value) # if value.instance_of? Hash

  @data[key] = value
  ###response = @data.put(key, value) || STDERR.printf("get error: %s\n", @data.errmsg(@data.ecode))#, expires_in(options), raw?(options))
  # logger.error("TokyoError (#{e}): #{e.message}")
  # false
end