File: node.rb

package info (click to toggle)
ruby-concurrent 1.1.6%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 30,284 kB
  • sloc: ruby: 30,875; java: 6,117; javascript: 1,114; ansic: 288; makefile: 10; sh: 6
file content (81 lines) | stat: -rw-r--r-- 2,264 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
require 'concurrent/atomic/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