simple_cache_rs 0.9.3 → 0.10.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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.3
1
+ 0.10.0
@@ -5,8 +5,11 @@ module SimpleCache::Marshal
5
5
  extend self
6
6
 
7
7
  def uid(key)
8
- md5 = Digest::MD5.hexdigest(key)
9
- md5.unpack("LL").inject { |a,b| (a << 31) + b }
8
+ md5(key).unpack("LL").inject { |a,b| (a << 31) + b }
9
+ end
10
+
11
+ def md5(key)
12
+ Digest::MD5.hexdigest(key)
10
13
  end
11
14
 
12
15
  def unmarshal(marshalled)
data/lib/simple_cache.rb CHANGED
@@ -19,7 +19,7 @@ module SimpleCache
19
19
  else raise uri.scheme.inspect
20
20
  end
21
21
 
22
- cache.extend SimpleCache
22
+ cache.extend SimpleCache::Interface
23
23
  end
24
24
 
25
25
  singleton_class.class_eval do
@@ -33,15 +33,103 @@ module SimpleCache
33
33
  Thread.current["simple_cache_store"] ||= new(url)
34
34
  end
35
35
 
36
- extend Forwardable
37
- delegate [:fetch, :store, :clear, :cached] => :cache_store
36
+ def fetch(key, &block)
37
+ key = SimpleCache.cache_key(key)
38
+ cache_store.fetch(key, &block)
39
+ end
40
+
41
+ def store(key, value)
42
+ key = SimpleCache.cache_key(key)
43
+ cache_store.store key, value
44
+ end
45
+
46
+ def clear(key)
47
+ key = SimpleCache.cache_key(key)
48
+ cache_store.clear key
49
+ end
50
+
51
+ def cached(key, ttl = nil, &block)
52
+ key = SimpleCache.cache_key(key)
53
+ cache_store.cached key, ttl, &block
54
+ end
38
55
  end
39
56
 
40
- def cached(key, ttl = nil, &block)
41
- fetch(key) do
42
- value = yield
43
- store(key, value, ttl) unless ttl == 0 || ttl == false
44
- value
57
+ module Interface
58
+ @@requests = @@misses = 0
59
+
60
+ def cached(key, ttl = nil, &block)
61
+ @@requests += 1
62
+
63
+ fetch(key) do
64
+ @@misses += 1
65
+
66
+ value = yield
67
+ store(key, value, ttl) unless ttl == 0 || ttl == false
68
+ value
69
+ end
70
+ end
71
+
72
+ def self.stats
73
+ return {} if @@requests == 0
74
+
75
+ {
76
+ :hits => @@requests - @@misses,
77
+ :misses => @@misses
78
+ }
45
79
  end
46
80
  end
81
+
82
+ def self.cache_key(obj)
83
+ return SimpleCache::Marshal.md5(obj.cache_key) if obj.respond_to?(:cache_key)
84
+
85
+ case obj
86
+ when String
87
+ SimpleCache::Marshal.md5 obj
88
+ when Hash
89
+ parts = []
90
+ obj.each { |k,v| parts << cache_key(k) << cache_key(v) }
91
+ SimpleCache::Marshal.md5 parts.join("/")
92
+ when Array
93
+ parts = obj.map { |part| cache_key(part) }
94
+ SimpleCache::Marshal.md5 parts.join(":")
95
+ else
96
+ SimpleCache::Marshal.md5 self.inspect
97
+ end
98
+ end
99
+
100
+ # The SimplyCached module contains a method to easily implement
101
+ # memoized-like caching on top of SimpleCache
102
+ module SimplyCached
103
+ def simply_cached(method, options = {})
104
+ ttl = options[:ttl]
105
+
106
+ uncached_method = "#{method}__uncached".to_sym
107
+
108
+ alias_method uncached_method, method
109
+
110
+ define_method(method) do |*args|
111
+ cache_key = args.empty? ? self : [ self ] + args
112
+ current_ttl = if ttl.respond_to?(:call)
113
+ ttl.send(:call, *args)
114
+ else
115
+ ttl
116
+ end
117
+
118
+ SimpleCache.cached(cache_key, current_ttl) do
119
+ self.send uncached_method, *args
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ class Module
127
+ include SimpleCache::SimplyCached
128
+ end
129
+
130
+ at_exit do
131
+ stats = SimpleCache::Interface.stats
132
+ next if stats.empty?
133
+
134
+ STDERR.puts "SimpleCache stats: #{stats[:hits]} hits, #{stats[:misses]} misses"
47
135
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "simple_cache_rs"
8
- s.version = "0.9.3"
8
+ s.version = "0.10.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["radiospiel"]
12
- s.date = "2012-05-03"
12
+ s.date = "2012-05-23"
13
13
  s.description = "A sensibly fast, yet simplistic file based cache."
14
14
  s.email = "eno@open-lab.org"
15
15
  s.extra_rdoc_files = [
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "lib/simple_cache/sqlite_store.rb",
31
31
  "simple_cache.gemspec",
32
32
  "simple_cache_rs.gemspec",
33
+ "test/memoize_test.rb",
33
34
  "test/redis_store_test.rb",
34
35
  "test/simple_cache_test.rb",
35
36
  "test/sqlite_store_test.rb",
@@ -0,0 +1,42 @@
1
+ require_relative 'test_helper'
2
+
3
+ class SimpleCache::MemoizeTest < Test::Unit::TestCase
4
+ class X
5
+ attr :cache_key
6
+
7
+ def initialize(value)
8
+ @value = value
9
+ @cache_key = { :value => @value[0,2] }.inspect
10
+ end
11
+
12
+ def do_something
13
+ @value.length
14
+ end
15
+
16
+ simply_cached :do_something
17
+ end
18
+
19
+ def setup
20
+ SimpleCache.url = "#{File.dirname(__FILE__)}/memoize_test"
21
+ end
22
+
23
+ def test_simply_cached
24
+ foo = X.new "11"
25
+ assert_equal(2, foo.do_something)
26
+ assert_equal(2, foo.do_something)
27
+
28
+ # The following constructs an object with the same cache_key. If the
29
+ # do_something method is properly cached, it must return the identical
30
+ # value; if it was not cached then do_something would return a different
31
+ # value (i.e. 4)
32
+ bar = X.new "1111"
33
+ assert_equal(2, bar.do_something)
34
+ assert_equal(2, bar.do_something)
35
+
36
+ # The following constructs an object with a different cache_key.
37
+ # The do_something method must return a different value.
38
+ baz = X.new "222"
39
+ assert_equal(3, baz.do_something)
40
+ assert_equal(3, baz.do_something)
41
+ end
42
+ end
@@ -4,7 +4,7 @@ class SimpleCache::SqliteStoreTest < Test::Unit::TestCase
4
4
  include SimpleCache::TestCase
5
5
 
6
6
  def simple_cache
7
- @simple_cache ||= SimpleCache.new("simple_cache_test").tap(&:clear)
7
+ @simple_cache ||= SimpleCache.new("#{ROOT}/test/simple_cache_test").tap(&:clear)
8
8
  end
9
9
 
10
10
  def teardown
data/test/test_helper.rb CHANGED
@@ -16,15 +16,13 @@ SimpleCov.start do
16
16
  add_filter "test/*.rb"
17
17
  end
18
18
 
19
+ ROOT = File.join(File.dirname(__FILE__), '..')
20
+
19
21
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
20
22
  $LOAD_PATH.unshift(File.dirname(__FILE__))
21
23
  require 'simple_cache'
22
24
 
23
25
  module SimpleCache::TestCase
24
- def test_simple_cache_kindof
25
- assert simple_cache.kind_of?(SimpleCache)
26
- end
27
-
28
26
  def test_simple_cache
29
27
  assert_equal(nil, simple_cache.fetch("bar"))
30
28
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_cache_rs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-03 00:00:00.000000000 Z
12
+ date: 2012-05-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sqlite3
16
- requirement: &70161923648460 !ruby/object:Gem::Requirement
16
+ requirement: &70171064055940 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70161923648460
24
+ version_requirements: *70171064055940
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bundler
27
- requirement: &70161923647820 !ruby/object:Gem::Requirement
27
+ requirement: &70171064054980 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70161923647820
35
+ version_requirements: *70171064054980
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: jeweler
38
- requirement: &70161923640800 !ruby/object:Gem::Requirement
38
+ requirement: &70171064052800 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70161923640800
46
+ version_requirements: *70171064052800
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: simplecov
49
- requirement: &70161923639800 !ruby/object:Gem::Requirement
49
+ requirement: &70171064051480 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70161923639800
57
+ version_requirements: *70171064051480
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: ruby-debug19
60
- requirement: &70161923638540 !ruby/object:Gem::Requirement
60
+ requirement: &70171064050440 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70161923638540
68
+ version_requirements: *70171064050440
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: timecop
71
- requirement: &70161923634620 !ruby/object:Gem::Requirement
71
+ requirement: &70171064035160 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70161923634620
79
+ version_requirements: *70171064035160
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: redis
82
- requirement: &70161923633860 !ruby/object:Gem::Requirement
82
+ requirement: &70171064032640 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70161923633860
90
+ version_requirements: *70171064032640
91
91
  description: A sensibly fast, yet simplistic file based cache.
92
92
  email: eno@open-lab.org
93
93
  executables: []
@@ -109,6 +109,7 @@ files:
109
109
  - lib/simple_cache/sqlite_store.rb
110
110
  - simple_cache.gemspec
111
111
  - simple_cache_rs.gemspec
112
+ - test/memoize_test.rb
112
113
  - test/redis_store_test.rb
113
114
  - test/simple_cache_test.rb
114
115
  - test/sqlite_store_test.rb
@@ -128,7 +129,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
128
129
  version: '0'
129
130
  segments:
130
131
  - 0
131
- hash: -4386423963111190464
132
+ hash: -1481443802176194731
132
133
  required_rubygems_version: !ruby/object:Gem::Requirement
133
134
  none: false
134
135
  requirements: