Class: KVDAG::Vertex
- Inherits:
-
Object
- Object
- KVDAG::Vertex
- Includes:
- Comparable, AttributeNode
- Defined in:
- lib/kvdag/vertex.rb
Overview
A vertex in a KVDAG
Instance Attribute Summary collapse
-
#dag ⇒ Object
readonly
Returns the value of attribute dag.
-
#edges ⇒ Object
readonly
Returns the value of attribute edges.
Attributes included from AttributeNode
Instance Method Summary collapse
-
#<=>(other) ⇒ Object
Comparable ordering for a DAG:.
-
#ancestors(filter = {}, &block) ⇒ Object
:call-seq: vtx.ancestors -> all ancestors vtx.ancestors(filter) -> ancestors matching
filter
vtx.ancestors {|anc| … } -> call block with each ancestor. -
#children(filter = {}, &block) ⇒ Object
:call-seq: vtx.children -> all children vtx.children(filter) -> children matching
filter
vtx.children {|cld| … } -> call block with each child. -
#descendants(filter = {}, &block) ⇒ Object
:call-seq: vtx.descendants -> all descendants vtx.descendants(filter) -> descendants matching
filter
vtx.descendants {|desc| … } -> call block with each descendant. -
#edge(other, attrs = {}) ⇒ Object
Create an edge towards an
other
vertex, optionally loaded with key-values. -
#initialize(dag, attrs = {}) ⇒ Vertex
constructor
A new instance of Vertex.
- #inspect ⇒ Object (also: #to_s)
-
#parents(filter = {}, &block) ⇒ Object
:call-seq: vtx.parents -> all parents vtx.parents(filter) -> parents matching
filter
vtx.parents {|cld| … } -> call block with each parent. -
#reachable?(other) ⇒ Boolean
Is
other
vertex reachable via any of my #edges?. -
#reachable_from?(other) ⇒ Boolean
Am I reachable from
other
via any of its #edges?. -
#to_hash_proxy ⇒ Object
Return the proxied key-value hash tree visible from this vertex via its edges and all its ancestors.
Methods included from AttributeNode
#[], #[]=, #fetch, #filter, #match?, #merge!, #to_hash
Constructor Details
#initialize(dag, attrs = {}) ⇒ Vertex
Returns a new instance of Vertex.
17 18 19 20 21 22 23 24 |
# File 'lib/kvdag/vertex.rb', line 17 def initialize(dag, attrs = {}) @edges = Set.new @dag = dag @attrs = dag.hash_proxy_class.new(attrs) @child_cache = Set.new @dag.vertices << self end |
Instance Attribute Details
#dag ⇒ Object (readonly)
Returns the value of attribute dag.
7 8 9 |
# File 'lib/kvdag/vertex.rb', line 7 def dag @dag end |
#edges ⇒ Object (readonly)
Returns the value of attribute edges.
8 9 10 |
# File 'lib/kvdag/vertex.rb', line 8 def edges @edges end |
Instance Method Details
#<=>(other) ⇒ Object
Comparable ordering for a DAG:
Reachable vertices are lesser. Unreachable vertices are equal.
143 144 145 146 147 |
# File 'lib/kvdag/vertex.rb', line 143 def <=>(other) return -1 if reachable?(other) return 1 if reachable_from?(other) return 0 end |
#ancestors(filter = {}, &block) ⇒ Object
:call-seq:
vtx.ancestors -> all ancestors
vtx.ancestors(filter) -> ancestors matching +filter+
vtx.ancestors {|anc| ... } -> call block with each ancestor
Return the set of this object and all its parents, and their parents, recursively, possibly filtered by #match? expressions. If a block is given, call it with each ancestor.
103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/kvdag/vertex.rb', line 103 def ancestors(filter = {}, &block) result = Set.new result << self if match?(filter) parents.each { |p| result += p.ancestors(filter) } if block_given? result.each(&block) else result end end |
#children(filter = {}, &block) ⇒ Object
:call-seq:
vtx.children -> all children
vtx.children(filter) -> children matching +filter+
vtx.children {|cld| ... } -> call block with each child
Returns the set of all direct children, possibly filtered by #match? expressions. If a block is given, call it with each child.
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/kvdag/vertex.rb', line 62 def children(filter = {}, &block) result = @child_cache.select { |child| child.match?(filter) } if block_given? result.each(&block) else result end end |
#descendants(filter = {}, &block) ⇒ Object
:call-seq:
vtx.descendants -> all descendants
vtx.descendants(filter) -> descendants matching +filter+
vtx.descendants {|desc| ... } -> call block with each descendant
Return the set of this object and all its children, and their children, recursively, possibly filtered by #match? expressions. If a block is given, call it with each descendant.
125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/kvdag/vertex.rb', line 125 def descendants(filter = {}, &block) result = Set.new result << self if match?(filter) children.each { |c| result += c.descendants(filter) } if block_given? result.each(&block) else result end end |
#edge(other, attrs = {}) ⇒ Object
Create an edge towards an other
vertex, optionally loaded with key-values.
A KVDAG::VertexError is raised if vertices belong to different KVDAG.
A KVDAG::CyclicError is raised if the edge would cause a cycle in the KVDAG.
158 159 160 161 162 163 164 165 166 167 |
# File 'lib/kvdag/vertex.rb', line 158 def edge(other, attrs = {}) other = other.to_vertex unless other.is_a?(Vertex) raise VertexError.new('Not in the same DAG') if @dag != other.dag raise CyclicError.new('Would become cyclic') if other.reachable?(self) edge = Edge.new(@dag, other, attrs) @edges << edge other.add_child(self) edge end |
#inspect ⇒ Object Also known as: to_s
26 27 28 |
# File 'lib/kvdag/vertex.rb', line 26 def inspect '#<%s @attr=%s @edges=%s>' % [self.class, @attrs.to_hash, @edges.to_a] end |
#parents(filter = {}, &block) ⇒ Object
:call-seq:
vtx.parents -> all parents
vtx.parents(filter) -> parents matching +filter+
vtx.parents {|cld| ... } -> call block with each parent
Returns the set of all direct parents, possibly filtered by #match? expressions. If a block is given, call it with each parent.
40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/kvdag/vertex.rb', line 40 def parents(filter = {}, &block) result = Set.new(edges.map { |edge| edge.to_vertex }.select { |parent| parent.match?(filter) }) if block_given? result.each(&block) else result end end |
#reachable?(other) ⇒ Boolean
Is other
vertex reachable via any of my #edges?
A KVDAG::VertexError is raised if vertices belong to different KVDAG.
79 80 81 82 83 |
# File 'lib/kvdag/vertex.rb', line 79 def reachable?(other) raise VertexError.new('Not in the same DAG') unless @dag.equal?(other.dag) equal?(other) || parents.any? { |parent| parent.reachable?(other) } end |
#reachable_from?(other) ⇒ Boolean
Am I reachable from other
via any of its #edges?
A KVDAG::VertexError is raised if vertices belong to different KVDAG.
90 91 92 |
# File 'lib/kvdag/vertex.rb', line 90 def reachable_from?(other) other.reachable?(self) end |
#to_hash_proxy ⇒ Object
Return the proxied key-value hash tree visible from this vertex via its edges and all its ancestors.
Calling #to_hash instead will return a regular hash tree, without any special properties, e.g. for serializing as YAML or JSON.
175 176 177 178 179 180 181 |
# File 'lib/kvdag/vertex.rb', line 175 def to_hash_proxy result = @dag.hash_proxy_class.new edges.each do |edge| result.merge!(edge.to_hash_proxy) end result.merge!(@attrs) end |