memodis 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +43 -1
- data/Rakefile +1 -16
- data/VERSION +1 -1
- data/examples/main.rb +1 -1
- data/lib/memodis/dist_cache.rb +17 -16
- data/lib/memodis.rb +3 -4
- metadata +2 -17
data/README.rdoc
CHANGED
@@ -1,6 +1,48 @@
|
|
1
1
|
= memodis
|
2
2
|
|
3
|
-
|
3
|
+
semi-transparent memoization; backed by redis;
|
4
|
+
|
5
|
+
writes are sent to the master, reads are sent to an approriate slave.
|
6
|
+
|
7
|
+
Two features:
|
8
|
+
1. Memodis#memoize
|
9
|
+
1. Memodis::DistCache
|
10
|
+
|
11
|
+
== Example
|
12
|
+
|
13
|
+
def fib(num)
|
14
|
+
return num if num < 2
|
15
|
+
fib(num - 1) + fib(num - 2)
|
16
|
+
end
|
17
|
+
|
18
|
+
puts "Before memoize: "
|
19
|
+
puts fib(33) => 3524578 # after ~ 7 seconds
|
20
|
+
|
21
|
+
extend Memodis
|
22
|
+
memoize :fib, Memodis::DistCache.new({
|
23
|
+
:key_gen => lambda { |k| "fib(#{k})" },
|
24
|
+
:decoder => :integer,
|
25
|
+
:expires => (10 * 60),
|
26
|
+
:master => '127.0.0.1:16379 127.0.0.1:16380'.split,
|
27
|
+
:slaves => '127.0.0.1:16389 127.0.0.1:16390
|
28
|
+
127.0.0.1:16391 127.0.0.1:16392
|
29
|
+
127.0.0.1:16393 127.0.0.1:16394'.split
|
30
|
+
})
|
31
|
+
|
32
|
+
puts "After memoize: "
|
33
|
+
puts fib(33) => 3524578 # after ~ 0.03 seconds
|
34
|
+
puts fib(33) => 3524578 # after ~ 0.0001 seconds
|
35
|
+
puts fib(33) => 3524578 # after ~ 0.0001 seconds
|
36
|
+
|
37
|
+
|
38
|
+
== Background
|
39
|
+
1. http://blog.grayproductions.net/articles/caching_and_memoization
|
40
|
+
1. http://code.google.com/p/redis & http://github.com/ezmobius/redis-rb
|
41
|
+
|
42
|
+
== Important Moving Parts
|
43
|
+
1. http://code.google.com/p/redis/wiki/GetCommand
|
44
|
+
1. http://code.google.com/p/redis/wiki/SetCommand
|
45
|
+
1. http://code.google.com/p/redis/wiki/SetnxCommand
|
4
46
|
|
5
47
|
== Note on Patches/Pull Requests
|
6
48
|
|
data/Rakefile
CHANGED
@@ -6,21 +6,7 @@ begin
|
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
7
|
gem.name = "memodis"
|
8
8
|
gem.summary = %Q{redis backed memoization helpers}
|
9
|
-
gem.description = %Q{
|
10
|
-
semi-transparent memoization; backed by redis; redis-rb and redis-namespace
|
11
|
-
|
12
|
-
Background
|
13
|
-
-----------
|
14
|
-
1) http://blog.grayproductions.net/articles/caching_and_memoization
|
15
|
-
2) http://code.google.com/p/redis & http://github.com/ezmobius/redis-rb
|
16
|
-
|
17
|
-
Important Moving Parts
|
18
|
-
----------------------
|
19
|
-
1) http://code.google.com/p/redis/wiki/GetCommand
|
20
|
-
2) http://code.google.com/p/redis/wiki/SetCommand
|
21
|
-
3) http://code.google.com/p/redis/wiki/SetnxCommand
|
22
|
-
4) http://github.com/defunkt/redis-namespace
|
23
|
-
}
|
9
|
+
gem.description = %Q{ semi-transparent memoization; backed by redis; }
|
24
10
|
gem.email = "levicook@gmail.com"
|
25
11
|
gem.homepage = "http://github.com/levicook/memodis"
|
26
12
|
gem.authors = ["levicook@gmail.com"]
|
@@ -86,7 +72,6 @@ task :default => :test
|
|
86
72
|
require 'rake/rdoctask'
|
87
73
|
Rake::RDocTask.new do |rdoc|
|
88
74
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
89
|
-
|
90
75
|
rdoc.rdoc_dir = 'rdoc'
|
91
76
|
rdoc.title = "memodis #{version}"
|
92
77
|
rdoc.rdoc_files.include('README*')
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/examples/main.rb
CHANGED
@@ -25,7 +25,7 @@ memoize :fib, Memodis::DistCache.new({
|
|
25
25
|
127.0.0.1:16393 127.0.0.1:16394'.split
|
26
26
|
})
|
27
27
|
|
28
|
-
puts "
|
28
|
+
puts "After memoize: "
|
29
29
|
puts Hitimes::Interval.measure { print fib(33); print ': ' }
|
30
30
|
puts Hitimes::Interval.measure { print fib(33); print ': ' }
|
31
31
|
puts Hitimes::Interval.measure { print fib(33); print ': ' }
|
data/lib/memodis/dist_cache.rb
CHANGED
@@ -9,13 +9,11 @@ module Memodis
|
|
9
9
|
CODERS.freeze
|
10
10
|
|
11
11
|
def initialize(options)
|
12
|
-
|
13
12
|
@master = DistRedis.new({
|
14
13
|
:db => options[:db],
|
15
14
|
:hosts => options[:master],
|
16
15
|
:timeout => options[:timeout],
|
17
16
|
})
|
18
|
-
|
19
17
|
@slaves = options[:slaves].map do |h|
|
20
18
|
host, port = h.split(':')
|
21
19
|
Redis.new({
|
@@ -25,30 +23,20 @@ module Memodis
|
|
25
23
|
:timeout => options[:timeout],
|
26
24
|
})
|
27
25
|
end
|
28
|
-
|
29
|
-
@
|
30
|
-
when Proc; options[:encoder]
|
31
|
-
else; CODERS[options[:encoder]]
|
32
|
-
end
|
33
|
-
|
34
|
-
@decoder = case options[:decoder]
|
35
|
-
when Proc; options[:decoder]
|
36
|
-
else; CODERS[options[:decoder]]
|
37
|
-
end
|
38
|
-
|
26
|
+
@encoder = resolve_coder(options[:encoder])
|
27
|
+
@decoder = resolve_coder(options[:decoder])
|
39
28
|
@key_gen = options.fetch(:key_gen, lambda { |k| k })
|
40
|
-
|
41
29
|
@expires = options[:expires]
|
42
30
|
end
|
43
31
|
|
44
32
|
def []= key, val
|
45
|
-
key =
|
33
|
+
key = canonicalize(key)
|
46
34
|
@master.set(key, encode(val))
|
47
35
|
@master.expire(key, @expires) unless @expires.nil?
|
48
36
|
end
|
49
37
|
|
50
38
|
def [] key
|
51
|
-
key =
|
39
|
+
key = canonicalize(key)
|
52
40
|
if val = get(key)
|
53
41
|
decode(val)
|
54
42
|
else
|
@@ -58,6 +46,10 @@ module Memodis
|
|
58
46
|
|
59
47
|
private
|
60
48
|
|
49
|
+
def canonicalize(key)
|
50
|
+
@key_gen.call(key)
|
51
|
+
end
|
52
|
+
|
61
53
|
def indexed_slaves
|
62
54
|
@indexed_slaves ||= @slaves.inject(Hash.new) do |index, slave|
|
63
55
|
slave_info = slave.info
|
@@ -83,6 +75,15 @@ module Memodis
|
|
83
75
|
@encoder.call(val)
|
84
76
|
end
|
85
77
|
|
78
|
+
def resolve_coder(coder_spec)
|
79
|
+
case coder_spec
|
80
|
+
when Proc
|
81
|
+
coder_spec
|
82
|
+
else
|
83
|
+
CODERS[coder_spec]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
86
87
|
end
|
87
88
|
|
88
89
|
end
|
data/lib/memodis.rb
CHANGED
@@ -8,10 +8,9 @@ module Memodis
|
|
8
8
|
# slurp cool vendor goodies into our namespace. would declare them
|
9
9
|
# as gem dependencies, but they don't seem to be published...
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
class_eval((
|
14
|
-
class_eval((VENDOR_PATH+'weak_cache.rb').read) unless defined? Memodis::WeakCache
|
11
|
+
vendor_path = Pathname.new(__FILE__).parent.parent + 'vendor'
|
12
|
+
class_eval((vendor_path+'memoizable.rb').read) unless defined? Memodis::Memoizable
|
13
|
+
class_eval((vendor_path+'weak_cache.rb').read) unless defined? Memodis::WeakCache
|
15
14
|
|
16
15
|
include Memodis::Memoizable
|
17
16
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memodis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- levicook@gmail.com
|
@@ -42,22 +42,7 @@ dependencies:
|
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: "0"
|
44
44
|
version:
|
45
|
-
description:
|
46
|
-
|
47
|
-
semi-transparent memoization; backed by redis; redis-rb and redis-namespace
|
48
|
-
|
49
|
-
Background
|
50
|
-
-----------
|
51
|
-
1) http://blog.grayproductions.net/articles/caching_and_memoization
|
52
|
-
2) http://code.google.com/p/redis & http://github.com/ezmobius/redis-rb
|
53
|
-
|
54
|
-
Important Moving Parts
|
55
|
-
----------------------
|
56
|
-
1) http://code.google.com/p/redis/wiki/GetCommand
|
57
|
-
2) http://code.google.com/p/redis/wiki/SetCommand
|
58
|
-
3) http://code.google.com/p/redis/wiki/SetnxCommand
|
59
|
-
4) http://github.com/defunkt/redis-namespace
|
60
|
-
|
45
|
+
description: " semi-transparent memoization; backed by redis; "
|
61
46
|
email: levicook@gmail.com
|
62
47
|
executables: []
|
63
48
|
|