moneta 0.7.9 → 0.7.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. data/.travis.yml +2 -2
  2. data/CHANGES +6 -0
  3. data/Gemfile +2 -0
  4. data/README.md +7 -4
  5. data/Rakefile +2 -2
  6. data/lib/moneta.rb +1 -0
  7. data/lib/moneta/adapters/activerecord.rb +1 -2
  8. data/lib/moneta/adapters/cassandra.rb +31 -26
  9. data/lib/moneta/adapters/cookie.rb +2 -2
  10. data/lib/moneta/adapters/couch.rb +5 -3
  11. data/lib/moneta/adapters/daybreak.rb +13 -9
  12. data/lib/moneta/adapters/dbm.rb +7 -3
  13. data/lib/moneta/adapters/file.rb +4 -3
  14. data/lib/moneta/adapters/fog.rb +5 -2
  15. data/lib/moneta/adapters/gdbm.rb +7 -3
  16. data/lib/moneta/adapters/hbase.rb +11 -9
  17. data/lib/moneta/adapters/kyotocabinet.rb +13 -8
  18. data/lib/moneta/adapters/leveldb.rb +9 -5
  19. data/lib/moneta/adapters/localmemcache.rb +7 -3
  20. data/lib/moneta/adapters/memcached/dalli.rb +16 -11
  21. data/lib/moneta/adapters/memcached/native.rb +20 -15
  22. data/lib/moneta/adapters/memory.rb +2 -1
  23. data/lib/moneta/adapters/mongo.rb +13 -8
  24. data/lib/moneta/adapters/pstore.rb +24 -21
  25. data/lib/moneta/adapters/redis.rb +14 -12
  26. data/lib/moneta/adapters/restclient.rb +10 -7
  27. data/lib/moneta/adapters/riak.rb +5 -1
  28. data/lib/moneta/adapters/sdbm.rb +7 -3
  29. data/lib/moneta/adapters/sequel.rb +13 -8
  30. data/lib/moneta/adapters/sqlite.rb +15 -10
  31. data/lib/moneta/adapters/tdb.rb +8 -4
  32. data/lib/moneta/adapters/tokyocabinet.rb +15 -10
  33. data/lib/moneta/adapters/tokyotyrant.rb +107 -0
  34. data/lib/moneta/cache.rb +17 -17
  35. data/lib/moneta/mixins.rb +7 -5
  36. data/lib/moneta/version.rb +1 -1
  37. data/lib/rack/moneta_store.rb +1 -1
  38. data/lib/rack/session/moneta.rb +6 -3
  39. data/script/benchmarks +28 -28
  40. data/script/generate-specs +96 -41
  41. data/script/memusage +40 -0
  42. data/script/start-services +1 -0
  43. data/spec/helper.rb +4 -1
  44. data/spec/moneta/adapter_tokyotyrant_spec.rb +30 -0
  45. data/spec/moneta/cache_file_memory_spec.rb +3 -3
  46. data/spec/moneta/cache_memory_null_spec.rb +1 -1
  47. data/spec/moneta/simple_tokyotyrant_spec.rb +155 -0
  48. data/spec/moneta/simple_tokyotyrant_with_expires_spec.rb +157 -0
  49. data/spec/monetaspecs.rb +79 -37
  50. data/spec/rack/moneta_store_spec.rb +1 -1
  51. data/spec/rack/session_moneta_spec.rb +27 -0
  52. metadata +10 -3
@@ -7,31 +7,36 @@ module Moneta
7
7
  class KyotoCabinet < Memory
8
8
  # @param [Hash] options
9
9
  # @option options [String] :file Database file
10
+ # @option options [::KyotoCabinet::DB] :backend Use existing backend instance
10
11
  def initialize(options = {})
11
- raise ArgumentError, 'Option :file is required' unless options[:file]
12
- @hash = ::KyotoCabinet::DB.new
13
- raise @hash.error.to_s unless @hash.open(options[:file],
14
- ::KyotoCabinet::DB::OWRITER | ::KyotoCabinet::DB::OCREATE)
12
+ if options[:backend]
13
+ @backend = options[:backend]
14
+ else
15
+ raise ArgumentError, 'Option :file is required' unless options[:file]
16
+ @backend = ::KyotoCabinet::DB.new
17
+ raise @backend.error.to_s unless @backend.open(options[:file],
18
+ ::KyotoCabinet::DB::OWRITER | ::KyotoCabinet::DB::OCREATE)
19
+ end
15
20
  end
16
21
 
17
22
  # (see Proxy#key?)
18
23
  def key?(key, options = {})
19
- @hash.check(key) >= 0
24
+ @backend.check(key) >= 0
20
25
  end
21
26
 
22
27
  # (see Proxy#delete)
23
28
  def delete(key, options = {})
24
- @hash.seize(key)
29
+ @backend.seize(key)
25
30
  end
26
31
 
27
32
  # (see Proxy#create)
28
33
  def create(key, value, options = {})
29
- @hash.add(key, value)
34
+ @backend.add(key, value)
30
35
  end
31
36
 
32
37
  # (see Proxy#close)
33
38
  def close
34
- @hash.close
39
+ @backend.close
35
40
  nil
36
41
  end
37
42
  end
@@ -8,25 +8,29 @@ module Moneta
8
8
  # @param [Hash] options
9
9
  # @option options [String] :dir - Database path
10
10
  # @option options All other options passed to `LevelDB::DB#new`
11
+ # @option options [::LevelDB::DB] :backend Use existing backend instance
11
12
  def initialize(options = {})
12
- raise ArgumentError, 'Option :dir is required' unless options[:dir]
13
- @hash = ::LevelDB::DB.new(options[:dir])
13
+ @backend = options[:backend] ||
14
+ begin
15
+ raise ArgumentError, 'Option :dir is required' unless options[:dir]
16
+ ::LevelDB::DB.new(options[:dir])
17
+ end
14
18
  end
15
19
 
16
20
  # (see Proxy#key?)
17
21
  def key?(key, options = {})
18
- @hash.includes?(key)
22
+ @backend.includes?(key)
19
23
  end
20
24
 
21
25
  # (see Proxy#clear)
22
26
  def clear(options = {})
23
- @hash.each {|k,v| delete(k, options) }
27
+ @backend.each {|k,v| delete(k, options) }
24
28
  self
25
29
  end
26
30
 
27
31
  # (see Proxy#close)
28
32
  def close
29
- @hash.close
33
+ @backend.close
30
34
  nil
31
35
  end
32
36
  end
@@ -10,15 +10,19 @@ module Moneta
10
10
 
11
11
  # @param [Hash] options
12
12
  # @option options [String] :file Database file
13
+ # @option options [::LocalMemCache] :backend Use existing backend instance
13
14
  def initialize(options = {})
14
- raise ArgumentError, 'Option :file is required' unless options[:file]
15
- @hash = ::LocalMemCache.new(:filename => options[:file])
15
+ @backend = options[:backend] ||
16
+ begin
17
+ raise ArgumentError, 'Option :file is required' unless options[:file]
18
+ ::LocalMemCache.new(:filename => options[:file])
19
+ end
16
20
  end
17
21
 
18
22
  # (see Proxy#delete)
19
23
  def delete(key, options = {})
20
24
  value = load(key, options)
21
- @hash.delete(key)
25
+ @backend.delete(key)
22
26
  value
23
27
  end
24
28
  end
@@ -9,37 +9,42 @@ module Moneta
9
9
  include ExpiresSupport
10
10
 
11
11
  supports :create, :increment
12
+ attr_reader :backend
12
13
 
13
14
  # @param [Hash] options
14
15
  # @option options [String] :server ('127.0.0.1:11211') Memcached server
15
16
  # @option options [Integer] :expires Default expiration time
17
+ # @option options [::Dalli::Client] :backend Use existing backend instance
16
18
  # @option options Other options passed to `Dalli::Client#new`
17
19
  def initialize(options = {})
18
20
  self.default_expires = options.delete(:expires)
19
- server = options.delete(:server) || '127.0.0.1:11211'
20
- @cache = ::Dalli::Client.new(server, options)
21
+ @backend = options[:backend] ||
22
+ begin
23
+ server = options.delete(:server) || '127.0.0.1:11211'
24
+ ::Dalli::Client.new(server, options)
25
+ end
21
26
  end
22
27
 
23
28
  # (see Proxy#load)
24
29
  def load(key, options = {})
25
- value = @cache.get(key)
30
+ value = @backend.get(key)
26
31
  if value
27
32
  expires = expires_value(options, nil)
28
- @cache.set(key, value, expires || nil, :raw => true) if expires != nil
33
+ @backend.set(key, value, expires || nil, :raw => true) if expires != nil
29
34
  value
30
35
  end
31
36
  end
32
37
 
33
38
  # (see Proxy#store)
34
39
  def store(key, value, options = {})
35
- @cache.set(key, value, expires_value(options) || nil, :raw => true)
40
+ @backend.set(key, value, expires_value(options) || nil, :raw => true)
36
41
  value
37
42
  end
38
43
 
39
44
  # (see Proxy#delete)
40
45
  def delete(key, options = {})
41
- value = @cache.get(key)
42
- @cache.delete(key)
46
+ value = @backend.get(key)
47
+ @backend.delete(key)
43
48
  value
44
49
  end
45
50
 
@@ -48,7 +53,7 @@ module Moneta
48
53
  # FIXME: There is a Dalli bug, load(key) returns a wrong value after increment
49
54
  # therefore we set default = nil and create the counter manually
50
55
  # See https://github.com/mperham/dalli/issues/309
51
- result = amount >= 0 ? @cache.incr(key, amount, nil, nil) : @cache.decr(key, -amount, nil, nil)
56
+ result = amount >= 0 ? @backend.incr(key, amount, nil, nil) : @backend.decr(key, -amount, nil, nil)
52
57
  if result
53
58
  result
54
59
  elsif create(key, amount.to_s, options)
@@ -60,18 +65,18 @@ module Moneta
60
65
 
61
66
  # (see Proxy#clear)
62
67
  def clear(options = {})
63
- @cache.flush_all
68
+ @backend.flush_all
64
69
  self
65
70
  end
66
71
 
67
72
  # (see Defaults#create)
68
73
  def create(key, value, options = {})
69
- @cache.add(key, value, expires_value(options) || nil, :raw => true)
74
+ @backend.add(key, value, expires_value(options) || nil, :raw => true)
70
75
  end
71
76
 
72
77
  # (see Proxy#close)
73
78
  def close
74
- @cache.close
79
+ @backend.close
75
80
  nil
76
81
  end
77
82
  end
@@ -9,28 +9,33 @@ module Moneta
9
9
  include ExpiresSupport
10
10
 
11
11
  supports :create, :increment
12
+ attr_reader :backend
12
13
 
13
14
  # @param [Hash] options
14
15
  # @option options [String] :server ('127.0.0.1:11211') Memcached server
15
16
  # @option options [String] :namespace Key namespace
16
17
  # @option options [Integer] :expires (604800) Default expiration time
18
+ # @option options [::Memcached] :backend Use existing backend instance
17
19
  # @option options Other options passed to `Memcached#new`
18
20
  def initialize(options = {})
19
21
  server = options.delete(:server) || '127.0.0.1:11211'
20
22
  self.default_expires = options.delete(:expires)
21
- options.merge!(:prefix_key => options.delete(:namespace)) if options[:namespace]
22
- # We don't want a limitation on the key charset. Therefore we use the binary protocol.
23
- # It is also faster.
24
- options[:binary_protocol] = true unless options.include?(:binary_protocol)
25
- @cache = ::Memcached.new(server, options)
23
+ @backend = options[:backend] ||
24
+ begin
25
+ options.merge!(:prefix_key => options.delete(:namespace)) if options[:namespace]
26
+ # We don't want a limitation on the key charset. Therefore we use the binary protocol.
27
+ # It is also faster.
28
+ options[:binary_protocol] = true unless options.include?(:binary_protocol)
29
+ ::Memcached.new(server, options)
30
+ end
26
31
  end
27
32
 
28
33
  # (see Proxy#load)
29
34
  def load(key, options = {})
30
- value = @cache.get(key, false)
35
+ value = @backend.get(key, false)
31
36
  if value
32
37
  expires = expires_value(options, nil)
33
- @cache.set(key, value, expires || 0, false) if expires != nil
38
+ @backend.set(key, value, expires || 0, false) if expires != nil
34
39
  value
35
40
  end
36
41
  rescue ::Memcached::NotFound
@@ -39,14 +44,14 @@ module Moneta
39
44
  # (see Proxy#store)
40
45
  def store(key, value, options = {})
41
46
  # TTL must be Fixnum
42
- @cache.set(key, value, expires_value(options) || 0, false)
47
+ @backend.set(key, value, expires_value(options) || 0, false)
43
48
  value
44
49
  end
45
50
 
46
51
  # (see Proxy#delete)
47
52
  def delete(key, options = {})
48
- value = @cache.get(key, false)
49
- @cache.delete(key)
53
+ value = @backend.get(key, false)
54
+ @backend.delete(key)
50
55
  value
51
56
  rescue ::Memcached::NotFound
52
57
  end
@@ -54,13 +59,13 @@ module Moneta
54
59
  # (see Proxy#increment)
55
60
  def increment(key, amount = 1, options = {})
56
61
  result = if amount >= 0
57
- @cache.increment(key, amount)
62
+ @backend.increment(key, amount)
58
63
  else
59
- @cache.decrement(key, -amount)
64
+ @backend.decrement(key, -amount)
60
65
  end
61
66
  # HACK: Throw error if applied to invalid value
62
67
  # see https://github.com/evan/memcached/issues/110
63
- Utils.to_int((@cache.get(key, false) rescue nil)) if result == 0
68
+ Utils.to_int((@backend.get(key, false) rescue nil)) if result == 0
64
69
  result
65
70
  rescue ::Memcached::NotFound => ex
66
71
  retry unless create(key, amount.to_s, options)
@@ -69,7 +74,7 @@ module Moneta
69
74
 
70
75
  # (see Defaults#create)
71
76
  def create(key, value, options = {})
72
- @cache.add(key, value, expires_value(options) || 0, false)
77
+ @backend.add(key, value, expires_value(options) || 0, false)
73
78
  true
74
79
  rescue ::Memcached::ConnectionDataExists
75
80
  false
@@ -77,7 +82,7 @@ module Moneta
77
82
 
78
83
  # (see Proxy#clear)
79
84
  def clear(options = {})
80
- @cache.flush
85
+ @backend.flush
81
86
  self
82
87
  end
83
88
  end
@@ -9,8 +9,9 @@ module Moneta
9
9
  include CreateSupport
10
10
 
11
11
  # @param [Hash] options Options hash
12
+ # @option options [Hash] :backend Use existing backend instance
12
13
  def initialize(options = {})
13
- @hash = {}
14
+ @backend = options[:backend] || {}
14
15
  end
15
16
  end
16
17
  end
@@ -13,6 +13,7 @@ module Moneta
13
13
  include ExpiresSupport
14
14
 
15
15
  supports :create, :increment
16
+ attr_reader :backend
16
17
 
17
18
  # @param [Hash] options
18
19
  # @option options [String] :collection ('moneta') MongoDB collection name
@@ -22,19 +23,23 @@ module Moneta
22
23
  # @option options [Integer] :port (MongoDB default port) MongoDB server port
23
24
  # @option options [String] :db ('moneta') MongoDB database
24
25
  # @option options [Integer] :expires Default expiration time
26
+ # @option options [::Mongo::MongoClient] :backend Use existing backend instance
25
27
  def initialize(options = {})
26
28
  self.default_expires = options.delete(:expires)
27
29
  collection = options.delete(:collection) || 'moneta'
28
- host = options.delete(:host) || '127.0.0.1'
29
- port = options.delete(:port) || ::Mongo::MongoClient::DEFAULT_PORT
30
30
  db = options.delete(:db) || 'moneta'
31
- user = options.delete(:user)
32
- password = options.delete(:password)
33
- client = ::Mongo::MongoClient.new(host, port, options)
34
- db = client.db(db)
31
+ @backend = options[:backend] ||
32
+ begin
33
+ host = options.delete(:host) || '127.0.0.1'
34
+ port = options.delete(:port) || ::Mongo::MongoClient::DEFAULT_PORT
35
+ user = options.delete(:user)
36
+ password = options.delete(:password)
37
+ ::Mongo::MongoClient.new(host, port, options)
38
+ end
39
+ db = @backend.db(db)
35
40
  db.authenticate(user, password, true) if user && password
36
41
  @collection = db.collection(collection)
37
- if client.server_version >= '2.2'
42
+ if @backend.server_version >= '2.2'
38
43
  @collection.ensure_index([['expiresAt', ::Mongo::ASCENDING]], :expireAfterSeconds => 0)
39
44
  else
40
45
  warn 'Moneta::Adapters::Mongo - You are using MongoDB version < 2.2, expired documents will not be deleted'
@@ -105,7 +110,7 @@ module Moneta
105
110
 
106
111
  # (see Proxy#close)
107
112
  def close
108
- @collection.db.connection.close
113
+ @backend.close
109
114
  nil
110
115
  end
111
116
  end
@@ -8,51 +8,56 @@ module Moneta
8
8
  include Defaults
9
9
 
10
10
  supports :create, :increment
11
+ attr_reader :backend
11
12
 
12
13
  # @param [Hash] options
13
14
  # @option options [String] :file PStore file
15
+ # @option options [::PStore] :backend Use existing backend instance
14
16
  def initialize(options = {})
15
- raise ArgumentError, 'Option :file is required' unless options[:file]
16
- FileUtils.mkpath(::File.dirname(options[:file]))
17
- @pstore = new_store(options)
17
+ @backend = options[:backend] ||
18
+ begin
19
+ raise ArgumentError, 'Option :file is required' unless options[:file]
20
+ FileUtils.mkpath(::File.dirname(options[:file]))
21
+ new_store(options)
22
+ end
18
23
  end
19
24
 
20
25
  # (see Proxy#key?)
21
26
  def key?(key, options = {})
22
- @pstore.transaction(true) { @pstore.root?(key) }
27
+ @backend.transaction(true) { @backend.root?(key) }
23
28
  end
24
29
 
25
30
  # (see Proxy#load)
26
31
  def load(key, options = {})
27
- @pstore.transaction(true) { @pstore[key] }
32
+ @backend.transaction(true) { @backend[key] }
28
33
  end
29
34
 
30
35
  # (see Proxy#store)
31
36
  def store(key, value, options = {})
32
- @pstore.transaction { @pstore[key] = value }
37
+ @backend.transaction { @backend[key] = value }
33
38
  end
34
39
 
35
40
  # (see Proxy#delete)
36
41
  def delete(key, options = {})
37
- @pstore.transaction { @pstore.delete(key) }
42
+ @backend.transaction { @backend.delete(key) }
38
43
  end
39
44
 
40
45
  # (see Proxy#increment)
41
46
  def increment(key, amount = 1, options = {})
42
- @pstore.transaction do
43
- value = Utils.to_int(@pstore[key]) + amount
44
- @pstore[key] = value.to_s
47
+ @backend.transaction do
48
+ value = Utils.to_int(@backend[key]) + amount
49
+ @backend[key] = value.to_s
45
50
  value
46
51
  end
47
52
  end
48
53
 
49
54
  # (see Proxy#create)
50
55
  def create(key, value, options = {})
51
- @pstore.transaction do
52
- if @pstore.root?(key)
56
+ @backend.transaction do
57
+ if @backend.root?(key)
53
58
  false
54
59
  else
55
- @pstore[key] = value
60
+ @backend[key] = value
56
61
  true
57
62
  end
58
63
  end
@@ -60,9 +65,9 @@ module Moneta
60
65
 
61
66
  # (see Proxy#clear)
62
67
  def clear(options = {})
63
- @pstore.transaction do
64
- @pstore.roots.each do |key|
65
- @pstore.delete(key)
68
+ @backend.transaction do
69
+ @backend.roots.each do |key|
70
+ @backend.delete(key)
66
71
  end
67
72
  end
68
73
  self
@@ -70,12 +75,10 @@ module Moneta
70
75
 
71
76
  protected
72
77
 
73
- if RUBY_VERSION > '1.9'
74
- def new_store(options)
78
+ def new_store(options)
79
+ if RUBY_VERSION > '1.9'
75
80
  ::PStore.new(options[:file], options[:threadsafe])
76
- end
77
- else
78
- def new_store(options)
81
+ else
79
82
  ::PStore.new(options[:file])
80
83
  end
81
84
  end
@@ -9,13 +9,15 @@ module Moneta
9
9
  include ExpiresSupport
10
10
 
11
11
  supports :create, :increment
12
+ attr_reader :backend
12
13
 
13
14
  # @param [Hash] options
14
15
  # @option options [Integer] :expires Default expiration time
16
+ # @option options [::Redis] :backend Use existing backend instance
15
17
  # @option options Other options passed to `Redis#new`
16
18
  def initialize(options = {})
17
19
  self.default_expires = options.delete(:expires)
18
- @redis = ::Redis.new(options)
20
+ @backend = options[:backend] || ::Redis.new(options)
19
21
  end
20
22
 
21
23
  # (see Proxy#key?)
@@ -23,7 +25,7 @@ module Moneta
23
25
  # This method considers false and 0 as "no-expire" and every positive
24
26
  # number as a time to live in seconds.
25
27
  def key?(key, options = {})
26
- if @redis.exists(key)
28
+ if @backend.exists(key)
27
29
  update_expires(key, options, nil)
28
30
  true
29
31
  else
@@ -33,7 +35,7 @@ module Moneta
33
35
 
34
36
  # (see Proxy#load)
35
37
  def load(key, options = {})
36
- value = @redis.get(key)
38
+ value = @backend.get(key)
37
39
  update_expires(key, options, nil)
38
40
  value
39
41
  end
@@ -41,9 +43,9 @@ module Moneta
41
43
  # (see Proxy#store)
42
44
  def store(key, value, options = {})
43
45
  if expires = expires_value(options)
44
- @redis.setex(key, expires, value)
46
+ @backend.setex(key, expires, value)
45
47
  else
46
- @redis.set(key, value)
48
+ @backend.set(key, value)
47
49
  end
48
50
  value
49
51
  end
@@ -51,25 +53,25 @@ module Moneta
51
53
  # (see Proxy#delete)
52
54
  def delete(key, options = {})
53
55
  if value = load(key, options)
54
- @redis.del(key)
56
+ @backend.del(key)
55
57
  value
56
58
  end
57
59
  end
58
60
 
59
61
  # (see Proxy#increment)
60
62
  def increment(key, amount = 1, options = {})
61
- @redis.incrby(key, amount)
63
+ @backend.incrby(key, amount)
62
64
  end
63
65
 
64
66
  # (see Proxy#clear)
65
67
  def clear(options = {})
66
- @redis.flushdb
68
+ @backend.flushdb
67
69
  self
68
70
  end
69
71
 
70
72
  # (see Defaults#create)
71
73
  def create(key, value, options = {})
72
- if @redis.setnx(key, value)
74
+ if @backend.setnx(key, value)
73
75
  update_expires(key, options)
74
76
  true
75
77
  else
@@ -79,7 +81,7 @@ module Moneta
79
81
 
80
82
  # (see Proxy#close)
81
83
  def close
82
- @redis.quit
84
+ @backend.quit
83
85
  nil
84
86
  end
85
87
 
@@ -88,9 +90,9 @@ module Moneta
88
90
  def update_expires(key, options, default = @default_expires)
89
91
  case expires = expires_value(options, default)
90
92
  when false
91
- @redis.persist(key)
93
+ @backend.persist(key)
92
94
  when Numeric
93
- @redis.expire(key, expires)
95
+ @backend.expire(key, expires)
94
96
  end
95
97
  end
96
98
  end