tem_mr_search 0.3 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +2 -0
- data/lib/tem_mr_search/client.rb +15 -6
- data/lib/tem_mr_search/map_reduce_executor.rb +45 -8
- data/lib/tem_mr_search/map_reduce_job.rb +10 -3
- data/lib/tem_mr_search/map_reduce_planner.rb +47 -24
- data/lib/tem_mr_search/server.rb +2 -2
- data/tem_mr_search.gemspec +1 -1
- data/test/test_client_server.rb +4 -3
- data/test/test_map_reduce_executor.rb +23 -7
- data/test/test_map_reduce_planner.rb +14 -9
- data/testdata/parallel_plan_431.yml +36 -36
- data/testdata/parallel_plan_740.yml +60 -60
- data/testdata/serial_plan_410.yml +21 -21
- data/testdata/serial_plan_431.yml +38 -38
- data/testdata/serial_plan_740.yml +61 -61
- metadata +1 -1
data/CHANGELOG
CHANGED
data/lib/tem_mr_search/client.rb
CHANGED
|
@@ -37,16 +37,25 @@ class Client
|
|
|
37
37
|
# server_addr:: string with the address of the Map-Reduce server's RPC port.
|
|
38
38
|
# client_query:: a ClientQuery instance expressing the Map-Reduce search
|
|
39
39
|
#
|
|
40
|
-
# Returns
|
|
40
|
+
# Returns a hash with the following keys:
|
|
41
|
+
# :result:: the result of the Map-Reduce computation
|
|
42
|
+
# :timings:: timing statistics on the job's execution
|
|
41
43
|
def self.search(server_addr, client_query)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
tem_certs = {}
|
|
45
|
+
tem_ids = {}
|
|
46
|
+
[:mapper, :reducer, :finalizer].each do |sec|
|
|
47
|
+
tem_info = get_tem server_addr
|
|
48
|
+
tem_ids[sec] = tem_info[:id]
|
|
49
|
+
# TODO: check the endorsement certificate.
|
|
50
|
+
tem_certs[sec] = tem_info[:pubek]
|
|
51
|
+
end
|
|
52
|
+
client_query.bind tem_certs
|
|
45
53
|
|
|
46
54
|
output = issue_request server_addr, :type => :search,
|
|
47
|
-
:
|
|
55
|
+
:root_tems => tem_ids,
|
|
48
56
|
:map_reduce => client_query.to_hash
|
|
49
|
-
|
|
57
|
+
return nil unless output
|
|
58
|
+
output.merge! :result => client_query.unpack_output(output[:result])
|
|
50
59
|
end
|
|
51
60
|
|
|
52
61
|
# Asks for an item in the server's database.
|
|
@@ -23,9 +23,11 @@ class MapReduceExecutor
|
|
|
23
23
|
# job:: the Map-Reduce job (see Tem::Mr::Search::MapReduceJob)
|
|
24
24
|
# db:: the database to run Map-Reduce over
|
|
25
25
|
# tems:: sessions to the available TEMs
|
|
26
|
-
#
|
|
26
|
+
# root_tems:: the indexes of the TEMs that have the initial SECpacks bound
|
|
27
|
+
# to them (hash with the keys +:mapper+, +:reducer+ and
|
|
28
|
+
# +:finalizer+)
|
|
27
29
|
# planner_class:: (optional) replacement for the default planner strategy
|
|
28
|
-
def initialize(job, db, tems,
|
|
30
|
+
def initialize(job, db, tems, root_tems, planner_class = nil)
|
|
29
31
|
planner_class ||= MapReducePlanner
|
|
30
32
|
|
|
31
33
|
@db = db # Writable only in main thread.
|
|
@@ -35,15 +37,20 @@ class MapReduceExecutor
|
|
|
35
37
|
@tem_certs = Array.new @tems.length
|
|
36
38
|
|
|
37
39
|
# Writable only in main thread.
|
|
38
|
-
@planner = planner_class.new job, db.length, tems.length,
|
|
40
|
+
@planner = planner_class.new job, db.length, tems.length, root_tems
|
|
39
41
|
|
|
40
42
|
# Protected by @lock
|
|
41
|
-
@tem_parts = { :mapper => {
|
|
42
|
-
:reducer => {
|
|
43
|
-
:finalizer => {
|
|
43
|
+
@tem_parts = { :mapper => { root_tems[:mapper] => job.mapper },
|
|
44
|
+
:reducer => {root_tems[:reducer] => job.reducer },
|
|
45
|
+
:finalizer => { root_tems[:finalizer] => job.finalizer } }
|
|
44
46
|
# Protected by @lock
|
|
45
47
|
@outputs = {}
|
|
46
48
|
|
|
49
|
+
# Protected by @lock
|
|
50
|
+
@timings = { :tems => Array.new(@tems.length, 0.0),
|
|
51
|
+
:tasks => { :map => 0.0, :reduce => 0.0, :finalize => 0.0,
|
|
52
|
+
:migrate => 0.0 } }
|
|
53
|
+
|
|
47
54
|
# Thread-safe.
|
|
48
55
|
@thread_queues = tems.map { |tem| Queue.new }
|
|
49
56
|
@main_queue = Queue.new
|
|
@@ -51,6 +58,10 @@ class MapReduceExecutor
|
|
|
51
58
|
end
|
|
52
59
|
|
|
53
60
|
# Executes the job.
|
|
61
|
+
#
|
|
62
|
+
# Returns a hash with the following keys:
|
|
63
|
+
# :result:: the job's result
|
|
64
|
+
# :timings:: timing statistics on the job's execution
|
|
54
65
|
def execute
|
|
55
66
|
collect_tem_ids
|
|
56
67
|
|
|
@@ -67,8 +78,8 @@ class MapReduceExecutor
|
|
|
67
78
|
@planner.action_done action
|
|
68
79
|
end
|
|
69
80
|
|
|
70
|
-
return @outputs[@planner.output_id]
|
|
71
|
-
end
|
|
81
|
+
return { :result => @outputs[@planner.output_id], :timings => @timings }
|
|
82
|
+
end
|
|
72
83
|
|
|
73
84
|
# Collects identification information from all the TEMs.
|
|
74
85
|
def collect_tem_ids
|
|
@@ -95,14 +106,22 @@ class MapReduceExecutor
|
|
|
95
106
|
#
|
|
96
107
|
# This method is called on the thread corresponding to the TEM that the action
|
|
97
108
|
# is supposed to execute on.
|
|
109
|
+
#
|
|
110
|
+
# The method's return value is unspecified.
|
|
98
111
|
def execute_action(action, tem_index)
|
|
99
112
|
case action[:action]
|
|
100
113
|
when :migrate
|
|
101
114
|
in_part = @lock.synchronize { @tem_parts[action[:secpack]][tem_index] }
|
|
102
115
|
target_ecert = @tem_certs[action[:to]]
|
|
116
|
+
|
|
117
|
+
t0 = Time.now
|
|
103
118
|
out_part = in_part.migrate target_ecert, @tems[tem_index]
|
|
119
|
+
time_delta = Time.now - t0
|
|
120
|
+
|
|
104
121
|
@lock.synchronize do
|
|
105
122
|
@tem_parts[action[:secpack]][action[:to]] = out_part
|
|
123
|
+
@timings[:tems][tem_index] += time_delta
|
|
124
|
+
@timings[:tasks][:migrate] += time_delta
|
|
106
125
|
end
|
|
107
126
|
|
|
108
127
|
when :map
|
|
@@ -111,9 +130,15 @@ class MapReduceExecutor
|
|
|
111
130
|
mapper = @tem_parts[:mapper][tem_index]
|
|
112
131
|
item = @db.item(action[:item])
|
|
113
132
|
end
|
|
133
|
+
|
|
134
|
+
t0 = Time.now
|
|
114
135
|
output = mapper.map_object item, @tems[tem_index]
|
|
136
|
+
time_delta = Time.now - t0
|
|
137
|
+
|
|
115
138
|
@lock.synchronize do
|
|
116
139
|
@outputs[action[:output_id]] = output
|
|
140
|
+
@timings[:tems][tem_index] += time_delta
|
|
141
|
+
@timings[:tasks][:map] += time_delta
|
|
117
142
|
end
|
|
118
143
|
|
|
119
144
|
when :reduce
|
|
@@ -123,9 +148,15 @@ class MapReduceExecutor
|
|
|
123
148
|
output1 = @outputs[action[:output1_id]]
|
|
124
149
|
output2 = @outputs[action[:output2_id]]
|
|
125
150
|
end
|
|
151
|
+
|
|
152
|
+
t0 = Time.now
|
|
126
153
|
output = reducer.reduce_outputs output1, output2, @tems[tem_index]
|
|
154
|
+
time_delta = Time.now - t0
|
|
155
|
+
|
|
127
156
|
@lock.synchronize do
|
|
128
157
|
@outputs[action[:output_id]] = output
|
|
158
|
+
@timings[:tems][tem_index] += time_delta
|
|
159
|
+
@timings[:tasks][:reduce] += time_delta
|
|
129
160
|
end
|
|
130
161
|
|
|
131
162
|
when :finalize
|
|
@@ -134,9 +165,15 @@ class MapReduceExecutor
|
|
|
134
165
|
finalizer = @tem_parts[:finalizer][tem_index]
|
|
135
166
|
output = @outputs[action[:output_id]]
|
|
136
167
|
end
|
|
168
|
+
|
|
169
|
+
t0 = Time.now
|
|
137
170
|
final_output = finalizer.finalize_output output, @tems[tem_index]
|
|
171
|
+
time_delta = Time.now - t0
|
|
172
|
+
|
|
138
173
|
@lock.synchronize do
|
|
139
174
|
@outputs[action[:final_id]] = final_output
|
|
175
|
+
@timings[:tems][tem_index] += time_delta
|
|
176
|
+
@timings[:tasks][:finalize] += time_delta
|
|
140
177
|
end
|
|
141
178
|
end
|
|
142
179
|
end
|
|
@@ -48,9 +48,16 @@ class MapReduceJob
|
|
|
48
48
|
:finalize => @finalizer.to_plain_object }
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
# Binds the SECpacks in this job to the given
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
# Binds the SECpacks in this job to the given keys.
|
|
52
|
+
#
|
|
53
|
+
# Args:
|
|
54
|
+
# tem_pubeks:: the public keys to bind the SECpacks to; hash with the keys
|
|
55
|
+
# +:mapper+, +:reducer+ and +:finalizer+; each key is mapped to
|
|
56
|
+
# a TEM key
|
|
57
|
+
def bind(tem_pubeks)
|
|
58
|
+
@mapper.bind tem_pubeks[:mapper]
|
|
59
|
+
@reducer.bind tem_pubeks[:reducer]
|
|
60
|
+
@finalizer.bind tem_pubeks[:finalizer]
|
|
54
61
|
end
|
|
55
62
|
|
|
56
63
|
# Base class for the Map-Reduce SECpack wrappers.
|
|
@@ -36,19 +36,37 @@ class MapReducePlanner
|
|
|
36
36
|
# job:: the Map-Reduce job (see Tem::Mr::Search::MapReduceJob)
|
|
37
37
|
# num_items: how many data items does the Map-Reduce run over
|
|
38
38
|
# num_tems:: how many TEMs are available
|
|
39
|
-
#
|
|
40
|
-
|
|
39
|
+
# root_tems:: the indexes of the TEMs that have the initial SECpacks bound
|
|
40
|
+
# to them (hash with the keys +:mapper+, +:reducer+ and
|
|
41
|
+
# +:finalizer+)
|
|
42
|
+
def initialize(job, num_items, num_tems, root_tems)
|
|
41
43
|
@job = job
|
|
42
|
-
@
|
|
44
|
+
@root_tems = root_tems
|
|
43
45
|
|
|
44
46
|
@without = { :mapper => RBTree.new, :reducer => RBTree.new }
|
|
45
|
-
@with = { :mapper => Set.new([
|
|
46
|
-
:reducer => Set.new([
|
|
47
|
+
@with = { :mapper => Set.new([@root_tems[:mapper]]),
|
|
48
|
+
:reducer => Set.new([@root_tems[:reducer]]) }
|
|
47
49
|
@free_tems = RBTree.new
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
|
|
51
|
+
# TEM ordering: the mapper root is first, the reducer root is last, and the
|
|
52
|
+
# finalizer root is second
|
|
53
|
+
@ordered_tems = (0...num_tems).to_a
|
|
54
|
+
@ordered_tems -= @root_tems.values
|
|
55
|
+
@ordered_tems = [@root_tems[:mapper]] + @ordered_tems
|
|
56
|
+
unless @ordered_tems.include? @root_tems[:reducer]
|
|
57
|
+
@ordered_tems += [@root_tems[:reducer]]
|
|
58
|
+
end
|
|
59
|
+
unless @ordered_tems.include? @root_tems[:finalizer]
|
|
60
|
+
@ordered_tems = [@ordered_tems[0], @root_tems[:finalizer]] +
|
|
61
|
+
@ordered_tems[1..-1]
|
|
62
|
+
end
|
|
63
|
+
# Reverted index for the TEM ordering.
|
|
64
|
+
@rindex_tems = Array.new(num_tems)
|
|
65
|
+
@ordered_tems.each_with_index { |t, i| @rindex_tems[t] = i }
|
|
66
|
+
|
|
67
|
+
@ordered_tems.each_with_index do |tem, i|
|
|
68
|
+
@free_tems[[i, tem]] = true
|
|
69
|
+
@without.each { |k, v| v[[i, tem]] = true unless tem == @root_tems[k] }
|
|
52
70
|
end
|
|
53
71
|
|
|
54
72
|
@unmapped_items = (0...num_items).to_a.reverse
|
|
@@ -125,10 +143,11 @@ class MapReducePlanner
|
|
|
125
143
|
return actions if @without[sec_type].length == 0
|
|
126
144
|
free_tems = free_tems_with_sec sec_type
|
|
127
145
|
free_tems.each do |source_tem|
|
|
128
|
-
break if @without[sec_type].length == 0
|
|
129
|
-
target_tem = @without[sec_type].min
|
|
130
|
-
|
|
131
|
-
@
|
|
146
|
+
break if @without[sec_type].length == 0
|
|
147
|
+
target_tem = (sec_type == :mapper ? @without[sec_type].min :
|
|
148
|
+
@without[sec_type].max).first.last
|
|
149
|
+
@without[sec_type].delete [@rindex_tems[target_tem], target_tem]
|
|
150
|
+
@free_tems.delete [@rindex_tems[source_tem], source_tem]
|
|
132
151
|
actions.push :action => :migrate, :secpack => sec_type,
|
|
133
152
|
:with => source_tem, :to => target_tem
|
|
134
153
|
end
|
|
@@ -138,7 +157,7 @@ class MapReducePlanner
|
|
|
138
157
|
|
|
139
158
|
# Informs the planner that a SECpack migration has completed.
|
|
140
159
|
def done_migrating(action)
|
|
141
|
-
@free_tems[action[:with]] = true
|
|
160
|
+
@free_tems[[@rindex_tems[action[:with]], action[:with]]] = true
|
|
142
161
|
@with[action[:secpack]] << action[:to]
|
|
143
162
|
end
|
|
144
163
|
private :done_migrating
|
|
@@ -151,7 +170,7 @@ class MapReducePlanner
|
|
|
151
170
|
return actions if @unmapped_items.empty?
|
|
152
171
|
free_tems_with_sec(:mapper).each do |tem|
|
|
153
172
|
break unless item = @unmapped_items.pop
|
|
154
|
-
@free_tems.delete tem
|
|
173
|
+
@free_tems.delete [@rindex_tems[tem], tem]
|
|
155
174
|
actions.push :action => :map, :item => item, :with => tem,
|
|
156
175
|
:output_id => next_output_id
|
|
157
176
|
end
|
|
@@ -166,7 +185,7 @@ class MapReducePlanner
|
|
|
166
185
|
#
|
|
167
186
|
# The return value is not specified.
|
|
168
187
|
def done_mapping(action)
|
|
169
|
-
@free_tems[action[:with]] = true
|
|
188
|
+
@free_tems[[@rindex_tems[action[:with]], action[:with]]] = true
|
|
170
189
|
@reduce_queue[action[:output_id]] = true
|
|
171
190
|
end
|
|
172
191
|
private :done_mapping
|
|
@@ -177,14 +196,14 @@ class MapReducePlanner
|
|
|
177
196
|
def reduce_actions
|
|
178
197
|
actions = []
|
|
179
198
|
return actions if @reduce_queue.length <= 1
|
|
180
|
-
free_tems_with_sec(:reducer).each do |tem|
|
|
199
|
+
free_tems_with_sec(:reducer).reverse.each do |tem|
|
|
181
200
|
break if @reduce_queue.length <= 1
|
|
182
201
|
output1_id, output2_id = *[0, 1].map do |i|
|
|
183
202
|
output_id = @reduce_queue.min.first
|
|
184
203
|
@reduce_queue.delete output_id
|
|
185
204
|
output_id
|
|
186
205
|
end
|
|
187
|
-
@free_tems.delete tem
|
|
206
|
+
@free_tems.delete [@rindex_tems[tem], tem]
|
|
188
207
|
actions.push :action => :reduce, :with => tem, :output1_id => output1_id,
|
|
189
208
|
:output2_id => output2_id, :output_id => next_output_id
|
|
190
209
|
end
|
|
@@ -199,7 +218,7 @@ class MapReducePlanner
|
|
|
199
218
|
#
|
|
200
219
|
# The return value is not specified.
|
|
201
220
|
def done_reducing(action)
|
|
202
|
-
@free_tems[action[:with]] = true
|
|
221
|
+
@free_tems[[@rindex_tems[action[:with]], action[:with]]] = true
|
|
203
222
|
if action[:output_id] == @last_reduce_id
|
|
204
223
|
@done_reducing = true
|
|
205
224
|
return
|
|
@@ -212,9 +231,13 @@ class MapReducePlanner
|
|
|
212
231
|
#
|
|
213
232
|
# See next_actions! for a description of the return value.
|
|
214
233
|
def finalize_actions
|
|
215
|
-
|
|
234
|
+
root_tem = @root_tems[:finalizer]
|
|
235
|
+
unless @done_reducing and !@output_id and
|
|
236
|
+
@free_tems[[@rindex_tems[root_tem], root_tem]]
|
|
237
|
+
return []
|
|
238
|
+
end
|
|
216
239
|
@finalize_ready = false
|
|
217
|
-
return [ :action => :finalize, :with =>
|
|
240
|
+
return [ :action => :finalize, :with => root_tem,
|
|
218
241
|
:output_id => @last_reduce_id, :final_id => next_output_id ]
|
|
219
242
|
end
|
|
220
243
|
private :finalize_actions
|
|
@@ -226,7 +249,7 @@ class MapReducePlanner
|
|
|
226
249
|
#
|
|
227
250
|
# The return value is not specified.
|
|
228
251
|
def done_finalizing(action)
|
|
229
|
-
@free_tems[action[:with]] = true
|
|
252
|
+
@free_tems[[@rindex_tems[action[:with]], action[:with]]] = true
|
|
230
253
|
@output_id = action[:final_id]
|
|
231
254
|
end
|
|
232
255
|
private :done_finalizing
|
|
@@ -237,8 +260,8 @@ class MapReducePlanner
|
|
|
237
260
|
# sec_type:: the SECpack type (+:mapper+ or +:reducer+)
|
|
238
261
|
def free_tems_with_sec(sec_type)
|
|
239
262
|
tems = []
|
|
240
|
-
@free_tems.each do |
|
|
241
|
-
tems <<
|
|
263
|
+
@free_tems.each do |index_tem, true_value|
|
|
264
|
+
tems << index_tem.last if @with[sec_type].include? index_tem.last
|
|
242
265
|
end
|
|
243
266
|
tems
|
|
244
267
|
end
|
data/lib/tem_mr_search/server.rb
CHANGED
|
@@ -85,8 +85,8 @@ class Server
|
|
|
85
85
|
when :search
|
|
86
86
|
refresh_tems!
|
|
87
87
|
job = MapReduceJob.new request[:map_reduce]
|
|
88
|
-
|
|
89
|
-
executor = MapReduceExecutor.new job, @db, @tems,
|
|
88
|
+
root_tems = request[:root_tems]
|
|
89
|
+
executor = MapReduceExecutor.new job, @db, @tems, root_tems
|
|
90
90
|
executor.execute
|
|
91
91
|
when :fetch
|
|
92
92
|
@db.item_by_id(request[:id]) || :not_found
|
data/tem_mr_search.gemspec
CHANGED
data/test/test_client_server.rb
CHANGED
|
@@ -72,12 +72,13 @@ class ClientServerTest < MrTestCase
|
|
|
72
72
|
[$tem]
|
|
73
73
|
end
|
|
74
74
|
_test_request do |server_addr|
|
|
75
|
-
|
|
75
|
+
data = Client.search server_addr, @client_query
|
|
76
76
|
gold_item = @db.item 5
|
|
77
|
-
assert_equal fare_id(gold_item), result[:id],
|
|
77
|
+
assert_equal fare_id(gold_item), data[:result][:id],
|
|
78
78
|
'Incorrect Map-Reduce result (ID)'
|
|
79
|
-
assert_equal fare_score(gold_item), result[:score],
|
|
79
|
+
assert_equal fare_score(gold_item), data[:result][:score],
|
|
80
80
|
'Incorrect Map-Reduce result (score)'
|
|
81
|
+
assert data[:timings], 'No timing statistics in Map-Reduce result'
|
|
81
82
|
end
|
|
82
83
|
end
|
|
83
84
|
end
|
|
@@ -17,20 +17,36 @@ class MapReduceExecutorTest < MrTestCase
|
|
|
17
17
|
super
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def _test_executor(tems,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
def _test_executor(tems, root_tems)
|
|
21
|
+
certs = {}
|
|
22
|
+
[:mapper, :reducer, :finalizer].each do |sec|
|
|
23
|
+
certs[sec] = tems[root_tems[sec]].pubek
|
|
24
|
+
end
|
|
25
|
+
@client_query.bind certs
|
|
26
|
+
executor = MRExecutor.new @client_query, @db, tems, root_tems
|
|
27
|
+
data = executor.execute
|
|
28
|
+
result = @client_query.unpack_output data[:result]
|
|
29
|
+
|
|
25
30
|
gold_item = @db.item 5
|
|
26
31
|
assert_equal fare_id(gold_item), result[:id],
|
|
27
32
|
'Incorrect Map-Reduce result (ID)'
|
|
28
33
|
assert_equal fare_score(gold_item), result[:score],
|
|
29
34
|
'Incorrect Map-Reduce result (score)'
|
|
35
|
+
|
|
36
|
+
assert data[:timings], 'No timings returned'
|
|
37
|
+
assert data[:timings][:tasks], 'No tasks data in the timings'
|
|
38
|
+
[:map, :reduce, :finalize, :migrate].each do |task|
|
|
39
|
+
assert data[:timings][:tasks][task], "No data on #{task} in the timings"
|
|
40
|
+
end
|
|
41
|
+
assert_operator data[:timings][:tems], :kind_of?, Array,
|
|
42
|
+
'No per-TEM data in the timings'
|
|
43
|
+
|
|
44
|
+
# Dump timing stats to show scheduler performance.
|
|
45
|
+
p data[:timings]
|
|
30
46
|
end
|
|
31
47
|
|
|
32
48
|
def test_executor_with_autoconf
|
|
33
|
-
_test_executor [$tem], 0
|
|
49
|
+
_test_executor [$tem], {:mapper => 0, :reducer => 0, :finalizer => 0}
|
|
34
50
|
end
|
|
35
51
|
|
|
36
52
|
def test_executor_with_cluster
|
|
@@ -39,6 +55,6 @@ class MapReduceExecutorTest < MrTestCase
|
|
|
39
55
|
|
|
40
56
|
tems.each { |tem| tem.emit if tem.activate }
|
|
41
57
|
|
|
42
|
-
_test_executor tems, 0
|
|
58
|
+
_test_executor tems, {:mapper => 0, :reducer => 7, :finalizer => 0}
|
|
43
59
|
end
|
|
44
60
|
end
|
|
@@ -31,25 +31,30 @@ class MapReducePlannerTest < Test::Unit::TestCase
|
|
|
31
31
|
all_actions
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
def _test_planning(method_name, items, tems,
|
|
35
|
-
planner = MRPlanner.new nil, items, tems,
|
|
34
|
+
def _test_planning(method_name, items, tems, root_tems, gold_file)
|
|
35
|
+
planner = MRPlanner.new nil, items, tems, root_tems
|
|
36
36
|
all_actions = self.send method_name, planner
|
|
37
37
|
gold_actions = File.open(File.join(@testdata_path, gold_file), 'r') do |f|
|
|
38
38
|
YAML.load f
|
|
39
39
|
end
|
|
40
40
|
assert_equal gold_actions, all_actions, "Failed #{method_name}: " +
|
|
41
|
-
"#{tems} tems with
|
|
41
|
+
"#{tems} tems with roots #{root_tems.inspect}, #{items} items"
|
|
42
42
|
assert_equal items * 2 - 1, planner.output_id, "Wrong final output_id"
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def test_planning
|
|
46
|
-
[[:parallel_planning, 7, 4, 0,
|
|
47
|
-
|
|
48
|
-
[:
|
|
49
|
-
|
|
50
|
-
[:serial_planning, 4,
|
|
46
|
+
[[:parallel_planning, 7, 4, { :mapper => 0, :reducer => 3, :finalizer => 1},
|
|
47
|
+
'parallel_plan_740.yml'],
|
|
48
|
+
[:parallel_planning, 4, 3, { :mapper => 1, :reducer => 2, :finalizer => 0},
|
|
49
|
+
'parallel_plan_431.yml'],
|
|
50
|
+
[:serial_planning, 4, 1, { :mapper => 0, :reducer => 0, :finalizer => 0},
|
|
51
|
+
'serial_plan_410.yml'],
|
|
52
|
+
[:serial_planning, 7, 4, { :mapper => 0, :reducer => 3, :finalizer => 0},
|
|
53
|
+
'serial_plan_740.yml'],
|
|
54
|
+
[:serial_planning, 4, 3, { :mapper => 0, :reducer => 2, :finalizer => 1},
|
|
55
|
+
'serial_plan_431.yml'],
|
|
51
56
|
].each do |testcase|
|
|
52
|
-
_test_planning
|
|
57
|
+
_test_planning(*testcase)
|
|
53
58
|
end
|
|
54
59
|
end
|
|
55
60
|
end
|
|
@@ -1,52 +1,52 @@
|
|
|
1
1
|
---
|
|
2
|
-
- - :
|
|
3
|
-
:action: :migrate
|
|
2
|
+
- - :action: :migrate
|
|
4
3
|
:with: 1
|
|
4
|
+
:secpack: :mapper
|
|
5
5
|
:to: 0
|
|
6
|
-
-
|
|
7
|
-
:
|
|
8
|
-
:
|
|
9
|
-
:to: 2
|
|
10
|
-
- :secpack: :reducer
|
|
11
|
-
:action: :migrate
|
|
12
|
-
:with: 1
|
|
6
|
+
- :action: :migrate
|
|
7
|
+
:with: 2
|
|
8
|
+
:secpack: :reducer
|
|
13
9
|
:to: 0
|
|
14
|
-
- - :
|
|
15
|
-
:action: :migrate
|
|
16
|
-
:with: 0
|
|
17
|
-
:to: 2
|
|
18
|
-
- :output_id: 0
|
|
19
|
-
:action: :map
|
|
10
|
+
- - :action: :migrate
|
|
20
11
|
:with: 1
|
|
12
|
+
:secpack: :mapper
|
|
13
|
+
:to: 2
|
|
14
|
+
- :action: :migrate
|
|
15
|
+
:with: 0
|
|
16
|
+
:secpack: :reducer
|
|
17
|
+
:to: 1
|
|
18
|
+
- - :action: :map
|
|
21
19
|
:item: 0
|
|
22
|
-
|
|
23
|
-
:
|
|
24
|
-
|
|
20
|
+
:with: 1
|
|
21
|
+
:output_id: 0
|
|
22
|
+
- :action: :map
|
|
25
23
|
:item: 1
|
|
26
|
-
- - :output_id: 2
|
|
27
|
-
:action: :map
|
|
28
24
|
:with: 0
|
|
25
|
+
:output_id: 1
|
|
26
|
+
- :action: :map
|
|
29
27
|
:item: 2
|
|
30
|
-
|
|
31
|
-
:
|
|
32
|
-
|
|
28
|
+
:with: 2
|
|
29
|
+
:output_id: 2
|
|
30
|
+
- - :action: :map
|
|
33
31
|
:item: 3
|
|
34
|
-
|
|
35
|
-
:
|
|
32
|
+
:with: 1
|
|
33
|
+
:output_id: 3
|
|
34
|
+
- :action: :reduce
|
|
35
|
+
:with: 2
|
|
36
36
|
:output_id: 4
|
|
37
|
-
:
|
|
37
|
+
:output1_id: 0
|
|
38
|
+
:output2_id: 1
|
|
39
|
+
- - :action: :reduce
|
|
38
40
|
:with: 2
|
|
39
|
-
- - :output1_id: 2
|
|
40
|
-
:output2_id: 3
|
|
41
41
|
:output_id: 5
|
|
42
|
-
:
|
|
43
|
-
:
|
|
44
|
-
- - :
|
|
45
|
-
:
|
|
42
|
+
:output1_id: 2
|
|
43
|
+
:output2_id: 3
|
|
44
|
+
- - :action: :reduce
|
|
45
|
+
:with: 2
|
|
46
46
|
:output_id: 6
|
|
47
|
-
:
|
|
47
|
+
:output1_id: 4
|
|
48
|
+
:output2_id: 5
|
|
49
|
+
- - :action: :finalize
|
|
48
50
|
:with: 0
|
|
49
|
-
|
|
50
|
-
:action: :finalize
|
|
51
|
-
:with: 1
|
|
51
|
+
:output_id: 6
|
|
52
52
|
:final_id: 7
|
|
@@ -1,87 +1,87 @@
|
|
|
1
1
|
---
|
|
2
|
-
- - :
|
|
3
|
-
:action: :migrate
|
|
2
|
+
- - :action: :migrate
|
|
4
3
|
:with: 0
|
|
4
|
+
:secpack: :mapper
|
|
5
5
|
:to: 1
|
|
6
|
-
-
|
|
7
|
-
:
|
|
6
|
+
- :action: :migrate
|
|
7
|
+
:with: 3
|
|
8
|
+
:secpack: :reducer
|
|
9
|
+
:to: 2
|
|
10
|
+
- - :action: :migrate
|
|
8
11
|
:with: 0
|
|
12
|
+
:secpack: :mapper
|
|
9
13
|
:to: 2
|
|
10
|
-
- :
|
|
11
|
-
:action: :migrate
|
|
14
|
+
- :action: :migrate
|
|
12
15
|
:with: 1
|
|
16
|
+
:secpack: :mapper
|
|
13
17
|
:to: 3
|
|
14
|
-
-
|
|
15
|
-
:action: :migrate
|
|
16
|
-
:with: 0
|
|
17
|
-
:to: 1
|
|
18
|
-
- :output_id: 0
|
|
19
|
-
:action: :map
|
|
20
|
-
:with: 1
|
|
21
|
-
:item: 0
|
|
22
|
-
- :output_id: 1
|
|
23
|
-
:action: :map
|
|
18
|
+
- :action: :migrate
|
|
24
19
|
:with: 2
|
|
25
|
-
:
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
:secpack: :reducer
|
|
21
|
+
:to: 1
|
|
22
|
+
- :action: :migrate
|
|
28
23
|
:with: 3
|
|
29
|
-
:
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
:secpack: :reducer
|
|
25
|
+
:to: 0
|
|
26
|
+
- - :action: :map
|
|
27
|
+
:item: 0
|
|
32
28
|
:with: 0
|
|
33
|
-
:
|
|
34
|
-
- :
|
|
35
|
-
:
|
|
29
|
+
:output_id: 0
|
|
30
|
+
- :action: :map
|
|
31
|
+
:item: 1
|
|
36
32
|
:with: 1
|
|
37
|
-
:
|
|
38
|
-
- :
|
|
39
|
-
:
|
|
33
|
+
:output_id: 1
|
|
34
|
+
- :action: :map
|
|
35
|
+
:item: 2
|
|
40
36
|
:with: 2
|
|
37
|
+
:output_id: 2
|
|
38
|
+
- :action: :map
|
|
41
39
|
:item: 3
|
|
42
|
-
- :output_id: 4
|
|
43
|
-
:action: :map
|
|
44
40
|
:with: 3
|
|
41
|
+
:output_id: 3
|
|
42
|
+
- - :action: :map
|
|
45
43
|
:item: 4
|
|
46
|
-
- - :output_id: 5
|
|
47
|
-
:action: :map
|
|
48
44
|
:with: 0
|
|
45
|
+
:output_id: 4
|
|
46
|
+
- :action: :map
|
|
49
47
|
:item: 5
|
|
50
|
-
- :output_id: 6
|
|
51
|
-
:action: :map
|
|
52
48
|
:with: 1
|
|
49
|
+
:output_id: 5
|
|
50
|
+
- :action: :map
|
|
53
51
|
:item: 6
|
|
54
|
-
- :output1_id: 0
|
|
55
|
-
:output2_id: 1
|
|
56
|
-
:output_id: 7
|
|
57
|
-
:action: :reduce
|
|
58
52
|
:with: 2
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
:output_id: 8
|
|
62
|
-
:action: :reduce
|
|
53
|
+
:output_id: 6
|
|
54
|
+
- :action: :reduce
|
|
63
55
|
:with: 3
|
|
64
|
-
|
|
65
|
-
:
|
|
56
|
+
:output_id: 7
|
|
57
|
+
:output1_id: 0
|
|
58
|
+
:output2_id: 1
|
|
59
|
+
- - :action: :reduce
|
|
60
|
+
:with: 3
|
|
61
|
+
:output_id: 8
|
|
62
|
+
:output1_id: 2
|
|
63
|
+
:output2_id: 3
|
|
64
|
+
- :action: :reduce
|
|
65
|
+
:with: 2
|
|
66
66
|
:output_id: 9
|
|
67
|
-
:
|
|
68
|
-
:
|
|
69
|
-
- :
|
|
70
|
-
:output2_id: 7
|
|
71
|
-
:output_id: 10
|
|
72
|
-
:action: :reduce
|
|
67
|
+
:output1_id: 4
|
|
68
|
+
:output2_id: 5
|
|
69
|
+
- :action: :reduce
|
|
73
70
|
:with: 1
|
|
74
|
-
|
|
75
|
-
:
|
|
71
|
+
:output_id: 10
|
|
72
|
+
:output1_id: 6
|
|
73
|
+
:output2_id: 7
|
|
74
|
+
- - :action: :reduce
|
|
75
|
+
:with: 3
|
|
76
76
|
:output_id: 11
|
|
77
|
-
:
|
|
78
|
-
:
|
|
79
|
-
- - :
|
|
77
|
+
:output1_id: 8
|
|
78
|
+
:output2_id: 9
|
|
79
|
+
- - :action: :reduce
|
|
80
|
+
:with: 3
|
|
81
|
+
:output_id: 12
|
|
82
|
+
:output1_id: 10
|
|
80
83
|
:output2_id: 11
|
|
84
|
+
- - :action: :finalize
|
|
85
|
+
:with: 1
|
|
81
86
|
:output_id: 12
|
|
82
|
-
:action: :reduce
|
|
83
|
-
:with: 0
|
|
84
|
-
- - :output_id: 12
|
|
85
|
-
:action: :finalize
|
|
86
|
-
:with: 0
|
|
87
87
|
:final_id: 13
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
---
|
|
2
|
-
- - :
|
|
3
|
-
:action: :map
|
|
4
|
-
:with: 0
|
|
2
|
+
- - :action: :map
|
|
5
3
|
:item: 0
|
|
6
|
-
- - :output_id: 1
|
|
7
|
-
:action: :map
|
|
8
4
|
:with: 0
|
|
5
|
+
:output_id: 0
|
|
6
|
+
- - :action: :map
|
|
9
7
|
:item: 1
|
|
10
|
-
- - :output_id: 2
|
|
11
|
-
:action: :map
|
|
12
8
|
:with: 0
|
|
9
|
+
:output_id: 1
|
|
10
|
+
- - :action: :map
|
|
13
11
|
:item: 2
|
|
14
|
-
- - :output_id: 3
|
|
15
|
-
:action: :map
|
|
16
12
|
:with: 0
|
|
13
|
+
:output_id: 2
|
|
14
|
+
- - :action: :map
|
|
17
15
|
:item: 3
|
|
18
|
-
|
|
19
|
-
:
|
|
16
|
+
:with: 0
|
|
17
|
+
:output_id: 3
|
|
18
|
+
- - :action: :reduce
|
|
19
|
+
:with: 0
|
|
20
20
|
:output_id: 4
|
|
21
|
-
:
|
|
21
|
+
:output1_id: 0
|
|
22
|
+
:output2_id: 1
|
|
23
|
+
- - :action: :reduce
|
|
22
24
|
:with: 0
|
|
23
|
-
- - :output1_id: 2
|
|
24
|
-
:output2_id: 3
|
|
25
25
|
:output_id: 5
|
|
26
|
-
:
|
|
26
|
+
:output1_id: 2
|
|
27
|
+
:output2_id: 3
|
|
28
|
+
- - :action: :reduce
|
|
27
29
|
:with: 0
|
|
28
|
-
- - :output1_id: 4
|
|
29
|
-
:output2_id: 5
|
|
30
30
|
:output_id: 6
|
|
31
|
-
:
|
|
32
|
-
:
|
|
33
|
-
- - :
|
|
34
|
-
:action: :finalize
|
|
31
|
+
:output1_id: 4
|
|
32
|
+
:output2_id: 5
|
|
33
|
+
- - :action: :finalize
|
|
35
34
|
:with: 0
|
|
35
|
+
:output_id: 6
|
|
36
36
|
:final_id: 7
|
|
@@ -1,56 +1,56 @@
|
|
|
1
1
|
---
|
|
2
|
-
- - :
|
|
3
|
-
:action: :migrate
|
|
4
|
-
:with: 1
|
|
5
|
-
:to: 0
|
|
6
|
-
- - :secpack: :mapper
|
|
7
|
-
:action: :migrate
|
|
2
|
+
- - :action: :migrate
|
|
8
3
|
:with: 0
|
|
9
|
-
:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
:with:
|
|
13
|
-
:
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
:secpack: :mapper
|
|
5
|
+
:to: 1
|
|
6
|
+
- :action: :migrate
|
|
7
|
+
:with: 2
|
|
8
|
+
:secpack: :reducer
|
|
9
|
+
:to: 1
|
|
10
|
+
- - :action: :migrate
|
|
16
11
|
:with: 0
|
|
12
|
+
:secpack: :mapper
|
|
13
|
+
:to: 2
|
|
14
|
+
- :action: :map
|
|
17
15
|
:item: 0
|
|
18
|
-
|
|
19
|
-
:
|
|
16
|
+
:with: 1
|
|
17
|
+
:output_id: 0
|
|
18
|
+
- - :action: :migrate
|
|
20
19
|
:with: 2
|
|
20
|
+
:secpack: :reducer
|
|
21
|
+
:to: 0
|
|
22
|
+
- - :action: :map
|
|
21
23
|
:item: 1
|
|
22
|
-
- - :secpack: :reducer
|
|
23
|
-
:action: :migrate
|
|
24
|
-
:with: 1
|
|
25
|
-
:to: 2
|
|
26
|
-
- - :output_id: 2
|
|
27
|
-
:action: :map
|
|
28
24
|
:with: 0
|
|
25
|
+
:output_id: 1
|
|
26
|
+
- - :action: :map
|
|
29
27
|
:item: 2
|
|
30
|
-
|
|
31
|
-
:
|
|
32
|
-
|
|
28
|
+
:with: 1
|
|
29
|
+
:output_id: 2
|
|
30
|
+
- - :action: :map
|
|
33
31
|
:item: 3
|
|
34
|
-
|
|
35
|
-
:
|
|
32
|
+
:with: 2
|
|
33
|
+
:output_id: 3
|
|
34
|
+
- - :action: :reduce
|
|
35
|
+
:with: 0
|
|
36
36
|
:output_id: 4
|
|
37
|
-
:
|
|
38
|
-
:
|
|
37
|
+
:output1_id: 0
|
|
38
|
+
:output2_id: 1
|
|
39
39
|
- []
|
|
40
40
|
|
|
41
|
-
- - :
|
|
42
|
-
:
|
|
41
|
+
- - :action: :reduce
|
|
42
|
+
:with: 2
|
|
43
43
|
:output_id: 5
|
|
44
|
-
:
|
|
45
|
-
:
|
|
44
|
+
:output1_id: 2
|
|
45
|
+
:output2_id: 3
|
|
46
46
|
- []
|
|
47
47
|
|
|
48
|
-
- - :
|
|
49
|
-
:
|
|
48
|
+
- - :action: :reduce
|
|
49
|
+
:with: 2
|
|
50
50
|
:output_id: 6
|
|
51
|
-
:
|
|
52
|
-
:
|
|
53
|
-
- - :
|
|
54
|
-
:action: :finalize
|
|
51
|
+
:output1_id: 4
|
|
52
|
+
:output2_id: 5
|
|
53
|
+
- - :action: :finalize
|
|
55
54
|
:with: 1
|
|
55
|
+
:output_id: 6
|
|
56
56
|
:final_id: 7
|
|
@@ -1,93 +1,93 @@
|
|
|
1
1
|
---
|
|
2
|
-
- - :
|
|
3
|
-
:action: :migrate
|
|
2
|
+
- - :action: :migrate
|
|
4
3
|
:with: 0
|
|
4
|
+
:secpack: :mapper
|
|
5
5
|
:to: 1
|
|
6
|
-
-
|
|
7
|
-
:
|
|
6
|
+
- :action: :migrate
|
|
7
|
+
:with: 3
|
|
8
|
+
:secpack: :reducer
|
|
9
|
+
:to: 2
|
|
10
|
+
- - :action: :migrate
|
|
8
11
|
:with: 0
|
|
12
|
+
:secpack: :mapper
|
|
9
13
|
:to: 2
|
|
10
|
-
- :
|
|
11
|
-
:action: :migrate
|
|
14
|
+
- :action: :migrate
|
|
12
15
|
:with: 1
|
|
16
|
+
:secpack: :mapper
|
|
13
17
|
:to: 3
|
|
14
|
-
- - :
|
|
15
|
-
:action: :migrate
|
|
16
|
-
:with: 0
|
|
17
|
-
:to: 1
|
|
18
|
-
- :output_id: 0
|
|
19
|
-
:action: :map
|
|
18
|
+
- - :action: :migrate
|
|
20
19
|
:with: 2
|
|
20
|
+
:secpack: :reducer
|
|
21
|
+
:to: 1
|
|
22
|
+
- :action: :migrate
|
|
23
|
+
:with: 3
|
|
24
|
+
:secpack: :reducer
|
|
25
|
+
:to: 0
|
|
26
|
+
- - :action: :map
|
|
21
27
|
:item: 0
|
|
22
|
-
|
|
23
|
-
:
|
|
24
|
-
|
|
28
|
+
:with: 0
|
|
29
|
+
:output_id: 0
|
|
30
|
+
- - :action: :map
|
|
25
31
|
:item: 1
|
|
26
|
-
|
|
27
|
-
:
|
|
28
|
-
|
|
32
|
+
:with: 1
|
|
33
|
+
:output_id: 1
|
|
34
|
+
- - :action: :map
|
|
29
35
|
:item: 2
|
|
30
|
-
- - :secpack: :reducer
|
|
31
|
-
:action: :migrate
|
|
32
|
-
:with: 0
|
|
33
|
-
:to: 2
|
|
34
|
-
- - :output_id: 3
|
|
35
|
-
:action: :map
|
|
36
36
|
:with: 2
|
|
37
|
+
:output_id: 2
|
|
38
|
+
- - :action: :map
|
|
37
39
|
:item: 3
|
|
38
|
-
- - :secpack: :reducer
|
|
39
|
-
:action: :migrate
|
|
40
|
-
:with: 1
|
|
41
|
-
:to: 3
|
|
42
|
-
- - :output_id: 4
|
|
43
|
-
:action: :map
|
|
44
40
|
:with: 3
|
|
41
|
+
:output_id: 3
|
|
42
|
+
- - :action: :map
|
|
45
43
|
:item: 4
|
|
46
|
-
- - :output_id: 5
|
|
47
|
-
:action: :map
|
|
48
44
|
:with: 0
|
|
45
|
+
:output_id: 4
|
|
46
|
+
- - :action: :map
|
|
49
47
|
:item: 5
|
|
50
|
-
|
|
51
|
-
:
|
|
52
|
-
|
|
48
|
+
:with: 1
|
|
49
|
+
:output_id: 5
|
|
50
|
+
- - :action: :map
|
|
53
51
|
:item: 6
|
|
54
|
-
|
|
55
|
-
:
|
|
52
|
+
:with: 2
|
|
53
|
+
:output_id: 6
|
|
54
|
+
- - :action: :reduce
|
|
55
|
+
:with: 3
|
|
56
56
|
:output_id: 7
|
|
57
|
-
:
|
|
58
|
-
:
|
|
59
|
-
- - :
|
|
60
|
-
:
|
|
57
|
+
:output1_id: 0
|
|
58
|
+
:output2_id: 1
|
|
59
|
+
- - :action: :reduce
|
|
60
|
+
:with: 0
|
|
61
61
|
:output_id: 8
|
|
62
|
-
:
|
|
63
|
-
:
|
|
64
|
-
- - :
|
|
65
|
-
:
|
|
62
|
+
:output1_id: 2
|
|
63
|
+
:output2_id: 3
|
|
64
|
+
- - :action: :reduce
|
|
65
|
+
:with: 1
|
|
66
66
|
:output_id: 9
|
|
67
|
-
:
|
|
68
|
-
:
|
|
67
|
+
:output1_id: 4
|
|
68
|
+
:output2_id: 5
|
|
69
69
|
- []
|
|
70
70
|
|
|
71
|
-
- - :
|
|
72
|
-
:
|
|
71
|
+
- - :action: :reduce
|
|
72
|
+
:with: 3
|
|
73
73
|
:output_id: 10
|
|
74
|
-
:
|
|
75
|
-
:
|
|
74
|
+
:output1_id: 6
|
|
75
|
+
:output2_id: 7
|
|
76
76
|
- []
|
|
77
77
|
|
|
78
|
-
- - :
|
|
79
|
-
:
|
|
78
|
+
- - :action: :reduce
|
|
79
|
+
:with: 2
|
|
80
80
|
:output_id: 11
|
|
81
|
-
:
|
|
82
|
-
:
|
|
81
|
+
:output1_id: 8
|
|
82
|
+
:output2_id: 9
|
|
83
83
|
- []
|
|
84
84
|
|
|
85
|
-
- - :
|
|
86
|
-
:
|
|
85
|
+
- - :action: :reduce
|
|
86
|
+
:with: 3
|
|
87
87
|
:output_id: 12
|
|
88
|
-
:
|
|
89
|
-
:
|
|
90
|
-
- - :
|
|
91
|
-
:action: :finalize
|
|
88
|
+
:output1_id: 10
|
|
89
|
+
:output2_id: 11
|
|
90
|
+
- - :action: :finalize
|
|
92
91
|
:with: 0
|
|
92
|
+
:output_id: 12
|
|
93
93
|
:final_id: 13
|