moneta 0.7.9 → 0.7.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|