Class: ThreadSafe::AtomicReferenceCacheBackend::Node

### Home Classes Methods

### In Files

- lib/thread_safe/atomic_reference_cache_backend.rb

### Parent

Object

### Methods

- ::new
- #key?
- #locked?
- #matches?
- #pure_hash
- #try_await_lock
- #try_lock_via_hash
- #unlock_via_hash

### Included Modules

- ThreadSafe::Util::CheapLockable

### Class/Module Index

Quicksearch

- ThreadSafe
- ThreadSafe::Array
- ThreadSafe::AtomicReferenceCacheBackend
- ThreadSafe::AtomicReferenceCacheBackend::Node
- ThreadSafe::AtomicReferenceCacheBackend::Table
- ThreadSafe::Cache
- ThreadSafe::Hash
- ThreadSafe::MriCacheBackend
- ThreadSafe::NonConcurrentCacheBackend
- ThreadSafe::SynchronizedCacheBackend
- ThreadSafe::Util
- ThreadSafe::Util::Adder
- ThreadSafe::Util::CheapLockable
- ThreadSafe::Util::PowerOfTwoTuple
- ThreadSafe::Util::Striped64
- ThreadSafe::Util::Striped64::Cell
- ThreadSafe::Util::Volatile
- ThreadSafe::Util::VolatileTuple
- SynchronizedDelegator
- Threadsafe

No matching classes.

# ThreadSafe::AtomicReferenceCacheBackend::Node

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+.

### Constants

HASH_BITS
LOCKED
MOVED

  Encodings for special uses of Node hash fields. See above for explanation.

SPIN_LOCK_ATTEMPTS
WAITING

### Attributes

key[R]

### Public Class Methods

new(hash, key, value, next_node = nil) click to toggle source

    # File lib/thread_safe/atomic_reference_cache_backend.rb, line 243
    def initialize(hash, key, value, next_node = nil)
      super()
      @key = key
      self.lazy_set_hash(hash)
      self.lazy_set_value(value)
      self.next = next_node
    end

### Public Instance Methods

key?(key) click to toggle source

    # File lib/thread_safe/atomic_reference_cache_backend.rb, line 281
    def key?(key)
      @key.eql?(key)
    end

locked?() click to toggle source

    # File lib/thread_safe/atomic_reference_cache_backend.rb, line 303
    def locked?
      self.class.locked_hash?(hash)
    end

matches?(key, hash) click to toggle source

    # File lib/thread_safe/atomic_reference_cache_backend.rb, line 285
    def matches?(key, hash)
      pure_hash == hash && key?(key)
    end

pure_hash() click to toggle source

    # File lib/thread_safe/atomic_reference_cache_backend.rb, line 289
    def pure_hash
      hash & HASH_BITS
    end

try_await_lock(table, i) click to toggle source

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`.

    # File lib/thread_safe/atomic_reference_cache_backend.rb, line 260
    def try_await_lock(table, i)
      if table && i >= 0 && i < table.size # bounds check, TODO: why are we bounds checking?
        spins = SPIN_LOCK_ATTEMPTS
        randomizer = base_randomizer = Util::XorShiftRandom.get
        while equal?(table.volatile_get(i)) && self.class.locked_hash?(my_hash = hash)
          if spins >= 0
            if (randomizer = (randomizer >> 1)).even? # spin at random
              if (spins -= 1) == 0
                Thread.pass # yield before blocking
              else
                randomizer = base_randomizer = Util::XorShiftRandom.xorshift(base_randomizer) if randomizer.zero?
              end
            end
          elsif cas_hash(my_hash, my_hash | WAITING)
            force_aquire_lock(table, i)
            break
          end
        end
      end
    end

try_lock_via_hash(node_hash = hash) click to toggle source

    # File lib/thread_safe/atomic_reference_cache_backend.rb, line 293
    def try_lock_via_hash(node_hash = hash)
      if cas_hash(node_hash, locked_hash = node_hash | LOCKED)
        begin
          yield
        ensure
          unlock_via_hash(locked_hash, node_hash)
        end
      end
    end

unlock_via_hash(locked_hash, node_hash) click to toggle source

    # File lib/thread_safe/atomic_reference_cache_backend.rb, line 307
    def unlock_via_hash(locked_hash, node_hash)
      unless cas_hash(locked_hash, node_hash)
        self.hash = node_hash
        cheap_synchronize { cheap_broadcast }
      end
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.