moneta 0.6.0 → 0.7.0

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 (212) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +39 -0
  3. data/Gemfile +61 -0
  4. data/LICENSE +2 -2
  5. data/README.md +450 -0
  6. data/Rakefile +29 -51
  7. data/SPEC.md +75 -0
  8. data/benchmarks/run.rb +195 -0
  9. data/lib/action_dispatch/middleware/session/moneta_store.rb +11 -0
  10. data/lib/active_support/cache/moneta_store.rb +55 -0
  11. data/lib/moneta.rb +121 -67
  12. data/lib/moneta/adapters/activerecord.rb +87 -0
  13. data/lib/moneta/adapters/cassandra.rb +91 -0
  14. data/lib/moneta/adapters/client.rb +69 -0
  15. data/lib/moneta/adapters/cookie.rb +35 -0
  16. data/lib/moneta/adapters/couch.rb +57 -0
  17. data/lib/moneta/adapters/datamapper.rb +75 -0
  18. data/lib/moneta/adapters/dbm.rb +25 -0
  19. data/lib/moneta/adapters/file.rb +79 -0
  20. data/lib/moneta/adapters/fog.rb +51 -0
  21. data/lib/moneta/adapters/gdbm.rb +25 -0
  22. data/lib/moneta/adapters/hbase.rb +101 -0
  23. data/lib/moneta/adapters/leveldb.rb +35 -0
  24. data/lib/moneta/adapters/localmemcache.rb +28 -0
  25. data/lib/moneta/adapters/lruhash.rb +85 -0
  26. data/lib/moneta/adapters/memcached.rb +11 -0
  27. data/lib/moneta/adapters/memcached_dalli.rb +69 -0
  28. data/lib/moneta/adapters/memcached_native.rb +70 -0
  29. data/lib/moneta/adapters/memory.rb +10 -0
  30. data/lib/moneta/adapters/mongo.rb +50 -0
  31. data/lib/moneta/adapters/null.rb +30 -0
  32. data/lib/moneta/adapters/pstore.rb +69 -0
  33. data/lib/moneta/adapters/redis.rb +68 -0
  34. data/lib/moneta/adapters/riak.rb +57 -0
  35. data/lib/moneta/adapters/sdbm.rb +35 -0
  36. data/lib/moneta/adapters/sequel.rb +79 -0
  37. data/lib/moneta/adapters/sqlite.rb +65 -0
  38. data/lib/moneta/adapters/tokyocabinet.rb +41 -0
  39. data/lib/moneta/adapters/yaml.rb +15 -0
  40. data/lib/moneta/base.rb +78 -0
  41. data/lib/moneta/builder.rb +39 -0
  42. data/lib/moneta/cache.rb +84 -0
  43. data/lib/moneta/expires.rb +71 -0
  44. data/lib/moneta/lock.rb +25 -0
  45. data/lib/moneta/logger.rb +61 -0
  46. data/lib/moneta/mixins.rb +65 -0
  47. data/lib/moneta/net.rb +18 -0
  48. data/lib/moneta/optionmerger.rb +39 -0
  49. data/lib/moneta/proxy.rb +86 -0
  50. data/lib/moneta/server.rb +81 -0
  51. data/lib/moneta/shared.rb +60 -0
  52. data/lib/moneta/stack.rb +78 -0
  53. data/lib/moneta/transformer.rb +159 -0
  54. data/lib/moneta/transformer/config.rb +42 -0
  55. data/lib/moneta/transformer/helper.rb +37 -0
  56. data/lib/moneta/version.rb +5 -0
  57. data/lib/moneta/wrapper.rb +33 -0
  58. data/lib/rack/cache/moneta.rb +93 -0
  59. data/lib/rack/moneta_cookies.rb +64 -0
  60. data/lib/rack/session/moneta.rb +63 -0
  61. data/moneta.gemspec +19 -0
  62. data/spec/action_dispatch/fixtures/session_autoload_test/foo.rb +10 -0
  63. data/spec/action_dispatch/session_moneta_store_spec.rb +196 -0
  64. data/spec/active_support/cache_moneta_store_spec.rb +197 -0
  65. data/spec/generate.rb +1489 -0
  66. data/spec/helper.rb +91 -0
  67. data/spec/moneta/adapter_activerecord_spec.rb +32 -0
  68. data/spec/moneta/adapter_cassandra_spec.rb +30 -0
  69. data/spec/moneta/adapter_client_spec.rb +19 -0
  70. data/spec/moneta/adapter_cookie_spec.rb +18 -0
  71. data/spec/moneta/adapter_couch_spec.rb +18 -0
  72. data/spec/moneta/adapter_datamapper_spec.rb +49 -0
  73. data/spec/moneta/adapter_dbm_spec.rb +18 -0
  74. data/spec/moneta/adapter_file_spec.rb +18 -0
  75. data/spec/moneta/adapter_fog_spec.rb +23 -0
  76. data/spec/moneta/adapter_gdbm_spec.rb +18 -0
  77. data/spec/moneta/adapter_hbase_spec.rb +18 -0
  78. data/spec/moneta/adapter_leveldb_spec.rb +18 -0
  79. data/spec/moneta/adapter_localmemcache_spec.rb +18 -0
  80. data/spec/moneta/adapter_lruhash_spec.rb +31 -0
  81. data/spec/moneta/adapter_memcached_dalli_spec.rb +30 -0
  82. data/spec/moneta/adapter_memcached_native_spec.rb +31 -0
  83. data/spec/moneta/adapter_memcached_spec.rb +30 -0
  84. data/spec/moneta/adapter_memory_spec.rb +39 -0
  85. data/spec/moneta/adapter_mongo_spec.rb +18 -0
  86. data/spec/moneta/adapter_pstore_spec.rb +21 -0
  87. data/spec/moneta/adapter_redis_spec.rb +30 -0
  88. data/spec/moneta/adapter_riak_spec.rb +22 -0
  89. data/spec/moneta/adapter_sdbm_spec.rb +18 -0
  90. data/spec/moneta/adapter_sequel_spec.rb +18 -0
  91. data/spec/moneta/adapter_sqlite_spec.rb +18 -0
  92. data/spec/moneta/adapter_tokyocabinet_bdb_spec.rb +18 -0
  93. data/spec/moneta/adapter_tokyocabinet_hdb_spec.rb +18 -0
  94. data/spec/moneta/adapter_yaml_spec.rb +21 -0
  95. data/spec/moneta/cache_file_memory_spec.rb +34 -0
  96. data/spec/moneta/cache_memory_null_spec.rb +23 -0
  97. data/spec/moneta/expires_file_spec.rb +76 -0
  98. data/spec/moneta/expires_memory_spec.rb +65 -0
  99. data/spec/moneta/lock_spec.rb +42 -0
  100. data/spec/moneta/null_adapter_spec.rb +26 -0
  101. data/spec/moneta/optionmerger_spec.rb +92 -0
  102. data/spec/moneta/proxy_expires_memory_spec.rb +55 -0
  103. data/spec/moneta/proxy_redis_spec.rb +23 -0
  104. data/spec/moneta/shared_spec.rb +30 -0
  105. data/spec/moneta/simple_activerecord_spec.rb +51 -0
  106. data/spec/moneta/simple_activerecord_with_expires_spec.rb +52 -0
  107. data/spec/moneta/simple_cassandra_spec.rb +52 -0
  108. data/spec/moneta/simple_client_tcp_spec.rb +67 -0
  109. data/spec/moneta/simple_client_unix_spec.rb +53 -0
  110. data/spec/moneta/simple_couch_spec.rb +51 -0
  111. data/spec/moneta/simple_couch_with_expires_spec.rb +52 -0
  112. data/spec/moneta/simple_datamapper_spec.rb +53 -0
  113. data/spec/moneta/simple_datamapper_with_expires_spec.rb +54 -0
  114. data/spec/moneta/simple_datamapper_with_repository_spec.rb +53 -0
  115. data/spec/moneta/simple_dbm_spec.rb +51 -0
  116. data/spec/moneta/simple_dbm_with_expires_spec.rb +52 -0
  117. data/spec/moneta/simple_file_spec.rb +51 -0
  118. data/spec/moneta/simple_file_with_expires_spec.rb +52 -0
  119. data/spec/moneta/simple_fog_spec.rb +56 -0
  120. data/spec/moneta/simple_fog_with_expires_spec.rb +58 -0
  121. data/spec/moneta/simple_gdbm_spec.rb +51 -0
  122. data/spec/moneta/simple_gdbm_with_expires_spec.rb +52 -0
  123. data/spec/moneta/simple_hashfile_spec.rb +51 -0
  124. data/spec/moneta/simple_hashfile_with_expires_spec.rb +52 -0
  125. data/spec/moneta/simple_hbase_spec.rb +51 -0
  126. data/spec/moneta/simple_hbase_with_expires_spec.rb +52 -0
  127. data/spec/moneta/simple_leveldb_spec.rb +51 -0
  128. data/spec/moneta/simple_leveldb_with_expires_spec.rb +52 -0
  129. data/spec/moneta/simple_localmemcache_spec.rb +51 -0
  130. data/spec/moneta/simple_localmemcache_with_expires_spec.rb +52 -0
  131. data/spec/moneta/simple_lruhash_spec.rb +51 -0
  132. data/spec/moneta/simple_lruhash_with_expires_spec.rb +52 -0
  133. data/spec/moneta/simple_memcached_dalli_spec.rb +52 -0
  134. data/spec/moneta/simple_memcached_native_spec.rb +52 -0
  135. data/spec/moneta/simple_memcached_spec.rb +52 -0
  136. data/spec/moneta/simple_memory_spec.rb +51 -0
  137. data/spec/moneta/simple_memory_with_compress_spec.rb +51 -0
  138. data/spec/moneta/simple_memory_with_expires_spec.rb +52 -0
  139. data/spec/moneta/simple_memory_with_json_key_serializer_spec.rb +37 -0
  140. data/spec/moneta/simple_memory_with_json_serializer_spec.rb +28 -0
  141. data/spec/moneta/simple_memory_with_json_value_serializer_spec.rb +35 -0
  142. data/spec/moneta/simple_memory_with_prefix_spec.rb +51 -0
  143. data/spec/moneta/simple_memory_with_snappy_compress_spec.rb +51 -0
  144. data/spec/moneta/simple_mongo_spec.rb +51 -0
  145. data/spec/moneta/simple_mongo_with_expires_spec.rb +52 -0
  146. data/spec/moneta/simple_null_spec.rb +36 -0
  147. data/spec/moneta/simple_pstore_spec.rb +51 -0
  148. data/spec/moneta/simple_pstore_with_expires_spec.rb +52 -0
  149. data/spec/moneta/simple_redis_spec.rb +52 -0
  150. data/spec/moneta/simple_riak_spec.rb +55 -0
  151. data/spec/moneta/simple_riak_with_expires_spec.rb +56 -0
  152. data/spec/moneta/simple_sdbm_spec.rb +51 -0
  153. data/spec/moneta/simple_sdbm_with_expires_spec.rb +52 -0
  154. data/spec/moneta/simple_sequel_spec.rb +51 -0
  155. data/spec/moneta/simple_sequel_with_expires_spec.rb +52 -0
  156. data/spec/moneta/simple_sqlite_spec.rb +51 -0
  157. data/spec/moneta/simple_sqlite_with_expires_spec.rb +52 -0
  158. data/spec/moneta/simple_tokyocabinet_spec.rb +51 -0
  159. data/spec/moneta/simple_tokyocabinet_with_expires_spec.rb +52 -0
  160. data/spec/moneta/simple_yaml_spec.rb +50 -0
  161. data/spec/moneta/simple_yaml_with_expires_spec.rb +51 -0
  162. data/spec/moneta/stack_file_memory_spec.rb +25 -0
  163. data/spec/moneta/stack_memory_file_spec.rb +24 -0
  164. data/spec/moneta/transformer_bencode_spec.rb +30 -0
  165. data/spec/moneta/transformer_bert_spec.rb +30 -0
  166. data/spec/moneta/transformer_bson_spec.rb +30 -0
  167. data/spec/moneta/transformer_bzip2_spec.rb +27 -0
  168. data/spec/moneta/transformer_json_spec.rb +30 -0
  169. data/spec/moneta/transformer_lzma_spec.rb +27 -0
  170. data/spec/moneta/transformer_lzo_spec.rb +27 -0
  171. data/spec/moneta/transformer_marshal_base64_spec.rb +54 -0
  172. data/spec/moneta/transformer_marshal_escape_spec.rb +54 -0
  173. data/spec/moneta/transformer_marshal_hmac_spec.rb +54 -0
  174. data/spec/moneta/transformer_marshal_md5_spec.rb +54 -0
  175. data/spec/moneta/transformer_marshal_md5_spread_spec.rb +54 -0
  176. data/spec/moneta/transformer_marshal_prefix_spec.rb +54 -0
  177. data/spec/moneta/transformer_marshal_rmd160_spec.rb +54 -0
  178. data/spec/moneta/transformer_marshal_sha1_spec.rb +54 -0
  179. data/spec/moneta/transformer_marshal_sha256_spec.rb +54 -0
  180. data/spec/moneta/transformer_marshal_sha384_spec.rb +54 -0
  181. data/spec/moneta/transformer_marshal_sha512_spec.rb +54 -0
  182. data/spec/moneta/transformer_marshal_truncate_spec.rb +54 -0
  183. data/spec/moneta/transformer_marshal_uuencode_spec.rb +54 -0
  184. data/spec/moneta/transformer_msgpack_spec.rb +30 -0
  185. data/spec/moneta/transformer_ox_spec.rb +51 -0
  186. data/spec/moneta/transformer_quicklz_spec.rb +27 -0
  187. data/spec/moneta/transformer_snappy_spec.rb +27 -0
  188. data/spec/moneta/transformer_tnet_spec.rb +30 -0
  189. data/spec/moneta/transformer_yaml_spec.rb +51 -0
  190. data/spec/moneta/transformer_zlib_spec.rb +27 -0
  191. data/spec/monetaspecs.rb +2663 -0
  192. data/spec/rack/cache_moneta_spec.rb +355 -0
  193. data/spec/rack/moneta_cookies_spec.rb +81 -0
  194. data/spec/rack/session_moneta_spec.rb +305 -0
  195. metadata +359 -56
  196. data/README +0 -51
  197. data/TODO +0 -4
  198. data/lib/moneta/basic_file.rb +0 -111
  199. data/lib/moneta/berkeley.rb +0 -53
  200. data/lib/moneta/couch.rb +0 -63
  201. data/lib/moneta/datamapper.rb +0 -117
  202. data/lib/moneta/file.rb +0 -91
  203. data/lib/moneta/lmc.rb +0 -52
  204. data/lib/moneta/memcache.rb +0 -52
  205. data/lib/moneta/memory.rb +0 -11
  206. data/lib/moneta/mongodb.rb +0 -58
  207. data/lib/moneta/redis.rb +0 -49
  208. data/lib/moneta/rufus.rb +0 -41
  209. data/lib/moneta/s3.rb +0 -162
  210. data/lib/moneta/sdbm.rb +0 -33
  211. data/lib/moneta/tyrant.rb +0 -58
  212. data/lib/moneta/xattr.rb +0 -58
@@ -0,0 +1,51 @@
1
+ require 'fog'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # Fog backend (Cloud storage services)
6
+ # @api public
7
+ class Fog < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :dir - Fog directory
14
+ # * Other options passed to Fog::Storage#new
15
+ def initialize(options = {})
16
+ raise ArgumentError, 'Option :dir is required' unless dir = options.delete(:dir)
17
+ storage = ::Fog::Storage.new(options)
18
+ @directory = storage.directories.create(:key => dir)
19
+ end
20
+
21
+ def key?(key, options = {})
22
+ @directory.files.head(key) != nil
23
+ end
24
+
25
+ def load(key, options = {})
26
+ value = @directory.files.get(key)
27
+ value && value.body
28
+ end
29
+
30
+ def delete(key, options = {})
31
+ if value = @directory.files.get(key)
32
+ body = value.body
33
+ value.destroy
34
+ body
35
+ end
36
+ end
37
+
38
+ def store(key, value, options = {})
39
+ @directory.files.create(:key => key, :body => value)
40
+ value
41
+ end
42
+
43
+ def clear(options = {})
44
+ @directory.files.all.each do |file|
45
+ file.destroy
46
+ end
47
+ self
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,25 @@
1
+ require 'gdbm'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # GDBM backend
6
+ # @api public
7
+ class GDBM < Memory
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :file - Database file
14
+ def initialize(options = {})
15
+ raise ArgumentError, 'Option :file is required' unless options[:file]
16
+ @hash = ::GDBM.new(options[:file])
17
+ end
18
+
19
+ def close
20
+ @hash.close
21
+ nil
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,101 @@
1
+ require 'hbaserb'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # HBase thrift backend
6
+ # @api public
7
+ class HBase < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :host - Server host name (default 127.0.0.1)
14
+ # * :port - Server port (default 9090)
15
+ # * :table - Table name (default moneta)
16
+ # * :column_family - Column family (default moneta)
17
+ # * :column - Column (default value)
18
+ def initialize(options = {})
19
+ options[:host] ||= '127.0.0.1'
20
+ options[:port] ||= '9090'
21
+ options[:table] ||= 'moneta'
22
+ options[:column] ||= 'value'
23
+ cf = (options[:column_family] || 'moneta')
24
+ @db = HBaseRb::Client.new(options[:host], options[:port])
25
+ @db.create_table(options[:table], cf) unless @db.has_table?(options[:table])
26
+ @table = @db.get_table(options[:table])
27
+ @column = "#{cf}:#{options[:column]}"
28
+ end
29
+
30
+ def key?(key, options = {})
31
+ @table.get(key, @column).first != nil
32
+ end
33
+
34
+ def load(key, options = {})
35
+ cell = @table.get(key, @column).first
36
+ cell && unpack(cell.value)
37
+ end
38
+
39
+ def store(key, value, options = {})
40
+ @table.mutate_row(key, @column => pack(value))
41
+ value
42
+ end
43
+
44
+ def increment(key, amount = 1, options = {})
45
+ result = @table.atomic_increment(key, @column, amount)
46
+ # HACK: Throw error if applied to invalid value
47
+ if result == 0
48
+ value = load(key)
49
+ raise 'Tried to increment non integer value' unless value.to_s == value.to_i.to_s
50
+ end
51
+ result
52
+ end
53
+
54
+ def delete(key, options = {})
55
+ if value = load(key, options)
56
+ @table.delete_row(key)
57
+ unpack(value)
58
+ end
59
+ end
60
+
61
+ def clear(options = {})
62
+ @table.create_scanner do |row|
63
+ @table.delete_row(row.row)
64
+ end
65
+ self
66
+ end
67
+
68
+ def close
69
+ @db.close
70
+ nil
71
+ end
72
+
73
+ private
74
+
75
+ def pack(value)
76
+ intvalue = value.to_i
77
+ if intvalue >= 0 && intvalue <= 0xFFFFFFFFFFFFFFFF && intvalue.to_s == value
78
+ # Pack as 8 byte big endian
79
+ [intvalue].pack('Q>')
80
+ elsif value.bytesize >= 8
81
+ # Add nul character to make value distinguishable from integer
82
+ value << "\0"
83
+ else
84
+ value
85
+ end
86
+ end
87
+
88
+ def unpack(value)
89
+ if value.bytesize == 8
90
+ # Unpack 8 byte big endian
91
+ value.unpack('Q>').first.to_s
92
+ elsif value.bytesize >= 9 && value[-1] == ?\0
93
+ # Remove nul character
94
+ value[0..-2]
95
+ else
96
+ value
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,35 @@
1
+ require 'leveldb'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # LevelDB backend
6
+ # @api public
7
+ class LevelDB < Memory
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :dir - Database path
14
+ # * All other options passed to LevelDB::DB#new
15
+ def initialize(options = {})
16
+ raise ArgumentError, 'Option :dir is required' unless options[:dir]
17
+ @hash = ::LevelDB::DB.new(options[:dir])
18
+ end
19
+
20
+ def key?(key, options = {})
21
+ @hash.includes?(key)
22
+ end
23
+
24
+ def clear(options = {})
25
+ @hash.each {|k,v| delete(k, options) }
26
+ self
27
+ end
28
+
29
+ def close
30
+ @hash.close
31
+ nil
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ require 'localmemcache'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # LocalMemCache backend
6
+ # @api public
7
+ class LocalMemCache < Base
8
+ include Mixins::HashAdapter
9
+
10
+ # Constructor
11
+ #
12
+ # @param [Hash] options
13
+ #
14
+ # Options:
15
+ # * :file - Database file
16
+ def initialize(options = {})
17
+ raise ArgumentError, 'Option :file is required' unless options[:file]
18
+ @hash = ::LocalMemCache.new(:filename => options[:file])
19
+ end
20
+
21
+ def delete(key, options = {})
22
+ value = load(key, options)
23
+ @hash.delete(key)
24
+ value
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,85 @@
1
+ module Moneta
2
+ module Adapters
3
+ # LRUHash backend
4
+ #
5
+ # Based on Hashery::LRUHash but simpler and measures memory usage instead of hash size.
6
+ #
7
+ # @api public
8
+ class LRUHash < Base
9
+ include Mixins::IncrementSupport
10
+
11
+ # Constructor
12
+ #
13
+ # @param [Hash] options
14
+ #
15
+ # Options:
16
+ # * :max_size - Maximum byte size of hash values (default 1024000)
17
+ def initialize(options = {})
18
+ @max_size = options[:max_size] || 1024000
19
+ clear
20
+ end
21
+
22
+ def key?(key, options = {})
23
+ @entry.key?(key)
24
+ end
25
+
26
+ def load(key, options = {})
27
+ if entry = @entry[key]
28
+ entry.insert_after(@list)
29
+ entry.value
30
+ end
31
+ end
32
+
33
+ def store(key, value, options = {})
34
+ if entry = @entry[key]
35
+ @size -= entry.value.bytesize
36
+ else
37
+ @entry[key] = entry = Entry.new
38
+ entry.key = key
39
+ end
40
+ entry.value = value
41
+ @size += entry.value.bytesize
42
+ entry.insert_after(@list)
43
+ delete(@list.prev.key) while @list.next != @list.prev && @size > @max_size
44
+ value
45
+ end
46
+
47
+ def delete(key, options = {})
48
+ if entry = @entry.delete(key)
49
+ @size -= entry.value.bytesize
50
+ entry.unlink
51
+ entry.value
52
+ end
53
+ end
54
+
55
+ def clear(options = {})
56
+ @entry, @size = {}, 0
57
+ @list = Entry.new
58
+ @list.prev = @list.next = @list
59
+ self
60
+ end
61
+
62
+ private
63
+
64
+ class Entry
65
+ attr_accessor :key, :value, :prev, :next
66
+
67
+ def unlink
68
+ @prev.next = @next if @prev
69
+ @next.prev = @prev if @next
70
+ @prev = @next = nil
71
+ end
72
+
73
+ def insert_after(entry)
74
+ if entry.next != self
75
+ unlink
76
+ @next = entry.next
77
+ @prev = entry
78
+ entry.next.prev = self
79
+ entry.next = self
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,11 @@
1
+ module Moneta
2
+ module Adapters
3
+ begin
4
+ require 'moneta/adapters/memcached_native'
5
+ Memcached = MemcachedNative
6
+ rescue LoadError
7
+ require 'moneta/adapters/memcached_dalli'
8
+ Memcached = MemcachedDalli
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,69 @@
1
+ require 'dalli'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # Memcached backend (using gem dalli)
6
+ # @api public
7
+ class MemcachedDalli < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :server - Memcached server (default localhost:11211)
14
+ # * :expires - Default expiration time (default none)
15
+ # * Other options passed to Dalli::Client#new
16
+ def initialize(options = {})
17
+ options[:expires_in] = options.delete(:expires)
18
+ server = options.delete(:server) || 'localhost:11211'
19
+ @cache = ::Dalli::Client.new(server, options)
20
+ end
21
+
22
+ def load(key, options = {})
23
+ value = @cache.get(key)
24
+ if value && options.include?(:expires)
25
+ store(key, value, options)
26
+ else
27
+ value
28
+ end
29
+ end
30
+
31
+ def store(key, value, options = {})
32
+ @cache.set(key, value, options[:expires], :raw => true)
33
+ value
34
+ end
35
+
36
+ def delete(key, options = {})
37
+ value = @cache.get(key)
38
+ @cache.delete(key)
39
+ value
40
+ end
41
+
42
+ def increment(key, amount = 1, options = {})
43
+ # FIXME: There is a Dalli bug, load(key) returns a wrong value after increment
44
+ # therefore we set default = nil and create the counter manually
45
+ result = if amount >= 0
46
+ @cache.incr(key, amount, options[:expires], nil)
47
+ else
48
+ @cache.decr(key, -amount, options[:expires], nil)
49
+ end
50
+ if result
51
+ result
52
+ else
53
+ store(key, amount, options)
54
+ amount
55
+ end
56
+ end
57
+
58
+ def clear(options = {})
59
+ @cache.flush_all
60
+ self
61
+ end
62
+
63
+ def close
64
+ @cache.close
65
+ nil
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,70 @@
1
+ require 'memcached'
2
+
3
+ module Moneta
4
+ module Adapters
5
+ # Memcached backend (using gem memcached)
6
+ # @api public
7
+ class MemcachedNative < Base
8
+ # Constructor
9
+ #
10
+ # @param [Hash] options
11
+ #
12
+ # Options:
13
+ # * :server - Memcached server (default localhost:11211)
14
+ # * :namespace - Key namespace
15
+ # * :expires - Default expiration time (default 604800)
16
+ # * Other options passed to Memcached#new
17
+ def initialize(options = {})
18
+ server = options.delete(:server) || 'localhost:11211'
19
+ @expires = options.delete(:expires) || 604800
20
+ options.merge!(:prefix_key => options.delete(:namespace)) if options[:namespace]
21
+ @cache = ::Memcached.new(server, options)
22
+ end
23
+
24
+ def load(key, options = {})
25
+ value = @cache.get(key, false)
26
+ if value && options.include?(:expires)
27
+ store(key, value, options)
28
+ else
29
+ value
30
+ end
31
+ rescue ::Memcached::NotFound
32
+ end
33
+
34
+ def store(key, value, options = {})
35
+ # TTL must be Fixnum
36
+ @cache.set(key, value, options[:expires] || @expires, false)
37
+ value
38
+ end
39
+
40
+ def delete(key, options = {})
41
+ value = @cache.get(key, false)
42
+ @cache.delete(key)
43
+ value
44
+ rescue ::Memcached::NotFound
45
+ end
46
+
47
+ def increment(key, amount = 1, options = {})
48
+ result = if amount >= 0
49
+ @cache.increment(key, amount)
50
+ else
51
+ @cache.decrement(key, -amount)
52
+ end
53
+ # HACK: Throw error if applied to invalid value
54
+ if result == 0
55
+ value = @cache.get(key, false) rescue nil
56
+ raise 'Tried to increment non integer value' unless value.to_s == value.to_i.to_s
57
+ end
58
+ result
59
+ rescue ::Memcached::NotFound => ex
60
+ store(key, amount.to_s, options)
61
+ amount
62
+ end
63
+
64
+ def clear(options = {})
65
+ @cache.flush
66
+ self
67
+ end
68
+ end
69
+ end
70
+ end