Class: Turbine::Node

Inherits:
Object
  • Object
show all
Includes:
Properties
Defined in:
lib/turbine/node.rb

Overview

In graph theory, a node is the fundamental unit of which graphs are formed: a directed graph consists of a set of nodes and a set of edges.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Properties

#get, #properties, #properties=, #set

Constructor Details

#initialize(key, properties = nil) ⇒ Node

Creates a new Node.

key - A unique identifier for the node. The uniqueness of the key

is not checked upon initializing, but instead when the node
is added to the graph (Graph#add).

properties - Optional key/value properties to be associated with the

node.

Returns the node.



19
20
21
22
23
24
25
# File 'lib/turbine/node.rb', line 19

def initialize(key, properties = nil)
  @key        = key
  @in_edges   = Set.new
  @out_edges  = Set.new

  self.properties = properties
end

Instance Attribute Details

#keyObject (readonly)

Public: Returns the unique key which identifies the node.



8
9
10
# File 'lib/turbine/node.rb', line 8

def key
  @key
end

Instance Method Details

#ancestors(label = nil) ⇒ Object

Public: Returns an enumerator containing all nodes which are inward nodes, and all of their inward nodes.

Uses a BreadthFirst traversal so that immediately adjacent nodes are visited before more distant nodes.

Returns an Enumerator containing Nodes.



91
92
93
# File 'lib/turbine/node.rb', line 91

def ancestors(label = nil)
  Pipeline.dsl(self).ancestors(label)
end

#connect_to(target, label = nil, properties = nil) ⇒ Object

Public: Connects this node to another.

target - The node to which you want to connect. The target node

will be the "from" end of the edge.

label - An optional label describing the relationship between the

two nodes.

properties - Optional key/value properties to be associated with the

edge.

Example:

phil = Turbine::Node.new(:phil)
luke = Turbine::Node.new(:luke)

phil.connect_to(luke, :child)

Returns the Edge which was created.

Raises a Turbine::DuplicateEdgeError if the Edge already existed.



137
138
139
140
141
142
# File 'lib/turbine/node.rb', line 137

def connect_to(target, label = nil, properties = nil)
  Edge.new(self, target, label, properties).tap do |edge|
    self.connect_via(edge)
    target.connect_via(edge)
  end
end

#connect_via(edge) ⇒ Object

Internal: Given an Edge, establishes the connection for this node.

Please note that you need to call connect_via on both the “from” and “to” nodes. Unless you need to create the connection using a subclass of Edge, you will likey prefer using the simpler connect_to.

Example:

phil  = Turbine::Node.new(:phil)
haley = Turbine::Node.new(:haley)

edge  = Turbine::Edge.new(phil, haley, :child)

# Adds an link from "phil" to "haley".
phil.connect_via(edge)
haley.connect_via(edge)

Raises a Turbine::CannotConnectError if this node is not the from or to node specified by the edge.

Returns the given edge.



185
186
187
188
189
190
# File 'lib/turbine/node.rb', line 185

def connect_via(edge)
  connect_endpoint(@in_edges, edge)  if edge.to   == self
  connect_endpoint(@out_edges, edge) if edge.from == self

  edge
end

#descendants(label = nil) ⇒ Object

Public: Returns an enumerator containing all nodes which are outward nodes, and all of their outward nodes.

Uses a BreadthFirst traversal so that immediately adjacent nodes are visited before more distant nodes.

Returns an Enumerator containing Nodes.



80
81
82
# File 'lib/turbine/node.rb', line 80

def descendants(label = nil)
  Pipeline.dsl(self).descendants(label)
end

#disconnect_from(target, label = nil) ⇒ Object

Public: Disconnects this node from the target. Assumes that the receiver is the from node.

target - The node from which the receiver is to be disconnected. label - An optional label; only the edge with this label will be

removed, with other edges kept intact. No label will remove all
outward edges between the receiver and the target.

Raises NoSuchEdge if the two nodes are not connected.

Returns nothing.



155
156
157
158
159
160
161
162
# File 'lib/turbine/node.rb', line 155

def disconnect_from(target, label = nil)
  edges(:out, label).select { |edge| edge.to == target }.each do |edge|
    disconnect_via(edge)
    target.disconnect_via(edge)
  end

  nil
end

#disconnect_via(edge) ⇒ Object

Internal: Given an edge, removes the connection for this node.

Please note that you need to call disconnect_via on both the “from” and “to” nodes.

Example:

haley = Turbine::Node.new(:haley)
dylan = Turbine::Node.new(:dylan)

edge  = haley.connect_to(dylan, :boyfriend)

haley.disconnect_via(edge)
dylan.disconnect_via(edge)

Returns nothing.



208
209
210
211
212
213
# File 'lib/turbine/node.rb', line 208

def disconnect_via(edge)
  @in_edges.delete(edge)
  @out_edges.delete(edge)

  nil
end

#edges(direction, label = nil) ⇒ Object

Internal: Low-level method which retrieves all of the edges in a given direction, in an array.

Returns an array of edges.



99
100
101
# File 'lib/turbine/node.rb', line 99

def edges(direction, label = nil)
  select_edges(direction == :in ? @in_edges : @out_edges, label)
end

#in(label = nil) ⇒ Object

Public: Returns nodes which have an outgoing edge to this node.

label - An optional label by which to filter the in edges, before

fetching the matched nodes.

Returns an array of Node instances.



33
34
35
# File 'lib/turbine/node.rb', line 33

def in(label = nil)
  Pipeline.dsl(self).in(label)
end

#in_edges(label = nil) ⇒ Object

Public: Returns this node’s incoming edges.

label - An optional label; only edges with this label will be returned.

Passing nil will return all in edges.

Raises an InvalidEdgeFilterError if you supply both a label and block for filtering the edges.

Returns an array of Edges.



56
57
58
# File 'lib/turbine/node.rb', line 56

def in_edges(label = nil)
  Pipeline.dsl(self).in_edges(label)
end

#inspectObject Also known as: to_s

Public: Returns a human-readable version of the node.



112
113
114
# File 'lib/turbine/node.rb', line 112

def inspect
  "#<#{ self.class.name } key=#{ @key.inspect }>"
end

#nodes(direction, label = nil) ⇒ Object

Internal: Low-level method which retrieves all of the nodes in a given direction, in an array.

Returns an array of nodes.



107
108
109
# File 'lib/turbine/node.rb', line 107

def nodes(direction, label = nil)
  edges(direction, label).map(&(direction == :in ? :from : :to))
end

#out(label = nil) ⇒ Object

Public: Returns verticies to which this node has outgoing edges.

label - An optional label by which to filter the out edges, before

fetching the matched nodes.

Returns an array of Node instances.



43
44
45
# File 'lib/turbine/node.rb', line 43

def out(label = nil)
  Pipeline.dsl(self).out(label)
end

#out_edges(label = nil) ⇒ Object

Public: Returns this node’s outgoing edges.

label - An optional label; only edges with this label will be returned.

Passing nil will return all out edges.

Raises an InvalidEdgeFilterError if you supply both a label and block for filtering the edges.

Returns an array of Edges.



69
70
71
# File 'lib/turbine/node.rb', line 69

def out_edges(label = nil)
  Pipeline.dsl(self).out_edges(label)
end