tem_mr_search 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ v0.2.5. Symmetric encryption for partial outputs.
2
+
1
3
  v0.2.4. Disabled Nagle's algorithm to shave off 100ms in query times.
2
4
 
3
5
  v0.2.3. Slightly more robust communication code in the RPC server/client.
data/Rakefile CHANGED
@@ -1,3 +1,9 @@
1
+ # Rakefile for the tem_mr_search Rubygem.
2
+ #
3
+ # Author:: Victor Costan
4
+ # Copyright:: Copyright (C) 2009 Massachusetts Institute of Technology
5
+ # License:: MIT
6
+
1
7
  require 'rubygems'
2
8
  gem 'echoe'
3
9
  require 'echoe'
@@ -10,7 +16,7 @@ Echoe.new('tem_mr_search') do |p|
10
16
  p.email = 'victor@costan.us'
11
17
  p.summary = 'Tem Map-Reduce proof of concept: database search.'
12
18
  p.url = 'http://tem.rubyforge.org'
13
- p.dependencies = ['tem_ruby >=0.13.0', 'tem_multi_proxy >=0.2.6']
19
+ p.dependencies = ['tem_ruby >=0.14.0', 'tem_multi_proxy >=0.2.7']
14
20
 
15
21
  p.need_tar_gz = !Gem.win_platform?
16
22
  p.need_zip = !Gem.win_platform?
@@ -1,11 +1,25 @@
1
+ # Client for the map-reduce RPC server.
2
+ #
3
+ # Author:: Victor Costan
4
+ # Copyright:: Copyright (C) 2009 Massachusetts Institute of Technology
5
+ # License:: MIT
6
+
1
7
  # :nodoc: namespace
2
8
  module Tem::Mr::Search
3
9
 
10
+
11
+ # Client for the map-reduce RPC server.
4
12
  class Client
5
13
  OP = Zerg::Support::Protocols::ObjectProtocol
6
14
  OPAdapter = Zerg::Support::Sockets::ProtocolAdapter.adapter_module OP
7
15
 
8
16
  # Performs a private database search using a Map-Reduce.
17
+ #
18
+ # Args:
19
+ # server_addr:: string with the address of the Map-Reduce server's RPC port.
20
+ # client_query:: a ClientQuery instance expressing the Map-Reduce search
21
+ #
22
+ # Returns the result of the Map-Reduce computation.
9
23
  def self.search(server_addr, client_query)
10
24
  output = issue_request server_addr, :type => :search, :root_tem => 0,
11
25
  :map_reduce => client_query.to_hash
@@ -34,6 +48,8 @@ class Client
34
48
  end
35
49
 
36
50
  # Issues a request against a Map-Reduce server and returns the response.
51
+ #
52
+ # This method should not be called directly.
37
53
  def self.issue_request(server_addr, request)
38
54
  socket = Zerg::Support::SocketFactory.socket :out_addr => server_addr,
39
55
  :out_port => Server::DEFAULT_PORT, :no_delay => true
@@ -43,6 +59,6 @@ class Client
43
59
  socket.close
44
60
  response
45
61
  end
46
- end
62
+ end # class Tem::Mr::Search::Client
47
63
 
48
64
  end # namespace Tem::Mr::Search
@@ -12,8 +12,7 @@ class ClientQuery < MapReduceJob
12
12
  # This is expected to be called with the encrypted output returned by the
13
13
  # search provider.
14
14
  def unpack_output(output)
15
- # TODO(costan): decrypt output once we enable encryption
16
- decrypted_output = output
15
+ decrypted_output = @query_key.decrypt output
17
16
  unpack_decrypted_output decrypted_output
18
17
  end
19
18
  end
@@ -1,26 +1,50 @@
1
+ # Mock database for the secure Map-Reduce proof of concept.
2
+ #
3
+ # Author:: Victor Costan
4
+ # Copyright:: Copyright (C) 2009 Massachusetts Institute of Technology
5
+ # License:: MIT
6
+
1
7
  # :nodoc: namespace
2
8
  module Tem::Mr::Search
3
-
9
+
10
+ # Mock database for the Map-Reduce proof of concept.
4
11
  class Db
5
12
  attr_reader :data
6
13
  attr_reader :id_attribute
7
14
 
15
+ # Creates a new mock database.
16
+ #
17
+ # Args:
18
+ # path:: filesystem path to the YAML file containing the database
8
19
  def initialize(path)
9
20
  @data = File.open(path, 'r') { |f| YAML.load f }
10
21
  @id_attribute = 'flight'
11
22
  end
12
23
 
24
+ # The number of records in the database.
13
25
  def length
14
26
  @data.length
15
27
  end
16
28
 
29
+ # Retrieves an item in table scan order.
30
+ #
31
+ # Args:
32
+ # item_index:: the item's 0-based index in table scan order
33
+ #
34
+ # Returns a hash with the item data.
17
35
  def item(item_index)
18
36
  @data[item_index]
19
37
  end
20
38
 
39
+ # Retrieves an item using its primary key.
40
+ #
41
+ # Args:
42
+ # item_id:: the item's primary key
43
+ #
44
+ # Returns a hash with the item data.
21
45
  def item_by_id(item_id)
22
46
  @data.find { |item| item[@id_attribute] == item_id }
23
47
  end
24
- end
48
+ end # class Tem::Mr::Search::Db
25
49
 
26
- end # namespace Tem::Mr::search
50
+ end # namespace Tem::Mr::Search
@@ -1,9 +1,21 @@
1
+ # Coordination code (executor) for performing a Map-Reduce computation.
2
+ #
3
+ # Author:: Victor Costan
4
+ # Copyright:: Copyright (C) 2009 Massachusetts Institute of Technology
5
+ # License:: MIT
6
+
1
7
  require 'thread'
2
8
 
3
9
 
4
10
  # :nodoc: namespace
5
11
  module Tem::Mr::Search
6
12
 
13
+ # Coordination code (executor) for performing a Map-Reduce computation.
14
+ #
15
+ # The executor distributes the Map-Reduce computation across multiple TEMs. The
16
+ # strategy used to allocate tasks to TEMs is expressed by a MapReducePlanner
17
+ # class, and the executor instantiates that class. The executor is responsible
18
+ # for coordinating between the TEMs and the planner.
7
19
  class MapReduceExecutor
8
20
  # Creates an executor for a Map-Reduce job.
9
21
  #
@@ -61,6 +73,7 @@ class MapReduceExecutor
61
73
  @main_queue << action
62
74
  end
63
75
  end
76
+ private :executor_thread
64
77
 
65
78
  # Executes a Map-Reduce planner action.
66
79
  #
@@ -108,8 +121,9 @@ class MapReduceExecutor
108
121
  @lock.synchronize do
109
122
  @outputs[action[:final_id]] = final_output
110
123
  end
111
- end
124
+ end
112
125
  end
113
- end
126
+ private :execute_action
127
+ end # class Tem::Mr::Search::MapReduceExecutor
114
128
 
115
129
  end # namespace Tem::Mr::Search
@@ -1,6 +1,22 @@
1
+ # Expresses a Map-Reduce computation whose components are performed on TEMs.
2
+ #
3
+ # Author:: Victor Costan
4
+ # Copyright:: Copyright (C) 2009 Massachusetts Institute of Technology
5
+ # License:: MIT
6
+
1
7
  # :nodoc: namespace
2
8
  module Tem::Mr::Search
3
9
 
10
+ # Expresses a Map-Reduce computation whose components are performed on TEMs.
11
+ #
12
+ # Client code should put together Map-Reduce computations using QueryBuilder or
13
+ # similar builder classes. In turn, builders construct and return MapReduceJob
14
+ # instances.
15
+ #
16
+ # Jobs can be serialized to a hash for network transmission. To de-serialize a
17
+ # job, pass the hash to the hash constructor:
18
+ # hash = job.to_hash
19
+ # job = MapReduceJob.new hash
4
20
  class MapReduceJob
5
21
  attr_reader :mapper, :reducer, :finalizer, :attributes, :id_attribute
6
22
 
@@ -18,7 +34,7 @@ class MapReduceJob
18
34
  {
19
35
  :id => output[0, 8].reverse.pack('C*').unpack('q').first,
20
36
  :score => Tem::Abi.read_tem_short(output, 8),
21
- :check => output[13, 3]
37
+ :check => output[13, 10]
22
38
  }
23
39
  end
24
40
 
@@ -1,9 +1,34 @@
1
+ # Allocates the individual components of a Map-Reduce job across TEMs.
2
+ #
3
+ # Author:: Victor Costan
4
+ # Copyright:: Copyright (C) 2009 Massachusetts Institute of Technology
5
+ # License:: MIT
6
+
1
7
  require 'rbtree'
2
8
  require 'set'
3
9
 
4
10
  # :nodoc: namespace
5
11
  module Tem::Mr::Search
6
12
 
13
+ # Allocates the individual components of a Map-Reduce job across TEMs.
14
+ #
15
+ # This class is instantiated and used by MapReduceExecutor. It should not be
16
+ # used directly in client code, except for the purpose of replacing the default
17
+ # planner.
18
+ #
19
+ # The Map-Reduce coordinator calls next_actions! on the planner, to obtain a
20
+ # list of actions that can be carried out. The planner guarantees that the
21
+ # actions are independent of each other, and that all their dependencies are
22
+ # satisfied. When the coordinator learns about the completion of some actions,
23
+ # it updates the planner's state by calling action_done. After action_done is
24
+ # called, new_action should be called again to obtain new actions that can be
25
+ # carried out.
26
+ #
27
+ # Partial results (outputs) in the Map-Reduce computation are identified by
28
+ # unique numbers starting from 0. The output IDs can be used as file names, if
29
+ # the outputs are stored in a distributed file system. When the computation is
30
+ # done (calling done? returns +true+), the +output_id+ attribute will contain
31
+ # the ID of the computation's final result.
7
32
  class MapReducePlanner
8
33
  # Creates a planner for a Map-Reduce job.
9
34
  #
@@ -32,8 +57,69 @@ class MapReducePlanner
32
57
  @last_reduce_id = 2 * num_items - 2
33
58
  @done_reducing, @output_id = false, nil
34
59
  end
60
+
61
+ # Issues a set of actions that can be performed right now.
62
+ #
63
+ # The method alters the planner's state assuming the actions will be
64
+ # performed.
65
+ #
66
+ # Returns an array of hashes, with one hash per action to be performed. The
67
+ # +:action+ key specifies the type of action to be performed, and can be
68
+ # +:migrate+ +:map+, +:reduce+, or +:finalize. All the actions have the
69
+ # +:with+ key, which is the ID (0-based index) of the TEM that will be doing
70
+ # the action.
71
+ #
72
+ # Migrate actions have the following keys:
73
+ # :secpack:: the type of SECpack to be migrated ( +:mapper+ or +:reducer+ )
74
+ # :with:: the ID of the TEM doing the migration
75
+ # :to:: the number of the TEM that the SECpack should be migrated to
76
+ #
77
+ # Map actions have the following keys:
78
+ # :item_id:: the ID of the item to be mapped (number in Table-Scan order)
79
+ # :with:: the ID of the TEM doing the mapping
80
+ # :output_id:: ID for the result of the map operation
81
+ #
82
+ # Reduce actions have the following keys:
83
+ # :output1_id, :output2_id:: the IDs of the partial outputs to be reduced
84
+ # :with:: the ID of the TEM doing the reducing
85
+ # :output_id:: the ID for the result of the reduce operation
86
+ #
87
+ # The finalize action has the following keys:
88
+ # :output_id:: the ID of the last partial output, which will be finalized
89
+ # :with:: the ID of the TEM doing the finalization
90
+ # :final_id:: the ID for the computation's final result
91
+ def next_actions!
92
+ actions = migrate_actions :mapper
93
+ actions += migrate_actions :reducer
94
+ actions += map_actions
95
+ actions += reduce_actions
96
+ actions += finalize_actions
97
+ actions
98
+ end
99
+
100
+ # Informs the planner that an action issued by next_actions! was completed.
101
+ #
102
+ # Args:
103
+ # action:: an action hash, as returned by next_actions!
104
+ #
105
+ # The return value is not specified.
106
+ def action_done(action)
107
+ dispatch = { :migrate => :done_migrating, :map => :done_mapping, :reduce =>
108
+ :done_reducing, :finalize => :done_finalizing }
109
+ self.send dispatch[action[:action]], action
110
+ end
111
+
112
+ # True when the Map-Reduce computation is complete.
113
+ def done?
114
+ !@output_id.nil?
115
+ end
116
+
117
+ # The output ID of the Map-Reduce's final result.
118
+ attr_reader :output_id
35
119
 
36
120
  # Generates migrating actions for a SECpack type that are possible now.
121
+ #
122
+ # See next_actions! for a description of the return value.
37
123
  def migrate_actions(sec_type)
38
124
  actions = []
39
125
  return actions if @without[sec_type].length == 0
@@ -56,24 +142,10 @@ class MapReducePlanner
56
142
  @with[action[:secpack]] << action[:to]
57
143
  end
58
144
  private :done_migrating
59
-
60
- # A sorted array of the free TEMs that have a SECpack type.
61
- def free_tems_with_sec(sec_type)
62
- tems = []
63
- @free_tems.each do |tem, true_value|
64
- tems << tem if @with[sec_type].include? tem
65
- end
66
- tems
67
- end
68
-
69
- # A unique output_id.
70
- def next_output_id
71
- next_id = @last_output_id
72
- @last_output_id += 1
73
- next_id
74
- end
75
-
145
+
76
146
  # Generates mapping actions possible right now.
147
+ #
148
+ # See next_actions! for a description of the return value.
77
149
  def map_actions
78
150
  actions = []
79
151
  return actions if @unmapped_items.empty?
@@ -88,6 +160,11 @@ class MapReducePlanner
88
160
  private :map_actions
89
161
 
90
162
  # Informs the planner that a data mapping has completed.
163
+ #
164
+ # Args:
165
+ # action:: an action hash, as returned by map_actions
166
+ #
167
+ # The return value is not specified.
91
168
  def done_mapping(action)
92
169
  @free_tems[action[:with]] = true
93
170
  @reduce_queue[action[:output_id]] = true
@@ -95,6 +172,8 @@ class MapReducePlanner
95
172
  private :done_mapping
96
173
 
97
174
  # Generates reducing actions possible right now.
175
+ #
176
+ # See next_actions! for a description of the return value.
98
177
  def reduce_actions
99
178
  actions = []
100
179
  return actions if @reduce_queue.length <= 1
@@ -114,6 +193,11 @@ class MapReducePlanner
114
193
  private :reduce_actions
115
194
 
116
195
  # Informs the planner that a data reduction has completed.
196
+ #
197
+ # Args:
198
+ # action:: an action hash, as returned by reduce_actions
199
+ #
200
+ # The return value is not specified.
117
201
  def done_reducing(action)
118
202
  @free_tems[action[:with]] = true
119
203
  if action[:output_id] == @last_reduce_id
@@ -125,6 +209,8 @@ class MapReducePlanner
125
209
  private :done_reducing
126
210
 
127
211
  # Generates finalizing actions possible right now.
212
+ #
213
+ # See next_actions! for a description of the return value.
128
214
  def finalize_actions
129
215
  return [] unless @done_reducing and !@output_id and @free_tems[@root_tem]
130
216
  @finalize_ready = false
@@ -134,36 +220,40 @@ class MapReducePlanner
134
220
  private :finalize_actions
135
221
 
136
222
  # Informs the planner that an action issued by next_action was done.
223
+ #
224
+ # Args:
225
+ # action:: an action hash, as returned by finalize_actions
226
+ #
227
+ # The return value is not specified.
137
228
  def done_finalizing(action)
138
229
  @free_tems[action[:with]] = true
139
230
  @output_id = action[:final_id]
140
231
  end
141
232
  private :done_finalizing
142
233
 
143
- # True when the Map-Reduce job is complete.
144
- def done?
145
- !@output_id.nil?
234
+ # A sorted array of the free TEMs that have a SECpack type migrated to them.
235
+ #
236
+ # Args:
237
+ # sec_type:: the SECpack type (+:mapper+ or +:reducer+)
238
+ def free_tems_with_sec(sec_type)
239
+ tems = []
240
+ @free_tems.each do |tem, true_value|
241
+ tems << tem if @with[sec_type].include? tem
242
+ end
243
+ tems
146
244
  end
245
+ private :free_tems_with_sec
147
246
 
148
- # The output ID of the Map-Reduce's final result.
149
- attr_reader :output_id
150
-
151
- # Informs the planner that an action issued by next_actions was completed.
152
- def action_done(action)
153
- dispatch = { :migrate => :done_migrating, :map => :done_mapping, :reduce =>
154
- :done_reducing, :finalize => :done_finalizing }
155
- self.send dispatch[action[:action]], action
247
+ # Generates a unique output ID.
248
+ #
249
+ # Returns the unique output ID, which is a non-negative integer. Future calls
250
+ # of this method are guaranteed to return different output IDs.
251
+ def next_output_id
252
+ next_id = @last_output_id
253
+ @last_output_id += 1
254
+ next_id
156
255
  end
256
+ private :next_output_id
257
+ end # class Tem::Mr::Search::MapReducePlanner
157
258
 
158
- # Issues a set of actions that can be performed right now.
159
- def next_actions!
160
- actions = migrate_actions :mapper
161
- actions += migrate_actions :reducer
162
- actions += map_actions
163
- actions += reduce_actions
164
- actions += finalize_actions
165
- actions
166
- end
167
- end
168
-
169
- end # namespace Tem::Mr::search
259
+ end # namespace Tem::Mr::Search
@@ -29,7 +29,7 @@ class QueryBuilder
29
29
  @map_secpack = Tem::Assembler.assemble do |s|
30
30
  s.label :_secret
31
31
  s.label :_key
32
- s.zeros :tem_ubyte, 16
32
+ s.data :tem_ubyte, @query_key.to_tem_key
33
33
  s.label :_check_bytes
34
34
  s.data :tem_ubyte, @check_bytes
35
35
 
@@ -39,15 +39,21 @@ class QueryBuilder
39
39
  s.ret
40
40
 
41
41
  s.entry
42
- s.ldbc 16
42
+ s.ldbc 24
43
43
  s.outnew
44
- s.call :_ranking
44
+ # Compute score.
45
+ s.call :_ranking
46
+ # Compute padding.
45
47
  s.ldbc 3
46
48
  s.ldwc :_nonce
47
49
  s.rnd
48
- s.mcfxb :from => :_check_bytes, :to => :_check, :size => 3
49
- # TODO(costan): encryption instead of plain dump
50
- s.outfxb :from => :_id, :size => 16
50
+ s.mcfxb :from => :_check_bytes, :to => :_check,
51
+ :size => @check_bytes.length
52
+
53
+ # Encrypt output.
54
+ s.ldwc :const => :_key
55
+ s.rdk
56
+ s.kefxb :from => :_id, :size => 23, :to => 0xFFFF
51
57
  s.halt
52
58
 
53
59
  s.label :_plain
@@ -68,7 +74,7 @@ class QueryBuilder
68
74
  s.zeros :tem_ubyte, 3
69
75
  # Check bytes to prevent malicious input corruption.
70
76
  s.label :_check
71
- s.zeros :tem_ubyte, 3
77
+ s.zeros :tem_ubyte, @check_bytes.length
72
78
 
73
79
  s.stack 64
74
80
  end
@@ -79,7 +85,7 @@ class QueryBuilder
79
85
  @reduce_secpack = Tem::Assembler.assemble do |s|
80
86
  s.label :_secret
81
87
  s.label :_key
82
- s.zeros :tem_ubyte, 16
88
+ s.data :tem_ubyte, @query_key.to_tem_key
83
89
  s.label :_check
84
90
  s.data :tem_ubyte, @check_bytes
85
91
 
@@ -90,15 +96,19 @@ class QueryBuilder
90
96
  s.ret
91
97
 
92
98
  s.entry
93
- s.ldbc 16
99
+ s.ldbc :const => 24
94
100
  s.outnew
95
- # Decode inputs.
101
+ # Decrypt inputs.
102
+ s.ldwc :const => :_key
103
+ s.rdk
104
+ s.stw :_key_id
96
105
  [1, 2].each do |i|
97
- # TODO(costan): decrypt instead of copying
98
- s.mcfxb :from => :"_output#{i}", :to => :"_id#{i}", :size => 16
106
+ s.ldw :_key_id
107
+ s.kdfxb :from => :"_output#{i}", :to => :"_id#{i}", :size => 24
99
108
 
100
109
  # Compare the check bytes and abort if the inputs were tampered with.
101
- s.mcmpfxb :op1 => :"_check#{i}", :op2 => :"_check", :size => 3
110
+ s.mcmpfxb :op1 => :"_check#{i}", :op2 => :"_check",
111
+ :size => @check_bytes.length
102
112
  s.jz :"_check_#{i}_ok"
103
113
  s.halt
104
114
  s.label :"_check_#{i}_ok"
@@ -119,20 +129,24 @@ class QueryBuilder
119
129
  s.ldbc 3
120
130
  s.ldwc :_nonce1
121
131
  s.rnd
122
- # TODO(costan): encrypt instead of copying
123
- s.outfxb :from => :_id1, :size => 16
132
+ # Encrypt output.
133
+ s.ldwc :const => :_key
134
+ s.rdk
135
+ s.kefxb :from => :_id1, :size => 23, :to => 0xFFFF
124
136
  s.halt
125
137
 
126
138
  s.label :_plain
127
139
  # The comparison result produced by the user comparison procedure.
128
140
  s.label :comparison
129
141
  s.zeros :tem_short, 1
142
+ s.label :_key_id
143
+ s.zeros :tem_short, 1
130
144
 
131
145
  # The two inputs to reduce.
132
146
  [1, 2].each do |i|
133
147
  # Encrypted map/reduce output.
134
148
  s.label :"_output#{i}"
135
- s.zeros :tem_ubyte, 16
149
+ s.zeros :tem_ubyte, 24
136
150
  # Unencrypted input (decrypted inside TEM).
137
151
  s.label :"_id#{i}"
138
152
  s.zeros :tem_ubyte, 8
@@ -141,9 +155,9 @@ class QueryBuilder
141
155
  s.label :"_nonce#{i}"
142
156
  s.zeros :tem_ubyte, 3
143
157
  s.label :"_check#{i}"
144
- s.zeros :tem_ubyte, 3
158
+ s.zeros :tem_ubyte, @check_bytes.length
145
159
  end
146
- s.stack 8
160
+ s.stack 16
147
161
  end
148
162
  end
149
163
 
@@ -158,9 +172,8 @@ class QueryBuilder
158
172
  end
159
173
 
160
174
  def initialize
161
- @check_bytes = [1, 2, 3]
162
- # TODO(costan): generate query key
163
- @query_key = nil
175
+ @check_bytes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
176
+ @query_key = Tem::Keys::Symmetric.generate
164
177
  end
165
178
  end # class QueryBuilder
166
179
 
@@ -1,9 +1,31 @@
1
+ # Map-Reduce RPC server.
2
+ #
3
+ # Author:: Victor Costan
4
+ # Copyright:: Copyright (C) 2009 Massachusetts Institute of Technology
5
+ # License:: MIT
6
+
1
7
  require 'logger'
2
8
  require 'yaml'
3
9
 
4
10
  # :nodoc: namespace
5
11
  module Tem::Mr::Search
6
12
 
13
+
14
+ # Map-Reduce RPC server.
15
+ #
16
+ # The RPC server models the data provider in the secure Map-Reduce proof of
17
+ # concept.
18
+ #
19
+ # The server accepts database queries expressed as Map-Reduce computations,
20
+ # where each computation is enclosed in a SECpack. This makes it impossible for
21
+ # the data provider to learn about the query. Map-Reduce computations have a
22
+ # single result: the ID of the record that's the query response, and its score.
23
+ #
24
+ # The server also accepts direct queries for single database records, so clients
25
+ # can retrieve the record whose ID they learn from the Map-Reduce result.
26
+ #
27
+ # The db_dump and shutdown requests are for demonstration and testing purposes,
28
+ # and would not be exposed in production servers.
7
29
  class Server
8
30
  DEFAULT_PORT = 9052
9
31
 
data/lib/tem_mr_search.rb CHANGED
@@ -1,3 +1,9 @@
1
+ # Main include file for the tem_mr_search Rubygem.
2
+ #
3
+ # Author:: Victor Costan
4
+ # Copyright:: Copyright (C) 2009 Massachusetts Institute of Technology
5
+ # License:: MIT
6
+
1
7
  require 'rubygems'
2
8
  require 'tem_multi_proxy'
3
9
  require 'tem_ruby'
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{tem_mr_search}
5
- s.version = "0.2.4"
5
+ s.version = "0.2.5"
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"]
9
- s.date = %q{2009-11-11}
9
+ s.date = %q{2009-11-15}
10
10
  s.default_executable = %q{tem_mr_search_server}
11
11
  s.description = %q{Tem Map-Reduce proof of concept: database search.}
12
12
  s.email = %q{victor@costan.us}
@@ -26,14 +26,14 @@ Gem::Specification.new do |s|
26
26
  s.specification_version = 3
27
27
 
28
28
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
29
- s.add_runtime_dependency(%q<tem_ruby>, [">= 0.13.0"])
30
- s.add_runtime_dependency(%q<tem_multi_proxy>, [">= 0.2.6"])
29
+ s.add_runtime_dependency(%q<tem_ruby>, [">= 0.14.0"])
30
+ s.add_runtime_dependency(%q<tem_multi_proxy>, [">= 0.2.7"])
31
31
  else
32
- s.add_dependency(%q<tem_ruby>, [">= 0.13.0"])
33
- s.add_dependency(%q<tem_multi_proxy>, [">= 0.2.6"])
32
+ s.add_dependency(%q<tem_ruby>, [">= 0.14.0"])
33
+ s.add_dependency(%q<tem_multi_proxy>, [">= 0.2.7"])
34
34
  end
35
35
  else
36
- s.add_dependency(%q<tem_ruby>, [">= 0.13.0"])
37
- s.add_dependency(%q<tem_multi_proxy>, [">= 0.2.6"])
36
+ s.add_dependency(%q<tem_ruby>, [">= 0.14.0"])
37
+ s.add_dependency(%q<tem_multi_proxy>, [">= 0.2.7"])
38
38
  end
39
39
  end
@@ -31,7 +31,8 @@ class QueryBuildersTest < MrTestCase
31
31
  assert_equal fare_id(win_fare), output[:id], 'The wrong fare won (bad ID)'
32
32
  assert_equal fare_score(win_fare), output[:score],
33
33
  'The wrong fare won (bad score)'
34
- assert_equal [1, 2, 3], output[:check], 'Incorrect check bytes'
34
+ assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], output[:check],
35
+ 'Incorrect check bytes'
35
36
 
36
37
  assert_not_equal enc_output, output1, 'Nonce fail'
37
38
  assert_not_equal enc_output, output2, 'Nonce fail'
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.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Costan
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-11 00:00:00 -05:00
12
+ date: 2009-11-15 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.13.0
23
+ version: 0.14.0
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: tem_multi_proxy
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.2.6
33
+ version: 0.2.7
34
34
  version:
35
35
  description: "Tem Map-Reduce proof of concept: database search."
36
36
  email: victor@costan.us