ref 1.0.5 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -0
  3. data/lib/ref.rb +28 -29
  4. data/lib/ref/abstract_reference_key_map.rb +72 -28
  5. data/lib/ref/abstract_reference_value_map.rb +61 -18
  6. data/lib/ref/reference_queue.rb +8 -8
  7. data/lib/ref/soft_reference.rb +7 -7
  8. data/lib/ref/version.rb +3 -0
  9. data/lib/ref/weak_reference/pure_ruby.rb +9 -9
  10. data/lib/ref_ext.jar +0 -0
  11. metadata +23 -49
  12. data/README.rdoc +0 -40
  13. data/VERSION +0 -1
  14. data/lib/org/jruby/ext/ref/references.jar +0 -0
  15. data/lib/ref/mock.rb +0 -150
  16. data/lib/ref/safe_monitor.rb +0 -50
  17. data/lib/ref/weak_reference/iron_ruby.rb +0 -14
  18. data/test/mock_test.rb +0 -33
  19. data/test/mock_test.rbc +0 -856
  20. data/test/reference_key_map_behavior.rb +0 -155
  21. data/test/reference_key_map_behavior.rbc +0 -4241
  22. data/test/reference_queue_test.rb +0 -60
  23. data/test/reference_queue_test.rbc +0 -1938
  24. data/test/reference_value_map_behavior.rb +0 -135
  25. data/test/reference_value_map_behavior.rbc +0 -3560
  26. data/test/soft_key_map_test.rb +0 -13
  27. data/test/soft_key_map_test.rbc +0 -331
  28. data/test/soft_reference_test.rb +0 -49
  29. data/test/soft_reference_test.rbc +0 -1481
  30. data/test/soft_value_map_test.rb +0 -13
  31. data/test/soft_value_map_test.rbc +0 -331
  32. data/test/strong_reference_test.rb +0 -15
  33. data/test/strong_reference_test.rbc +0 -546
  34. data/test/test_helper.rb +0 -4
  35. data/test/test_helper.rbc +0 -143
  36. data/test/weak_key_map_test.rb +0 -13
  37. data/test/weak_key_map_test.rbc +0 -331
  38. data/test/weak_reference_test.rb +0 -54
  39. data/test/weak_reference_test.rbc +0 -1510
  40. data/test/weak_value_map_test.rb +0 -13
  41. data/test/weak_value_map_test.rbc +0 -331
@@ -19,12 +19,12 @@ module Ref
19
19
  class SoftReference < Reference
20
20
  @@strong_references = [{}]
21
21
  @@gc_flag_set = false
22
-
22
+
23
23
  # Number of garbage collection cycles after an object is used before a reference to it can be reclaimed.
24
24
  MIN_GC_CYCLES = 10
25
-
26
- @@lock = SafeMonitor.new
27
-
25
+
26
+ @@lock = Monitor.new
27
+
28
28
  @@finalizer = lambda do |object_id|
29
29
  @@lock.synchronize do
30
30
  while @@strong_references.size >= MIN_GC_CYCLES do
@@ -34,14 +34,14 @@ module Ref
34
34
  @@gc_flag_set = false
35
35
  end
36
36
  end
37
-
37
+
38
38
  # Create a new soft reference to an object.
39
39
  def initialize(obj)
40
40
  @referenced_object_id = obj.__id__
41
41
  @weak_reference = WeakReference.new(obj)
42
42
  add_strong_reference(obj)
43
43
  end
44
-
44
+
45
45
  # Get the referenced object. If the object has been reclaimed by the
46
46
  # garbage collector, then this will return nil.
47
47
  def object
@@ -50,7 +50,7 @@ module Ref
50
50
  add_strong_reference(obj) if obj
51
51
  obj
52
52
  end
53
-
53
+
54
54
  private
55
55
  # Create a strong reference to the object. This reference will live
56
56
  # for three passes of the garbage collector.
@@ -0,0 +1,3 @@
1
+ module Ref
2
+ VERSION = '2.0.0'
3
+ end
@@ -4,25 +4,25 @@ module Ref
4
4
  # subclass Delegator which is very heavy to instantiate and utilizes a
5
5
  # because it does not fair amount of memory under Ruby 1.8.
6
6
  class WeakReference < Reference
7
-
7
+
8
8
  class ReferencePointer
9
9
  def initialize(object)
10
10
  @referenced_object_id = object.__id__
11
11
  add_backreference(object)
12
12
  end
13
-
13
+
14
14
  def cleanup
15
15
  obj = ObjectSpace._id2ref(@referenced_object_id) rescue nil
16
16
  remove_backreference(obj) if obj
17
17
  end
18
-
18
+
19
19
  def object
20
20
  obj = ObjectSpace._id2ref(@referenced_object_id)
21
21
  obj if verify_backreferences(obj)
22
22
  rescue RangeError
23
23
  nil
24
24
  end
25
-
25
+
26
26
  private
27
27
  # Verify that the object is the same one originally set for the weak reference.
28
28
  def verify_backreferences(obj) #:nodoc:
@@ -30,7 +30,7 @@ module Ref
30
30
  backreferences = obj.instance_variable_get(:@__weak_backreferences__) if obj.instance_variable_defined?(:@__weak_backreferences__)
31
31
  backreferences && backreferences.include?(object_id)
32
32
  end
33
-
33
+
34
34
  # Add a backreference to the object.
35
35
  def add_backreference(obj) #:nodoc:
36
36
  return unless supports_backreference?(obj)
@@ -41,7 +41,7 @@ module Ref
41
41
  end
42
42
  backreferences << object_id
43
43
  end
44
-
44
+
45
45
  # Remove backreferences from the object.
46
46
  def remove_backreference(obj) #:nodoc:
47
47
  return unless supports_backreference?(obj)
@@ -51,16 +51,16 @@ module Ref
51
51
  obj.send(:remove_instance_variable, :@__weak_backreferences__) if backreferences.empty?
52
52
  end
53
53
  end
54
-
54
+
55
55
  def supports_backreference?(obj)
56
56
  obj.respond_to?(:instance_variable_get) && obj.respond_to?(:instance_variable_defined?)
57
57
  rescue NoMethodError
58
58
  false
59
59
  end
60
60
  end
61
-
61
+
62
62
  @@weak_references = {}
63
- @@lock = SafeMonitor.new
63
+ @@lock = Monitor.new
64
64
 
65
65
  # Finalizer that cleans up weak references when references are destroyed.
66
66
  @@reference_finalizer = lambda do |object_id|
Binary file
metadata CHANGED
@@ -1,98 +1,72 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ref
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Durand
8
- autorequire:
8
+ - The Ruby Concurrency Team
9
+ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-05-20 00:00:00.000000000 Z
12
+ date: 2015-07-10 00:00:00.000000000 Z
12
13
  dependencies: []
13
- description: Library that implements weak, soft, and strong references in Ruby that
14
- work across multiple runtimes (MRI, REE, YARV, Jruby, Rubinius, and IronRuby). Also
15
- includes implementation of maps/hashes that use references and a reference queue.
14
+ description: Library that implements weak, soft, and strong references in Ruby that work across multiple runtimes (MRI,Jruby and Rubinius). Also includes implementation of maps/hashes that use references and a reference queue.
16
15
  email:
17
16
  - bbdurand@gmail.com
17
+ - concurrent-ruby@googlegroups.com
18
18
  executables: []
19
19
  extensions: []
20
20
  extra_rdoc_files:
21
- - README.rdoc
21
+ - README.md
22
22
  files:
23
- - README.rdoc
24
- - VERSION
25
23
  - MIT_LICENSE
26
- - lib/org/jruby/ext/ref/references.jar
24
+ - README.md
25
+ - ext/java/org/jruby/ext/ref/ReferencesService.java
26
+ - ext/java/org/jruby/ext/ref/RubySoftReference.java
27
+ - ext/java/org/jruby/ext/ref/RubyWeakReference.java
28
+ - lib/ref.rb
27
29
  - lib/ref/abstract_reference_key_map.rb
28
30
  - lib/ref/abstract_reference_value_map.rb
29
- - lib/ref/mock.rb
30
31
  - lib/ref/reference.rb
31
32
  - lib/ref/reference_queue.rb
32
- - lib/ref/safe_monitor.rb
33
33
  - lib/ref/soft_key_map.rb
34
34
  - lib/ref/soft_reference.rb
35
35
  - lib/ref/soft_value_map.rb
36
36
  - lib/ref/strong_reference.rb
37
+ - lib/ref/version.rb
37
38
  - lib/ref/weak_key_map.rb
38
- - lib/ref/weak_reference/iron_ruby.rb
39
+ - lib/ref/weak_reference.rb
39
40
  - lib/ref/weak_reference/pure_ruby.rb
40
41
  - lib/ref/weak_reference/weak_ref.rb
41
- - lib/ref/weak_reference.rb
42
42
  - lib/ref/weak_value_map.rb
43
- - lib/ref.rb
44
- - test/mock_test.rb
45
- - test/mock_test.rbc
46
- - test/reference_key_map_behavior.rb
47
- - test/reference_key_map_behavior.rbc
48
- - test/reference_queue_test.rb
49
- - test/reference_queue_test.rbc
50
- - test/reference_value_map_behavior.rb
51
- - test/reference_value_map_behavior.rbc
52
- - test/soft_key_map_test.rb
53
- - test/soft_key_map_test.rbc
54
- - test/soft_reference_test.rb
55
- - test/soft_reference_test.rbc
56
- - test/soft_value_map_test.rb
57
- - test/soft_value_map_test.rbc
58
- - test/strong_reference_test.rb
59
- - test/strong_reference_test.rbc
60
- - test/test_helper.rb
61
- - test/test_helper.rbc
62
- - test/weak_key_map_test.rb
63
- - test/weak_key_map_test.rbc
64
- - test/weak_reference_test.rb
65
- - test/weak_reference_test.rbc
66
- - test/weak_value_map_test.rb
67
- - test/weak_value_map_test.rbc
68
- - ext/java/org/jruby/ext/ref/ReferencesService.java
69
- - ext/java/org/jruby/ext/ref/RubySoftReference.java
70
- - ext/java/org/jruby/ext/ref/RubyWeakReference.java
71
- homepage: http://github.com/bdurand/ref
43
+ - lib/ref_ext.jar
44
+ homepage: http://github.com/ruby-concurrency/ref
72
45
  licenses:
73
46
  - MIT
74
47
  metadata: {}
75
- post_install_message:
48
+ post_install_message:
76
49
  rdoc_options:
77
50
  - --charset=UTF-8
78
51
  - --main
79
- - README.rdoc
52
+ - README.md
80
53
  require_paths:
81
54
  - lib
82
55
  required_ruby_version: !ruby/object:Gem::Requirement
83
56
  requirements:
84
57
  - - '>='
85
58
  - !ruby/object:Gem::Version
86
- version: '0'
59
+ version: 1.9.3
87
60
  required_rubygems_version: !ruby/object:Gem::Requirement
88
61
  requirements:
89
62
  - - '>='
90
63
  - !ruby/object:Gem::Version
91
64
  version: '0'
92
65
  requirements: []
93
- rubyforge_project:
94
- rubygems_version: 2.0.0
95
- signing_key:
66
+ rubyforge_project:
67
+ rubygems_version: 2.4.5
68
+ signing_key:
96
69
  specification_version: 4
97
70
  summary: Library that implements weak, soft, and strong references in Ruby.
98
71
  test_files: []
72
+ has_rdoc: true
@@ -1,40 +0,0 @@
1
- This library provides object references for Ruby as well as some common utilities for working with references. Object references are used to point to other objects and come in three distinct flavors that interact differently with the garbage collector.
2
-
3
- * Ref::StrongReference - This is a plain old pointer to another object.
4
- * Ref::WeakReference - This is a pointer to another object, but it is not seen by the garbage collector and the memory used by the object can be reclaimed at any time.
5
- * Ref::SoftReference - This is similar to a weak reference, but the garbage collector is not as eager to reclaim the referenced object.
6
-
7
- All of these classes extend from a common Ref::Reference class and have a common interface.
8
-
9
- Weak and soft references are useful when you have instantiated objects that you may want to use again but can recreate if necessary. Since the garbage collector determines when to reclaim the memory used by the objects, you don't need to worry about bloating the Ruby heap.
10
-
11
- = Example Usage
12
-
13
- ref = Ref::WeakReference.new("hello")
14
- ref.object # should be "hello"
15
- ObjectSpace.garbage_collect
16
- ref.object # should be nil (assuming the garbage collector reclaimed the reference)
17
-
18
- = Goodies
19
-
20
- This library also includes tools for some common uses of weak and soft references.
21
-
22
- * Ref::WeakKeyMap - A map of keys to values where the keys are weak references
23
- * Ref::WeakValueMap - A map of keys to values where the values are weak references
24
- * Ref::SoftKeyMap - A map of keys to values where the keys are soft references
25
- * Ref::SoftValueMap - A map of keys to values where the values are soft references
26
- * Ref::ReferenceQueue - A thread safe implementation of a queue that will add references to itself as their objects are garbage collected.
27
-
28
- = Problems with WeakRef
29
-
30
- Ruby does come with the WeakRef class in the standard library. However, there are issues with this class across several different Ruby runtimes. This gem provides a common interface to weak references that works across MRI, Ruby Enterprise Edition, YARV, Jruby, Rubinius, and IronRuby.
31
-
32
- 1. MRI and REE 1.8 - WeakRef extends from Delegator which is a very heavy weight class under Ruby 1.8. Creating a WeakRef object will allocate thousands of other objects and use up hundreds of kilobytes of memory. This makes WeakRef all but unusable even if you only need several hundred of them.
33
- 2. YARV 1.9 - WeakRef is unsafe to use because the garbage collector can run in a different system thread than a thread allocating memory. This exposes a bug where a WeakRef may end up pointing to a completely different object than it originally referenced.
34
- 3. Jruby and IronRuby - Jruby and IronRuby using the Ruby 1.8 libraries suffers from the same performance issue with the Delegator class. Furthermore, these VM's don't implement the method used to load an object from the heap using an object id and so cannot use a pure Ruby method to implement weak references.
35
- 4. Rubinius - Rubinius implements WeakRef with a lighter weight version of delegation and works very well.
36
- 5. MRI Ruby 2.0 has a good implementation of WeakRef.
37
-
38
- = BasicObject
39
-
40
- Not that weak references will not work with MRI/REE 1.8 or YARV 1.9. References will be created, but the objects will never be stored so the reference object will always treat the object as if it is always garbage collected. BasicObject does not implement the necessary methods to maintain the reference.
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.0.5
@@ -1,150 +0,0 @@
1
- module Ref
2
- # This module provides mock weak and strong references that are designed to be
3
- # used in tests. You can define a block where all weak and soft references created
4
- # will be mock references. You can then mimic running the garbage collector on
5
- # the objects pointed to by the references.
6
- #
7
- # Example usage:
8
- #
9
- # Ref::Mock.use do
10
- # obj = Object.new
11
- # ref = Ref::WeakReference.new(obj)
12
- # ref.object # obj
13
- # Ref::Mock.gc(obj) # mimics the garbage collector reclaiming the referenced object
14
- # ref.object # nil
15
- # end
16
- module Mock
17
- class << self
18
- # Use the mock implementation inside a block and then restore the original implementation.
19
- def use
20
- if object_space
21
- yield
22
- else
23
- setup
24
- begin
25
- yield
26
- ensure
27
- cleanup
28
- end
29
- end
30
- end
31
-
32
- # Start using mock references.
33
- def setup
34
- raise "Ref::Mock already setup" if object_space
35
-
36
- @object_space = {}
37
-
38
- class << ObjectSpace
39
- unless method_defined?(:define_finalizer_with_mock_reference)
40
- def define_finalizer_with_mock_reference(obj, finalizer)
41
- if ::Ref::Mock.object_space.include?(obj.__id__)
42
- ::Ref::Mock.object_space[obj.__id__] << finalizer
43
- else
44
- define_finalizer_without_mock_reference(obj, finalizer)
45
- end
46
- end
47
- end
48
-
49
- alias_method :define_finalizer_without_mock_reference, :define_finalizer
50
- alias_method :define_finalizer, :define_finalizer_with_mock_reference
51
- end
52
-
53
- class << WeakReference
54
- unless method_defined?(:new_with_mock_reference)
55
- def new_with_mock_reference(obj)
56
- if self == Mock::MockWeakReference
57
- new_without_mock_reference(obj)
58
- else
59
- Mock::MockWeakReference.new(obj)
60
- end
61
- end
62
- end
63
-
64
- alias_method :new_without_mock_reference, :new
65
- alias_method :new, :new_with_mock_reference
66
- end
67
-
68
- class << SoftReference
69
- unless method_defined?(:new_with_mock_reference)
70
- def new_with_mock_reference(obj)
71
- if self == Mock::MockSoftReference
72
- new_without_mock_reference(obj)
73
- else
74
- Mock::MockSoftReference.new(obj)
75
- end
76
- end
77
- end
78
-
79
- alias_method :new_without_mock_reference, :new
80
- alias_method :new, :new_with_mock_reference
81
- end
82
- end
83
-
84
- # Stop using mock references.
85
- def cleanup
86
- @object_space = nil
87
- class << ObjectSpace
88
- alias_method :define_finalizer_with_mock_reference, :define_finalizer
89
- alias_method :define_finalizer, :define_finalizer_without_mock_reference
90
- end
91
-
92
- class << WeakReference
93
- alias_method :new_with_mock_reference, :new
94
- alias_method :new, :new_without_mock_reference
95
- end
96
-
97
- class << SoftReference
98
- alias_method :new_with_mock_reference, :new
99
- alias_method :new, :new_without_mock_reference
100
- end
101
- end
102
-
103
- def object_space # :nodoc:
104
- @object_space if instance_variable_defined?(:@object_space)
105
- end
106
-
107
- # Simulate garbage collection of the objects passed in as arguments. If no objects
108
- # are specified, all objects will be reclaimed.
109
- def gc(*objects)
110
- objects = if objects.empty?
111
- object_space.keys
112
- else
113
- objects.map { |obj| obj.__id__ }
114
- end
115
-
116
- objects.each do |id|
117
- finalizers = object_space.delete(id)
118
- if finalizers
119
- finalizers.each{|finalizer| finalizer.call(id)}
120
- end
121
- end
122
- end
123
- end
124
-
125
- module MockReference #:nodoc:
126
- def initialize(obj)
127
- @object = obj
128
- @referenced_object_id = obj.__id__
129
- raise "Reference::Mock not setup yet" unless Mock.object_space
130
- Mock.object_space[obj.__id__] ||= []
131
- end
132
-
133
- def object
134
- if @object && Mock.object_space.include?(@object.__id__)
135
- @object
136
- else
137
- @object = nil
138
- end
139
- end
140
- end
141
-
142
- class MockWeakReference < WeakReference #:nodoc:
143
- include MockReference
144
- end
145
-
146
- class MockSoftReference < SoftReference #:nodoc:
147
- include MockReference
148
- end
149
- end
150
- end
@@ -1,50 +0,0 @@
1
- begin
2
- require 'thread'
3
- rescue LoadError
4
- # Threads not available. Monitor will do nothing.
5
- end
6
-
7
- module Ref
8
- # The Monitor class in Ruby 1.8 has some bugs and also threads may not be available on all
9
- # runtimes. This class provides a simple, safe re-entrant mutex as an alternative.
10
- class SafeMonitor
11
- def initialize
12
- @owner = nil
13
- @count = 0
14
- @mutex = defined?(Mutex) ? Mutex.new : nil
15
- end
16
-
17
- # Acquire an exclusive lock.
18
- def lock
19
- if @mutex
20
- if @owner != Thread.current.object_id
21
- @mutex.lock
22
- @owner = Thread.current.object_id
23
- end
24
- @count += 1
25
- end
26
- true
27
- end
28
-
29
- # Release the exclusive lock.
30
- def unlock
31
- if @mutex
32
- if @owner == Thread.current.object_id
33
- @count -= 1
34
- if @count == 0
35
- @owner = nil
36
- @mutex.unlock
37
- end
38
- end
39
- end
40
- end
41
-
42
- # Run a block of code with an exclusive lock.
43
- def synchronize
44
- lock
45
- yield
46
- ensure
47
- unlock
48
- end
49
- end
50
- end