concurrent-ruby 0.9.2 → 1.0.0.pre1

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -1
  3. data/README.md +67 -68
  4. data/lib/concurrent.rb +14 -1
  5. data/lib/concurrent/array.rb +38 -0
  6. data/lib/concurrent/async.rb +0 -17
  7. data/lib/concurrent/atomic/abstract_thread_local_var.rb +40 -0
  8. data/lib/concurrent/atomic/atomic_boolean.rb +81 -118
  9. data/lib/concurrent/atomic/atomic_fixnum.rb +98 -162
  10. data/lib/concurrent/atomic/atomic_reference.rb +0 -7
  11. data/lib/concurrent/atomic/count_down_latch.rb +62 -103
  12. data/lib/concurrent/atomic/cyclic_barrier.rb +2 -0
  13. data/lib/concurrent/atomic/java_count_down_latch.rb +39 -0
  14. data/lib/concurrent/atomic/java_thread_local_var.rb +50 -0
  15. data/lib/concurrent/atomic/mutex_atomic_boolean.rb +60 -0
  16. data/lib/concurrent/atomic/mutex_atomic_fixnum.rb +91 -0
  17. data/lib/concurrent/atomic/mutex_count_down_latch.rb +43 -0
  18. data/lib/concurrent/atomic/mutex_semaphore.rb +115 -0
  19. data/lib/concurrent/atomic/ruby_thread_local_var.rb +172 -0
  20. data/lib/concurrent/atomic/semaphore.rb +84 -178
  21. data/lib/concurrent/atomic/thread_local_var.rb +63 -294
  22. data/lib/concurrent/atomic_reference/mutex_atomic.rb +14 -8
  23. data/lib/concurrent/atomics.rb +0 -33
  24. data/lib/concurrent/collection/java_non_concurrent_priority_queue.rb +84 -0
  25. data/lib/concurrent/collection/map/atomic_reference_map_backend.rb +921 -0
  26. data/lib/concurrent/collection/map/mri_map_backend.rb +66 -0
  27. data/lib/concurrent/collection/map/non_concurrent_map_backend.rb +142 -0
  28. data/lib/concurrent/collection/map/synchronized_map_backend.rb +86 -0
  29. data/lib/concurrent/collection/non_concurrent_priority_queue.rb +143 -0
  30. data/lib/concurrent/collection/ruby_non_concurrent_priority_queue.rb +150 -0
  31. data/lib/concurrent/concern/logging.rb +1 -1
  32. data/lib/concurrent/concern/obligation.rb +0 -12
  33. data/lib/concurrent/configuration.rb +18 -148
  34. data/lib/concurrent/delay.rb +5 -4
  35. data/lib/concurrent/exchanger.rb +327 -41
  36. data/lib/concurrent/executor/abstract_executor_service.rb +134 -0
  37. data/lib/concurrent/executor/executor.rb +4 -29
  38. data/lib/concurrent/executor/executor_service.rb +23 -359
  39. data/lib/concurrent/executor/immediate_executor.rb +3 -2
  40. data/lib/concurrent/executor/java_executor_service.rb +100 -0
  41. data/lib/concurrent/executor/java_single_thread_executor.rb +3 -2
  42. data/lib/concurrent/executor/java_thread_pool_executor.rb +3 -4
  43. data/lib/concurrent/executor/ruby_executor_service.rb +72 -0
  44. data/lib/concurrent/executor/ruby_single_thread_executor.rb +7 -5
  45. data/lib/concurrent/executor/ruby_thread_pool_executor.rb +3 -11
  46. data/lib/concurrent/executor/safe_task_executor.rb +1 -1
  47. data/lib/concurrent/executor/serial_executor_service.rb +34 -0
  48. data/lib/concurrent/executor/serialized_execution.rb +8 -31
  49. data/lib/concurrent/executor/serialized_execution_delegator.rb +28 -0
  50. data/lib/concurrent/executor/simple_executor_service.rb +1 -10
  51. data/lib/concurrent/executor/timer_set.rb +4 -8
  52. data/lib/concurrent/executors.rb +13 -2
  53. data/lib/concurrent/future.rb +2 -2
  54. data/lib/concurrent/hash.rb +35 -0
  55. data/lib/concurrent/ivar.rb +9 -14
  56. data/lib/concurrent/map.rb +178 -0
  57. data/lib/concurrent/promise.rb +2 -2
  58. data/lib/concurrent/scheduled_task.rb +9 -69
  59. data/lib/concurrent/thread_safe/synchronized_delegator.rb +50 -0
  60. data/lib/concurrent/thread_safe/util.rb +23 -0
  61. data/lib/concurrent/thread_safe/util/adder.rb +71 -0
  62. data/lib/concurrent/thread_safe/util/array_hash_rbx.rb +28 -0
  63. data/lib/concurrent/thread_safe/util/cheap_lockable.rb +115 -0
  64. data/lib/concurrent/thread_safe/util/power_of_two_tuple.rb +37 -0
  65. data/lib/concurrent/thread_safe/util/striped64.rb +236 -0
  66. data/lib/concurrent/thread_safe/util/volatile.rb +73 -0
  67. data/lib/concurrent/thread_safe/util/xor_shift_random.rb +48 -0
  68. data/lib/concurrent/timer_task.rb +3 -3
  69. data/lib/concurrent/tuple.rb +86 -0
  70. data/lib/concurrent/version.rb +2 -2
  71. metadata +37 -10
  72. data/lib/concurrent/atomic/condition.rb +0 -78
  73. data/lib/concurrent/collection/priority_queue.rb +0 -360
  74. data/lib/concurrent/utilities.rb +0 -5
  75. data/lib/concurrent/utility/timeout.rb +0 -39
  76. data/lib/concurrent/utility/timer.rb +0 -26
  77. data/lib/concurrent_ruby.rb +0 -2
@@ -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
@@ -1,5 +0,0 @@
1
- # DEPRECATED Remove this file at v1.0
2
- require 'concurrent/utility/monotonic_time'
3
- require 'concurrent/utility/processor_counter'
4
- require 'concurrent/utility/timeout'
5
- require 'concurrent/utility/timer'
@@ -1,39 +0,0 @@
1
- require 'rbconfig'
2
- require 'thread'
3
-
4
- require 'concurrent/errors'
5
- require 'concurrent/concern/deprecation'
6
-
7
- module Concurrent
8
- extend Concern::Deprecation
9
-
10
- # [DEPRECATED] Wait the given number of seconds for the block operation to complete.
11
- # Intended to be a simpler and more reliable replacement to the Ruby
12
- # standard library `Timeout::timeout` method. It does not kill the task
13
- # so it finishes anyway. Advantage is that it cannot cause any ugly errors by
14
- # killing threads.
15
- #
16
- # @param [Integer] seconds The number of seconds to wait
17
- # @return [Object] The result of the block operation
18
- #
19
- # @raise [Concurrent::TimeoutError] when the block operation does not complete
20
- # in the allotted number of seconds.
21
- #
22
- # @see http://ruby-doc.org/stdlib-2.2.0/libdoc/timeout/rdoc/Timeout.html Ruby Timeout::timeout
23
- #
24
- # @!macro monotonic_clock_warning
25
- #
26
- # @deprecated timeout is deprecated and will be removed
27
- def timeout(seconds, &block)
28
- deprecated 'timeout is deprecated and will be removed'
29
-
30
- future = Future.execute(&block)
31
- future.wait(seconds)
32
- if future.complete?
33
- future.value!
34
- else
35
- raise TimeoutError
36
- end
37
- end
38
- module_function :timeout
39
- end
@@ -1,26 +0,0 @@
1
- require 'concurrent/configuration'
2
- require 'concurrent/concern/deprecation'
3
-
4
- module Concurrent
5
- extend Concern::Deprecation
6
-
7
- # [DEPRECATED] Perform the given operation asynchronously after
8
- # the given number of seconds.
9
- #
10
- # @param [Fixnum] seconds the interval in seconds to wait before executing the task
11
- #
12
- # @yield the task to execute
13
- #
14
- # @return [Concurrent::ScheduledTask] IVar representing the task
15
- #
16
- # @see Concurrent::ScheduledTask
17
- #
18
- # @deprecated use `ScheduledTask` instead
19
- def timer(seconds, *args, &block)
20
- deprecated_method 'Concurrent.timer', 'ScheduledTask'
21
- raise ArgumentError.new('no block given') unless block_given?
22
- raise ArgumentError.new('interval must be greater than or equal to zero') if seconds < 0
23
- Concurrent.global_timer_set.post(seconds, *args, &block)
24
- end
25
- module_function :timer
26
- end
@@ -1,2 +0,0 @@
1
- warn "'[DEPRECATED] use `require 'concurrent'` instead of `require 'concurrent_ruby'`"
2
- require 'concurrent'