threadsafe-lru 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -1,3 +1,4 @@
1
+ require 'threadsafe-lru/DoubleLinkedList'
1
2
  require 'threadsafe-lru/ThreadSafeLruCache'
2
3
 
3
4
  module ThreadSafeLru
@@ -1,6 +1,72 @@
1
- module ThreadSafeLru
1
+ module ThreadSafeLru
2
+ class ListNode
3
+ def initialize value
4
+ @value=value
5
+ end
6
+
7
+ def insert_between prev_node, next_node
8
+ self.next=next_node
9
+ self.prev=prev_node
10
+ prev_node.next=self
11
+ next_node.prev=self
12
+ self
13
+ end
14
+
15
+ def remove
16
+ self.prev.next=self.next
17
+ self.next.prev=self.prev
18
+ self.next=nil
19
+ self.prev=nil
20
+ end
21
+
22
+ attr_reader :value
23
+ attr_accessor :next
24
+ attr_accessor :prev
25
+
26
+ end
27
+
2
28
  class DoubleLinkedList
3
-
4
-
29
+
30
+ def initialize
31
+ @head=ListNode.new "head"
32
+ @tail=ListNode.new "tail"
33
+ @head.next=@tail
34
+ @tail.prev=@head
35
+ end
36
+
37
+
38
+ def add_to_head value
39
+ new_node=ListNode.new value
40
+ new_node.insert_between @head,@head.next
41
+ new_node
42
+ end
43
+
44
+ def bump_to_top node
45
+ node.remove
46
+ node.insert_between @head,@head.next
47
+ end
48
+
49
+ def remove_last
50
+ node=@tail.prev
51
+ node.remove
52
+ node
53
+ end
54
+
55
+ def clear
56
+ @head.next=@tail
57
+ @tail.prev=@head
58
+ end
59
+
60
+
61
+ def to_a
62
+ result=[]
63
+ current=@head.next
64
+ while current != @tail
65
+ result << current.value
66
+ current=current.next
67
+ end
68
+ result
69
+ end
70
+
5
71
  end
6
72
  end
@@ -1,4 +1,5 @@
1
1
  require 'thread'
2
+ require 'threadsafe-lru/DoubleLinkedList'
2
3
 
3
4
  module ThreadSafeLru
4
5
  class LruCache
@@ -6,19 +7,20 @@ module ThreadSafeLru
6
7
  @size=size
7
8
  @cached_values={}
8
9
  @factory_block=block
9
- @recently_used=[]
10
+ @recently_used=ThreadSafeLru::DoubleLinkedList.new
10
11
  @lock=Mutex.new
11
12
  end
12
13
 
13
14
  def size
14
- @recently_used.size
15
+ @cached_values.size
15
16
  end
16
17
 
17
18
 
18
19
  def drop key
19
20
  @lock.synchronize do
20
- @cached_values.delete key
21
- @recently_used.delete key
21
+ node=@cached_values.delete key
22
+ node.remove if node
23
+
22
24
  end
23
25
  end
24
26
 
@@ -42,19 +44,18 @@ module ThreadSafeLru
42
44
 
43
45
  def get_node key
44
46
  if @cached_values.has_key?(key)
45
- @recently_used.delete(key)
46
- @recently_used << key
47
+ dll_node=@cached_values[key]
48
+ @recently_used.bump_to_top dll_node
47
49
  else
48
- while (@recently_used.size >= @size) do
49
- dropped=@recently_used.shift
50
- @cached_values.delete(dropped)
50
+ while (size >= @size) do
51
+ dropped=@recently_used.remove_last
52
+ @cached_values.delete(dropped.value.key)
51
53
  end
52
54
  node=Node.new key
53
- @cached_values[key]=node
54
- @recently_used << key
55
+ dll_node=@recently_used.add_to_head node
56
+ @cached_values[key]=dll_node
55
57
  end
56
-
57
- @cached_values[key]
58
+ @cached_values[key].value
58
59
  end
59
60
 
60
61
  end
@@ -67,6 +68,8 @@ module ThreadSafeLru
67
68
  @lock=Mutex.new
68
69
  end
69
70
 
71
+ attr_reader :key
72
+
70
73
  def get_value block
71
74
  @lock.synchronize do
72
75
  unless (@produced)
@@ -1,3 +1,3 @@
1
1
  module ThreadSafeLru
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1,77 @@
1
+ require 'threadsafe-lru'
2
+
3
+ module ThreadSafeLru
4
+ describe DoubleLinkedList do
5
+
6
+ describe :clear do
7
+ it "should clear all values" do
8
+ subject.add_to_head("value1")
9
+ subject.clear
10
+ subject.to_a.should == []
11
+ end
12
+ end
13
+
14
+ describe :add_to_head do
15
+ it "should append node to head" do
16
+ subject.add_to_head("value1").should be_a ListNode
17
+ subject.to_a.should == ["value1"]
18
+ subject.add_to_head("value0").should be_a ListNode
19
+ subject.to_a.should == ["value0","value1"]
20
+ end
21
+ end
22
+
23
+ describe :remove_last do
24
+ it "should remove last element from the linked list" do
25
+ subject.add_to_head("v1")
26
+ subject.add_to_head("v2")
27
+ subject.remove_last
28
+ subject.to_a.should == ["v2"]
29
+ end
30
+ end
31
+
32
+ describe :bump_to_top do
33
+ it "should move node to the top of the list" do
34
+ last=subject.add_to_head("v1")
35
+ first=subject.add_to_head("v2")
36
+ subject.bump_to_top last
37
+ subject.to_a.should == ["v1","v2"]
38
+ end
39
+ end
40
+ end
41
+
42
+ describe ListNode do
43
+ subject {ListNode.new "value"}
44
+
45
+ describe :insert_between do
46
+ let(:prev_node) {ListNode.new "prev"}
47
+ let(:next_node) {ListNode.new "next"}
48
+
49
+ it "should insert node in the chain between prev and next" do
50
+ subject.insert_between(prev_node,next_node)
51
+ subject.prev.should == prev_node
52
+ subject.next.should == next_node
53
+ prev_node.next.should == subject
54
+ next_node.prev.should == subject
55
+ end
56
+ end
57
+
58
+ describe :remove do
59
+ let(:prev_node) {ListNode.new "prev"}
60
+ let(:next_node) {ListNode.new "next"}
61
+ it "should remove itself from the chain" do
62
+ subject.insert_between prev_node, next_node
63
+ subject.remove
64
+ subject.next.should == nil
65
+ subject.prev.should == nil
66
+
67
+ prev_node.next.should == next_node
68
+ next_node.prev.should == prev_node
69
+
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+
76
+
77
+ end
metadata CHANGED
@@ -1,49 +1,50 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: threadsafe-lru
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.0.2
4
+ version: 0.0.3
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Dragan Milic
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-18 00:00:00.000000000 Z
12
+ date: 2013-04-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- version_requirements: !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
17
18
  requirements:
18
19
  - - ! '>='
19
20
  - !ruby/object:Gem::Version
20
21
  version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
21
25
  none: false
22
- requirement: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - ! '>='
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0'
27
- none: false
28
- prerelease: false
29
- type: :development
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: autotest
32
- version_requirements: !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
33
34
  requirements:
34
35
  - - ! '>='
35
36
  - !ruby/object:Gem::Version
36
37
  version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
37
41
  none: false
38
- requirement: !ruby/object:Gem::Requirement
39
42
  requirements:
40
43
  - - ! '>='
41
44
  - !ruby/object:Gem::Version
42
45
  version: '0'
43
- none: false
44
- prerelease: false
45
- type: :development
46
- description: Thread safe implemenation of in-memory LRU cache compatible with Java Memory Model
46
+ description: Thread safe implemenation of in-memory LRU cache compatible with Java
47
+ Memory Model
47
48
  email:
48
49
  - dragan@netice9.com
49
50
  executables: []
@@ -52,39 +53,40 @@ extra_rdoc_files: []
52
53
  files:
53
54
  - .gitignore
54
55
  - .project
56
+ - .rspec
55
57
  - LICENSE
56
58
  - README.md
57
- - autotest/discover.rb
58
59
  - lib/threadsafe-lru.rb
59
60
  - lib/threadsafe-lru/DoubleLinkedList.rb
60
61
  - lib/threadsafe-lru/ThreadSafeLruCache.rb
61
62
  - lib/threadsafe-lru/version.rb
63
+ - spec/threadsafe-lru/DoubleLinkedList_spec.rb
62
64
  - spec/threadsafe-lru/ThreadSafeLruCache_spec.rb
63
65
  - threadsafe-lru.gemspec
64
66
  homepage: https://github.com/draganm/threadsafe-lru
65
67
  licenses: []
66
- post_install_message:
68
+ post_install_message:
67
69
  rdoc_options: []
68
70
  require_paths:
69
71
  - lib
70
72
  required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
71
74
  requirements:
72
75
  - - ! '>='
73
76
  - !ruby/object:Gem::Version
74
77
  version: '0'
75
- none: false
76
78
  required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
77
80
  requirements:
78
81
  - - ! '>='
79
82
  - !ruby/object:Gem::Version
80
83
  version: '0'
81
- none: false
82
84
  requirements: []
83
- rubyforge_project:
84
- rubygems_version: 1.8.24
85
- signing_key:
85
+ rubyforge_project:
86
+ rubygems_version: 1.8.25
87
+ signing_key:
86
88
  specification_version: 3
87
89
  summary: Thread safe in memory LRU cache
88
90
  test_files:
91
+ - spec/threadsafe-lru/DoubleLinkedList_spec.rb
89
92
  - spec/threadsafe-lru/ThreadSafeLruCache_spec.rb
90
- ...
@@ -1 +0,0 @@
1
- Autotest.add_discovery {"rspec2"}