moneta 0.7.8 → 0.7.9
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 +1 -0
- data/CHANGES +6 -0
- data/Gemfile +1 -0
- data/README.md +107 -40
- data/SPEC.md +8 -0
- data/lib/moneta.rb +6 -7
- data/lib/moneta/adapters/activerecord.rb +2 -0
- data/lib/moneta/adapters/client.rb +9 -0
- data/lib/moneta/adapters/datamapper.rb +2 -0
- data/lib/moneta/adapters/file.rb +2 -0
- data/lib/moneta/adapters/kyotocabinet.rb +39 -0
- data/lib/moneta/adapters/lruhash.rb +1 -1
- data/lib/moneta/adapters/memcached/dalli.rb +3 -5
- data/lib/moneta/adapters/memcached/native.rb +2 -0
- data/lib/moneta/adapters/mongo.rb +2 -0
- data/lib/moneta/adapters/pstore.rb +2 -0
- data/lib/moneta/adapters/redis.rb +3 -3
- data/lib/moneta/adapters/sequel.rb +2 -0
- data/lib/moneta/adapters/sqlite.rb +2 -0
- data/lib/moneta/adapters/tokyocabinet.rb +2 -3
- data/lib/moneta/adapters/yaml.rb +1 -1
- data/lib/moneta/cache.rb +5 -0
- data/lib/moneta/expires.rb +1 -0
- data/lib/moneta/mixins.rb +68 -1
- data/lib/moneta/proxy.rb +5 -0
- data/lib/moneta/server.rb +1 -1
- data/lib/moneta/stack.rb +16 -0
- data/lib/moneta/synchronize.rb +3 -1
- data/lib/moneta/version.rb +1 -1
- data/lib/moneta/weak.rb +15 -1
- data/lib/moneta/wrapper.rb +5 -0
- data/script/benchmarks +2 -0
- data/script/generate-specs +64 -37
- data/script/install-bundle +2 -1
- data/script/install-kyotocabinet +17 -0
- data/spec/moneta/adapter_activerecord_spec.rb +5 -0
- data/spec/moneta/adapter_cassandra_spec.rb +5 -0
- data/spec/moneta/adapter_cassandra_with_default_expires_spec.rb +5 -0
- data/spec/moneta/adapter_client_spec.rb +5 -0
- data/spec/moneta/adapter_cookie_spec.rb +5 -0
- data/spec/moneta/adapter_couch_spec.rb +5 -0
- data/spec/moneta/adapter_datamapper_spec.rb +5 -0
- data/spec/moneta/adapter_daybreak_spec.rb +5 -0
- data/spec/moneta/adapter_dbm_spec.rb +5 -0
- data/spec/moneta/adapter_file_spec.rb +5 -0
- data/spec/moneta/adapter_fog_spec.rb +5 -0
- data/spec/moneta/adapter_gdbm_spec.rb +5 -0
- data/spec/moneta/adapter_hbase_spec.rb +5 -0
- data/spec/moneta/adapter_kyotocabinet_spec.rb +29 -0
- data/spec/moneta/adapter_leveldb_spec.rb +5 -0
- data/spec/moneta/adapter_localmemcache_spec.rb +5 -0
- data/spec/moneta/adapter_lruhash_spec.rb +5 -0
- data/spec/moneta/adapter_memcached_dalli_spec.rb +5 -0
- data/spec/moneta/adapter_memcached_dalli_with_default_expires_spec.rb +5 -0
- data/spec/moneta/adapter_memcached_native_spec.rb +5 -0
- data/spec/moneta/adapter_memcached_native_with_default_expires_spec.rb +5 -0
- data/spec/moneta/adapter_memcached_spec.rb +5 -0
- data/spec/moneta/adapter_memcached_with_default_expires_spec.rb +5 -0
- data/spec/moneta/adapter_memory_spec.rb +5 -0
- data/spec/moneta/adapter_mongo_spec.rb +5 -0
- data/spec/moneta/adapter_mongo_with_default_expires_spec.rb +5 -0
- data/spec/moneta/adapter_pstore_spec.rb +5 -0
- data/spec/moneta/adapter_redis_spec.rb +5 -0
- data/spec/moneta/adapter_redis_with_default_expires_spec.rb +5 -0
- data/spec/moneta/adapter_restclient_spec.rb +5 -0
- data/spec/moneta/adapter_riak_spec.rb +5 -0
- data/spec/moneta/adapter_sdbm_spec.rb +5 -0
- data/spec/moneta/adapter_sequel_spec.rb +5 -0
- data/spec/moneta/adapter_sqlite_spec.rb +5 -0
- data/spec/moneta/adapter_tdb_spec.rb +5 -0
- data/spec/moneta/adapter_tokyocabinet_bdb_spec.rb +5 -0
- data/spec/moneta/adapter_tokyocabinet_hdb_spec.rb +5 -0
- data/spec/moneta/adapter_yaml_spec.rb +5 -0
- data/spec/moneta/cache_file_memory_spec.rb +5 -0
- data/spec/moneta/cache_memory_null_spec.rb +5 -0
- data/spec/moneta/expires_file_spec.rb +5 -0
- data/spec/moneta/expires_memory_spec.rb +5 -0
- data/spec/moneta/expires_memory_with_default_expires_spec.rb +5 -0
- data/spec/moneta/lock_spec.rb +5 -0
- data/spec/moneta/mutex_spec.rb +4 -0
- data/spec/moneta/null_adapter_spec.rb +4 -0
- data/spec/moneta/optionmerger_spec.rb +8 -0
- data/spec/moneta/pool_spec.rb +5 -0
- data/spec/moneta/proxy_expires_memory_spec.rb +5 -0
- data/spec/moneta/proxy_redis_spec.rb +5 -0
- data/spec/moneta/semaphore_spec.rb +4 -0
- data/spec/moneta/shared_tcp_spec.rb +5 -0
- data/spec/moneta/shared_unix_spec.rb +5 -0
- data/spec/moneta/simple_activerecord_spec.rb +5 -0
- data/spec/moneta/simple_activerecord_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_cassandra_spec.rb +5 -0
- data/spec/moneta/simple_client_tcp_spec.rb +5 -0
- data/spec/moneta/simple_client_unix_spec.rb +5 -0
- data/spec/moneta/simple_couch_spec.rb +5 -0
- data/spec/moneta/simple_couch_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_datamapper_spec.rb +5 -0
- data/spec/moneta/simple_datamapper_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_datamapper_with_repository_spec.rb +5 -0
- data/spec/moneta/simple_daybreak_spec.rb +5 -0
- data/spec/moneta/simple_daybreak_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_dbm_spec.rb +5 -0
- data/spec/moneta/simple_dbm_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_file_spec.rb +5 -0
- data/spec/moneta/simple_file_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_fog_spec.rb +5 -0
- data/spec/moneta/simple_fog_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_gdbm_spec.rb +5 -0
- data/spec/moneta/simple_gdbm_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_hashfile_spec.rb +5 -0
- data/spec/moneta/simple_hashfile_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_hbase_spec.rb +5 -0
- data/spec/moneta/simple_hbase_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_kyotocabinet_spec.rb +154 -0
- data/spec/moneta/simple_kyotocabinet_with_expires_spec.rb +156 -0
- data/spec/moneta/simple_leveldb_spec.rb +5 -0
- data/spec/moneta/simple_leveldb_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_localmemcache_spec.rb +5 -0
- data/spec/moneta/simple_localmemcache_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_lruhash_spec.rb +5 -0
- data/spec/moneta/simple_lruhash_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_memcached_dalli_spec.rb +5 -0
- data/spec/moneta/simple_memcached_native_spec.rb +5 -0
- data/spec/moneta/simple_memcached_spec.rb +5 -0
- data/spec/moneta/simple_memory_spec.rb +5 -0
- data/spec/moneta/simple_memory_with_compress_spec.rb +5 -0
- data/spec/moneta/simple_memory_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_memory_with_json_key_serializer_spec.rb +5 -0
- data/spec/moneta/simple_memory_with_json_serializer_spec.rb +5 -0
- data/spec/moneta/simple_memory_with_json_value_serializer_spec.rb +5 -0
- data/spec/moneta/simple_memory_with_prefix_spec.rb +5 -0
- data/spec/moneta/simple_memory_with_snappy_compress_spec.rb +5 -0
- data/spec/moneta/simple_mongo_spec.rb +5 -0
- data/spec/moneta/simple_null_spec.rb +5 -0
- data/spec/moneta/simple_pstore_spec.rb +5 -0
- data/spec/moneta/simple_pstore_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_redis_spec.rb +5 -0
- data/spec/moneta/simple_restclient_spec.rb +5 -0
- data/spec/moneta/simple_riak_spec.rb +5 -0
- data/spec/moneta/simple_riak_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_sdbm_spec.rb +5 -0
- data/spec/moneta/simple_sdbm_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_sequel_spec.rb +5 -0
- data/spec/moneta/simple_sequel_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_sqlite_spec.rb +5 -0
- data/spec/moneta/simple_sqlite_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_tdb_spec.rb +5 -0
- data/spec/moneta/simple_tdb_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_tokyocabinet_spec.rb +5 -0
- data/spec/moneta/simple_tokyocabinet_with_expires_spec.rb +5 -0
- data/spec/moneta/simple_yaml_spec.rb +5 -0
- data/spec/moneta/simple_yaml_with_expires_spec.rb +5 -0
- data/spec/moneta/stack_file_memory_spec.rb +5 -0
- data/spec/moneta/stack_memory_file_spec.rb +7 -4
- data/spec/moneta/transformer_bencode_spec.rb +5 -0
- data/spec/moneta/transformer_bert_spec.rb +5 -0
- data/spec/moneta/transformer_bson_spec.rb +5 -0
- data/spec/moneta/transformer_bzip2_spec.rb +5 -0
- data/spec/moneta/transformer_json_spec.rb +5 -0
- data/spec/moneta/transformer_key_inspect_spec.rb +5 -0
- data/spec/moneta/transformer_key_marshal_spec.rb +5 -0
- data/spec/moneta/transformer_key_to_s_spec.rb +5 -0
- data/spec/moneta/transformer_key_yaml_spec.rb +5 -0
- data/spec/moneta/transformer_lzma_spec.rb +5 -0
- data/spec/moneta/transformer_lzo_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_base64_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_escape_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_hmac_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_md5_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_md5_spread_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_prefix_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_rmd160_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_sha1_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_sha256_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_sha384_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_sha512_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_truncate_spec.rb +5 -0
- data/spec/moneta/transformer_marshal_uuencode_spec.rb +5 -0
- data/spec/moneta/transformer_msgpack_spec.rb +5 -0
- data/spec/moneta/transformer_ox_spec.rb +5 -0
- data/spec/moneta/transformer_quicklz_spec.rb +5 -0
- data/spec/moneta/transformer_snappy_spec.rb +5 -0
- data/spec/moneta/transformer_tnet_spec.rb +5 -0
- data/spec/moneta/transformer_value_marshal_spec.rb +5 -0
- data/spec/moneta/transformer_value_yaml_spec.rb +5 -0
- data/spec/moneta/transformer_yaml_spec.rb +5 -0
- data/spec/moneta/transformer_zlib_spec.rb +5 -0
- data/spec/moneta/weak_create_spec.rb +10 -91
- data/spec/moneta/weak_increment_spec.rb +10 -91
- data/spec/monetaspecs.rb +19 -0
- metadata +10 -2
|
@@ -12,6 +12,8 @@ module Moneta
|
|
|
12
12
|
include Defaults
|
|
13
13
|
include ExpiresSupport
|
|
14
14
|
|
|
15
|
+
supports :create, :increment
|
|
16
|
+
|
|
15
17
|
# @param [Hash] options
|
|
16
18
|
# @option options [String] :collection ('moneta') MongoDB collection name
|
|
17
19
|
# @option options [String] :host ('127.0.0.1') MongoDB server host
|
|
@@ -8,6 +8,8 @@ module Moneta
|
|
|
8
8
|
include Defaults
|
|
9
9
|
include ExpiresSupport
|
|
10
10
|
|
|
11
|
+
supports :create, :increment
|
|
12
|
+
|
|
11
13
|
# @param [Hash] options
|
|
12
14
|
# @option options [Integer] :expires Default expiration time
|
|
13
15
|
# @option options Other options passed to `Redis#new`
|
|
@@ -56,9 +58,7 @@ module Moneta
|
|
|
56
58
|
|
|
57
59
|
# (see Proxy#increment)
|
|
58
60
|
def increment(key, amount = 1, options = {})
|
|
59
|
-
|
|
60
|
-
update_expires(key, options)
|
|
61
|
-
value
|
|
61
|
+
@redis.incrby(key, amount)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
# (see Proxy#clear)
|
|
@@ -9,14 +9,13 @@ module Moneta
|
|
|
9
9
|
# @option options [String] :file Database file
|
|
10
10
|
# @option options [Symbol] :type (:hdb) Database type (:bdb and :hdb possible)
|
|
11
11
|
def initialize(options = {})
|
|
12
|
-
file = options[:file]
|
|
13
12
|
raise ArgumentError, 'Option :file is required' unless options[:file]
|
|
14
13
|
if options[:type] == :bdb
|
|
15
14
|
@hash = ::TokyoCabinet::BDB.new
|
|
16
|
-
@hash.open(file, ::TokyoCabinet::BDB::OWRITER | ::TokyoCabinet::BDB::OCREAT)
|
|
15
|
+
@hash.open(options[:file], ::TokyoCabinet::BDB::OWRITER | ::TokyoCabinet::BDB::OCREAT)
|
|
17
16
|
else
|
|
18
17
|
@hash = ::TokyoCabinet::HDB.new
|
|
19
|
-
@hash.open(file, ::TokyoCabinet::HDB::OWRITER | ::TokyoCabinet::HDB::OCREAT)
|
|
18
|
+
@hash.open(options[:file], ::TokyoCabinet::HDB::OWRITER | ::TokyoCabinet::HDB::OCREAT)
|
|
20
19
|
end or raise @hash.errmsg(@hash.ecode)
|
|
21
20
|
end
|
|
22
21
|
|
data/lib/moneta/adapters/yaml.rb
CHANGED
data/lib/moneta/cache.rb
CHANGED
data/lib/moneta/expires.rb
CHANGED
|
@@ -12,6 +12,7 @@ module Moneta
|
|
|
12
12
|
# @param [Hash] options
|
|
13
13
|
# @option options [String] :expires Default expiration time
|
|
14
14
|
def initialize(adapter, options = {})
|
|
15
|
+
raise 'Store already supports feature :expires' if adapter.supports?(:expires)
|
|
15
16
|
super
|
|
16
17
|
self.default_expires = options[:expires]
|
|
17
18
|
end
|
data/lib/moneta/mixins.rb
CHANGED
|
@@ -45,7 +45,7 @@ module Moneta
|
|
|
45
45
|
# @return [OptionMerger]
|
|
46
46
|
# @api public
|
|
47
47
|
def expires(expires)
|
|
48
|
-
with(:expires => expires, :only => [:store, :create
|
|
48
|
+
with(:expires => expires, :only => [:store, :create])
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
|
|
@@ -54,6 +54,34 @@ module Moneta
|
|
|
54
54
|
module Defaults
|
|
55
55
|
include OptionSupport
|
|
56
56
|
|
|
57
|
+
# @api private
|
|
58
|
+
module ClassMethods
|
|
59
|
+
# Returns features list
|
|
60
|
+
#
|
|
61
|
+
# @return [Array<Symbol>] list of features
|
|
62
|
+
def features
|
|
63
|
+
@features ||= superclass.respond_to?(:features) ? superclass.features : [].freeze
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Declares that this adapter supports the given feature.
|
|
67
|
+
#
|
|
68
|
+
# @example
|
|
69
|
+
# class MyAdapter
|
|
70
|
+
# include Moneta::Defaults
|
|
71
|
+
# supports :create
|
|
72
|
+
# def create(key, value, options = {})
|
|
73
|
+
# # implement create!
|
|
74
|
+
# end
|
|
75
|
+
# end
|
|
76
|
+
def supports(*features)
|
|
77
|
+
@features = (self.features + features).uniq.freeze
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.included(base)
|
|
82
|
+
base.extend(ClassMethods)
|
|
83
|
+
end
|
|
84
|
+
|
|
57
85
|
# Exists the value with key
|
|
58
86
|
#
|
|
59
87
|
# @param [Object] key
|
|
@@ -76,6 +104,8 @@ module Moneta
|
|
|
76
104
|
# @param [Object] key
|
|
77
105
|
# @param [Integer] amount
|
|
78
106
|
# @param [Hash] options
|
|
107
|
+
# @option options [String] :prefix Prefix key (See {Transformer})
|
|
108
|
+
# @option options Other options as defined by the adapters or middleware
|
|
79
109
|
# @return [Object] value from store
|
|
80
110
|
# @api public
|
|
81
111
|
def increment(key, amount = 1, options = {})
|
|
@@ -91,6 +121,8 @@ module Moneta
|
|
|
91
121
|
# @param [Object] key
|
|
92
122
|
# @param [Integer] amount
|
|
93
123
|
# @param [Hash] options
|
|
124
|
+
# @option options [String] :prefix Prefix key (See {Transformer})
|
|
125
|
+
# @option options Other options as defined by the adapters or middleware
|
|
94
126
|
# @return [Object] value from store
|
|
95
127
|
# @api public
|
|
96
128
|
def decrement(key, amount = 1, options = {})
|
|
@@ -110,6 +142,9 @@ module Moneta
|
|
|
110
142
|
# block and return its return value.
|
|
111
143
|
# @param [Object] key
|
|
112
144
|
# @param [Hash] options
|
|
145
|
+
# @option options [Integer] :expires Update expiration time (See {Expires})
|
|
146
|
+
# @option options [Boolean] :raw Raw access without value transformation (See {Transformer})
|
|
147
|
+
# @option options [String] :prefix Prefix key (See {Transformer})
|
|
113
148
|
# @return [Object] value from store
|
|
114
149
|
#
|
|
115
150
|
# @overload fetch(key, default, options = {})
|
|
@@ -117,6 +152,9 @@ module Moneta
|
|
|
117
152
|
# @param [Object] key
|
|
118
153
|
# @param [Object] default Default value
|
|
119
154
|
# @param [Hash] options
|
|
155
|
+
# @option options [Integer] :expires Update expiration time (See {Expires})
|
|
156
|
+
# @option options [Boolean] :raw Raw access without value transformation (See {Transformer})
|
|
157
|
+
# @option options [String] :prefix Prefix key (See {Transformer})
|
|
120
158
|
# @return [Object] value from store
|
|
121
159
|
#
|
|
122
160
|
# @api public
|
|
@@ -157,11 +195,28 @@ module Moneta
|
|
|
157
195
|
# @param [Object] key
|
|
158
196
|
# @param [Object] value
|
|
159
197
|
# @param [Hash] options
|
|
198
|
+
# @option options [Integer] :expires Update expiration time (See {Expires})
|
|
199
|
+
# @option options [Boolean] :raw Raw access without value transformation (See {Transformer})
|
|
200
|
+
# @option options [String] :prefix Prefix key (See {Transformer})
|
|
160
201
|
# @return [Boolean] key was set
|
|
161
202
|
# @api public
|
|
162
203
|
def create(key, value, options = {})
|
|
163
204
|
raise NotImplementedError, 'create is not supported'
|
|
164
205
|
end
|
|
206
|
+
|
|
207
|
+
# Returns features list
|
|
208
|
+
#
|
|
209
|
+
# @return [Array<Symbol>] list of features
|
|
210
|
+
def features
|
|
211
|
+
self.class.features
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Return true if adapter supports the given feature.
|
|
215
|
+
#
|
|
216
|
+
# @return [Boolean]
|
|
217
|
+
def supports?(feature)
|
|
218
|
+
features.include?(feature)
|
|
219
|
+
end
|
|
165
220
|
end
|
|
166
221
|
|
|
167
222
|
# @api private
|
|
@@ -173,6 +228,10 @@ module Moneta
|
|
|
173
228
|
store(key, value.to_s, options)
|
|
174
229
|
value
|
|
175
230
|
end
|
|
231
|
+
|
|
232
|
+
def self.included(base)
|
|
233
|
+
base.supports(:increment) if base.respond_to?(:supports)
|
|
234
|
+
end
|
|
176
235
|
end
|
|
177
236
|
|
|
178
237
|
# Implements simple create using key? and store.
|
|
@@ -190,6 +249,10 @@ module Moneta
|
|
|
190
249
|
true
|
|
191
250
|
end
|
|
192
251
|
end
|
|
252
|
+
|
|
253
|
+
def self.included(base)
|
|
254
|
+
base.supports(:create) if base.respond_to?(:supports)
|
|
255
|
+
end
|
|
193
256
|
end
|
|
194
257
|
|
|
195
258
|
# @api private
|
|
@@ -293,5 +356,9 @@ module Moneta
|
|
|
293
356
|
raise ArgumentError, ":expires must be Numeric or false, got #{value.inspect}"
|
|
294
357
|
end
|
|
295
358
|
end
|
|
359
|
+
|
|
360
|
+
def self.included(base)
|
|
361
|
+
base.supports(:expires) if base.respond_to?(:supports)
|
|
362
|
+
end
|
|
296
363
|
end
|
|
297
364
|
end
|
data/lib/moneta/proxy.rb
CHANGED
data/lib/moneta/server.rb
CHANGED
|
@@ -92,7 +92,7 @@ module Moneta
|
|
|
92
92
|
def handle(client)
|
|
93
93
|
method, *args = read(client)
|
|
94
94
|
case method
|
|
95
|
-
when :key?, :load, :delete, :increment, :create
|
|
95
|
+
when :key?, :load, :delete, :increment, :create, :features
|
|
96
96
|
write(client, @store.send(method, *args))
|
|
97
97
|
when :store, :clear
|
|
98
98
|
@store.send(method, *args)
|
data/lib/moneta/stack.rb
CHANGED
|
@@ -67,6 +67,13 @@ module Moneta
|
|
|
67
67
|
last
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
+
# (see Proxy#create)
|
|
71
|
+
def create(key, value, options = {})
|
|
72
|
+
last = false
|
|
73
|
+
@stack.each {|s| last = s.create(key, value, options) }
|
|
74
|
+
last
|
|
75
|
+
end
|
|
76
|
+
|
|
70
77
|
# (see Proxy#delete)
|
|
71
78
|
def delete(key, options = {})
|
|
72
79
|
@stack.inject(nil) do |value, s|
|
|
@@ -86,5 +93,14 @@ module Moneta
|
|
|
86
93
|
@stack.each {|s| s.close }
|
|
87
94
|
nil
|
|
88
95
|
end
|
|
96
|
+
|
|
97
|
+
# (see Proxy#features)
|
|
98
|
+
def features
|
|
99
|
+
@features ||=
|
|
100
|
+
begin
|
|
101
|
+
features = @stack.map(&:features)
|
|
102
|
+
features.inject(features.first, &:&).freeze
|
|
103
|
+
end
|
|
104
|
+
end
|
|
89
105
|
end
|
|
90
106
|
end
|
data/lib/moneta/synchronize.rb
CHANGED
|
@@ -74,6 +74,7 @@ module Moneta
|
|
|
74
74
|
# @param [Moneta store] store The store we want to lock
|
|
75
75
|
# @param [Object] lock Key of the lock entry
|
|
76
76
|
def initialize(store, lock)
|
|
77
|
+
raise 'Store must support feature :create' unless store.supports?(:create)
|
|
77
78
|
@store, @lock = store, lock
|
|
78
79
|
end
|
|
79
80
|
|
|
@@ -94,7 +95,7 @@ module Moneta
|
|
|
94
95
|
# semaphore = Moneta::Semaphore.new(store, 'semaphore', 2)
|
|
95
96
|
# semaphore.synchronize do
|
|
96
97
|
# # Synchronized access
|
|
97
|
-
# ...
|
|
98
|
+
# # ...
|
|
98
99
|
# end
|
|
99
100
|
#
|
|
100
101
|
# @api public
|
|
@@ -103,6 +104,7 @@ module Moneta
|
|
|
103
104
|
# @param [Object] counter Key of the counter entry
|
|
104
105
|
# @param [Fixnum] max Maximum number of threads which are allowed to enter the critical section
|
|
105
106
|
def initialize(store, counter, max = 1)
|
|
107
|
+
raise 'Store must support feature :increment' unless store.supports?(:increment)
|
|
106
108
|
@store, @counter, @max = store, counter, max
|
|
107
109
|
@store.increment(@counter, 0, :expires => false) # Ensure that counter exists
|
|
108
110
|
end
|
data/lib/moneta/version.rb
CHANGED
data/lib/moneta/weak.rb
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
module Moneta
|
|
2
2
|
# Adds weak create support to the underlying store
|
|
3
3
|
#
|
|
4
|
-
# @note The
|
|
4
|
+
# @note The create method will not be thread or multi-process safe (this is meant by weak)
|
|
5
5
|
# @api public
|
|
6
6
|
class WeakCreate < Proxy
|
|
7
7
|
include CreateSupport
|
|
8
|
+
|
|
9
|
+
# @param [Moneta store] adapter The underlying store
|
|
10
|
+
# @param [Hash] options
|
|
11
|
+
def initialize(adapter, options = {})
|
|
12
|
+
raise 'Store already supports feature :create' if adapter.supports?(:create)
|
|
13
|
+
super
|
|
14
|
+
end
|
|
8
15
|
end
|
|
9
16
|
|
|
10
17
|
# Adds weak increment support to the underlying store
|
|
@@ -13,5 +20,12 @@ module Moneta
|
|
|
13
20
|
# @api public
|
|
14
21
|
class WeakIncrement < Proxy
|
|
15
22
|
include IncrementSupport
|
|
23
|
+
|
|
24
|
+
# @param [Moneta store] adapter The underlying store
|
|
25
|
+
# @param [Hash] options
|
|
26
|
+
def initialize(adapter, options = {})
|
|
27
|
+
raise 'Store already supports feature :increment' if adapter.supports?(:increment)
|
|
28
|
+
super
|
|
29
|
+
end
|
|
16
30
|
end
|
|
17
31
|
end
|
data/lib/moneta/wrapper.rb
CHANGED
data/script/benchmarks
CHANGED
|
@@ -46,6 +46,7 @@ class MonetaBenchmarks
|
|
|
46
46
|
:GDBM => { :file => "#{DIR}/gdbm" },
|
|
47
47
|
:HBase => {},
|
|
48
48
|
:HashFile => { :dir => "#{DIR}/hashfile" },
|
|
49
|
+
:KyotoCabinet => { :file => 'kyotocabinet.kch' },
|
|
49
50
|
:LRUHash => {},
|
|
50
51
|
:LevelDB => { :dir => "#{DIR}/leveldb" },
|
|
51
52
|
:LocalMemCache => { :file => "#{DIR}/lmc" },
|
|
@@ -60,6 +61,7 @@ class MonetaBenchmarks
|
|
|
60
61
|
:Sequel => { :db => 'sqlite:/' },
|
|
61
62
|
:Sqlite => { :file => ':memory:' },
|
|
62
63
|
:TDB => { :file => "#{DIR}/tdb" },
|
|
64
|
+
:TokyoCabinet => { :file => 'tokyocabinet' },
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
CONFIGS = {
|
data/script/generate-specs
CHANGED
|
@@ -2,27 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
PATH = File.expand_path(File.join(__FILE__, '..', '..', 'spec'))
|
|
4
4
|
|
|
5
|
-
class Array
|
|
6
|
-
def without(*x)
|
|
7
|
-
a = dup
|
|
8
|
-
x.each {|y| a.delete(y) }
|
|
9
|
-
a
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def with(*x)
|
|
13
|
-
a = dup
|
|
14
|
-
x.each {|y| a << y }
|
|
15
|
-
a
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
5
|
class Specs
|
|
20
|
-
attr_reader :key, :value, :specs
|
|
6
|
+
attr_reader :key, :value, :specs, :features
|
|
21
7
|
|
|
22
8
|
def initialize(options = {})
|
|
23
9
|
@specs = options.delete(:specs).to_a
|
|
24
10
|
@key = options.delete(:key) || %w(object string hash boolean nil integer)
|
|
25
11
|
@value = options.delete(:value) || %w(object string hash boolean nil integer)
|
|
12
|
+
@features = []
|
|
13
|
+
[:expires, :expires_native, :increment, :create].each do |feature|
|
|
14
|
+
@features << feature if @specs.include?(feature)
|
|
15
|
+
end
|
|
16
|
+
@features.sort_by!(&:to_s)
|
|
17
|
+
@features.uniq!
|
|
26
18
|
end
|
|
27
19
|
|
|
28
20
|
def new(options)
|
|
@@ -46,15 +38,15 @@ class Specs
|
|
|
46
38
|
end
|
|
47
39
|
|
|
48
40
|
def without_increment
|
|
49
|
-
new(:specs => specs
|
|
41
|
+
new(:specs => specs - [:increment] + [:not_increment])
|
|
50
42
|
end
|
|
51
43
|
|
|
52
44
|
def without_persist
|
|
53
|
-
new(:specs => specs
|
|
45
|
+
new(:specs => specs - [:persist, :multiprocess] + [:not_persist])
|
|
54
46
|
end
|
|
55
47
|
|
|
56
48
|
def without_multiprocess
|
|
57
|
-
new(:specs => specs
|
|
49
|
+
new(:specs => specs - [:multiprocess])
|
|
58
50
|
end
|
|
59
51
|
|
|
60
52
|
def with_expires
|
|
@@ -71,45 +63,45 @@ class Specs
|
|
|
71
63
|
def with_native_expires
|
|
72
64
|
a = specs.dup
|
|
73
65
|
a << :create_expires if a.include?(:create)
|
|
74
|
-
new(:specs => a
|
|
66
|
+
new(:specs => a + [:expires])
|
|
75
67
|
end
|
|
76
68
|
|
|
77
69
|
def without_marshallable
|
|
78
|
-
new(:specs => specs
|
|
70
|
+
new(:specs => specs - [:marshallable_value, :marshallable_key])
|
|
79
71
|
end
|
|
80
72
|
|
|
81
73
|
def without_transform
|
|
82
|
-
new(:specs => specs
|
|
74
|
+
new(:specs => specs - [:marshallable_value, :marshallable_key, :transform_value])
|
|
83
75
|
end
|
|
84
76
|
|
|
85
77
|
def returnsame
|
|
86
|
-
new(:specs => specs
|
|
78
|
+
new(:specs => specs - [:returndifferent] + [:returnsame])
|
|
87
79
|
end
|
|
88
80
|
|
|
89
81
|
def without_marshallable_key
|
|
90
|
-
new(:specs => specs
|
|
82
|
+
new(:specs => specs - [:marshallable_key])
|
|
91
83
|
end
|
|
92
84
|
|
|
93
85
|
def without_marshallable_value
|
|
94
|
-
new(:specs => specs
|
|
86
|
+
new(:specs => specs - [:marshallable_value])
|
|
95
87
|
end
|
|
96
88
|
|
|
97
89
|
def without_store
|
|
98
|
-
new(:specs => specs
|
|
90
|
+
new(:specs => specs - [:store, :transform_value, :marshallable_value])
|
|
99
91
|
end
|
|
100
92
|
|
|
101
93
|
def with_default_expires
|
|
102
|
-
new(:specs => specs
|
|
94
|
+
new(:specs => specs + [:default_expires])
|
|
103
95
|
end
|
|
104
96
|
|
|
105
97
|
def without_create
|
|
106
|
-
new(:specs => specs
|
|
98
|
+
new(:specs => specs - [:create, :create_expires] + [:not_create])
|
|
107
99
|
end
|
|
108
100
|
end
|
|
109
101
|
|
|
110
|
-
ADAPTER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :increment, :persist, :multiprocess, :create], :key => %w(string), :value => %w(string))
|
|
111
|
-
STANDARD_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :marshallable_key, :marshallable_value, :transform_value, :increment, :persist, :multiprocess, :create])
|
|
112
|
-
TRANSFORMER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :transform_value, :increment, :create])
|
|
102
|
+
ADAPTER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :increment, :persist, :multiprocess, :create, :features], :key => %w(string), :value => %w(string))
|
|
103
|
+
STANDARD_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :marshallable_key, :marshallable_value, :transform_value, :increment, :persist, :multiprocess, :create, :features])
|
|
104
|
+
TRANSFORMER_SPECS = Specs.new(:specs => [:null, :store, :returndifferent, :transform_value, :increment, :create, :features])
|
|
113
105
|
|
|
114
106
|
header = "# Generated by #{File.basename(__FILE__)}\n"
|
|
115
107
|
|
|
@@ -338,6 +330,16 @@ end
|
|
|
338
330
|
:options => ':file => File.join(make_tempdir, "simple_tokyocabinet_with_expires"), :expires => true',
|
|
339
331
|
:specs => STANDARD_SPECS.without_multiprocess.with_expires
|
|
340
332
|
},
|
|
333
|
+
'simple_kyotocabinet' => {
|
|
334
|
+
:store => :KyotoCabinet,
|
|
335
|
+
:options => ':file => File.join(make_tempdir, "simple_kyotocabinet.kch")',
|
|
336
|
+
:specs => STANDARD_SPECS.without_multiprocess
|
|
337
|
+
},
|
|
338
|
+
'simple_kyotocabinet_with_expires' => {
|
|
339
|
+
:store => :KyotoCabinet,
|
|
340
|
+
:options => ':file => File.join(make_tempdir, "simple_kyotocabinet_with_expires.kch"), :expires => true',
|
|
341
|
+
:specs => STANDARD_SPECS.without_multiprocess.with_expires
|
|
342
|
+
},
|
|
341
343
|
'simple_sqlite' => {
|
|
342
344
|
:store => :Sqlite,
|
|
343
345
|
:options => ':file => File.join(make_tempdir, "simple_sqlite")',
|
|
@@ -478,16 +480,16 @@ end
|
|
|
478
480
|
'weak_create' => {
|
|
479
481
|
:build => %{Moneta.build do
|
|
480
482
|
use :WeakCreate
|
|
481
|
-
adapter :
|
|
483
|
+
adapter :Couch, :db => 'weak_create'
|
|
482
484
|
end},
|
|
483
|
-
:specs =>
|
|
485
|
+
:specs => ADAPTER_SPECS.without_increment
|
|
484
486
|
},
|
|
485
487
|
'weak_increment' => {
|
|
486
488
|
:build => %{Moneta.build do
|
|
487
489
|
use :WeakIncrement
|
|
488
|
-
adapter :
|
|
490
|
+
adapter :Couch, :db => 'weak_increment'
|
|
489
491
|
end},
|
|
490
|
-
:specs =>
|
|
492
|
+
:specs => ADAPTER_SPECS.without_create
|
|
491
493
|
},
|
|
492
494
|
'expires_memory' => {
|
|
493
495
|
:build => %{Moneta.build do
|
|
@@ -618,13 +620,11 @@ end},
|
|
|
618
620
|
'stack_memory_file' => {
|
|
619
621
|
:build => %{Moneta.build do
|
|
620
622
|
use(:Stack) do
|
|
621
|
-
add(Moneta.new(:Null))
|
|
622
|
-
add(Moneta::Adapters::Null.new)
|
|
623
623
|
add { adapter :Memory }
|
|
624
624
|
add { adapter :File, :dir => File.join(make_tempdir, "stack_memory_file") }
|
|
625
625
|
end
|
|
626
626
|
end},
|
|
627
|
-
:specs =>
|
|
627
|
+
:specs => ADAPTER_SPECS.returnsame
|
|
628
628
|
},
|
|
629
629
|
'lock' => {
|
|
630
630
|
:build => %{Moneta.build do
|
|
@@ -1289,6 +1289,10 @@ end}
|
|
|
1289
1289
|
:build => 'Moneta::Adapters::Sqlite.new(:file => File.join(make_tempdir, "adapter_sqlite"))',
|
|
1290
1290
|
:specs => ADAPTER_SPECS
|
|
1291
1291
|
},
|
|
1292
|
+
'adapter_kyotocabinet' => {
|
|
1293
|
+
:build => 'Moneta::Adapters::KyotoCabinet.new(:file => File.join(make_tempdir, "adapter_kyotocabinet.kch"))',
|
|
1294
|
+
:specs => ADAPTER_SPECS.without_multiprocess
|
|
1295
|
+
},
|
|
1292
1296
|
'adapter_tokyocabinet_bdb' => {
|
|
1293
1297
|
:build => 'Moneta::Adapters::TokyoCabinet.new(:file => File.join(make_tempdir, "adapter_tokyocabinet_bdb"), :type => :bdb)',
|
|
1294
1298
|
:specs => ADAPTER_SPECS.without_multiprocess
|
|
@@ -1496,6 +1500,10 @@ it 'has method #raw' do
|
|
|
1496
1500
|
store.raw.should equal(store.raw.raw)
|
|
1497
1501
|
end
|
|
1498
1502
|
|
|
1503
|
+
it 'has method #expires' do
|
|
1504
|
+
store.expires(10).default_options.should == {:store=>{:expires=>10},:create=>{:expires=>10}}
|
|
1505
|
+
end
|
|
1506
|
+
|
|
1499
1507
|
it 'has method #prefix' do
|
|
1500
1508
|
store.prefix('a').default_options.should == {:store=>{:prefix=>'a'},:load=>{:prefix=>'a'},:create=>{:prefix=>'a'},
|
|
1501
1509
|
:delete=>{:prefix=>'a'},:key? => {:prefix=>'a'},:increment=>{:prefix=>'a'}}
|
|
@@ -2166,6 +2174,21 @@ it 'might raise exception on invalid value' do
|
|
|
2166
2174
|
end
|
|
2167
2175
|
end}
|
|
2168
2176
|
|
|
2177
|
+
SPECS['features'] = %{it 'should report correct features' do
|
|
2178
|
+
store.features.sort_by(&:to_s).should == features
|
|
2179
|
+
end
|
|
2180
|
+
|
|
2181
|
+
it 'should have frozen features' do
|
|
2182
|
+
store.features.frozen?.should be_true
|
|
2183
|
+
end
|
|
2184
|
+
|
|
2185
|
+
it 'should have #supports?' do
|
|
2186
|
+
features.each do |f|
|
|
2187
|
+
store.supports?(f).should be_true
|
|
2188
|
+
end
|
|
2189
|
+
store.supports?(:unknown).should be_false
|
|
2190
|
+
end}
|
|
2191
|
+
|
|
2169
2192
|
specs_code = "#{header}\n"
|
|
2170
2193
|
SPECS.each do |key, code|
|
|
2171
2194
|
specs_code << "#################### #{key} ####################\n\n" <<
|
|
@@ -2205,6 +2228,10 @@ describe_moneta #{name.inspect} do
|
|
|
2205
2228
|
@log ||= File.open(File.join(make_tempdir, '#{name}.log'), 'a')
|
|
2206
2229
|
end
|
|
2207
2230
|
|
|
2231
|
+
def features
|
|
2232
|
+
#{specs.features.to_a.inspect}
|
|
2233
|
+
end
|
|
2234
|
+
|
|
2208
2235
|
#{preamble}def new_store
|
|
2209
2236
|
#{build.gsub("\n", "\n ")}
|
|
2210
2237
|
end
|