Class: ATP::Processors::Condition
Overview
This optimizes the condition nodes such that any adjacent flow nodes that have the same condition, will be grouped together under a single condition wrapper.
For example this AST:
(flow
(group
(name "g1")
(test
(name "test1"))
(flow-flag "bitmap" true
(test
(name "test2"))))
(flow-flag "bitmap" true
(group
(name "g1")
(flow-flag "x" true
(test
(name "test3")))
(flow-flag "y" true
(flow-flag "x" true
(test
(name "test4")))))))
Will be optimized to this:
(flow
(group
(name "g1")
(test
(name "test1"))
(flow-flag "bitmap" true
(test
(name "test2"))
(flow-flag "x" true
(test
(name "test3"))
(flow-flag "y" true
(test
(name "test4")))))))
Instance Method Summary
collapse
#clean_flag, #extract_volatiles, #handler_missing, #process, #process_all, #run, #volatile?, #volatile_flags
Instance Method Details
#can_be_combined?(node1, node2) ⇒ Boolean
110
111
112
113
114
115
116
|
# File 'lib/atp/processors/condition.rb', line 110
def can_be_combined?(node1, node2)
if condition_node?(node1) && condition_node?(node2)
!(conditions(node1) & conditions(node2)).empty?
else
false
end
end
|
#combine(node1, node2) ⇒ Object
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
# File 'lib/atp/processors/condition.rb', line 123
def combine(node1, node2)
common = conditions(node1) & conditions(node2)
common.each { |condition| conditions_to_remove << condition }
node1 = process(node1)
node1 = [node1] unless node1.is_a?(Array)
node2 = process(node2)
node2 = [node2] unless node2.is_a?(Array)
common.size.times { conditions_to_remove.pop }
node = nil
common.reverse_each do |condition|
if node
node = condition.updated(nil, condition.children + [node])
else
node = condition.updated(nil, condition.children + node1 + node2)
end
end
node
end
|
#condition_node?(node) ⇒ Boolean
118
119
120
121
|
# File 'lib/atp/processors/condition.rb', line 118
def condition_node?(node)
node.respond_to?(:type) && ATP::Flow::CONDITION_KEYS[node.type]
end
|
#conditions(node) ⇒ Object
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
# File 'lib/atp/processors/condition.rb', line 143
def conditions(node)
result = []
if [:if_enabled, :unless_enabled, :if_flag, :unless_flag].include?(node.type)
flag, *children = *node
unless volatile?(flag)
result << node.updated(nil, [flag])
end
result += conditions(children.first) if children.first && children.size == 1
elsif node.type == :group
name, *children = *node
if children.first.try(:type) == :id
result << node.updated(nil, [name, children.shift])
else
result << node.updated(nil, [name])
end
result += conditions(children.first) if children.first && children.size == 1
elsif ATP::Flow::CONDITION_NODE_TYPES.include?(node.type)
flag, *children = *node
result << node.updated(nil, [flag])
result += conditions(children.first) if children.first && children.size == 1
end
result
end
|
#conditions_to_remove ⇒ Object
170
171
172
|
# File 'lib/atp/processors/condition.rb', line 170
def conditions_to_remove
@conditions_to_remove ||= []
end
|
#on_condition_node(node) ⇒ Object
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
# File 'lib/atp/processors/condition.rb', line 65
def on_condition_node(node)
flag, *nodes = *node
if conditions_to_remove.any? { |c| node.type == c.type && c.to_a == [flag] }
if volatile?(flag)
result = node.updated(:inline, optimize(process_all(nodes)))
else
conditions_to_remove << node.updated(nil, [flag])
result = node.updated(:inline, optimize(process_all(nodes)))
conditions_to_remove.pop
end
else
if volatile?(flag)
result = node.updated(nil, [flag] + optimize(process_all(nodes)))
else
conditions_to_remove << node.updated(nil, [flag])
result = node.updated(nil, [flag] + optimize(process_all(nodes)))
conditions_to_remove.pop
end
end
result
end
|
#on_flow(node) ⇒ Object
46
47
48
49
|
# File 'lib/atp/processors/condition.rb', line 46
def on_flow(node)
(node)
node.updated(nil, optimize(process_all(node.children)))
end
|
#on_group(node) ⇒ Object
51
52
53
54
55
56
57
58
59
60
61
62
63
|
# File 'lib/atp/processors/condition.rb', line 51
def on_group(node)
name, *nodes = *node
if conditions_to_remove.any? { |c| node.type == c.type && c.to_a == [name] }
conditions_to_remove << node.updated(nil, [name])
result = node.updated(:inline, optimize(process_all(nodes)))
conditions_to_remove.pop
else
conditions_to_remove << node.updated(nil, [name])
result = node.updated(nil, [name] + optimize(process_all(nodes)))
conditions_to_remove.pop
end
result
end
|
#optimize(nodes) ⇒ Object
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/atp/processors/condition.rb', line 91
def optimize(nodes)
results = []
node1 = nil
nodes.each do |node2|
if node1
if can_be_combined?(node1, node2)
node1 = process(combine(node1, node2))
else
results << node1
node1 = node2
end
else
node1 = node2
end
end
results << node1 if node1
results
end
|