volatile_hash 0.0.1

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/.rvmrc ADDED
@@ -0,0 +1,2 @@
1
+ rvm use ruby-1.9.2-p180@colorize --create
2
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ volatile_hash (0.0.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.3)
10
+ rake (0.9.2.2)
11
+ rr (1.0.4)
12
+ rspec (2.8.0)
13
+ rspec-core (~> 2.8.0)
14
+ rspec-expectations (~> 2.8.0)
15
+ rspec-mocks (~> 2.8.0)
16
+ rspec-core (2.8.0)
17
+ rspec-expectations (2.8.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.8.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ rake (~> 0.9.2)
26
+ rr (~> 1.0.4)
27
+ rspec (~> 2.8.0)
28
+ volatile_hash!
data/README ADDED
@@ -0,0 +1,8 @@
1
+ Implements a Time-to-live based cache and a Least-recently-used cache.
2
+
3
+
4
+ = Test/Development
5
+
6
+ gem install bundler
7
+ bundle install
8
+ rake
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'rspec/core/rake_task'
2
+ task :default => :spec
3
+
4
+ RSpec::Core::RakeTask.new do |t|
5
+ # t.pattern = 'spec/**/*_spec.rb'
6
+ end
7
+
@@ -0,0 +1,54 @@
1
+ class VolatileHash
2
+ def initialize(options)
3
+ @strategy = options[:strategy] || 'ttl'
4
+ @cache = {}
5
+ if @strategy == 'ttl'
6
+ @registry = {}
7
+ @ttl = options[:ttl] || 3600
8
+ else #lru
9
+ @max_items = options[:max] || 10
10
+ @item_order = []
11
+ end
12
+ end
13
+
14
+ def [](key)
15
+ value = @cache[key]
16
+ if @strategy == 'ttl'
17
+ if expired?(key)
18
+ @cache.delete key
19
+ @registry.delete key
20
+ value = nil
21
+ end
22
+ else
23
+ lru_update key if @cache.has_key?(key)
24
+ end
25
+ value #in case of LRU, just return the value that was read
26
+ end
27
+
28
+ def []=(key, value)
29
+ if @strategy == 'ttl'
30
+ @registry[key] = Time.now + @ttl.to_f
31
+ @cache[key] = value
32
+ else
33
+ @item_order.unshift key
34
+ @cache[key] = value
35
+ lru_invalidate if @max_items < @item_order.length
36
+ end
37
+ end
38
+
39
+ private
40
+ def expired?(key)
41
+ Time.now > @registry[key]
42
+ end
43
+
44
+ def lru_invalidate
45
+ while @max_items < @item_order.length
46
+ @cache.delete @item_order.pop
47
+ end
48
+ end
49
+
50
+ def lru_update(key)
51
+ @item_order.delete key
52
+ @item_order.unshift key
53
+ end
54
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'volatile_hash'
5
+
6
+ RSpec.configure do |config|
7
+ # some (optional) config here
8
+ config.mock_with :rr
9
+ end
10
+
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ describe VolatileHash do
4
+ describe "TTL mode" do
5
+ before do
6
+ @cache = VolatileHash.new(:strategy => 'ttl', :ttl => 0.5, :max => 1)
7
+ @x = Object.new
8
+ @cache[:x] = @x.to_s
9
+ end
10
+
11
+ it "should remember cached values" do
12
+ @cache[:x].should == @x.to_s
13
+ end
14
+
15
+ it "should not have to re-calculate cached values" do
16
+ dont_allow(@x).to_s
17
+ @cache[:x] ||= @x.to_s
18
+ end
19
+
20
+ it "should forget cached values after the TTL expires" do
21
+ @cache[:x].should == @x.to_s
22
+
23
+ sleep(0.6)
24
+
25
+ @cache[:x].should be_nil
26
+ end
27
+
28
+ it "should not throw out least-recently used value" do
29
+ @cache[:y] =1
30
+
31
+ @cache[:x].should_not be_nil
32
+ @cache[:y].should_not be_nil
33
+ end
34
+ end
35
+
36
+ describe "LRU mode" do
37
+ before do
38
+ @cache = VolatileHash.new(:strategy => 'lru', :max => 3, :ttl => 0.1)
39
+ @x = Object.new
40
+ @y = Object.new
41
+ @z = Object.new
42
+ @cache[:x] = @x.to_s
43
+ end
44
+
45
+ it "should remember cached values" do
46
+ @cache[:x].should == @x.to_s
47
+ end
48
+
49
+ it "should not have to re-calculate cached values" do
50
+ dont_allow(@x).to_s
51
+ @cache[:x] ||= @x.to_s
52
+ end
53
+
54
+ it "should have only up to the last max values" do
55
+ @cache[:x].should == @x.to_s
56
+ @cache[:y].should be_nil
57
+ @cache[:z].should be_nil
58
+ @cache[:w].should be_nil
59
+
60
+ @cache[:y] = @y.to_s
61
+ @cache[:z] = @z.to_s
62
+ @cache[:w] = @z.to_s
63
+
64
+ @cache[:x].should be_nil
65
+ @cache[:y].should == @y.to_s
66
+ @cache[:z].should == @z.to_s
67
+ @cache[:w].should == @z.to_s
68
+ end
69
+
70
+ it "should throw out the least recently accessed value" do
71
+ @cache[:y] = @y.to_s
72
+ @cache[:z] = @z.to_s
73
+ @cache[:y].should == @y.to_s
74
+ @cache[:x].should == @x.to_s
75
+ @cache[:z].should == @z.to_s
76
+
77
+ @cache[:w] = @x.to_s
78
+
79
+ @cache[:x].should == @x.to_s
80
+ @cache[:y].should be_nil
81
+ @cache[:z].should == @z.to_s
82
+ @cache[:w].should == @x.to_s
83
+ end
84
+
85
+ it "should not expire by ttl" do
86
+ sleep(0.3)
87
+ @cache[:x].should_not be_nil
88
+ end
89
+
90
+ end
91
+ end
92
+
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'volatile_hash'
3
+ s.version = '0.0.1'
4
+ s.date = '2012-02-22'
5
+ s.summary = "Implements LRU and TTL caches"
6
+ s.description = "Implements key-based cache that can have a least-recently-used or time-to-live expiration strategy"
7
+ s.authors = ["Satya P"]
8
+ s.email = 'github@thesatya.com'
9
+ s.files = `git ls-files`.split("\n")
10
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
11
+ s.require_paths = ["lib"]
12
+
13
+ s.homepage = 'http://github.com/satyap/volatile_hash'
14
+
15
+ s.add_development_dependency 'rspec', '~> 2.8.0'
16
+ s.add_development_dependency 'rr', '~> 1.0.4'
17
+ s.add_development_dependency 'rake', '~> 0.9.2'
18
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: volatile_hash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Satya P
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-22 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &74297420 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.8.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *74297420
25
+ - !ruby/object:Gem::Dependency
26
+ name: rr
27
+ requirement: &74297180 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.4
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *74297180
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &74296950 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.2
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *74296950
47
+ description: Implements key-based cache that can have a least-recently-used or time-to-live
48
+ expiration strategy
49
+ email: github@thesatya.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .rvmrc
55
+ - Gemfile
56
+ - Gemfile.lock
57
+ - README
58
+ - Rakefile
59
+ - lib/volatile_hash.rb
60
+ - spec/spec_helper.rb
61
+ - spec/volatile_hash_spec.rb
62
+ - volatile_hash.gemspec
63
+ homepage: http://github.com/satyap/volatile_hash
64
+ licenses: []
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.10
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Implements LRU and TTL caches
87
+ test_files: []