concurrent-ruby 0.9.2-java → 1.0.0-java

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.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +49 -1
  3. data/README.md +86 -120
  4. data/lib/concurrent.rb +14 -5
  5. data/lib/concurrent/agent.rb +587 -0
  6. data/lib/concurrent/array.rb +39 -0
  7. data/lib/concurrent/async.rb +296 -149
  8. data/lib/concurrent/atom.rb +135 -45
  9. data/lib/concurrent/atomic/abstract_thread_local_var.rb +38 -0
  10. data/lib/concurrent/atomic/atomic_boolean.rb +83 -118
  11. data/lib/concurrent/atomic/atomic_fixnum.rb +101 -163
  12. data/lib/concurrent/atomic/atomic_reference.rb +1 -8
  13. data/lib/concurrent/atomic/count_down_latch.rb +62 -103
  14. data/lib/concurrent/atomic/cyclic_barrier.rb +3 -1
  15. data/lib/concurrent/atomic/event.rb +1 -1
  16. data/lib/concurrent/atomic/java_count_down_latch.rb +39 -0
  17. data/lib/concurrent/atomic/java_thread_local_var.rb +50 -0
  18. data/lib/concurrent/atomic/mutex_atomic_boolean.rb +60 -0
  19. data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +91 -0
  20. data/lib/concurrent/atomic/mutex_count_down_latch.rb +43 -0
  21. data/lib/concurrent/atomic/mutex_semaphore.rb +115 -0
  22. data/lib/concurrent/atomic/read_write_lock.rb +5 -4
  23. data/lib/concurrent/atomic/reentrant_read_write_lock.rb +3 -1
  24. data/lib/concurrent/atomic/ruby_thread_local_var.rb +172 -0
  25. data/lib/concurrent/atomic/semaphore.rb +84 -178
  26. data/lib/concurrent/atomic/thread_local_var.rb +65 -294
  27. data/lib/concurrent/atomic_reference/jruby+truffle.rb +1 -0
  28. data/lib/concurrent/atomic_reference/jruby.rb +1 -1
  29. data/lib/concurrent/atomic_reference/mutex_atomic.rb +14 -8
  30. data/lib/concurrent/atomic_reference/ruby.rb +1 -1
  31. data/lib/concurrent/atomics.rb +7 -37
  32. data/lib/concurrent/collection/copy_on_notify_observer_set.rb +7 -15
  33. data/lib/concurrent/collection/copy_on_write_observer_set.rb +7 -15
  34. data/lib/concurrent/collection/java_non_concurrent_priority_queue.rb +84 -0
  35. data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +927 -0
  36. data/lib/concurrent/collection/map/mri_map_backend.rb +66 -0
  37. data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +144 -0
  38. data/lib/concurrent/collection/map/synchronized_map_backend.rb +86 -0
  39. data/lib/concurrent/collection/non_concurrent_priority_queue.rb +143 -0
  40. data/lib/concurrent/collection/ruby_non_concurrent_priority_queue.rb +150 -0
  41. data/lib/concurrent/concern/dereferenceable.rb +9 -24
  42. data/lib/concurrent/concern/logging.rb +1 -1
  43. data/lib/concurrent/concern/obligation.rb +11 -20
  44. data/lib/concurrent/concern/observable.rb +38 -13
  45. data/lib/concurrent/configuration.rb +23 -152
  46. data/lib/concurrent/constants.rb +8 -0
  47. data/lib/concurrent/delay.rb +14 -12
  48. data/lib/concurrent/exchanger.rb +339 -41
  49. data/lib/concurrent/executor/abstract_executor_service.rb +134 -0
  50. data/lib/concurrent/executor/executor_service.rb +23 -359
  51. data/lib/concurrent/executor/immediate_executor.rb +3 -2
  52. data/lib/concurrent/executor/java_executor_service.rb +100 -0
  53. data/lib/concurrent/executor/java_single_thread_executor.rb +3 -3
  54. data/lib/concurrent/executor/java_thread_pool_executor.rb +3 -4
  55. data/lib/concurrent/executor/ruby_executor_service.rb +78 -0
  56. data/lib/concurrent/executor/ruby_single_thread_executor.rb +10 -66
  57. data/lib/concurrent/executor/ruby_thread_pool_executor.rb +25 -22
  58. data/lib/concurrent/executor/safe_task_executor.rb +6 -7
  59. data/lib/concurrent/executor/serial_executor_service.rb +34 -0
  60. data/lib/concurrent/executor/serialized_execution.rb +10 -33
  61. data/lib/concurrent/executor/serialized_execution_delegator.rb +28 -0
  62. data/lib/concurrent/executor/simple_executor_service.rb +1 -10
  63. data/lib/concurrent/executor/single_thread_executor.rb +20 -10
  64. data/lib/concurrent/executor/timer_set.rb +8 -10
  65. data/lib/concurrent/executors.rb +12 -2
  66. data/lib/concurrent/future.rb +6 -4
  67. data/lib/concurrent/hash.rb +35 -0
  68. data/lib/concurrent/immutable_struct.rb +5 -1
  69. data/lib/concurrent/ivar.rb +12 -16
  70. data/lib/concurrent/lazy_register.rb +11 -8
  71. data/lib/concurrent/map.rb +180 -0
  72. data/lib/concurrent/maybe.rb +6 -3
  73. data/lib/concurrent/mutable_struct.rb +7 -6
  74. data/lib/concurrent/mvar.rb +26 -2
  75. data/lib/concurrent/{executor/executor.rb → options.rb} +5 -29
  76. data/lib/concurrent/promise.rb +7 -5
  77. data/lib/concurrent/scheduled_task.rb +13 -71
  78. data/lib/concurrent/settable_struct.rb +5 -4
  79. data/lib/concurrent/synchronization.rb +15 -3
  80. data/lib/concurrent/synchronization/abstract_lockable_object.rb +98 -0
  81. data/lib/concurrent/synchronization/abstract_object.rb +7 -146
  82. data/lib/concurrent/synchronization/abstract_struct.rb +2 -3
  83. data/lib/concurrent/synchronization/condition.rb +6 -4
  84. data/lib/concurrent/synchronization/jruby_lockable_object.rb +13 -0
  85. data/lib/concurrent/synchronization/jruby_object.rb +44 -0
  86. data/lib/concurrent/synchronization/lock.rb +3 -2
  87. data/lib/concurrent/synchronization/lockable_object.rb +72 -0
  88. data/lib/concurrent/synchronization/mri_lockable_object.rb +71 -0
  89. data/lib/concurrent/synchronization/mri_object.rb +43 -0
  90. data/lib/concurrent/synchronization/object.rb +140 -73
  91. data/lib/concurrent/synchronization/rbx_lockable_object.rb +65 -0
  92. data/lib/concurrent/synchronization/rbx_object.rb +30 -73
  93. data/lib/concurrent/synchronization/volatile.rb +34 -0
  94. data/lib/concurrent/thread_safe/synchronized_delegator.rb +50 -0
  95. data/lib/concurrent/thread_safe/util.rb +14 -0
  96. data/lib/concurrent/thread_safe/util/adder.rb +74 -0
  97. data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +30 -0
  98. data/lib/concurrent/thread_safe/util/cheap_lockable.rb +118 -0
  99. data/lib/concurrent/thread_safe/util/power_of_two_tuple.rb +38 -0
  100. data/lib/concurrent/thread_safe/util/striped64.rb +241 -0
  101. data/lib/concurrent/thread_safe/util/volatile.rb +75 -0
  102. data/lib/concurrent/thread_safe/util/xor_shift_random.rb +50 -0
  103. data/lib/concurrent/timer_task.rb +3 -4
  104. data/lib/concurrent/tuple.rb +86 -0
  105. data/lib/concurrent/tvar.rb +5 -1
  106. data/lib/concurrent/utility/at_exit.rb +1 -1
  107. data/lib/concurrent/utility/engine.rb +4 -0
  108. data/lib/concurrent/utility/monotonic_time.rb +3 -4
  109. data/lib/concurrent/utility/native_extension_loader.rb +50 -30
  110. data/lib/concurrent/version.rb +2 -2
  111. data/lib/concurrent_ruby_ext.jar +0 -0
  112. metadata +47 -12
  113. data/lib/concurrent/atomic/condition.rb +0 -78
  114. data/lib/concurrent/collection/priority_queue.rb +0 -360
  115. data/lib/concurrent/synchronization/java_object.rb +0 -34
  116. data/lib/concurrent/synchronization/monitor_object.rb +0 -27
  117. data/lib/concurrent/synchronization/mutex_object.rb +0 -43
  118. data/lib/concurrent/utilities.rb +0 -5
  119. data/lib/concurrent/utility/timeout.rb +0 -39
  120. data/lib/concurrent/utility/timer.rb +0 -26
  121. data/lib/concurrent_ruby.rb +0 -2
@@ -1,12 +1,16 @@
1
1
  require 'set'
2
+ require 'concurrent/synchronization'
2
3
 
3
4
  module Concurrent
4
5
 
5
6
  # A `TVar` is a transactional variable - a single-element container that
6
7
  # is used as part of a transaction - see `Concurrent::atomically`.
7
8
  #
9
+ # @!macro thread_safe_variable_comparison
10
+ #
8
11
  # {include:file:doc/tvar.md}
9
- class TVar
12
+ class TVar < Synchronization::Object
13
+ safe_initialization!
10
14
 
11
15
  # Create a new `TVar` with an initial value.
12
16
  def initialize(value)
@@ -7,7 +7,7 @@ module Concurrent
7
7
  # Each handler is executed at most once.
8
8
  #
9
9
  # @!visibility private
10
- class AtExitImplementation < Synchronization::Object
10
+ class AtExitImplementation < Synchronization::LockableObject
11
11
  include Logger::Severity
12
12
 
13
13
  def initialize(*args)
@@ -19,6 +19,10 @@ module Concurrent
19
19
  ruby_engine == 'rbx'
20
20
  end
21
21
 
22
+ def on_truffle?
23
+ ruby_engine == 'jruby+truffle'
24
+ end
25
+
22
26
  def on_windows?
23
27
  !(RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/).nil?
24
28
  end
@@ -2,11 +2,10 @@ require 'concurrent/synchronization'
2
2
 
3
3
  module Concurrent
4
4
 
5
- class_definition = Class.new(Synchronization::Object) do
5
+ class_definition = Class.new(Synchronization::LockableObject) do
6
6
  def initialize
7
- super()
8
7
  @last_time = Time.now.to_f
9
- ensure_ivar_visibility!
8
+ super()
10
9
  end
11
10
 
12
11
  if defined?(Process::CLOCK_MONOTONIC)
@@ -44,7 +43,7 @@ module Concurrent
44
43
  private_constant :GLOBAL_MONOTONIC_CLOCK
45
44
 
46
45
  # @!macro [attach] monotonic_get_time
47
- #
46
+ #
48
47
  # Returns the current time a tracked by the application monotonic clock.
49
48
  #
50
49
  # @return [Float] The current monotonic time when `since` not given else
@@ -1,48 +1,67 @@
1
- require 'concurrent/synchronization/abstract_object' # for JRuby
2
1
  require 'concurrent/utility/engine'
3
2
 
4
3
  module Concurrent
4
+
5
5
  module Utility
6
6
 
7
7
  # @!visibility private
8
8
  module NativeExtensionLoader
9
9
 
10
- @c_ext_loaded ||= false
11
- @java_ext_loaded ||= false
12
-
13
- # @!visibility private
14
10
  def allow_c_extensions?
15
11
  Concurrent.on_cruby?
16
12
  end
17
13
 
18
- if Concurrent.on_cruby? && !@c_ext_loaded
19
- tries = [
20
- lambda do
21
- require 'concurrent/extension'
22
- @c_ext_loaded = true
23
- end,
24
- lambda do
25
- # may be a Windows cross-compiled native gem
26
- require "concurrent/#{RUBY_VERSION[0..2]}/extension"
27
- @c_ext_loaded = true
28
- end]
29
-
30
- tries.each do |try|
31
- begin
32
- try.call
33
- break
34
- rescue LoadError
35
- next
14
+ def c_extensions_loaded?
15
+ @c_extensions_loaded ||= false
16
+ end
17
+
18
+ def java_extensions_loaded?
19
+ @java_extensions_loaded ||= false
20
+ end
21
+
22
+ def set_c_extensions_loaded
23
+ @c_extensions_loaded = true
24
+ end
25
+
26
+ def set_java_extensions_loaded
27
+ @java_extensions_loaded = true
28
+ end
29
+
30
+ def load_native_extensions
31
+ unless defined? Synchronization::AbstractObject
32
+ raise 'native_extension_loader loaded before Synchronization::AbstractObject'
33
+ end
34
+
35
+ if Concurrent.on_cruby? && !c_extensions_loaded?
36
+ tries = [
37
+ lambda do
38
+ require 'concurrent/extension'
39
+ set_c_extensions_loaded
40
+ end,
41
+ lambda do
42
+ # may be a Windows cross-compiled native gem
43
+ require "concurrent/#{RUBY_VERSION[0..2]}/extension"
44
+ set_c_extensions_loaded
45
+ end]
46
+
47
+ tries.each do |try|
48
+ begin
49
+ try.call
50
+ break
51
+ rescue LoadError
52
+ next
53
+ end
36
54
  end
37
55
  end
38
- end
39
56
 
40
- if Concurrent.on_jruby? && !@java_ext_loaded
41
- begin
42
- require 'concurrent_ruby_ext'
43
- @java_ext_loaded = true
44
- rescue LoadError
45
- # move on with pure-Ruby implementations
57
+ if Concurrent.on_jruby? && !java_extensions_loaded?
58
+ begin
59
+ require 'concurrent_ruby_ext'
60
+ set_java_extensions_loaded
61
+ rescue LoadError
62
+ # move on with pure-Ruby implementations
63
+ raise 'On JRuby but Java extensions failed to load.'
64
+ end
46
65
  end
47
66
  end
48
67
  end
@@ -51,3 +70,4 @@ module Concurrent
51
70
  # @!visibility private
52
71
  extend Utility::NativeExtensionLoader
53
72
  end
73
+
@@ -1,4 +1,4 @@
1
1
  module Concurrent
2
- VERSION = '0.9.2'
3
- EDGE_VERSION = '0.1.2'
2
+ VERSION = '1.0.0'
3
+ EDGE_VERSION = '0.2.0'
4
4
  end
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concurrent-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 1.0.0
5
5
  platform: java
6
6
  authors:
7
7
  - Jerry D'Antonio
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-11-04 00:00:00.000000000 Z
12
+ date: 2015-11-13 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: |
15
15
  Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.
@@ -28,21 +28,31 @@ files:
28
28
  - LICENSE.txt
29
29
  - README.md
30
30
  - lib/concurrent.rb
31
+ - lib/concurrent/agent.rb
32
+ - lib/concurrent/array.rb
31
33
  - lib/concurrent/async.rb
32
34
  - lib/concurrent/atom.rb
35
+ - lib/concurrent/atomic/abstract_thread_local_var.rb
33
36
  - lib/concurrent/atomic/atomic_boolean.rb
34
37
  - lib/concurrent/atomic/atomic_fixnum.rb
35
38
  - lib/concurrent/atomic/atomic_reference.rb
36
- - lib/concurrent/atomic/condition.rb
37
39
  - lib/concurrent/atomic/count_down_latch.rb
38
40
  - lib/concurrent/atomic/cyclic_barrier.rb
39
41
  - lib/concurrent/atomic/event.rb
42
+ - lib/concurrent/atomic/java_count_down_latch.rb
43
+ - lib/concurrent/atomic/java_thread_local_var.rb
44
+ - lib/concurrent/atomic/mutex_atomic_boolean.rb
45
+ - lib/concurrent/atomic/mutex_atomic_fixnum.rb
46
+ - lib/concurrent/atomic/mutex_count_down_latch.rb
47
+ - lib/concurrent/atomic/mutex_semaphore.rb
40
48
  - lib/concurrent/atomic/read_write_lock.rb
41
49
  - lib/concurrent/atomic/reentrant_read_write_lock.rb
50
+ - lib/concurrent/atomic/ruby_thread_local_var.rb
42
51
  - lib/concurrent/atomic/semaphore.rb
43
52
  - lib/concurrent/atomic/thread_local_var.rb
44
53
  - lib/concurrent/atomic_reference/concurrent_update_error.rb
45
54
  - lib/concurrent/atomic_reference/direct_update.rb
55
+ - lib/concurrent/atomic_reference/jruby+truffle.rb
46
56
  - lib/concurrent/atomic_reference/jruby.rb
47
57
  - lib/concurrent/atomic_reference/mutex_atomic.rb
48
58
  - lib/concurrent/atomic_reference/numeric_cas_wrapper.rb
@@ -51,67 +61,92 @@ files:
51
61
  - lib/concurrent/atomics.rb
52
62
  - lib/concurrent/collection/copy_on_notify_observer_set.rb
53
63
  - lib/concurrent/collection/copy_on_write_observer_set.rb
54
- - lib/concurrent/collection/priority_queue.rb
64
+ - lib/concurrent/collection/java_non_concurrent_priority_queue.rb
65
+ - lib/concurrent/collection/map/atomic_reference_map_backend.rb
66
+ - lib/concurrent/collection/map/mri_map_backend.rb
67
+ - lib/concurrent/collection/map/non_concurrent_map_backend.rb
68
+ - lib/concurrent/collection/map/synchronized_map_backend.rb
69
+ - lib/concurrent/collection/non_concurrent_priority_queue.rb
70
+ - lib/concurrent/collection/ruby_non_concurrent_priority_queue.rb
55
71
  - lib/concurrent/concern/deprecation.rb
56
72
  - lib/concurrent/concern/dereferenceable.rb
57
73
  - lib/concurrent/concern/logging.rb
58
74
  - lib/concurrent/concern/obligation.rb
59
75
  - lib/concurrent/concern/observable.rb
60
76
  - lib/concurrent/configuration.rb
77
+ - lib/concurrent/constants.rb
61
78
  - lib/concurrent/dataflow.rb
62
79
  - lib/concurrent/delay.rb
63
80
  - lib/concurrent/edge.rb
64
81
  - lib/concurrent/errors.rb
65
82
  - lib/concurrent/exchanger.rb
83
+ - lib/concurrent/executor/abstract_executor_service.rb
66
84
  - lib/concurrent/executor/cached_thread_pool.rb
67
- - lib/concurrent/executor/executor.rb
68
85
  - lib/concurrent/executor/executor_service.rb
69
86
  - lib/concurrent/executor/fixed_thread_pool.rb
70
87
  - lib/concurrent/executor/immediate_executor.rb
71
88
  - lib/concurrent/executor/indirect_immediate_executor.rb
89
+ - lib/concurrent/executor/java_executor_service.rb
72
90
  - lib/concurrent/executor/java_single_thread_executor.rb
73
91
  - lib/concurrent/executor/java_thread_pool_executor.rb
92
+ - lib/concurrent/executor/ruby_executor_service.rb
74
93
  - lib/concurrent/executor/ruby_single_thread_executor.rb
75
94
  - lib/concurrent/executor/ruby_thread_pool_executor.rb
76
95
  - lib/concurrent/executor/safe_task_executor.rb
96
+ - lib/concurrent/executor/serial_executor_service.rb
77
97
  - lib/concurrent/executor/serialized_execution.rb
98
+ - lib/concurrent/executor/serialized_execution_delegator.rb
78
99
  - lib/concurrent/executor/simple_executor_service.rb
79
100
  - lib/concurrent/executor/single_thread_executor.rb
80
101
  - lib/concurrent/executor/thread_pool_executor.rb
81
102
  - lib/concurrent/executor/timer_set.rb
82
103
  - lib/concurrent/executors.rb
83
104
  - lib/concurrent/future.rb
105
+ - lib/concurrent/hash.rb
84
106
  - lib/concurrent/immutable_struct.rb
85
107
  - lib/concurrent/ivar.rb
86
108
  - lib/concurrent/lazy_register.rb
109
+ - lib/concurrent/map.rb
87
110
  - lib/concurrent/maybe.rb
88
111
  - lib/concurrent/mutable_struct.rb
89
112
  - lib/concurrent/mvar.rb
113
+ - lib/concurrent/options.rb
90
114
  - lib/concurrent/promise.rb
91
115
  - lib/concurrent/scheduled_task.rb
92
116
  - lib/concurrent/settable_struct.rb
93
117
  - lib/concurrent/synchronization.rb
118
+ - lib/concurrent/synchronization/abstract_lockable_object.rb
94
119
  - lib/concurrent/synchronization/abstract_object.rb
95
120
  - lib/concurrent/synchronization/abstract_struct.rb
96
121
  - lib/concurrent/synchronization/condition.rb
97
- - lib/concurrent/synchronization/java_object.rb
122
+ - lib/concurrent/synchronization/jruby_lockable_object.rb
123
+ - lib/concurrent/synchronization/jruby_object.rb
98
124
  - lib/concurrent/synchronization/lock.rb
99
- - lib/concurrent/synchronization/monitor_object.rb
100
- - lib/concurrent/synchronization/mutex_object.rb
125
+ - lib/concurrent/synchronization/lockable_object.rb
126
+ - lib/concurrent/synchronization/mri_lockable_object.rb
127
+ - lib/concurrent/synchronization/mri_object.rb
101
128
  - lib/concurrent/synchronization/object.rb
129
+ - lib/concurrent/synchronization/rbx_lockable_object.rb
102
130
  - lib/concurrent/synchronization/rbx_object.rb
131
+ - lib/concurrent/synchronization/volatile.rb
132
+ - lib/concurrent/thread_safe/synchronized_delegator.rb
133
+ - lib/concurrent/thread_safe/util.rb
134
+ - lib/concurrent/thread_safe/util/adder.rb
135
+ - lib/concurrent/thread_safe/util/array_hash_rbx.rb
136
+ - lib/concurrent/thread_safe/util/cheap_lockable.rb
137
+ - lib/concurrent/thread_safe/util/power_of_two_tuple.rb
138
+ - lib/concurrent/thread_safe/util/striped64.rb
139
+ - lib/concurrent/thread_safe/util/volatile.rb
140
+ - lib/concurrent/thread_safe/util/xor_shift_random.rb
103
141
  - lib/concurrent/timer_task.rb
142
+ - lib/concurrent/tuple.rb
104
143
  - lib/concurrent/tvar.rb
105
- - lib/concurrent/utilities.rb
106
144
  - lib/concurrent/utility/at_exit.rb
107
145
  - lib/concurrent/utility/engine.rb
108
146
  - lib/concurrent/utility/monotonic_time.rb
109
147
  - lib/concurrent/utility/native_extension_loader.rb
110
148
  - lib/concurrent/utility/processor_counter.rb
111
- - lib/concurrent/utility/timeout.rb
112
- - lib/concurrent/utility/timer.rb
113
149
  - lib/concurrent/version.rb
114
- - lib/concurrent_ruby.rb
115
150
  - lib/concurrent_ruby_ext.jar
116
151
  homepage: http://www.concurrent-ruby.com
117
152
  licenses:
@@ -1,78 +0,0 @@
1
- require 'concurrent/utility/monotonic_time'
2
- require 'concurrent/concern/deprecation'
3
-
4
- module Concurrent
5
-
6
- # Condition is a better implementation of standard Ruby ConditionVariable. The
7
- # biggest difference is the wait return value: Condition#wait returns
8
- # Condition::Result which make possible to know if waiting thread has been
9
- # woken up by an another thread (using #signal or #broadcast) or due to
10
- # timeout.
11
- #
12
- # Every #wait must be guarded by a locked Mutex or a ThreadError will be
13
- # risen. Although it's not mandatory, it's recommended to call also #signal
14
- # and #broadcast within the same mutex
15
- #
16
- # @deprecated
17
- class Condition
18
- include Concern::Deprecation
19
-
20
- class Result
21
- def initialize(remaining_time)
22
- @remaining_time = remaining_time
23
- end
24
-
25
- attr_reader :remaining_time
26
-
27
- # @return [Boolean] true if current thread has been waken up by a #signal
28
- # or a #broadcast call , otherwise false
29
- def woken_up?
30
- @remaining_time.nil? || @remaining_time > 0
31
- end
32
-
33
- # @return [Boolean] true if current thread has been waken up due to a
34
- # timeout, otherwise false
35
- def timed_out?
36
- @remaining_time != nil && @remaining_time <= 0
37
- end
38
-
39
- alias_method :can_wait?, :woken_up?
40
-
41
- end
42
-
43
- def initialize
44
- deprecated 'Will be replaced with Synchronization::Object in v1.0.'
45
- @condition = ConditionVariable.new
46
- end
47
-
48
- # @param [Mutex] mutex the locked mutex guarding the wait
49
- # @param [Object] timeout nil means no timeout
50
- # @return [Result]
51
- #
52
- # @!macro monotonic_clock_warning
53
- def wait(mutex, timeout = nil)
54
- start_time = Concurrent.monotonic_time
55
- @condition.wait(mutex, timeout)
56
-
57
- if timeout.nil?
58
- Result.new(nil)
59
- else
60
- Result.new(start_time + timeout - Concurrent.monotonic_time)
61
- end
62
- end
63
-
64
- # Wakes up a waiting thread
65
- # @return [true]
66
- def signal
67
- @condition.signal
68
- true
69
- end
70
-
71
- # Wakes up all waiting threads
72
- # @return [true]
73
- def broadcast
74
- @condition.broadcast
75
- true
76
- end
77
- end
78
- end
@@ -1,360 +0,0 @@
1
- module Concurrent
2
- module Collection
3
-
4
- # @!macro [attach] priority_queue
5
- #
6
- # A queue collection in which the elements are sorted based on their
7
- # comparison (spaceship) operator `<=>`. Items are added to the queue
8
- # at a position relative to their priority. On removal the element
9
- # with the "highest" priority is removed. By default the sort order is
10
- # from highest to lowest, but a lowest-to-highest sort order can be
11
- # set on construction.
12
- #
13
- # The API is based on the `Queue` class from the Ruby standard library.
14
- #
15
- # The pure Ruby implementation, `MutexPriorityQueue` uses a heap algorithm
16
- # stored in an array. The algorithm is based on the work of Robert Sedgewick
17
- # and Kevin Wayne.
18
- #
19
- # The JRuby native implementation is a thin wrapper around the standard
20
- # library `java.util.PriorityQueue`.
21
- #
22
- # When running under JRuby the class `PriorityQueue` extends `JavaPriorityQueue`.
23
- # When running under all other interpreters it extends `MutexPriorityQueue`.
24
- #
25
- # @note This implementation is *not* thread safe.
26
- #
27
- # @see http://en.wikipedia.org/wiki/Priority_queue
28
- # @see http://ruby-doc.org/stdlib-2.0.0/libdoc/thread/rdoc/Queue.html
29
- #
30
- # @see http://algs4.cs.princeton.edu/24pq/index.php#2.6
31
- # @see http://algs4.cs.princeton.edu/24pq/MaxPQ.java.html
32
- #
33
- # @see http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html
34
- #
35
- # @!visibility private
36
- # @!macro internal_implementation_note
37
- class MutexPriorityQueue
38
-
39
- # @!macro [attach] priority_queue_method_initialize
40
- #
41
- # Create a new priority queue with no items.
42
- #
43
- # @param [Hash] opts the options for creating the queue
44
- # @option opts [Symbol] :order (:max) dictates the order in which items are
45
- # stored: from highest to lowest when `:max` or `:high`; from lowest to
46
- # highest when `:min` or `:low`
47
- def initialize(opts = {})
48
- order = opts.fetch(:order, :max)
49
- @comparator = [:min, :low].include?(order) ? -1 : 1
50
- clear
51
- end
52
-
53
- # @!macro [attach] priority_queue_method_clear
54
- #
55
- # Removes all of the elements from this priority queue.
56
- def clear
57
- @queue = [nil]
58
- @length = 0
59
- true
60
- end
61
-
62
- # @!macro [attach] priority_queue_method_delete
63
- #
64
- # Deletes all items from `self` that are equal to `item`.
65
- #
66
- # @param [Object] item the item to be removed from the queue
67
- # @return [Object] true if the item is found else false
68
- def delete(item)
69
- original_length = @length
70
- k = 1
71
- while k <= @length
72
- if @queue[k] == item
73
- swap(k, @length)
74
- @length -= 1
75
- sink(k)
76
- @queue.pop
77
- else
78
- k += 1
79
- end
80
- end
81
- @length != original_length
82
- end
83
-
84
- # @!macro [attach] priority_queue_method_empty
85
- #
86
- # Returns `true` if `self` contains no elements.
87
- #
88
- # @return [Boolean] true if there are no items in the queue else false
89
- def empty?
90
- size == 0
91
- end
92
-
93
- # @!macro [attach] priority_queue_method_include
94
- #
95
- # Returns `true` if the given item is present in `self` (that is, if any
96
- # element == `item`), otherwise returns false.
97
- #
98
- # @param [Object] item the item to search for
99
- #
100
- # @return [Boolean] true if the item is found else false
101
- def include?(item)
102
- @queue.include?(item)
103
- end
104
- alias_method :has_priority?, :include?
105
-
106
- # @!macro [attach] priority_queue_method_length
107
- #
108
- # The current length of the queue.
109
- #
110
- # @return [Fixnum] the number of items in the queue
111
- def length
112
- @length
113
- end
114
- alias_method :size, :length
115
-
116
- # @!macro [attach] priority_queue_method_peek
117
- #
118
- # Retrieves, but does not remove, the head of this queue, or returns `nil`
119
- # if this queue is empty.
120
- #
121
- # @return [Object] the head of the queue or `nil` when empty
122
- def peek
123
- @queue[1]
124
- end
125
-
126
- # @!macro [attach] priority_queue_method_pop
127
- #
128
- # Retrieves and removes the head of this queue, or returns `nil` if this
129
- # queue is empty.
130
- #
131
- # @return [Object] the head of the queue or `nil` when empty
132
- def pop
133
- max = @queue[1]
134
- swap(1, @length)
135
- @length -= 1
136
- sink(1)
137
- @queue.pop
138
- max
139
- end
140
- alias_method :deq, :pop
141
- alias_method :shift, :pop
142
-
143
- # @!macro [attach] priority_queue_method_push
144
- #
145
- # Inserts the specified element into this priority queue.
146
- #
147
- # @param [Object] item the item to insert onto the queue
148
- def push(item)
149
- @length += 1
150
- @queue << item
151
- swim(@length)
152
- true
153
- end
154
- alias_method :<<, :push
155
- alias_method :enq, :push
156
-
157
- # @!macro [attach] priority_queue_method_from_list
158
- #
159
- # Create a new priority queue from the given list.
160
- #
161
- # @param [Enumerable] list the list to build the queue from
162
- # @param [Hash] opts the options for creating the queue
163
- #
164
- # @return [PriorityQueue] the newly created and populated queue
165
- def self.from_list(list, opts = {})
166
- queue = new(opts)
167
- list.each{|item| queue << item }
168
- queue
169
- end
170
-
171
- protected
172
-
173
- # Exchange the values at the given indexes within the internal array.
174
- #
175
- # @param [Integer] x the first index to swap
176
- # @param [Integer] y the second index to swap
177
- #
178
- # @!visibility private
179
- def swap(x, y)
180
- temp = @queue[x]
181
- @queue[x] = @queue[y]
182
- @queue[y] = temp
183
- end
184
-
185
- # Are the items at the given indexes ordered based on the priority
186
- # order specified at construction?
187
- #
188
- # @param [Integer] x the first index from which to retrieve a comparable value
189
- # @param [Integer] y the second index from which to retrieve a comparable value
190
- #
191
- # @return [Boolean] true if the two elements are in the correct priority order
192
- # else false
193
- #
194
- # @!visibility private
195
- def ordered?(x, y)
196
- (@queue[x] <=> @queue[y]) == @comparator
197
- end
198
-
199
- # Percolate down to maintain heap invariant.
200
- #
201
- # @param [Integer] k the index at which to start the percolation
202
- #
203
- # @!visibility private
204
- def sink(k)
205
- while (j = (2 * k)) <= @length do
206
- j += 1 if j < @length && ! ordered?(j, j+1)
207
- break if ordered?(k, j)
208
- swap(k, j)
209
- k = j
210
- end
211
- end
212
-
213
- # Percolate up to maintain heap invariant.
214
- #
215
- # @param [Integer] k the index at which to start the percolation
216
- #
217
- # @!visibility private
218
- def swim(k)
219
- while k > 1 && ! ordered?(k/2, k) do
220
- swap(k, k/2)
221
- k = k/2
222
- end
223
- end
224
- end
225
-
226
- if Concurrent.on_jruby?
227
-
228
- # @!macro priority_queue
229
- #
230
- # @!visibility private
231
- # @!macro internal_implementation_note
232
- class JavaPriorityQueue
233
-
234
- # @!macro priority_queue_method_initialize
235
- def initialize(opts = {})
236
- order = opts.fetch(:order, :max)
237
- if [:min, :low].include?(order)
238
- @queue = java.util.PriorityQueue.new(11) # 11 is the default initial capacity
239
- else
240
- @queue = java.util.PriorityQueue.new(11, java.util.Collections.reverseOrder())
241
- end
242
- end
243
-
244
- # @!macro priority_queue_method_clear
245
- def clear
246
- @queue.clear
247
- true
248
- end
249
-
250
- # @!macro priority_queue_method_delete
251
- def delete(item)
252
- found = false
253
- while @queue.remove(item) do
254
- found = true
255
- end
256
- found
257
- end
258
-
259
- # @!macro priority_queue_method_empty
260
- def empty?
261
- @queue.size == 0
262
- end
263
-
264
- # @!macro priority_queue_method_include
265
- def include?(item)
266
- @queue.contains(item)
267
- end
268
- alias_method :has_priority?, :include?
269
-
270
- # @!macro priority_queue_method_length
271
- def length
272
- @queue.size
273
- end
274
- alias_method :size, :length
275
-
276
- # @!macro priority_queue_method_peek
277
- def peek
278
- @queue.peek
279
- end
280
-
281
- # @!macro priority_queue_method_pop
282
- def pop
283
- @queue.poll
284
- end
285
- alias_method :deq, :pop
286
- alias_method :shift, :pop
287
-
288
- # @!macro priority_queue_method_push
289
- def push(item)
290
- @queue.add(item)
291
- end
292
- alias_method :<<, :push
293
- alias_method :enq, :push
294
-
295
- # @!macro priority_queue_method_from_list
296
- def self.from_list(list, opts = {})
297
- queue = new(opts)
298
- list.each{|item| queue << item }
299
- queue
300
- end
301
- end
302
- end
303
-
304
- # @!visibility private
305
- # @!macro internal_implementation_note
306
- PriorityQueueImplementation = case
307
- when Concurrent.on_jruby?
308
- JavaPriorityQueue
309
- else
310
- MutexPriorityQueue
311
- end
312
- private_constant :PriorityQueueImplementation
313
-
314
- # @!macro priority_queue
315
- #
316
- # @!visibility private
317
- class PriorityQueue < PriorityQueueImplementation
318
-
319
- alias_method :has_priority?, :include?
320
-
321
- alias_method :size, :length
322
-
323
- alias_method :deq, :pop
324
- alias_method :shift, :pop
325
-
326
- alias_method :<<, :push
327
- alias_method :enq, :push
328
-
329
- # @!method initialize(opts = {})
330
- # @!macro priority_queue_method_initialize
331
-
332
- # @!method clear
333
- # @!macro priority_queue_method_clear
334
-
335
- # @!method delete(item)
336
- # @!macro priority_queue_method_delete
337
-
338
- # @!method empty?
339
- # @!macro priority_queue_method_empty
340
-
341
- # @!method include?(item)
342
- # @!macro priority_queue_method_include
343
-
344
- # @!method length
345
- # @!macro priority_queue_method_length
346
-
347
- # @!method peek
348
- # @!macro priority_queue_method_peek
349
-
350
- # @!method pop
351
- # @!macro priority_queue_method_pop
352
-
353
- # @!method push(item)
354
- # @!macro priority_queue_method_push
355
-
356
- # @!method self.from_list(list, opts = {})
357
- # @!macro priority_queue_method_from_list
358
- end
359
- end
360
- end