threadsafe-lru 0.0.2 → 0.0.3

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/.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"}