require 'concurrent/edge/atomic_markable_reference' module Concurrent module Edge class LockFreeLinkedSet class Node < Synchronization::Object include Comparable safe_initialization! def initialize(data = nil, successor = nil) super() @SuccessorReference = AtomicMarkableReference.new(successor || Tail.new) @Data = data @Key = key_for data end def data @Data end def successor_reference @SuccessorReference end def key @Key end # Check to see if the node is the last in the list. def last? @SuccessorReference.value.is_a? Tail end # Next node in the list. Note: this is not the AtomicMarkableReference # of the next node, this is the actual Node itself. def next_node @SuccessorReference.value end # This method provides a unqiue key for the data which will be used for # ordering. This is configurable, and changes depending on how you wish # the nodes to be ordered. def key_for(data) data.hash end # We use `Object#hash` as a way to enforce ordering on the nodes. This # can be configurable in the future; for example, you could enforce a # split-ordering on the nodes in the set. def <=>(other) @Key <=> other.hash end end # Internal sentinel node for the Tail. It is always greater than all # other nodes, and it is self-referential; meaning its successor is # a self-loop. class Tail < Node def initialize(_data = nil, _succ = nil) @SuccessorReference = AtomicMarkableReference.new self end # Always greater than other nodes. This means that traversal will end # at the tail node since we are comparing node size in the traversal. def <=>(_other) 1 end end # Internal sentinel node for the Head of the set. Head is always smaller # than any other node. class Head < Node def <=>(_other) -1 end end end end end