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.
- data/.travis.yml +2 -2
- data/CHANGES +6 -0
- data/Gemfile +2 -0
- data/README.md +7 -4
- data/Rakefile +2 -2
- data/lib/moneta.rb +1 -0
- data/lib/moneta/adapters/activerecord.rb +1 -2
- data/lib/moneta/adapters/cassandra.rb +31 -26
- data/lib/moneta/adapters/cookie.rb +2 -2
- data/lib/moneta/adapters/couch.rb +5 -3
- data/lib/moneta/adapters/daybreak.rb +13 -9
- data/lib/moneta/adapters/dbm.rb +7 -3
- data/lib/moneta/adapters/file.rb +4 -3
- data/lib/moneta/adapters/fog.rb +5 -2
- data/lib/moneta/adapters/gdbm.rb +7 -3
- data/lib/moneta/adapters/hbase.rb +11 -9
- data/lib/moneta/adapters/kyotocabinet.rb +13 -8
- data/lib/moneta/adapters/leveldb.rb +9 -5
- data/lib/moneta/adapters/localmemcache.rb +7 -3
- data/lib/moneta/adapters/memcached/dalli.rb +16 -11
- data/lib/moneta/adapters/memcached/native.rb +20 -15
- data/lib/moneta/adapters/memory.rb +2 -1
- data/lib/moneta/adapters/mongo.rb +13 -8
- data/lib/moneta/adapters/pstore.rb +24 -21
- data/lib/moneta/adapters/redis.rb +14 -12
- data/lib/moneta/adapters/restclient.rb +10 -7
- data/lib/moneta/adapters/riak.rb +5 -1
- data/lib/moneta/adapters/sdbm.rb +7 -3
- data/lib/moneta/adapters/sequel.rb +13 -8
- data/lib/moneta/adapters/sqlite.rb +15 -10
- data/lib/moneta/adapters/tdb.rb +8 -4
- data/lib/moneta/adapters/tokyocabinet.rb +15 -10
- data/lib/moneta/adapters/tokyotyrant.rb +107 -0
- data/lib/moneta/cache.rb +17 -17
- data/lib/moneta/mixins.rb +7 -5
- data/lib/moneta/version.rb +1 -1
- data/lib/rack/moneta_store.rb +1 -1
- data/lib/rack/session/moneta.rb +6 -3
- data/script/benchmarks +28 -28
- data/script/generate-specs +96 -41
- data/script/memusage +40 -0
- data/script/start-services +1 -0
- data/spec/helper.rb +4 -1
- data/spec/moneta/adapter_tokyotyrant_spec.rb +30 -0
- data/spec/moneta/cache_file_memory_spec.rb +3 -3
- data/spec/moneta/cache_memory_null_spec.rb +1 -1
- data/spec/moneta/simple_tokyotyrant_spec.rb +155 -0
- data/spec/moneta/simple_tokyotyrant_with_expires_spec.rb +157 -0
- data/spec/monetaspecs.rb +79 -37
- data/spec/rack/moneta_store_spec.rb +1 -1
- data/spec/rack/session_moneta_spec.rb +27 -0
- 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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
@
|
24
|
+
@backend.check(key) >= 0
|
20
25
|
end
|
21
26
|
|
22
27
|
# (see Proxy#delete)
|
23
28
|
def delete(key, options = {})
|
24
|
-
@
|
29
|
+
@backend.seize(key)
|
25
30
|
end
|
26
31
|
|
27
32
|
# (see Proxy#create)
|
28
33
|
def create(key, value, options = {})
|
29
|
-
@
|
34
|
+
@backend.add(key, value)
|
30
35
|
end
|
31
36
|
|
32
37
|
# (see Proxy#close)
|
33
38
|
def close
|
34
|
-
@
|
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
|
-
|
13
|
-
|
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
|
-
@
|
22
|
+
@backend.includes?(key)
|
19
23
|
end
|
20
24
|
|
21
25
|
# (see Proxy#clear)
|
22
26
|
def clear(options = {})
|
23
|
-
@
|
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
|
-
@
|
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
|
-
|
15
|
-
|
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
|
-
@
|
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
|
-
|
20
|
-
|
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 = @
|
30
|
+
value = @backend.get(key)
|
26
31
|
if value
|
27
32
|
expires = expires_value(options, nil)
|
28
|
-
@
|
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
|
-
@
|
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 = @
|
42
|
-
@
|
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 ? @
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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 = @
|
35
|
+
value = @backend.get(key, false)
|
31
36
|
if value
|
32
37
|
expires = expires_value(options, nil)
|
33
|
-
@
|
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
|
-
@
|
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 = @
|
49
|
-
@
|
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
|
-
@
|
62
|
+
@backend.increment(key, amount)
|
58
63
|
else
|
59
|
-
@
|
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((@
|
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
|
-
@
|
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
|
-
@
|
85
|
+
@backend.flush
|
81
86
|
self
|
82
87
|
end
|
83
88
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
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
|
-
@
|
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
|
-
|
16
|
-
|
17
|
-
|
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
|
-
@
|
27
|
+
@backend.transaction(true) { @backend.root?(key) }
|
23
28
|
end
|
24
29
|
|
25
30
|
# (see Proxy#load)
|
26
31
|
def load(key, options = {})
|
27
|
-
@
|
32
|
+
@backend.transaction(true) { @backend[key] }
|
28
33
|
end
|
29
34
|
|
30
35
|
# (see Proxy#store)
|
31
36
|
def store(key, value, options = {})
|
32
|
-
@
|
37
|
+
@backend.transaction { @backend[key] = value }
|
33
38
|
end
|
34
39
|
|
35
40
|
# (see Proxy#delete)
|
36
41
|
def delete(key, options = {})
|
37
|
-
@
|
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
|
-
@
|
43
|
-
value = Utils.to_int(@
|
44
|
-
@
|
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
|
-
@
|
52
|
-
if @
|
56
|
+
@backend.transaction do
|
57
|
+
if @backend.root?(key)
|
53
58
|
false
|
54
59
|
else
|
55
|
-
@
|
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
|
-
@
|
64
|
-
@
|
65
|
-
@
|
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
|
-
|
74
|
-
|
78
|
+
def new_store(options)
|
79
|
+
if RUBY_VERSION > '1.9'
|
75
80
|
::PStore.new(options[:file], options[:threadsafe])
|
76
|
-
|
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
|
-
@
|
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 @
|
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 = @
|
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
|
-
@
|
46
|
+
@backend.setex(key, expires, value)
|
45
47
|
else
|
46
|
-
@
|
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
|
-
@
|
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
|
-
@
|
63
|
+
@backend.incrby(key, amount)
|
62
64
|
end
|
63
65
|
|
64
66
|
# (see Proxy#clear)
|
65
67
|
def clear(options = {})
|
66
|
-
@
|
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 @
|
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
|
-
@
|
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
|
-
@
|
93
|
+
@backend.persist(key)
|
92
94
|
when Numeric
|
93
|
-
@
|
95
|
+
@backend.expire(key, expires)
|
94
96
|
end
|
95
97
|
end
|
96
98
|
end
|