Skip to content

Commit 2014056

Browse files
committed
Moved VolatileTuple to top level and renamed Tuple.
1 parent dbb75a1 commit 2014056

File tree

6 files changed

+92
-57
lines changed

6 files changed

+92
-57
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ Derived from Ruby's [Struct](http://ruby-doc.org/core-2.2.0/Struct.html):
9191
* [ImmutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/ImmutableStruct.html) Immutable struct where values are set at construction and cannot be changed later.
9292
* [MutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/MutableStruct.html) Synchronized, mutable struct where values can be safely changed at any time.
9393
* [SettableStruct](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/SettableStruct.html) Synchronized, write-once struct where values can be set at most once, either at construction or any time thereafter.
94+
* [Tuple](http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Tuple.html) A fixed size array with volatile (synchronized, thread safe) getters/setters.
9495

9596
#### Java-inspired ThreadPools and Other Executors
9697

lib/concurrent.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
require 'concurrent/scheduled_task'
2727
require 'concurrent/settable_struct'
2828
require 'concurrent/timer_task'
29+
require 'concurrent/tuple'
2930
require 'concurrent/tvar'
3031
require 'concurrent/volatile'
3132

lib/concurrent/thread_safe/util.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ module Util
1010
MAX_INT = (2 ** FIXNUM_BIT_SIZE) - 1
1111
CPU_COUNT = 16 # is there a way to determine this?
1212

13+
autoload :Tuple, 'concurrent/tuple'
1314
autoload :Volatile, 'concurrent/volatile'
1415
autoload :Adder, 'concurrent/thread_safe/util/adder'
1516
autoload :CheapLockable, 'concurrent/thread_safe/util/cheap_lockable'
1617
autoload :PowerOfTwoTuple, 'concurrent/thread_safe/util/power_of_two_tuple'
1718
autoload :Striped64, 'concurrent/thread_safe/util/striped64'
18-
autoload :VolatileTuple, 'concurrent/thread_safe/util/volatile_tuple'
1919
autoload :XorShiftRandom, 'concurrent/thread_safe/util/xor_shift_random'
2020
end
2121
end

lib/concurrent/thread_safe/util/power_of_two_tuple.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'concurrent/tuple'
2+
13
module Concurrent
24

35
# @!visibility private
@@ -7,7 +9,7 @@ module ThreadSafe
79
module Util
810

911
# @!visibility private
10-
class PowerOfTwoTuple < VolatileTuple
12+
class PowerOfTwoTuple < Concurrent::Tuple
1113

1214
def initialize(size)
1315
raise ArgumentError, "size must be a power of 2 (#{size.inspect} provided)" unless size > 0 && size & (size - 1) == 0

lib/concurrent/tuple.rb

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
require 'concurrent/atomic/atomic_reference'
2+
3+
module Concurrent
4+
5+
# A fixed size array with volatile (synchronized, thread safe) getters/setters.
6+
# Mixes in Ruby's `Enumerable` module for enhanced search, sort, and traversal.
7+
#
8+
# @example
9+
# tuple = Concurrent::Tuple.new(16)
10+
#
11+
# tuple.set(0, :foo) #=> :foo | volatile write
12+
# tuple.get(0) #=> :foo | volatile read
13+
# tuple.compare_and_set(0, :foo, :bar) #=> true | strong CAS
14+
# tuple.cas(0, :foo, :baz) #=> false | strong CAS
15+
# tuple.get(0) #=> :bar | volatile read
16+
#
17+
# @see https://en.wikipedia.org/wiki/Tuple Tuple entry at Wikipedia
18+
# @see http://www.erlang.org/doc/reference_manual/data_types.html#id70396 Erlang Tuple
19+
# @see http://ruby-doc.org/core-2.2.2/Enumerable.html Enumerable
20+
class Tuple
21+
include Enumerable
22+
23+
# The (fixed) size of the tuple.
24+
attr_reader :size
25+
26+
# @!visibility private
27+
Tuple = defined?(Rubinius::Tuple) ? Rubinius::Tuple : Array
28+
private_constant :Tuple
29+
30+
# Create a new tuple of the given size.
31+
#
32+
# @param [Integer] size the number of elements in the tuple
33+
def initialize(size)
34+
@size = size
35+
@tuple = tuple = Tuple.new(size)
36+
i = 0
37+
while i < size
38+
tuple[i] = Concurrent::AtomicReference.new
39+
i += 1
40+
end
41+
end
42+
43+
# Get the value of the element at the given index.
44+
#
45+
# @param [Integer] i the index from which to retrieve the value
46+
# @return [Object] the value at the given index or nil if the index is out of bounds
47+
def get(i)
48+
return nil if i >= @size || i < 0
49+
@tuple[i].get
50+
end
51+
alias_method :volatile_get, :get
52+
53+
# Set the element at the given index to the given value
54+
#
55+
# @param [Integer] i the index for the element to set
56+
# @param [Object] value the value to set at the given index
57+
#
58+
# @return [Object] the new value of the element at the given index or nil if the index is out of bounds
59+
def set(i, value)
60+
return nil if i >= @size || i < 0
61+
@tuple[i].set(value)
62+
end
63+
alias_method :volatile_set, :set
64+
65+
# Set the value at the given index to the new value if and only if the current
66+
# value matches the given old value.
67+
#
68+
# @param [Integer] i the index for the element to set
69+
# @param [Object] old_value the value to compare against the current value
70+
# @param [Object] new_value the value to set at the given index
71+
#
72+
# @return [Boolean] true if the value at the given element was set else false
73+
def compare_and_set(i, old_value, new_value)
74+
return false if i >= @size || i < 0
75+
@tuple[i].compare_and_set(old_value, new_value)
76+
end
77+
alias_method :cas, :compare_and_set
78+
79+
# Calls the given block once for each element in self, passing that element as a parameter.
80+
#
81+
# @yieldparam [Object] ref the `Concurrent::AtomicReference` object at the current index
82+
def each
83+
@tuple.each {|ref| yield ref.get}
84+
end
85+
end
86+
end

lib/concurrent/volatile_tuple.rb

Lines changed: 0 additions & 55 deletions
This file was deleted.

0 commit comments

Comments
 (0)