twitter-status-bot/.gems/gems/thread_safe-0.3.4/lib/thread_safe/util/adder.rb

60 lines
2.1 KiB
Ruby

module ThreadSafe
module Util
# A Ruby port of the Doug Lea's jsr166e.LondAdder class version 1.8 available in public domain.
# Original source code available here: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/LongAdder.java?revision=1.8
#
# One or more variables that together maintain an initially zero
# sum. When updates (method +add+) are contended across threads,
# the set of variables may grow dynamically to reduce contention.
# Method +sum+ returns the current total combined across the
# variables maintaining the sum.
#
# This class is usually preferable to single +Atomic+ reference when
# multiple threads update a common sum that is used for purposes such
# as collecting statistics, not for fine-grained synchronization
# control. Under low update contention, the two classes have similar
# characteristics. But under high contention, expected throughput of
# this class is significantly higher, at the expense of higher space
# consumption.
class Adder < Striped64
# Adds the given value.
def add(x)
if (current_cells = cells) || !cas_base_computed {|current_base| current_base + x}
was_uncontended = true
hash = hash_code
unless current_cells && (cell = current_cells.volatile_get_by_hash(hash)) && (was_uncontended = cell.cas_computed {|current_value| current_value + x})
retry_update(x, hash, was_uncontended) {|current_value| current_value + x}
end
end
end
def increment
add(1)
end
def decrement
add(-1)
end
# Returns the current sum. The returned value is _NOT_ an
# atomic snapshot: Invocation in the absence of concurrent
# updates returns an accurate result, but concurrent updates that
# occur while the sum is being calculated might not be
# incorporated.
def sum
x = base
if current_cells = cells
current_cells.each do |cell|
x += cell.value if cell
end
end
x
end
def reset
internal_reset(0)
end
end
end
end