lru_redux 0.8.4 → 1.1.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.
- checksums.yaml +4 -4
- data/README.md +190 -29
- data/Rakefile +1 -1
- data/bench/bench.rb +27 -29
- data/bench/bench_ttl.rb +33 -0
- data/lib/lru_redux.rb +9 -14
- data/lib/lru_redux/cache.rb +54 -109
- data/lib/lru_redux/{cache19.rb → cache_legacy.rb} +0 -53
- data/lib/lru_redux/thread_safe_cache.rb +1 -73
- data/lib/lru_redux/ttl.rb +4 -0
- data/lib/lru_redux/ttl/cache.rb +192 -0
- data/lib/lru_redux/ttl/thread_safe_cache.rb +3 -0
- data/lib/lru_redux/util.rb +4 -0
- data/lib/lru_redux/util/safe_sync.rb +103 -0
- data/lib/lru_redux/util/safe_sync_jruby.rb +17 -0
- data/lib/lru_redux/version.rb +1 -1
- data/lru_redux.gemspec +6 -3
- data/test/cache_test.rb +10 -2
- data/test/thread_safe_cache_test.rb +1 -3
- data/test/ttl/cache_test.rb +91 -0
- data/test/ttl/thread_safe_cache_test.rb +16 -0
- metadata +33 -7
- data/lib/lru_redux/thread_safe_cache_jruby.rb +0 -13
@@ -2,11 +2,6 @@
|
|
2
2
|
#
|
3
3
|
# This is an ultra efficient 1.9 freindly implementation
|
4
4
|
class LruRedux::Cache
|
5
|
-
def initialize(max_size)
|
6
|
-
@max_size = max_size
|
7
|
-
@data = {}
|
8
|
-
end
|
9
|
-
|
10
5
|
def max_size=(size)
|
11
6
|
raise ArgumentError.new(:max_size) if @max_size < 1
|
12
7
|
@max_size = size
|
@@ -30,26 +25,6 @@ class LruRedux::Cache
|
|
30
25
|
end
|
31
26
|
end
|
32
27
|
|
33
|
-
def fetch(key)
|
34
|
-
found = true
|
35
|
-
value = @data.delete(key){ found = false }
|
36
|
-
if found
|
37
|
-
@data[key] = value
|
38
|
-
else
|
39
|
-
yield if block_given?
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def [](key)
|
44
|
-
found = true
|
45
|
-
value = @data.delete(key){ found = false }
|
46
|
-
if found
|
47
|
-
@data[key] = value
|
48
|
-
else
|
49
|
-
nil
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
28
|
def []=(key,val)
|
54
29
|
@data.delete(key)
|
55
30
|
@data[key] = val
|
@@ -58,34 +33,6 @@ class LruRedux::Cache
|
|
58
33
|
val
|
59
34
|
end
|
60
35
|
|
61
|
-
def each
|
62
|
-
array = @data.to_a
|
63
|
-
array.reverse!.each do |pair|
|
64
|
-
yield pair
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# used further up the chain, non thread safe each
|
69
|
-
alias_method :each_unsafe, :each
|
70
|
-
|
71
|
-
def to_a
|
72
|
-
array = @data.to_a
|
73
|
-
array.reverse!
|
74
|
-
end
|
75
|
-
|
76
|
-
def delete(k)
|
77
|
-
@data.delete(k)
|
78
|
-
end
|
79
|
-
|
80
|
-
def clear
|
81
|
-
@data.clear
|
82
|
-
end
|
83
|
-
|
84
|
-
def count
|
85
|
-
@data.size
|
86
|
-
end
|
87
|
-
|
88
|
-
|
89
36
|
# for cache validation only, ensures all is sound
|
90
37
|
def valid?
|
91
38
|
true
|
@@ -1,75 +1,3 @@
|
|
1
|
-
require 'monitor'
|
2
|
-
|
3
1
|
class LruRedux::ThreadSafeCache < LruRedux::Cache
|
4
|
-
include
|
5
|
-
|
6
|
-
def initialize(max_size)
|
7
|
-
super(max_size)
|
8
|
-
end
|
9
|
-
|
10
|
-
def max_size=(size)
|
11
|
-
synchronize do
|
12
|
-
super(size)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def getset(key)
|
17
|
-
synchronize do
|
18
|
-
super(key)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def fetch(key)
|
23
|
-
synchronize do
|
24
|
-
super(key)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def [](key)
|
29
|
-
synchronize do
|
30
|
-
super(key)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def []=(key, value)
|
35
|
-
synchronize do
|
36
|
-
super(key, value)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def each
|
41
|
-
synchronize do
|
42
|
-
super
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def to_a
|
47
|
-
synchronize do
|
48
|
-
super
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def delete(key)
|
53
|
-
synchronize do
|
54
|
-
super(key)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def clear
|
59
|
-
synchronize do
|
60
|
-
super
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def count
|
65
|
-
synchronize do
|
66
|
-
super
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def valid?
|
71
|
-
synchronize do
|
72
|
-
super
|
73
|
-
end
|
74
|
-
end
|
2
|
+
include LruRedux::Util::SafeSync
|
75
3
|
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
module LruRedux
|
2
|
+
module TTL
|
3
|
+
class Cache
|
4
|
+
attr_reader :max_size, :ttl
|
5
|
+
|
6
|
+
def initialize(*args)
|
7
|
+
max_size, ttl = args
|
8
|
+
|
9
|
+
ttl ||= :none
|
10
|
+
|
11
|
+
raise ArgumentError.new(:max_size) if
|
12
|
+
max_size < 1
|
13
|
+
raise ArgumentError.new(:ttl) unless
|
14
|
+
ttl == :none || ((ttl.is_a? Numeric) && ttl >= 0)
|
15
|
+
|
16
|
+
@max_size = max_size
|
17
|
+
@ttl = ttl
|
18
|
+
@data_lru = {}
|
19
|
+
@data_ttl = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def max_size=(max_size)
|
23
|
+
max_size ||= @max_size
|
24
|
+
|
25
|
+
raise ArgumentError.new(:max_size) if
|
26
|
+
max_size < 1
|
27
|
+
|
28
|
+
@max_size = max_size
|
29
|
+
|
30
|
+
resize
|
31
|
+
end
|
32
|
+
|
33
|
+
def ttl=(ttl)
|
34
|
+
ttl ||= @ttl
|
35
|
+
|
36
|
+
raise ArgumentError.new(:ttl) unless
|
37
|
+
ttl == :none || ((ttl.is_a? Numeric) && ttl >= 0)
|
38
|
+
|
39
|
+
@ttl = ttl
|
40
|
+
|
41
|
+
ttl_evict
|
42
|
+
end
|
43
|
+
|
44
|
+
def getset(key)
|
45
|
+
ttl_evict
|
46
|
+
|
47
|
+
found = true
|
48
|
+
value = @data_lru.delete(key){ found = false }
|
49
|
+
if found
|
50
|
+
@data_lru[key] = value
|
51
|
+
else
|
52
|
+
result = @data_lru[key] = yield
|
53
|
+
@data_ttl[key] = Time.now.to_f
|
54
|
+
|
55
|
+
if @data_lru.size > @max_size
|
56
|
+
key, _ = @data_lru.first
|
57
|
+
|
58
|
+
@data_ttl.delete(key)
|
59
|
+
@data_lru.delete(key)
|
60
|
+
end
|
61
|
+
|
62
|
+
result
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def fetch(key)
|
67
|
+
ttl_evict
|
68
|
+
|
69
|
+
found = true
|
70
|
+
value = @data_lru.delete(key){ found = false }
|
71
|
+
if found
|
72
|
+
@data_lru[key] = value
|
73
|
+
else
|
74
|
+
yield if block_given?
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def [](key)
|
79
|
+
ttl_evict
|
80
|
+
|
81
|
+
found = true
|
82
|
+
value = @data_lru.delete(key){ found = false }
|
83
|
+
if found
|
84
|
+
@data_lru[key] = value
|
85
|
+
else
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def []=(key, val)
|
91
|
+
ttl_evict
|
92
|
+
|
93
|
+
@data_lru.delete(key)
|
94
|
+
@data_ttl.delete(key)
|
95
|
+
|
96
|
+
@data_lru[key] = val
|
97
|
+
@data_ttl[key] = Time.now.to_f
|
98
|
+
|
99
|
+
if @data_lru.size > @max_size
|
100
|
+
key, _ = @data_lru.first
|
101
|
+
|
102
|
+
@data_ttl.delete(key)
|
103
|
+
@data_lru.delete(key)
|
104
|
+
end
|
105
|
+
|
106
|
+
val
|
107
|
+
end
|
108
|
+
|
109
|
+
def each
|
110
|
+
ttl_evict
|
111
|
+
|
112
|
+
array = @data_lru.to_a
|
113
|
+
array.reverse!.each do |pair|
|
114
|
+
yield pair
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# used further up the chain, non thread safe each
|
119
|
+
alias_method :each_unsafe, :each
|
120
|
+
|
121
|
+
def to_a
|
122
|
+
ttl_evict
|
123
|
+
|
124
|
+
array = @data_lru.to_a
|
125
|
+
array.reverse!
|
126
|
+
end
|
127
|
+
|
128
|
+
def delete(key)
|
129
|
+
ttl_evict
|
130
|
+
|
131
|
+
@data_lru.delete(key)
|
132
|
+
@data_ttl.delete(key)
|
133
|
+
end
|
134
|
+
|
135
|
+
alias_method :evict, :delete
|
136
|
+
|
137
|
+
def key?(key)
|
138
|
+
ttl_evict
|
139
|
+
|
140
|
+
@data_lru.key?(key)
|
141
|
+
end
|
142
|
+
|
143
|
+
alias_method :has_key?, :key?
|
144
|
+
|
145
|
+
def clear
|
146
|
+
@data_lru.clear
|
147
|
+
@data_ttl.clear
|
148
|
+
end
|
149
|
+
|
150
|
+
def expire
|
151
|
+
ttl_evict
|
152
|
+
end
|
153
|
+
|
154
|
+
def count
|
155
|
+
@data_lru.size
|
156
|
+
end
|
157
|
+
|
158
|
+
protected
|
159
|
+
|
160
|
+
# for cache validation only, ensures all is sound
|
161
|
+
def valid?
|
162
|
+
@data_lru.size == @data_ttl.size
|
163
|
+
end
|
164
|
+
|
165
|
+
def ttl_evict
|
166
|
+
return if @ttl == :none
|
167
|
+
|
168
|
+
ttl_horizon = Time.now.to_f - @ttl
|
169
|
+
key, time = @data_ttl.first
|
170
|
+
|
171
|
+
until time.nil? || time > ttl_horizon
|
172
|
+
@data_ttl.delete(key)
|
173
|
+
@data_lru.delete(key)
|
174
|
+
|
175
|
+
key, time = @data_ttl.first
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def resize
|
180
|
+
ttl_evict
|
181
|
+
|
182
|
+
while @data_lru.size > @max_size
|
183
|
+
key, _ = @data_lru.first
|
184
|
+
|
185
|
+
@data_ttl.delete(key)
|
186
|
+
@data_lru.delete(key)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'monitor'
|
2
|
+
|
3
|
+
module LruRedux
|
4
|
+
module Util
|
5
|
+
module SafeSync
|
6
|
+
include MonitorMixin
|
7
|
+
|
8
|
+
def initialize(*args)
|
9
|
+
super(*args)
|
10
|
+
end
|
11
|
+
|
12
|
+
def max_size=(max_size)
|
13
|
+
synchronize do
|
14
|
+
super(max_size)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def ttl=(ttl)
|
19
|
+
synchronize do
|
20
|
+
super(ttl)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def getset(key)
|
25
|
+
synchronize do
|
26
|
+
super(key)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def fetch(key)
|
31
|
+
synchronize do
|
32
|
+
super(key)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def [](key)
|
37
|
+
synchronize do
|
38
|
+
super(key)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def []=(key, value)
|
43
|
+
synchronize do
|
44
|
+
super(key, value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def each
|
49
|
+
synchronize do
|
50
|
+
super
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_a
|
55
|
+
synchronize do
|
56
|
+
super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def delete(key)
|
61
|
+
synchronize do
|
62
|
+
super(key)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def evict(key)
|
67
|
+
synchronize do
|
68
|
+
super(key)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def key?(key)
|
73
|
+
synchronize do
|
74
|
+
super(key)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def has_key?(key)
|
79
|
+
synchronize do
|
80
|
+
super(key)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def clear
|
85
|
+
synchronize do
|
86
|
+
super
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def count
|
91
|
+
synchronize do
|
92
|
+
super
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def valid?
|
97
|
+
synchronize do
|
98
|
+
super
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|