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 CHANGED
@@ -1,3 +1,5 @@
1
+ v0.3.1. Optimized Map-Reduce scheduler. 1.5x speed increase.
2
+
1
3
  v0.3. SECpack binding and migration. Now we're secure.
2
4
 
3
5
  v0.2.5. Symmetric encryption for partial outputs.
@@ -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 the result of the Map-Reduce computation.
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
- tem_info = get_tem server_addr
43
- # TODO: check the endorsement certificate.
44
- client_query.bind tem_info[:pubek]
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
- :root_tem => tem_info[:id],
55
+ :root_tems => tem_ids,
48
56
  :map_reduce => client_query.to_hash
49
- output ? client_query.unpack_output(output) : nil
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
- # root_tem:: the index of the TEM that has the root mapper and reducer
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, root_tem, planner_class = nil)
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, root_tem
40
+ @planner = planner_class.new job, db.length, tems.length, root_tems
39
41
 
40
42
  # Protected by @lock
41
- @tem_parts = { :mapper => { root_tem => job.mapper },
42
- :reducer => { root_tem => job.reducer },
43
- :finalizer => { root_tem => job.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 key.
52
- def bind(tem_pubek)
53
- [@mapper, @reducer, @finalizer].each { |part| part.bind tem_pubek }
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
- # root_tem:: the index of the TEM that has the root mapper and reducer
40
- def initialize(job, num_items, num_tems, root_tem)
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
- @root_tem = root_tem
44
+ @root_tems = root_tems
43
45
 
44
46
  @without = { :mapper => RBTree.new, :reducer => RBTree.new }
45
- @with = { :mapper => Set.new([root_tem]),
46
- :reducer => Set.new([root_tem]) }
47
+ @with = { :mapper => Set.new([@root_tems[:mapper]]),
48
+ :reducer => Set.new([@root_tems[:reducer]]) }
47
49
  @free_tems = RBTree.new
48
- 0.upto(num_tems - 1) do |tem|
49
- @free_tems[tem] = true
50
- next if tem == root_tem
51
- @without.each { |k, v| v[tem] = true }
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.first
130
- @without[sec_type].delete target_tem
131
- @free_tems.delete source_tem
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
- return [] unless @done_reducing and !@output_id and @free_tems[@root_tem]
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 => @root_tem,
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 |tem, true_value|
241
- tems << tem if @with[sec_type].include? tem
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
@@ -85,8 +85,8 @@ class Server
85
85
  when :search
86
86
  refresh_tems!
87
87
  job = MapReduceJob.new request[:map_reduce]
88
- root_tem = request[:root_tem]
89
- executor = MapReduceExecutor.new job, @db, @tems, root_tem
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
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{tem_mr_search}
5
- s.version = "0.3"
5
+ s.version = "0.3.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Victor Costan"]
@@ -72,12 +72,13 @@ class ClientServerTest < MrTestCase
72
72
  [$tem]
73
73
  end
74
74
  _test_request do |server_addr|
75
- result = Client.search server_addr, @client_query
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, root_tem)
21
- @client_query.bind tems[root_tem].pubek
22
- executor = MRExecutor.new @client_query, @db, tems, root_tem
23
- packed_output = executor.execute
24
- result = @client_query.unpack_output packed_output
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, root_tem, gold_file)
35
- planner = MRPlanner.new nil, items, tems, root_tem
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 root #{root_tem}, #{items} items"
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, 'parallel_plan_740.yml'],
47
- [:parallel_planning, 4, 3, 1, 'parallel_plan_431.yml'],
48
- [:serial_planning, 4, 1, 0, 'serial_plan_410.yml'],
49
- [:serial_planning, 7, 4, 0, 'serial_plan_740.yml'],
50
- [:serial_planning, 4, 3, 1, 'serial_plan_431.yml'],
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 *testcase
57
+ _test_planning(*testcase)
53
58
  end
54
59
  end
55
60
  end
@@ -1,52 +1,52 @@
1
1
  ---
2
- - - :secpack: :mapper
3
- :action: :migrate
2
+ - - :action: :migrate
4
3
  :with: 1
4
+ :secpack: :mapper
5
5
  :to: 0
6
- - - :secpack: :mapper
7
- :action: :migrate
8
- :with: 0
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
- - - :secpack: :reducer
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
- - :output_id: 1
23
- :action: :map
24
- :with: 2
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
- - :output_id: 3
31
- :action: :map
32
- :with: 1
28
+ :with: 2
29
+ :output_id: 2
30
+ - - :action: :map
33
31
  :item: 3
34
- - :output1_id: 0
35
- :output2_id: 1
32
+ :with: 1
33
+ :output_id: 3
34
+ - :action: :reduce
35
+ :with: 2
36
36
  :output_id: 4
37
- :action: :reduce
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
- :action: :reduce
43
- :with: 0
44
- - - :output1_id: 4
45
- :output2_id: 5
42
+ :output1_id: 2
43
+ :output2_id: 3
44
+ - - :action: :reduce
45
+ :with: 2
46
46
  :output_id: 6
47
- :action: :reduce
47
+ :output1_id: 4
48
+ :output2_id: 5
49
+ - - :action: :finalize
48
50
  :with: 0
49
- - - :output_id: 6
50
- :action: :finalize
51
- :with: 1
51
+ :output_id: 6
52
52
  :final_id: 7
@@ -1,87 +1,87 @@
1
1
  ---
2
- - - :secpack: :mapper
3
- :action: :migrate
2
+ - - :action: :migrate
4
3
  :with: 0
4
+ :secpack: :mapper
5
5
  :to: 1
6
- - - :secpack: :mapper
7
- :action: :migrate
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
- - :secpack: :mapper
11
- :action: :migrate
14
+ - :action: :migrate
12
15
  :with: 1
16
+ :secpack: :mapper
13
17
  :to: 3
14
- - - :secpack: :reducer
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
- :item: 1
26
- - :output_id: 2
27
- :action: :map
20
+ :secpack: :reducer
21
+ :to: 1
22
+ - :action: :migrate
28
23
  :with: 3
29
- :item: 2
30
- - - :secpack: :reducer
31
- :action: :migrate
24
+ :secpack: :reducer
25
+ :to: 0
26
+ - - :action: :map
27
+ :item: 0
32
28
  :with: 0
33
- :to: 2
34
- - :secpack: :reducer
35
- :action: :migrate
29
+ :output_id: 0
30
+ - :action: :map
31
+ :item: 1
36
32
  :with: 1
37
- :to: 3
38
- - :output_id: 3
39
- :action: :map
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
- - :output1_id: 2
60
- :output2_id: 3
61
- :output_id: 8
62
- :action: :reduce
53
+ :output_id: 6
54
+ - :action: :reduce
63
55
  :with: 3
64
- - - :output1_id: 4
65
- :output2_id: 5
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
- :action: :reduce
68
- :with: 0
69
- - :output1_id: 6
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
- - - :output1_id: 8
75
- :output2_id: 9
71
+ :output_id: 10
72
+ :output1_id: 6
73
+ :output2_id: 7
74
+ - - :action: :reduce
75
+ :with: 3
76
76
  :output_id: 11
77
- :action: :reduce
78
- :with: 0
79
- - - :output1_id: 10
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
- - - :output_id: 0
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
- - - :output1_id: 0
19
- :output2_id: 1
16
+ :with: 0
17
+ :output_id: 3
18
+ - - :action: :reduce
19
+ :with: 0
20
20
  :output_id: 4
21
- :action: :reduce
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
- :action: :reduce
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
- :action: :reduce
32
- :with: 0
33
- - - :output_id: 6
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
- - - :secpack: :mapper
3
- :action: :migrate
4
- :with: 1
5
- :to: 0
6
- - - :secpack: :mapper
7
- :action: :migrate
2
+ - - :action: :migrate
8
3
  :with: 0
9
- :to: 2
10
- - :secpack: :reducer
11
- :action: :migrate
12
- :with: 1
13
- :to: 0
14
- - - :output_id: 0
15
- :action: :map
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
- - :output_id: 1
19
- :action: :map
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
- - - :output_id: 3
31
- :action: :map
32
- :with: 2
28
+ :with: 1
29
+ :output_id: 2
30
+ - - :action: :map
33
31
  :item: 3
34
- - - :output1_id: 0
35
- :output2_id: 1
32
+ :with: 2
33
+ :output_id: 3
34
+ - - :action: :reduce
35
+ :with: 0
36
36
  :output_id: 4
37
- :action: :reduce
38
- :with: 1
37
+ :output1_id: 0
38
+ :output2_id: 1
39
39
  - []
40
40
 
41
- - - :output1_id: 2
42
- :output2_id: 3
41
+ - - :action: :reduce
42
+ :with: 2
43
43
  :output_id: 5
44
- :action: :reduce
45
- :with: 0
44
+ :output1_id: 2
45
+ :output2_id: 3
46
46
  - []
47
47
 
48
- - - :output1_id: 4
49
- :output2_id: 5
48
+ - - :action: :reduce
49
+ :with: 2
50
50
  :output_id: 6
51
- :action: :reduce
52
- :with: 0
53
- - - :output_id: 6
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
- - - :secpack: :mapper
3
- :action: :migrate
2
+ - - :action: :migrate
4
3
  :with: 0
4
+ :secpack: :mapper
5
5
  :to: 1
6
- - - :secpack: :mapper
7
- :action: :migrate
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
- - :secpack: :mapper
11
- :action: :migrate
14
+ - :action: :migrate
12
15
  :with: 1
16
+ :secpack: :mapper
13
17
  :to: 3
14
- - - :secpack: :reducer
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
- - - :output_id: 1
23
- :action: :map
24
- :with: 1
28
+ :with: 0
29
+ :output_id: 0
30
+ - - :action: :map
25
31
  :item: 1
26
- - :output_id: 2
27
- :action: :map
28
- :with: 3
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
- - - :output_id: 6
51
- :action: :map
52
- :with: 2
48
+ :with: 1
49
+ :output_id: 5
50
+ - - :action: :map
53
51
  :item: 6
54
- - - :output1_id: 0
55
- :output2_id: 1
52
+ :with: 2
53
+ :output_id: 6
54
+ - - :action: :reduce
55
+ :with: 3
56
56
  :output_id: 7
57
- :action: :reduce
58
- :with: 1
59
- - - :output1_id: 2
60
- :output2_id: 3
57
+ :output1_id: 0
58
+ :output2_id: 1
59
+ - - :action: :reduce
60
+ :with: 0
61
61
  :output_id: 8
62
- :action: :reduce
63
- :with: 3
64
- - - :output1_id: 4
65
- :output2_id: 5
62
+ :output1_id: 2
63
+ :output2_id: 3
64
+ - - :action: :reduce
65
+ :with: 1
66
66
  :output_id: 9
67
- :action: :reduce
68
- :with: 0
67
+ :output1_id: 4
68
+ :output2_id: 5
69
69
  - []
70
70
 
71
- - - :output1_id: 6
72
- :output2_id: 7
71
+ - - :action: :reduce
72
+ :with: 3
73
73
  :output_id: 10
74
- :action: :reduce
75
- :with: 1
74
+ :output1_id: 6
75
+ :output2_id: 7
76
76
  - []
77
77
 
78
- - - :output1_id: 8
79
- :output2_id: 9
78
+ - - :action: :reduce
79
+ :with: 2
80
80
  :output_id: 11
81
- :action: :reduce
82
- :with: 0
81
+ :output1_id: 8
82
+ :output2_id: 9
83
83
  - []
84
84
 
85
- - - :output1_id: 10
86
- :output2_id: 11
85
+ - - :action: :reduce
86
+ :with: 3
87
87
  :output_id: 12
88
- :action: :reduce
89
- :with: 0
90
- - - :output_id: 12
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tem_mr_search
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.3"
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Costan