lrucache 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,4 +2,5 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
- coverage/*
5
+ coverage/*
6
+ tmp/*
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm use ruby-1.9.2@lrucache --create
1
+ rvm use ruby-1.9.3@lrucache --create
data/README.md CHANGED
@@ -34,7 +34,7 @@ TTL (time-to-live)
34
34
  # Three hours later ...
35
35
  cache.fetch("banana") # nil
36
36
  cache.fetch("monkey") # "banana"
37
-
37
+
38
38
  # Three days later ...
39
39
  cache.fetch("banana") # nil
40
40
  cache.fetch("monkey") # nil
@@ -64,6 +64,19 @@ expires and the block is called for a new value, but exceptions are not handled.
64
64
  cache.fetch("banana") { "george" } # "george"
65
65
  cache.fetch("banana") { "barney" } # "george"
66
66
 
67
+ Eviction Handler
68
+ ================
69
+ Allows you to specify a block that gets called whenever a value gets evicted
70
+ from the cache because it is the least recently used.
71
+
72
+ cache = LRUCache.new(:max_size => 2,
73
+ :eviction_handler => lambda { |value| value.shave! })
74
+ cache.store(:yak) { yak }
75
+ cache.store(:dog) { dog }
76
+ cache.store(:cat) { cat } # --> shaves the yak as you would expect!
77
+ cache.delete(:cat) # --> does not shave the cat
78
+ cache.clear # --> no shaving involved
79
+
67
80
  ## Contributing
68
81
 
69
82
  1. Fork it
@@ -9,6 +9,7 @@ class LRUCache
9
9
  def initialize(opts={})
10
10
  @max_size = Integer(opts[:max_size] || 100)
11
11
  @default = opts[:default]
12
+ @eviction_handler = opts[:eviction_handler]
12
13
  @ttl = Float(opts[:ttl] || 0)
13
14
  @soft_ttl = Float(opts[:soft_ttl] || 0)
14
15
  @retry_delay = Float(opts[:retry_delay] || 0)
@@ -103,7 +104,8 @@ class LRUCache
103
104
 
104
105
  def delete(key)
105
106
  @pqueue.delete(key)
106
- @data.delete(key)
107
+ datum = @data.delete(key)
108
+ datum.value unless datum.nil?
107
109
  end
108
110
 
109
111
  private
@@ -150,7 +152,10 @@ class LRUCache
150
152
 
151
153
  def evict_lru!
152
154
  key, priority = @pqueue.delete_min
153
- @data.delete(key) unless priority.nil?
155
+ unless priority.nil?
156
+ datum = @data.delete(key)
157
+ @eviction_handler.call(datum.value) if @eviction_handler && datum
158
+ end
154
159
  end
155
160
 
156
161
  def access(key)
@@ -1,3 +1,3 @@
1
1
  class LRUCache
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -19,12 +19,12 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
21
  s.add_dependency "PriorityQueue", '~> 0.1.2'
22
-
23
- s.add_development_dependency "rspec", "~> 2.6.0"
24
- s.add_development_dependency "simplecov", "~> 0.4.2"
25
- s.add_development_dependency("rb-fsevent", "~> 0.4.3") if RUBY_PLATFORM =~ /darwin/i
26
- s.add_development_dependency "guard", "~> 0.6.2"
27
- s.add_development_dependency "guard-bundler", "~> 0.1.3"
28
- s.add_development_dependency "guard-rspec", "~> 0.4.2"
29
- s.add_development_dependency "timecop", "~> 0.3.5"
22
+
23
+ s.add_development_dependency "rspec", "~> 2.12.0"
24
+ s.add_development_dependency "simplecov", "~> 0.7.1"
25
+ s.add_development_dependency("rb-fsevent", "~> 0.9.2") if RUBY_PLATFORM =~ /darwin/i
26
+ s.add_development_dependency "guard", "~> 1.5.4"
27
+ s.add_development_dependency "guard-bundler", "~> 1.0.0"
28
+ s.add_development_dependency "guard-rspec", "~> 2.2.1"
29
+ s.add_development_dependency "timecop", "~> 0.5.3"
30
30
  end
@@ -54,6 +54,12 @@ describe LRUCache do
54
54
  c.instance_variable_get(:@data).should be_empty
55
55
  c.instance_variable_get(:@pqueue).should be_empty
56
56
  end
57
+
58
+ it "should not call the eviction handler" do
59
+ c = LRUCache.new(:eviction_handler => lambda { raise 'test failed' })
60
+ c[:a] = 'a'
61
+ expect { c.clear }.to_not raise_exception
62
+ end
57
63
  end
58
64
 
59
65
  describe ".include?(key)" do
@@ -156,9 +162,11 @@ describe LRUCache do
156
162
  end
157
163
  context "when the cache is full" do
158
164
  before(:each) do
159
- @cache = LRUCache.new(:max_size => 2)
160
- @cache[:b] = 'b'
161
- @cache[:c] = 'c'
165
+ @cache = LRUCache.new(
166
+ :max_size => 2,
167
+ :eviction_handler => lambda {|value| value << ' evicted' })
168
+ @cache[:b] = @b = 'b'
169
+ @cache[:c] = @c = 'c'
162
170
  @lru = :b
163
171
  end
164
172
  context "and the key is not present" do
@@ -175,6 +183,10 @@ describe LRUCache do
175
183
  @cache.should_receive(:access).with(:a)
176
184
  @cache.store(:a, 'a')
177
185
  end
186
+ it "should call the eviction handler" do
187
+ @cache.store(:a, 'a')
188
+ @b.should == 'b evicted'
189
+ end
178
190
  end
179
191
  context "and the key is present" do
180
192
  it "should not evict an entry" do
@@ -208,7 +220,7 @@ describe LRUCache do
208
220
  Timecop.freeze(now) { c.store(:a,'a') }
209
221
  stored = c.instance_variable_get(:@data)[:a]
210
222
  stored.value.should == 'a'
211
- stored.expiration.should == now + 1
223
+ stored.expiration.to_f.should == (now + 1).to_f
212
224
  end
213
225
  end
214
226
  context "when ttl is a Time" do
@@ -228,7 +240,7 @@ describe LRUCache do
228
240
  Timecop.freeze(now) { c.store(:a, 'a', "98.6") }
229
241
  stored = c.instance_variable_get(:@data)[:a]
230
242
  stored.value.should == 'a'
231
- stored.expiration.should == now + 98.6
243
+ stored.expiration.to_f.should == (now + 98.6).to_f
232
244
  end
233
245
  end
234
246
  context "when ttl cannot be parsed as a float" do
@@ -464,6 +476,20 @@ describe LRUCache do
464
476
  c.instance_variable_get(:@data).should_not include(:a)
465
477
  c.instance_variable_get(:@pqueue).should_not include([:a,1])
466
478
  end
479
+
480
+ it "should return the value associated with the key" do
481
+ c = LRUCache.new
482
+ c[:a] = 'a'
483
+ c.delete(:a).should == 'a'
484
+ c.delete(:a).should be_nil
485
+ c.delete(:b).should be_nil
486
+ end
487
+
488
+ it "should not call the eviction handler" do
489
+ c = LRUCache.new(:eviction_handler => lambda { raise 'test failed' })
490
+ c[:a] = 'a'
491
+ expect { c.delete(:a) }.to_not raise_exception
492
+ end
467
493
  end
468
494
 
469
495
  describe ".evict_lru!" do
@@ -509,4 +535,4 @@ describe LRUCache do
509
535
  end
510
536
  end
511
537
  end
512
- end
538
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lrucache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
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-11 00:00:00.000000000Z
12
+ date: 2012-11-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: PriorityQueue
16
- requirement: &70313120984040 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,84 +21,124 @@ dependencies:
21
21
  version: 0.1.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70313120984040
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.1.2
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: rspec
27
- requirement: &70313120983540 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ~>
31
36
  - !ruby/object:Gem::Version
32
- version: 2.6.0
37
+ version: 2.12.0
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *70313120983540
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.12.0
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: simplecov
38
- requirement: &70313120983080 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ~>
42
52
  - !ruby/object:Gem::Version
43
- version: 0.4.2
53
+ version: 0.7.1
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *70313120983080
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.7.1
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: rb-fsevent
49
- requirement: &70313120982580 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ~>
53
68
  - !ruby/object:Gem::Version
54
- version: 0.4.3
69
+ version: 0.9.2
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *70313120982580
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.9.2
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: guard
60
- requirement: &70313120982120 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ~>
64
84
  - !ruby/object:Gem::Version
65
- version: 0.6.2
85
+ version: 1.5.4
66
86
  type: :development
67
87
  prerelease: false
68
- version_requirements: *70313120982120
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 1.5.4
69
94
  - !ruby/object:Gem::Dependency
70
95
  name: guard-bundler
71
- requirement: &70313120981660 !ruby/object:Gem::Requirement
96
+ requirement: !ruby/object:Gem::Requirement
72
97
  none: false
73
98
  requirements:
74
99
  - - ~>
75
100
  - !ruby/object:Gem::Version
76
- version: 0.1.3
101
+ version: 1.0.0
77
102
  type: :development
78
103
  prerelease: false
79
- version_requirements: *70313120981660
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.0.0
80
110
  - !ruby/object:Gem::Dependency
81
111
  name: guard-rspec
82
- requirement: &70313120981200 !ruby/object:Gem::Requirement
112
+ requirement: !ruby/object:Gem::Requirement
83
113
  none: false
84
114
  requirements:
85
115
  - - ~>
86
116
  - !ruby/object:Gem::Version
87
- version: 0.4.2
117
+ version: 2.2.1
88
118
  type: :development
89
119
  prerelease: false
90
- version_requirements: *70313120981200
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 2.2.1
91
126
  - !ruby/object:Gem::Dependency
92
127
  name: timecop
93
- requirement: &70313120980740 !ruby/object:Gem::Requirement
128
+ requirement: !ruby/object:Gem::Requirement
94
129
  none: false
95
130
  requirements:
96
131
  - - ~>
97
132
  - !ruby/object:Gem::Version
98
- version: 0.3.5
133
+ version: 0.5.3
99
134
  type: :development
100
135
  prerelease: false
101
- version_requirements: *70313120980740
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 0.5.3
102
142
  description: A simple LRU-cache based on a hash and priority queue
103
143
  email:
104
144
  - chris@kindkid.com
@@ -139,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
179
  version: '0'
140
180
  requirements: []
141
181
  rubyforge_project: lrucache
142
- rubygems_version: 1.8.10
182
+ rubygems_version: 1.8.24
143
183
  signing_key:
144
184
  specification_version: 3
145
185
  summary: A simple LRU-cache based on a hash and priority queue