openaustralia/morph

View on GitHub
sorbet/rbi/gems/thread_safe@0.3.6.rbi

Summary

Maintainability
Test Coverage
# typed: true

# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `thread_safe` gem.
# Please instead update this file by running `bin/tapioca gem thread_safe`.

# This class provides a trivial way to synchronize all calls to a given object
# by wrapping it with a `Delegator` that performs `Monitor#enter/exit` calls
# around the delegated `#send`. Example:
#
#   array = [] # not thread-safe on many impls
#   array = SynchronizedDelegator.new([]) # thread-safe
#
# A simple `Monitor` provides a very coarse-grained way to synchronize a given
# object, in that it will cause synchronization for methods that have no need
# for it, but this is a trivial way to get thread-safety where none may exist
# currently on some implementations.
#
# This class is currently being considered for inclusion into stdlib, via
# https://bugs.ruby-lang.org/issues/8556
#
# source://thread_safe-0.3.6/lib/thread_safe/synchronized_delegator.rb:18
class SynchronizedDelegator < ::SimpleDelegator
  # @return [SynchronizedDelegator] a new instance of SynchronizedDelegator
  #
  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_delegator.rb:28
  def initialize(obj); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_delegator.rb:33
  def method_missing(method, *args, &block); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_delegator.rb:19
  def setup; end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_delegator.rb:24
  def teardown; end
end

# source://thread_safe-0.3.6/lib/thread_safe/version.rb:1
module ThreadSafe; end

# A thread-safe subclass of Array. This version locks
# against the object itself for every method call,
# ensuring only one thread can be reading or writing
# at a time. This includes iteration methods like
# #each.
#
# source://thread_safe-0.3.6/lib/thread_safe.rb:34
ThreadSafe::Array = Array

# A Ruby port of the Doug Lea's jsr166e.ConcurrentHashMapV8 class version 1.59
# available in public domain.
#
# Original source code available here:
# http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/ConcurrentHashMapV8.java?revision=1.59
#
# The Ruby port skips out the +TreeBin+ (red-black trees for use in bins whose
# size exceeds a threshold).
#
# A hash table supporting full concurrency of retrievals and high expected
# concurrency for updates. However, even though all operations are
# thread-safe, retrieval operations do _not_ entail locking, and there is
# _not_ any support for locking the entire table in a way that prevents all
# access.
#
# Retrieval operations generally do not block, so may overlap with update
# operations. Retrievals reflect the results of the most recently _completed_
# update operations holding upon their onset. (More formally, an update
# operation for a given key bears a _happens-before_ relation with any (non
# +nil+) retrieval for that key reporting the updated value.) For aggregate
# operations such as +clear()+, concurrent retrievals may reflect insertion or
# removal of only some entries. Similarly, the +each_pair+ iterator yields
# elements reflecting the state of the hash table at some point at or since
# the start of the +each_pair+. Bear in mind that the results of aggregate
# status methods including +size()+ and +empty?+} are typically useful only
# when a map is not undergoing concurrent updates in other threads. Otherwise
# the results of these methods reflect transient states that may be adequate
# for monitoring or estimation purposes, but not for program control.
#
# The table is dynamically expanded when there are too many collisions (i.e.,
# keys that have distinct hash codes but fall into the same slot modulo the
# table size), with the expected average effect of maintaining roughly two
# bins per mapping (corresponding to a 0.75 load factor threshold for
# resizing). There may be much variance around this average as mappings are
# added and removed, but overall, this maintains a commonly accepted
# time/space tradeoff for hash tables. However, resizing this or any other
# kind of hash table may be a relatively slow operation. When possible, it is
# a good idea to provide a size estimate as an optional :initial_capacity
# initializer argument. An additional optional :load_factor constructor
# argument provides a further means of customizing initial table capacity by
# specifying the table density to be used in calculating the amount of space
# to allocate for the given number of elements. Note that using many keys with
# exactly the same +hash+ is a sure way to slow down performance of any hash
# table.
#
# ## Design overview
#
# The primary design goal of this hash table is to maintain concurrent
# readability (typically method +[]+, but also iteration and related methods)
# while minimizing update contention. Secondary goals are to keep space
# consumption about the same or better than plain +Hash+, and to support high
# initial insertion rates on an empty table by many threads.
#
# Each key-value mapping is held in a +Node+. The validation-based approach
# explained below leads to a lot of code sprawl because retry-control
# precludes factoring into smaller methods.
#
# The table is lazily initialized to a power-of-two size upon the first
# insertion. Each bin in the table normally contains a list of +Node+s (most
# often, the list has only zero or one +Node+). Table accesses require
# volatile/atomic reads, writes, and CASes. The lists of nodes within bins are
# always accurately traversable under volatile reads, so long as lookups check
# hash code and non-nullness of value before checking key equality.
#
# We use the top two bits of +Node+ hash fields for control purposes -- they
# are available anyway because of addressing constraints. As explained further
# below, these top bits are used as follows:
#
#   - 00 - Normal
#   - 01 - Locked
#   - 11 - Locked and may have a thread waiting for lock
#   - 10 - +Node+ is a forwarding node
#
# The lower 28 bits of each +Node+'s hash field contain a the key's hash code,
# except for forwarding nodes, for which the lower bits are zero (and so
# always have hash field == +MOVED+).
#
# Insertion (via +[]=+ or its variants) of the first node in an empty bin is
# performed by just CASing it to the bin. This is by far the most common case
# for put operations under most key/hash distributions. Other update
# operations (insert, delete, and replace) require locks. We do not want to
# waste the space required to associate a distinct lock object with each bin,
# so instead use the first node of a bin list itself as a lock. Blocking
# support for these locks relies +Util::CheapLockable. However, we also need a
# +try_lock+ construction, so we overlay these by using bits of the +Node+
# hash field for lock control (see above), and so normally use builtin
# monitors only for blocking and signalling using
# +cheap_wait+/+cheap_broadcast+ constructions. See +Node#try_await_lock+.
#
# Using the first node of a list as a lock does not by itself suffice though:
# When a node is locked, any update must first validate that it is still the
# first node after locking it, and retry if not. Because new nodes are always
# appended to lists, once a node is first in a bin, it remains first until
# deleted or the bin becomes invalidated (upon resizing). However, operations
# that only conditionally update may inspect nodes until the point of update.
# This is a converse of sorts to the lazy locking technique described by
# Herlihy & Shavit.
#
# The main disadvantage of per-bin locks is that other update operations on
# other nodes in a bin list protected by the same lock can stall, for example
# when user +eql?+ or mapping functions take a long time. However,
# statistically, under random hash codes, this is not a common problem.
# Ideally, the frequency of nodes in bins follows a Poisson distribution
# (http://en.wikipedia.org/wiki/Poisson_distribution) with a parameter of
# about 0.5 on average, given the resizing threshold of 0.75, although with a
# large variance because of resizing granularity. Ignoring variance, the
# expected occurrences of list size k are (exp(-0.5) * pow(0.5, k) /
# factorial(k)). The first values are:
#
#   - 0:    0.60653066
#   - 1:    0.30326533
#   - 2:    0.07581633
#   - 3:    0.01263606
#   - 4:    0.00157952
#   - 5:    0.00015795
#   - 6:    0.00001316
#   - 7:    0.00000094
#   - 8:    0.00000006
#   - more: less than 1 in ten million
#
# Lock contention probability for two threads accessing distinct elements is
# roughly 1 / (8 * #elements) under random hashes.
#
# The table is resized when occupancy exceeds a percentage threshold
# (nominally, 0.75, but see below). Only a single thread performs the resize
# (using field +size_control+, to arrange exclusion), but the table otherwise
# remains usable for reads and updates. Resizing proceeds by transferring
# bins, one by one, from the table to the next table. Because we are using
# power-of-two expansion, the elements from each bin must either stay at same
# index, or move with a power of two offset. We eliminate unnecessary node
# creation by catching cases where old nodes can be reused because their next
# fields won't change. On average, only about one-sixth of them need cloning
# when a table doubles. The nodes they replace will be garbage collectable as
# soon as they are no longer referenced by any reader thread that may be in
# the midst of concurrently traversing table. Upon transfer, the old table bin
# contains only a special forwarding node (with hash field +MOVED+) that
# contains the next table as its key. On encountering a forwarding node,
# access and update operations restart, using the new table.
#
# Each bin transfer requires its bin lock. However, unlike other cases, a
# transfer can skip a bin if it fails to acquire its lock, and revisit it
# later. Method +rebuild+ maintains a buffer of TRANSFER_BUFFER_SIZE bins that
# have been skipped because of failure to acquire a lock, and blocks only if
# none are available (i.e., only very rarely). The transfer operation must
# also ensure that all accessible bins in both the old and new table are
# usable by any traversal. When there are no lock acquisition failures, this
# is arranged simply by proceeding from the last bin (+table.size - 1+) up
# towards the first. Upon seeing a forwarding node, traversals arrange to move
# to the new table without revisiting nodes. However, when any node is skipped
# during a transfer, all earlier table bins may have become visible, so are
# initialized with a reverse-forwarding node back to the old table until the
# new ones are established. (This sometimes requires transiently locking a
# forwarding node, which is possible under the above encoding.) These more
# expensive mechanics trigger only when necessary.
#
# The traversal scheme also applies to partial traversals of
# ranges of bins (via an alternate Traverser constructor)
# to support partitioned aggregate operations.  Also, read-only
# operations give up if ever forwarded to a null table, which
# provides support for shutdown-style clearing, which is also not
# currently implemented.
#
# Lazy table initialization minimizes footprint until first use.
#
# The element count is maintained using a +ThreadSafe::Util::Adder+,
# which avoids contention on updates but can encounter cache thrashing
# if read too frequently during concurrent access. To avoid reading so
# often, resizing is attempted either when a bin lock is
# contended, or upon adding to a bin already holding two or more
# nodes (checked before adding in the +x_if_absent+ methods, after
# adding in others). Under uniform hash distributions, the
# probability of this occurring at threshold is around 13%,
# meaning that only about 1 in 8 puts check threshold (and after
# resizing, many fewer do so). But this approximation has high
# variance for small table sizes, so we check on any collision
# for sizes <= 64. The bulk putAll operation further reduces
# contention by only committing count updates upon these size
# checks.
#
# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:180
class ThreadSafe::AtomicReferenceCacheBackend
  extend ::ThreadSafe::Util::Volatile

  # @return [AtomicReferenceCacheBackend] a new instance of AtomicReferenceCacheBackend
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:357
  def initialize(options = T.unsafe(nil)); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:382
  def [](key); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:390
  def []=(key, value); end

  # Implementation for clear. Steps through each bin, removing all nodes.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:529
  def clear; end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:430
  def compute(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:395
  def compute_if_absent(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:418
  def compute_if_present(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:480
  def delete(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:484
  def delete_pair(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:493
  def each_pair; end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:524
  def empty?; end

  # internalPut in the original CHMV8
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:460
  def get_and_set(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:364
  def get_or_default(key, else_value = T.unsafe(nil)); end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:386
  def key?(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:440
  def merge_pair(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:454
  def replace_if_exists(key, new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:450
  def replace_pair(key, old_value, new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:520
  def size; end

  private

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:678
  def attempt_compute(key, hash, current_table, i, node, node_hash); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:708
  def attempt_get_and_set(key, value, hash, current_table, i, node, node_hash); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:658
  def attempt_internal_compute_if_absent(key, hash, current_table, i, node, node_hash); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:594
  def attempt_internal_replace(key, expected_old_value, hash, current_table, i, node, node_hash); end

  # If table is too small and not already resizing, creates next table and
  # transfers bins. Rechecks occupancy after a transfer to see if another
  # resize is already needed because resizings are lagging additions.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:779
  def check_for_resize; end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:904
  def decrement_size(by = T.unsafe(nil)); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:617
  def find_value_in_node_list(node, key, hash, pure_hash); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:900
  def increment_size; end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:736
  def initialize_copy(other); end

  # Initializes table, using the size recorded in +size_control+.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:761
  def initialize_table; end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:633
  def internal_compute(key, &block); end

  # Internal versions of the insertion methods, each a
  # little more complicated than the last. All have
  # the same basic structure:
  #  1. If table uninitialized, create
  #  2. If bin empty, try to CAS new node
  #  3. If bin stale, use new table
  #  4. Lock and validate; if valid, scan and add or update
  #
  # The others interweave other checks and/or alternative actions:
  #  * Plain +get_and_set+ checks for and performs resize after insertion.
  #  * compute_if_absent prescans for mapping without lock (and fails to add
  #    if present), which also makes pre-emptive resize checks worthwhile.
  #
  # Someday when details settle down a bit more, it might be worth
  # some factoring to reduce sprawl.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:574
  def internal_replace(key, expected_old_value = T.unsafe(nil), &block); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:749
  def key_hash(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:847
  def lock_and_clean_up_reverse_forwarders(old_table, old_table_size, new_table, i, forwarder); end

  # Moves and/or copies the nodes in each bin to new table. See above for explanation.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:801
  def rebuild(table); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:867
  def split_bin(new_table, i, node, node_hash); end

  # Splits a normal bin with list headed by e into lo and hi parts; installs in given table.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:860
  def split_old_bin(table, new_table, i, node, node_hash, forwarder); end

  # Returns a power of two table size for the given desired capacity.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:754
  def table_size_for(entry_count); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:744
  def try_await_lock(current_table, i, node); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:788
  def try_in_resize_lock(current_table, size_ctrl); end
end

# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:339
ThreadSafe::AtomicReferenceCacheBackend::DEFAULT_CAPACITY = T.let(T.unsafe(nil), Integer)

# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:336
ThreadSafe::AtomicReferenceCacheBackend::HASH_BITS = T.let(T.unsafe(nil), Integer)

# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:334
ThreadSafe::AtomicReferenceCacheBackend::LOCKED = T.let(T.unsafe(nil), Integer)

# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:340
ThreadSafe::AtomicReferenceCacheBackend::MAX_CAPACITY = T.let(T.unsafe(nil), Integer)

# shorthands
#
# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:333
ThreadSafe::AtomicReferenceCacheBackend::MOVED = T.let(T.unsafe(nil), Integer)

# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:338
ThreadSafe::AtomicReferenceCacheBackend::NOW_RESIZING = T.let(T.unsafe(nil), Integer)

# Key-value entry. Nodes with a hash field of +MOVED+ are special, and do
# not contain user keys or values. Otherwise, keys are never +nil+, and
# +NULL+ +value+ fields indicate that a node is in the process of being
# deleted or created. For purposes of read-only access, a key may be read
# before a value, but can only be used after checking value to be +!= NULL+.
#
# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:226
class ThreadSafe::AtomicReferenceCacheBackend::Node
  include ::ThreadSafe::Util::CheapLockable
  extend ::ThreadSafe::Util::Volatile

  # @return [Node] a new instance of Node
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:243
  def initialize(hash, key, value, next_node = T.unsafe(nil)); end

  # Returns the value of attribute key.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:241
  def key; end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:281
  def key?(key); end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:303
  def locked?; end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:285
  def matches?(key, hash); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:289
  def pure_hash; end

  # Spins a while if +LOCKED+ bit set and this node is the first of its bin,
  # and then sets +WAITING+ bits on hash field and blocks (once) if they are
  # still set. It is OK for this method to return even if lock is not
  # available upon exit, which enables these simple single-wait mechanics.
  #
  # The corresponding signalling operation is performed within callers: Upon
  # detecting that +WAITING+ has been set when unlocking lock (via a failed
  # CAS from non-waiting +LOCKED+ state), unlockers acquire the
  # +cheap_synchronize+ lock and perform a +cheap_broadcast+.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:260
  def try_await_lock(table, i); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:293
  def try_lock_via_hash(node_hash = T.unsafe(nil)); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:307
  def unlock_via_hash(locked_hash, node_hash); end

  private

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:315
  def force_aquire_lock(table, i); end

  class << self
    # @return [Boolean]
    #
    # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:326
    def locked_hash?(hash); end
  end
end

# usable bits of normal node hash
#
# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:237
ThreadSafe::AtomicReferenceCacheBackend::Node::HASH_BITS = T.let(T.unsafe(nil), Integer)

# set/tested only as a bit
#
# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:235
ThreadSafe::AtomicReferenceCacheBackend::Node::LOCKED = T.let(T.unsafe(nil), Integer)

# Encodings for special uses of Node hash fields. See above for explanation.
#
# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:234
ThreadSafe::AtomicReferenceCacheBackend::Node::MOVED = T.let(T.unsafe(nil), Integer)

# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:239
ThreadSafe::AtomicReferenceCacheBackend::Node::SPIN_LOCK_ATTEMPTS = T.let(T.unsafe(nil), Integer)

# both bits set/tested together
#
# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:236
ThreadSafe::AtomicReferenceCacheBackend::Node::WAITING = T.let(T.unsafe(nil), Integer)

# The buffer size for skipped bins during transfers. The
# value is arbitrary but should be large enough to avoid
# most locking stalls during resizes.
#
# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:345
ThreadSafe::AtomicReferenceCacheBackend::TRANSFER_BUFFER_SIZE = T.let(T.unsafe(nil), Integer)

# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:181
class ThreadSafe::AtomicReferenceCacheBackend::Table < ::ThreadSafe::Util::PowerOfTwoTuple
  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:182
  def cas_new_node(i, hash, key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:212
  def delete_node_at(i, node, predecessor_node); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:206
  def try_lock_via_hash(i, node, node_hash); end

  # source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:186
  def try_to_cas_in_computed(i, hash, key); end
end

# source://thread_safe-0.3.6/lib/thread_safe/atomic_reference_cache_backend.rb:335
ThreadSafe::AtomicReferenceCacheBackend::WAITING = T.let(T.unsafe(nil), Integer)

# source://thread_safe-0.3.6/lib/thread_safe/cache.rb:23
class ThreadSafe::Cache < ::ThreadSafe::MriCacheBackend
  # @return [Cache] a new instance of Cache
  #
  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:24
  def initialize(options = T.unsafe(nil), &block); end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:35
  def [](key); end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:98
  def each_key; end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:102
  def each_value; end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:112
  def empty?; end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:52
  def fetch(key, default_value = T.unsafe(nil)); end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:64
  def fetch_or_store(key, default_value = T.unsafe(nil)); end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:35
  def get(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:106
  def key(value); end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:86
  def keys; end

  # @raise [TypeError]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:123
  def marshal_dump; end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:130
  def marshal_load(hash); end

  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:12
  def put(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:70
  def put_if_absent(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:92
  def values; end

  private

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:142
  def initialize_copy(other); end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:147
  def populate_from(hash); end

  # @raise [KeyError]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:138
  def raise_fetch_no_key; end

  # source://thread_safe-0.3.6/lib/thread_safe/cache.rb:152
  def validate_options_hash!(options); end
end

# source://thread_safe-0.3.6/lib/thread_safe/cache.rb:10
ThreadSafe::ConcurrentCacheBackend = ThreadSafe::MriCacheBackend

# A thread-safe subclass of Hash. This version locks
# against the object itself for every method call,
# ensuring only one thread can be reading or writing
# at a time. This includes iteration methods like
# #each.
#
# source://thread_safe-0.3.6/lib/thread_safe.rb:35
ThreadSafe::Hash = Hash

# source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:9
class ThreadSafe::MriCacheBackend < ::ThreadSafe::NonConcurrentCacheBackend
  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:12
  def []=(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:56
  def clear; end

  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:28
  def compute(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:16
  def compute_if_absent(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:24
  def compute_if_present(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:48
  def delete(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:52
  def delete_pair(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:44
  def get_and_set(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:32
  def merge_pair(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:40
  def replace_if_exists(key, new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:36
  def replace_pair(key, old_value, new_value); end
end

# We can get away with a single global write lock (instead of a per-instance
# one) because of the GVL/green threads.
#
# NOTE: a neat idea of writing a c-ext to manually perform atomic
# put_if_absent, while relying on Ruby not releasing a GVL while calling a
# c-ext will not work because of the potentially Ruby implemented `#hash`
# and `#eql?` key methods.
#
# source://thread_safe-0.3.6/lib/thread_safe/mri_cache_backend.rb:10
ThreadSafe::MriCacheBackend::WRITE_LOCK = T.let(T.unsafe(nil), Thread::Mutex)

# Various classes within allows for +nil+ values to be stored, so a special +NULL+ token is required to indicate the "nil-ness".
#
# source://thread_safe-0.3.6/lib/thread_safe.rb:9
ThreadSafe::NULL = T.let(T.unsafe(nil), Object)

# source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:2
class ThreadSafe::NonConcurrentCacheBackend
  # WARNING: all public methods of the class must operate on the @backend
  # directly without calling each other. This is important because of the
  # SynchronizedCacheBackend which uses a non-reentrant mutex for perfomance
  # reasons.
  #
  # @return [NonConcurrentCacheBackend] a new instance of NonConcurrentCacheBackend
  #
  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:7
  def initialize(options = T.unsafe(nil)); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:11
  def [](key); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:15
  def []=(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:88
  def clear; end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:49
  def compute(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:19
  def compute_if_absent(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:43
  def compute_if_present(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:75
  def delete(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:79
  def delete_pair(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:93
  def each_pair; end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:61
  def get_and_set(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:104
  def get_or_default(key, default_value); end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:67
  def key?(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:53
  def merge_pair(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:36
  def replace_if_exists(key, new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:27
  def replace_pair(key, old_value, new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:100
  def size; end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:71
  def value?(value); end

  private

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:11
  def _get(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:15
  def _set(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:118
  def dupped_backend; end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:112
  def initialize_copy(other); end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:122
  def pair?(key, expected_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/non_concurrent_cache_backend.rb:126
  def store_computed_value(key, new_value); end
end

# source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:2
class ThreadSafe::SynchronizedCacheBackend < ::ThreadSafe::NonConcurrentCacheBackend
  include ::Mutex_m

  # WARNING: Mutex_m is a non-reentrant lock, so the synchronized methods are
  # not allowed to call each other.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:8
  def [](key); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:12
  def []=(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:60
  def clear; end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:24
  def compute(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:16
  def compute_if_absent(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:20
  def compute_if_present(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:52
  def delete(key); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:56
  def delete_pair(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:40
  def get_and_set(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:68
  def get_or_default(key, default_value); end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:44
  def key?(key); end

  # source://RUBY_ROOT/mutex_m.rb:92
  def lock; end

  # source://RUBY_ROOT/mutex_m.rb:82
  def locked?; end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:28
  def merge_pair(key, value); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:36
  def replace_if_exists(key, new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:32
  def replace_pair(key, old_value, new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:64
  def size; end

  # source://RUBY_ROOT/mutex_m.rb:77
  def synchronize(&block); end

  # source://RUBY_ROOT/mutex_m.rb:87
  def try_lock; end

  # source://RUBY_ROOT/mutex_m.rb:97
  def unlock; end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:48
  def value?(value); end

  private

  # source://thread_safe-0.3.6/lib/thread_safe/synchronized_cache_backend.rb:73
  def dupped_backend; end
end

# source://thread_safe-0.3.6/lib/thread_safe/util.rb:2
module ThreadSafe::Util; end

# 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.
#
# source://thread_safe-0.3.6/lib/thread_safe/util/adder.rb:23
class ThreadSafe::Util::Adder < ::ThreadSafe::Util::Striped64
  # Adds the given value.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/adder.rb:24
  def add(x); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/adder.rb:38
  def decrement; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/adder.rb:34
  def increment; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/adder.rb:57
  def reset; 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.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/adder.rb:47
  def sum; end
end

# source://thread_safe-0.3.6/lib/thread_safe/util/atomic_reference.rb:3
ThreadSafe::Util::AtomicReference = ThreadSafe::Util::FullLockingAtomicReference

# is there a way to determine this?
#
# source://thread_safe-0.3.6/lib/thread_safe/util.rb:5
ThreadSafe::Util::CPU_COUNT = T.let(T.unsafe(nil), Integer)

# Provides a cheapest possible (mainly in terms of memory usage) +Mutex+
# with the +ConditionVariable+ bundled in.
#
# Usage:
#   class A
#     include CheapLockable
#
#     def do_exlusively
#       cheap_synchronize { yield }
#     end
#
#     def wait_for_something
#       cheap_synchronize do
#         cheap_wait until resource_available?
#         do_something
#         cheap_broadcast # wake up others
#       end
#     end
#   end
#
# source://thread_safe-0.3.6/lib/thread_safe/util/cheap_lockable.rb:22
module ThreadSafe::Util::CheapLockable
  extend ::ThreadSafe::Util::Volatile

  private

  # Wakes up all threads waiting for this object's +cheap_synchronize+ lock.
  # Must only be called in +cheap_broadcast+'s block.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/cheap_lockable.rb:98
  def cheap_broadcast; end

  # Non-reentrant Mutex#syncrhonize
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/cheap_lockable.rb:84
  def cheap_synchronize; end

  # Releases this object's +cheap_synchronize+ lock and goes to sleep waiting for other threads to +cheap_broadcast+, reacquires the lock on wakeup.
  # Must only be called in +cheap_broadcast+'s block.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/cheap_lockable.rb:91
  def cheap_wait; end
end

# source://thread_safe-0.3.6/lib/thread_safe/util.rb:3
ThreadSafe::Util::FIXNUM_BIT_SIZE = T.let(T.unsafe(nil), Integer)

# source://thread_safe-0.3.6/lib/thread_safe/util/atomic_reference.rb:12
class ThreadSafe::Util::FullLockingAtomicReference
  # source://thread_safe-0.3.6/lib/thread_safe/util/atomic_reference.rb:13
  def initialize(value = T.unsafe(nil)); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/atomic_reference.rb:28
  def compare_and_set(old_value, new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/atomic_reference.rb:18
  def get; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/atomic_reference.rb:23
  def set(new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/atomic_reference.rb:18
  def value; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/atomic_reference.rb:23
  def value=(new_value); end
end

# source://thread_safe-0.3.6/lib/thread_safe/util.rb:4
ThreadSafe::Util::MAX_INT = T.let(T.unsafe(nil), Integer)

# source://thread_safe-0.3.6/lib/thread_safe/util/power_of_two_tuple.rb:3
class ThreadSafe::Util::PowerOfTwoTuple < ::ThreadSafe::Util::VolatileTuple
  # @raise [ArgumentError]
  # @return [PowerOfTwoTuple] a new instance of PowerOfTwoTuple
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/power_of_two_tuple.rb:4
  def initialize(size); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/power_of_two_tuple.rb:9
  def hash_to_index(hash); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/power_of_two_tuple.rb:21
  def next_in_size_table; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/power_of_two_tuple.rb:13
  def volatile_get_by_hash(hash); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/power_of_two_tuple.rb:17
  def volatile_set_by_hash(hash, value); end
end

# A Ruby port of the Doug Lea's jsr166e.Striped64 class version 1.6
# available in public domain.
#
# Original source code available here:
# http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.6
#
# Class holding common representation and mechanics for classes supporting
# dynamic striping on 64bit values.
#
# This class maintains a lazily-initialized table of atomically updated
# variables, plus an extra +base+ field. The table size is a power of two.
# Indexing uses masked per-thread hash codes. Nearly all methods on this
# class are private, accessed directly by subclasses.
#
# Table entries are of class +Cell+; a variant of AtomicLong padded to
# reduce cache contention on most processors. Padding is overkill for most
# Atomics because they are usually irregularly scattered in memory and thus
# don't interfere much with each other. But Atomic objects residing in
# arrays will tend to be placed adjacent to each other, and so will most
# often share cache lines (with a huge negative performance impact) without
# this precaution.
#
# In part because +Cell+s are relatively large, we avoid creating them until
# they are needed. When there is no contention, all updates are made to the
# +base+ field. Upon first contention (a failed CAS on +base+ update), the
# table is initialized to size 2. The table size is doubled upon further
# contention until reaching the nearest power of two greater than or equal
# to the number of CPUS. Table slots remain empty (+nil+) until they are
# needed.
#
# A single spinlock (+busy+) is used for initializing and resizing the
# table, as well as populating slots with new +Cell+s. There is no need for
# a blocking lock: When the lock is not available, threads try other slots
# (or the base). During these retries, there is increased contention and
# reduced locality, which is still better than alternatives.
#
# Per-thread hash codes are initialized to random values. Contention and/or
# table collisions are indicated by failed CASes when performing an update
# operation (see method +retry_update+). Upon a collision, if the table size
# is less than the capacity, it is doubled in size unless some other thread
# holds the lock. If a hashed slot is empty, and lock is available, a new
# +Cell+ is created. Otherwise, if the slot exists, a CAS is tried. Retries
# proceed by "double hashing", using a secondary hash (XorShift) to try to
# find a free slot.
#
# The table size is capped because, when there are more threads than CPUs,
# supposing that each thread were bound to a CPU, there would exist a
# perfect hash function mapping threads to slots that eliminates collisions.
# When we reach capacity, we search for this mapping by randomly varying the
# hash codes of colliding threads. Because search is random, and collisions
# only become known via CAS failures, convergence can be slow, and because
# threads are typically not bound to CPUS forever, may not occur at all.
# However, despite these limitations, observed contention rates are
# typically low in these cases.
#
# It is possible for a +Cell+ to become unused when threads that once hashed
# to it terminate, as well as in the case where doubling the table causes no
# thread to hash to it under expanded mask. We do not try to detect or
# remove such cells, under the assumption that for long-running instances,
# observed contention levels will recur, so the cells will eventually be
# needed again; and for short-lived ones, it does not matter.
#
# source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:64
class ThreadSafe::Util::Striped64
  extend ::ThreadSafe::Util::Volatile

  # @return [Striped64] a new instance of Striped64
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:89
  def initialize; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/volatile.rb:44
  def busy?; end

  # Handles cases of updates involving initialization, resizing,
  # creating new Cells, and/or contention. See above for
  # explanation. This method suffers the usual non-modularity
  # problems of optimistic retry code, relying on rechecked sets of
  # reads.
  #
  # Arguments:
  # [+x+]
  #   the value
  # [+hash_code+]
  #   hash code used
  # [+x+]
  #   false if CAS failed before call
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:108
  def retry_update(x, hash_code, was_uncontended); end

  private

  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:172
  def cas_base_computed; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:192
  def expand_table_unless_stale(current_cells); end

  # @return [Boolean]
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:176
  def free?; end

  # A thread-local hash code accessor. The code is initially
  # random, but may be set to a different value upon collisions.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:153
  def hash_code; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:157
  def hash_code=(hash); end

  # Sets base and all +cells+ to the given value.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:162
  def internal_reset(initial_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:211
  def try_in_busy; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:180
  def try_initialize_cells(x, hash); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:202
  def try_to_install_new_cell(new_cell, hash); end
end

# Padded variant of AtomicLong supporting only raw accesses plus CAS.
# The +value+ field is placed between pads, hoping that the JVM doesn't
# reorder them.
#
# Optimisation note: It would be possible to use a release-only
# form of CAS here, if it were provided.
#
# source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:72
class ThreadSafe::Util::Striped64::Cell < ::ThreadSafe::Util::FullLockingAtomicReference
  # source://thread_safe-0.3.6/lib/thread_safe/util/atomic_reference.rb:28
  def cas(old_value, new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:77
  def cas_computed; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:73
  def padding_; end
end

# Static per-thread hash code key. Shared across all instances to
# reduce Thread locals pollution and because adjustments due to
# collisions in one table are likely to be appropriate for
# others.
#
# source://thread_safe-0.3.6/lib/thread_safe/util/striped64.rb:149
ThreadSafe::Util::Striped64::THREAD_LOCAL_KEY = T.let(T.unsafe(nil), Symbol)

# source://thread_safe-0.3.6/lib/thread_safe/util/volatile.rb:3
module ThreadSafe::Util::Volatile
  # Provides +volatile+ (in the JVM's sense) attribute accessors implemented
  # atop of the +AtomicReference+s.
  #
  # Usage:
  #   class Foo
  #     extend ThreadSafe::Util::Volatile
  #     attr_volatile :foo, :bar
  #
  #     def initialize(bar)
  #       super() # must super() into parent initializers before using the volatile attribute accessors
  #       self.bar = bar
  #     end
  #
  #     def hello
  #       my_foo = foo # volatile read
  #       self.foo = 1 # volatile write
  #       cas_foo(1, 2) # => true | a strong CAS
  #     end
  #   end
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/volatile.rb:23
  def attr_volatile(*attr_names); end
end

# A fixed size array with volatile volatile getters/setters.
# Usage:
#   arr = VolatileTuple.new(16)
#   arr.volatile_set(0, :foo)
#   arr.volatile_get(0)    # => :foo
#   arr.cas(0, :foo, :bar) # => true
#   arr.volatile_get(0)    # => :bar
#
# source://thread_safe-0.3.6/lib/thread_safe/util/volatile_tuple.rb:10
class ThreadSafe::Util::VolatileTuple
  include ::Enumerable

  # @return [VolatileTuple] a new instance of VolatileTuple
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/volatile_tuple.rb:15
  def initialize(size); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/volatile_tuple.rb:32
  def cas(i, old_value, new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/volatile_tuple.rb:32
  def compare_and_set(i, old_value, new_value); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/volatile_tuple.rb:41
  def each; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/volatile_tuple.rb:37
  def size; end

  # source://thread_safe-0.3.6/lib/thread_safe/util/volatile_tuple.rb:24
  def volatile_get(i); end

  # source://thread_safe-0.3.6/lib/thread_safe/util/volatile_tuple.rb:28
  def volatile_set(i, value); end
end

# source://thread_safe-0.3.6/lib/thread_safe/util/volatile_tuple.rb:13
ThreadSafe::Util::VolatileTuple::Tuple = Array

# A xorshift random number (positive +Fixnum+s) generator, provides
# reasonably cheap way to generate thread local random numbers without
# contending for the global +Kernel.rand+.
#
# Usage:
#   x = XorShiftRandom.get # uses Kernel.rand to generate an initial seed
#   while true
#     if (x = XorShiftRandom.xorshift).odd? # thread-localy generate a next random number
#       do_something_at_random
#     end
#   end
#
# source://thread_safe-0.3.6/lib/thread_safe/util/xor_shift_random.rb:14
module ThreadSafe::Util::XorShiftRandom
  extend ::ThreadSafe::Util::XorShiftRandom

  # Generates an initial non-zero positive +Fixnum+ via +Kernel.rand+.
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/xor_shift_random.rb:19
  def get; end

  # using the "yˆ=y>>a; yˆ=y<<b; yˆ=y>>c;" transform with the (a,b,c) tuple with values (1,1,54) to minimise Bignum overflows
  #
  # source://thread_safe-0.3.6/lib/thread_safe/util/xor_shift_random.rb:33
  def xorshift(x); end
end

# source://thread_safe-0.3.6/lib/thread_safe/util/xor_shift_random.rb:16
ThreadSafe::Util::XorShiftRandom::MAX_XOR_SHIFTABLE_INT = T.let(T.unsafe(nil), Integer)

# source://thread_safe-0.3.6/lib/thread_safe/version.rb:2
ThreadSafe::VERSION = T.let(T.unsafe(nil), String)

# NOTE: <= 0.2.0 used Threadsafe::VERSION
#
# @private
#
# source://thread_safe-0.3.6/lib/thread_safe/version.rb:7
module Threadsafe
  class << self
    # @private
    #
    # source://thread_safe-0.3.6/lib/thread_safe/version.rb:10
    def const_missing(name); end
  end
end