concurrent-ruby-edge 0.2.0.pre2 → 0.2.0.pre3
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.
- checksums.yaml +4 -4
- data/README.md +7 -5
- data/lib/concurrent/channel.rb +272 -6
- data/lib/concurrent/channel/buffer.rb +9 -0
- data/lib/concurrent/channel/buffer/base.rb +197 -0
- data/lib/concurrent/channel/buffer/buffered.rb +127 -0
- data/lib/concurrent/channel/buffer/dropping.rb +53 -0
- data/lib/concurrent/channel/buffer/sliding.rb +54 -0
- data/lib/concurrent/channel/buffer/ticker.rb +80 -0
- data/lib/concurrent/channel/buffer/timer.rb +78 -0
- data/lib/concurrent/channel/buffer/unbuffered.rb +151 -0
- data/lib/concurrent/channel/selector.rb +70 -0
- data/lib/concurrent/channel/selector/after_clause.rb +27 -0
- data/lib/concurrent/channel/selector/default_clause.rb +19 -0
- data/lib/concurrent/channel/selector/error_clause.rb +21 -0
- data/lib/concurrent/channel/selector/put_clause.rb +26 -0
- data/lib/concurrent/channel/selector/take_clause.rb +24 -0
- data/lib/concurrent/channel/tick.rb +55 -0
- data/lib/concurrent/edge/future.rb +23 -41
- data/lib/concurrent/edge/lock_free_linked_set.rb +2 -1
- metadata +20 -11
- data/lib/concurrent/channel/blocking_ring_buffer.rb +0 -82
- data/lib/concurrent/channel/buffered_channel.rb +0 -89
- data/lib/concurrent/channel/channel.rb +0 -19
- data/lib/concurrent/channel/ring_buffer.rb +0 -65
- data/lib/concurrent/channel/unbuffered_channel.rb +0 -39
- data/lib/concurrent/channel/waitable_list.rb +0 -48
@@ -1,89 +0,0 @@
|
|
1
|
-
require 'concurrent/synchronization'
|
2
|
-
require 'concurrent/channel/waitable_list'
|
3
|
-
|
4
|
-
module Concurrent
|
5
|
-
module Channel
|
6
|
-
|
7
|
-
# @api Channel
|
8
|
-
# @!macro edge_warning
|
9
|
-
class BufferedChannel < Synchronization::LockableObject
|
10
|
-
|
11
|
-
def initialize(size)
|
12
|
-
super()
|
13
|
-
synchronize { ns_initialize(size) }
|
14
|
-
end
|
15
|
-
|
16
|
-
def probe_set_size
|
17
|
-
@probe_set.size # TODO (pitr 12-Sep-2015): unsafe?
|
18
|
-
end
|
19
|
-
|
20
|
-
def buffer_queue_size
|
21
|
-
synchronize { @buffer.count }
|
22
|
-
end
|
23
|
-
|
24
|
-
def push(value)
|
25
|
-
until set_probe_or_ns_push_into_buffer(value)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def pop
|
30
|
-
probe = Channel::Probe.new
|
31
|
-
select(probe)
|
32
|
-
probe.value
|
33
|
-
end
|
34
|
-
|
35
|
-
def select(probe)
|
36
|
-
synchronize do
|
37
|
-
if @buffer.empty?
|
38
|
-
@probe_set.put(probe)
|
39
|
-
true
|
40
|
-
else
|
41
|
-
ns_shift_buffer if probe.try_set([ns_peek_buffer, self])
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def remove_probe(probe)
|
47
|
-
@probe_set.delete(probe)
|
48
|
-
end
|
49
|
-
|
50
|
-
protected
|
51
|
-
|
52
|
-
def ns_initialize(size)
|
53
|
-
@probe_set = WaitableList.new
|
54
|
-
@buffer = RingBuffer.new(size)
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def ns_push_into_buffer(value)
|
60
|
-
ns_wait while @buffer.full?
|
61
|
-
@buffer.offer value
|
62
|
-
ns_broadcast
|
63
|
-
end
|
64
|
-
|
65
|
-
def ns_peek_buffer
|
66
|
-
ns_wait while @buffer.empty?
|
67
|
-
@buffer.peek
|
68
|
-
end
|
69
|
-
|
70
|
-
def ns_shift_buffer
|
71
|
-
ns_wait while @buffer.empty?
|
72
|
-
result = @buffer.poll
|
73
|
-
ns_broadcast
|
74
|
-
result
|
75
|
-
end
|
76
|
-
|
77
|
-
def set_probe_or_ns_push_into_buffer(value)
|
78
|
-
synchronize do
|
79
|
-
if @probe_set.empty?
|
80
|
-
ns_push_into_buffer(value)
|
81
|
-
true
|
82
|
-
else
|
83
|
-
@probe_set.take.try_set([value, self])
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'concurrent/ivar'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
|
5
|
-
# @api Channel
|
6
|
-
# @!macro edge_warning
|
7
|
-
module Channel
|
8
|
-
|
9
|
-
Probe = IVar
|
10
|
-
|
11
|
-
def self.select(*channels)
|
12
|
-
probe = Probe.new
|
13
|
-
channels.each { |channel| channel.select(probe) }
|
14
|
-
result = probe.value
|
15
|
-
channels.each { |channel| channel.remove_probe(probe) }
|
16
|
-
result
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
module Concurrent
|
2
|
-
module Channel
|
3
|
-
|
4
|
-
# non-thread safe buffer
|
5
|
-
#
|
6
|
-
# @api Channel
|
7
|
-
# @!macro edge_warning
|
8
|
-
class RingBuffer
|
9
|
-
|
10
|
-
def initialize(capacity)
|
11
|
-
@buffer = ::Array.new(capacity)
|
12
|
-
@first = @last = 0
|
13
|
-
@count = 0
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
|
-
# @return [Integer] the capacity of the buffer
|
18
|
-
def capacity
|
19
|
-
@buffer.size
|
20
|
-
end
|
21
|
-
|
22
|
-
# @return [Integer] the number of elements currently in the buffer
|
23
|
-
def count
|
24
|
-
@count
|
25
|
-
end
|
26
|
-
|
27
|
-
# @return [Boolean] true if buffer is empty, false otherwise
|
28
|
-
def empty?
|
29
|
-
@count == 0
|
30
|
-
end
|
31
|
-
|
32
|
-
# @return [Boolean] true if buffer is full, false otherwise
|
33
|
-
def full?
|
34
|
-
@count == capacity
|
35
|
-
end
|
36
|
-
|
37
|
-
# @param [Object] value
|
38
|
-
# @return [Boolean] true if value has been inserted, false otherwise
|
39
|
-
def offer(value)
|
40
|
-
return false if full?
|
41
|
-
|
42
|
-
@buffer[@last] = value
|
43
|
-
@last = (@last + 1) % @buffer.size
|
44
|
-
@count += 1
|
45
|
-
true
|
46
|
-
end
|
47
|
-
|
48
|
-
# @return [Object] the first available value and removes it from the buffer. If buffer is empty returns nil
|
49
|
-
def poll
|
50
|
-
result = @buffer[@first]
|
51
|
-
@buffer[@first] = nil
|
52
|
-
@first = (@first + 1) % @buffer.size
|
53
|
-
@count -= 1
|
54
|
-
result
|
55
|
-
end
|
56
|
-
|
57
|
-
# @return [Object] the first available value and without removing it from
|
58
|
-
# the buffer. If buffer is empty returns nil
|
59
|
-
def peek
|
60
|
-
@buffer[@first]
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'concurrent/channel/waitable_list'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
module Channel
|
5
|
-
|
6
|
-
# @api Channel
|
7
|
-
# @!macro edge_warning
|
8
|
-
class UnbufferedChannel
|
9
|
-
|
10
|
-
def initialize
|
11
|
-
@probe_set = WaitableList.new
|
12
|
-
end
|
13
|
-
|
14
|
-
def probe_set_size
|
15
|
-
@probe_set.size
|
16
|
-
end
|
17
|
-
|
18
|
-
def push(value)
|
19
|
-
until @probe_set.take.try_set([value, self])
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def pop
|
24
|
-
probe = Channel::Probe.new
|
25
|
-
select(probe)
|
26
|
-
probe.value
|
27
|
-
end
|
28
|
-
|
29
|
-
def select(probe)
|
30
|
-
@probe_set.put(probe)
|
31
|
-
end
|
32
|
-
|
33
|
-
def remove_probe(probe)
|
34
|
-
@probe_set.delete(probe)
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require 'concurrent/synchronization'
|
2
|
-
|
3
|
-
module Concurrent
|
4
|
-
module Channel
|
5
|
-
|
6
|
-
# @api Channel
|
7
|
-
# @!macro edge_warning
|
8
|
-
class WaitableList < Synchronization::LockableObject
|
9
|
-
|
10
|
-
def initialize
|
11
|
-
super()
|
12
|
-
synchronize { ns_initialize }
|
13
|
-
end
|
14
|
-
|
15
|
-
def size
|
16
|
-
synchronize { @list.size }
|
17
|
-
end
|
18
|
-
|
19
|
-
def empty?
|
20
|
-
synchronize { @list.empty? }
|
21
|
-
end
|
22
|
-
|
23
|
-
def put(value)
|
24
|
-
synchronize do
|
25
|
-
@list << value
|
26
|
-
ns_signal
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def delete(value)
|
31
|
-
synchronize { @list.delete(value) }
|
32
|
-
end
|
33
|
-
|
34
|
-
def take
|
35
|
-
synchronize do
|
36
|
-
ns_wait_until { !@list.empty? }
|
37
|
-
@list.shift
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
protected
|
42
|
-
|
43
|
-
def ns_initialize
|
44
|
-
@list = []
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|