bud 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
data/lib/bud/rewrite.rb CHANGED
@@ -3,14 +3,13 @@ require 'rubygems'
3
3
  class RuleRewriter < Ruby2Ruby # :nodoc: all
4
4
  attr_accessor :rule_indx, :rules, :depends
5
5
 
6
- OP_LIST = Set.new([:<<, :<, :<=])
7
- TEMP_OP_LIST = Set.new([:-@, :~, :+@])
8
- MONOTONE_WHITELIST = Set.new([:==, :+, :<=, :-, :<, :>, :*, :~,
9
- :pairs, :matches, :combos, :flatten, :new,
10
- :lefts, :rights, :map, :flat_map, :pro, :merge,
11
- :cols, :key_cols, :val_cols, :payloads, :lambda,
12
- :tabname, :ip_port, :port, :ip, :int_ip_port,
13
- :current_value])
6
+ OP_LIST = [:<<, :<, :<=].to_set
7
+ TEMP_OP_LIST = [:-@, :~, :+@].to_set
8
+ MONOTONE_WHITELIST = [:==, :+, :<=, :-, :<, :>, :*, :~,
9
+ :pairs, :matches, :combos, :flatten, :new,
10
+ :lefts, :rights, :map, :flat_map, :pro, :merge,
11
+ :cols, :key_cols, :val_cols, :payloads, :lambda,
12
+ :tabname, :current_value].to_set
14
13
 
15
14
  def initialize(seed, bud_instance)
16
15
  @bud_instance = bud_instance
@@ -196,15 +195,17 @@ class RuleRewriter < Ruby2Ruby # :nodoc: all
196
195
  Bud::Lattice.global_morphs.include?(op)
197
196
  end
198
197
 
199
- # Rewrite top-level rhs array and hash literals to lambdas. During wiring,
200
- # these are turned into coll_expr collections.
198
+ # Rewrite top-level rhs literal expressions into lambdas. During wiring, these
199
+ # are turned into coll_expr collections. For normal relational Bloom, the only
200
+ # literal we expect to see is an array literal, but lattices can be
201
+ # initialized with other kinds of literals (e.g., integers for lmax).
201
202
  def lambda_rewrite(rhs)
202
203
  # the <= case
203
- if is_coll_literal(rhs[0])
204
+ if is_rhs_literal(rhs[0])
204
205
  return s(:iter, s(:call, nil, :lambda), s(:args), rhs)
205
206
  # the superator case
206
207
  elsif rhs[0] == :call \
207
- and rhs[1] and rhs[1][0] and is_coll_literal(rhs[1][0]) \
208
+ and rhs[1] and rhs[1][0] and is_rhs_literal(rhs[1][0]) \
208
209
  and rhs[2] and (rhs[2] == :+@ or rhs[2] == :-@ or rhs[2] == :~@)
209
210
  return s(rhs[0], s(:iter, s(:call, nil, :lambda), s(:args), rhs[1]), rhs[2], *rhs[3..-1])
210
211
  else
@@ -212,8 +213,8 @@ class RuleRewriter < Ruby2Ruby # :nodoc: all
212
213
  end
213
214
  end
214
215
 
215
- def is_coll_literal(e)
216
- [:array, :hash].include? e
216
+ def is_rhs_literal(e)
217
+ [:array, :hash, :lit].include? e
217
218
  end
218
219
 
219
220
  def collect_rhs(exp)
@@ -259,7 +260,7 @@ class RuleRewriter < Ruby2Ruby # :nodoc: all
259
260
  rhs_ast = MapRewriter.new.process(rhs_ast)
260
261
  rhs_ast = RenameRewriter.new(@bud_instance).process(rhs_ast)
261
262
  rhs_ast = LatticeRefRewriter.new(@bud_instance).process(rhs_ast)
262
- ufr = UnsafeFuncRewriter.new
263
+ ufr = UnsafeFuncRewriter.new(@bud_instance)
263
264
  rhs_ast = ufr.process(rhs_ast)
264
265
 
265
266
  if @bud_instance.options[:no_attr_rewrite]
@@ -336,16 +337,25 @@ class RenameRewriter < SexpProcessor
336
337
  end
337
338
  end
338
339
 
339
- # Check for whether the rule invokes any "unsafe" functions (funcs that might
340
- # return a different value every time they are called, e.g., budtime). Note that
341
- # although we call this a rewriter, it doesn't modify the input AST.
340
+ # Check for whether the rule invokes any "unsafe" functions (functions that
341
+ # might return a different value every time they are called, e.g., budtime). The
342
+ # test for "unsafe" functions is pretty naive: any function call with a nil
343
+ # receiver is treated as unsafe unless it is belongs to a list of "safe"
344
+ # functions (below) or it denotes a lattice identifier. In the latter case, the
345
+ # rule is akin to an implicit join with the lattice, so we only rescan it on
346
+ # deltas to the lattice (see "rescan_on_merge" in LatticeWrapper).
347
+ #
348
+ # Although this is called a rewriter, it doesn't modify the input AST.
342
349
  class UnsafeFuncRewriter < SexpProcessor
350
+ SAFE_FUNC_LIST = [:int_ip_port, :ip_port, :ip, :port].to_set
351
+
343
352
  attr_reader :unsafe_func_called
344
353
 
345
- def initialize
354
+ def initialize(bud_instance)
346
355
  super()
347
356
  self.require_empty = false
348
357
  self.expected = Sexp
358
+ @bud_instance = bud_instance
349
359
  @unsafe_func_called = false
350
360
  @elem_stack = []
351
361
  end
@@ -356,7 +366,9 @@ class UnsafeFuncRewriter < SexpProcessor
356
366
  # We assume that unsafe funcs have a nil receiver (Bud instance is implicit
357
367
  # receiver).
358
368
  if recv.nil? and @elem_stack.size > 0
359
- @unsafe_func_called = true unless RuleRewriter.is_monotone(op)
369
+ unless is_safe_func(op) || is_lattice?(op)
370
+ @unsafe_func_called = true
371
+ end
360
372
  end
361
373
 
362
374
  return s(tag, process(recv), op, *(args.map{|a| process(a)}))
@@ -375,6 +387,14 @@ class UnsafeFuncRewriter < SexpProcessor
375
387
  raise Bud::Error unless @elem_stack.pop == obj_id
376
388
  return rv
377
389
  end
390
+
391
+ def is_lattice?(op)
392
+ @bud_instance.lattices.has_key? op.to_sym
393
+ end
394
+
395
+ def is_safe_func(op)
396
+ SAFE_FUNC_LIST.include? op
397
+ end
378
398
  end
379
399
 
380
400
  # Rewrite references to lattice identifiers that appear in rule bodies. A
data/lib/bud/server.rb CHANGED
@@ -11,11 +11,8 @@ class Bud::BudServer < EM::Connection #:nodoc: all
11
11
 
12
12
  def receive_data(data)
13
13
  # Feed the received data to the deserializer
14
- @pac.feed data
15
-
16
- # streaming deserialize
17
- @pac.each do |obj|
18
- message_received(obj)
14
+ @pac.feed_each(data) do |obj|
15
+ recv_message(obj)
19
16
  end
20
17
 
21
18
  # apply the channel filter to each channel's pending tuples
@@ -54,7 +51,7 @@ class Bud::BudServer < EM::Connection #:nodoc: all
54
51
  @bud.rtracer.sleep if @bud.options[:rtrace]
55
52
  end
56
53
 
57
- def message_received(obj)
54
+ def recv_message(obj)
58
55
  unless (obj.class <= Array and obj.length == 3 and
59
56
  @bud.tables.include?(obj[0].to_sym) and
60
57
  obj[1].class <= Array and obj[2].class <= Array)
data/lib/bud/source.rb CHANGED
@@ -17,7 +17,7 @@ module Source
17
17
  lines = cache(filename, num)
18
18
  # Note: num is 1-based.
19
19
 
20
- parser = make_parser
20
+ parser = RubyParser.for_current_ruby
21
21
  stmt = "" # collection of lines that form one complete Ruby statement
22
22
  ast = nil
23
23
  lines[num .. -1].each do |l|
@@ -38,21 +38,6 @@ module Source
38
38
  ast
39
39
  end
40
40
 
41
- # ruby_parser 3.x can produce either 1.8- or 1.9-compatible ASTs. Since we
42
- # want to eventually turn the ASTs back into code we can eval() using the
43
- # current Ruby runtime, we want to generate an appropriately compatible AST.
44
- def Source.make_parser
45
- maj, min, patch = RUBY_VERSION.split(".")
46
- case [maj.to_i, min.to_i]
47
- when [1, 9] then
48
- Ruby19Parser.new
49
- when [1, 8] then
50
- Ruby18Parser.new
51
- else
52
- raise Bud::Error, "unrecognized RUBY_VERSION: #{RUBY_VERSION}"
53
- end
54
- end
55
-
56
41
  def Source.cache(filename, num) # returns array of lines
57
42
  if $cached_file_info.curr_file == filename
58
43
  retval = $cached_file_info.lines
data/lib/bud/state.rb CHANGED
@@ -149,7 +149,7 @@ module Bud
149
149
  @terminal = name
150
150
  end
151
151
  define_collection(name)
152
- @tables[name] = Bud::BudTerminal.new(name, [:line], self)
152
+ @tables[name] = Bud::BudTerminal.new(name, self)
153
153
  @channels[name] = @tables[name]
154
154
  end
155
155
 
data/lib/bud/viz.rb CHANGED
@@ -3,18 +3,18 @@ require 'bud/state'
3
3
  class VizOnline #:nodoc: all
4
4
  attr_reader :logtab
5
5
 
6
- META_TABLES = %w[t_cycle t_depends t_depends_tc t_provides t_rules
7
- t_stratum t_table_info t_table_schema].to_set
6
+ META_TABLES = %w[t_cycle t_depends t_provides t_rules t_stratum
7
+ t_table_info t_table_schema t_underspecified].to_set
8
8
 
9
9
  def initialize(bud_instance)
10
10
  @bud_instance = bud_instance
11
11
  @bud_instance.options[:dbm_dir] = "DBM_#{@bud_instance.class}_#{bud_instance.options[:tag]}_#{bud_instance.object_id}_#{bud_instance.port}"
12
12
  @table_info = bud_instance.tables[:t_table_info]
13
13
  @table_schema = bud_instance.tables[:t_table_schema]
14
- @logtab = new_tab("the_big_log", [:table, :time, :contents], bud_instance)
14
+ @logtab = new_tab(:the_big_log, [:table, :time, :contents], bud_instance)
15
15
  tmp_set = []
16
16
  @bud_instance.tables.each do |name, tbl|
17
- next if name == "the_big_log"
17
+ next if name == :the_big_log || name == :localtick
18
18
  # Temp collections don't have a schema until a fact has been inserted into
19
19
  # them; for now, we just include an empty schema for them in the viz
20
20
  if tbl.schema.nil?
@@ -56,11 +56,11 @@ class VizOnline #:nodoc: all
56
56
  row = row[0]
57
57
  end
58
58
 
59
- # bud.t_depends and t_rules have bud object in field[0]. Remove them since
60
- # bud instances cannot/must not be serialized.
59
+ # bud.t_depends and t_rules have bud object in field[0]. Replace them with
60
+ # a string, since bud instances cannot/must not be serialized.
61
61
  if row[0].class <= Bud
62
- row = row.to_a if row.class != Array
63
- row = [row[0].class.to_s] + row[1..-1] if row[0].class <= Bud
62
+ row = row.to_a
63
+ row = [row[0].class.to_s] + row[1..-1]
64
64
  end
65
65
  newrow = [tab, @bud_instance.budtime, row]
66
66
  begin
@@ -74,10 +74,9 @@ class VizOnline #:nodoc: all
74
74
  def do_cards
75
75
  @bud_instance.tables.each do |t|
76
76
  tab = t[0]
77
- next if tab == "the_big_log"
77
+ next if tab == :the_big_log
78
78
  next if @bud_instance.budtime > 0 and META_TABLES.include? tab.to_s
79
- # PAA: why did we previously exclude periodics?
80
- add_rows(t[1], tab) #####unless t[1].class == Bud::BudPeriodic
79
+ add_rows(t[1], tab)
81
80
  if t[1].class == Bud::BudChannel
82
81
  add_rows(t[1].pending, "#{tab}_snd")
83
82
  end
data/lib/bud/viz_util.rb CHANGED
@@ -180,8 +180,8 @@ module VizUtil #:nodoc: all
180
180
  convertor = Syntax::Convertors::HTML.for_syntax "ruby"
181
181
  shredded_rules.each do |s|
182
182
  # b/c accessors don't make it through serialization anymore
183
- bud_obj, rule_id, lhs, op, src, orig_src, nm_funcs_called = s.to_a
184
- fout = File.new("#{output_base}/#{rule_id}.html", "w+")
183
+ bud_obj, rule_id, lhs, op, src, orig_src, unsafe_funcs_called = s.to_a
184
+ fout = File.new("#{output_base}/#{rule_id}-#{lhs}.html", "w+")
185
185
  fout.puts header
186
186
  fout.puts "<h1>Rule #{rule_id}</h1><br>"
187
187
 
@@ -364,7 +364,12 @@ END_JS
364
364
  def write_table_content(fn, row)
365
365
  stream = File.open(fn, "a")
366
366
  stream.puts "<tr>"
367
- stream.puts row.map{|c| "<td>#{c.to_s}</td>"}.join(" ")
367
+ if row.class < Enumerable
368
+ stream.puts row.map{|c| "<td>#{c.to_s}</td>"}.join(" ")
369
+ else
370
+ # special case for periodics
371
+ stream.puts "<td>#{row.to_s}</td>"
372
+ end
368
373
  stream.puts "</tr>"
369
374
  stream.close
370
375
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.5
5
- prerelease:
4
+ version: 0.9.6
6
5
  platform: ruby
7
6
  authors:
8
7
  - Peter Alvaro
@@ -13,12 +12,11 @@ authors:
13
12
  autorequire:
14
13
  bindir: bin
15
14
  cert_chain: []
16
- date: 2012-11-24 00:00:00.000000000 Z
15
+ date: 2013-02-25 00:00:00.000000000 Z
17
16
  dependencies:
18
17
  - !ruby/object:Gem::Dependency
19
18
  name: eventmachine
20
19
  requirement: !ruby/object:Gem::Requirement
21
- none: false
22
20
  requirements:
23
21
  - - ! '>='
24
22
  - !ruby/object:Gem::Version
@@ -26,7 +24,6 @@ dependencies:
26
24
  type: :runtime
27
25
  prerelease: false
28
26
  version_requirements: !ruby/object:Gem::Requirement
29
- none: false
30
27
  requirements:
31
28
  - - ! '>='
32
29
  - !ruby/object:Gem::Version
@@ -34,7 +31,6 @@ dependencies:
34
31
  - !ruby/object:Gem::Dependency
35
32
  name: fastercsv
36
33
  requirement: !ruby/object:Gem::Requirement
37
- none: false
38
34
  requirements:
39
35
  - - ! '>='
40
36
  - !ruby/object:Gem::Version
@@ -42,7 +38,6 @@ dependencies:
42
38
  type: :runtime
43
39
  prerelease: false
44
40
  version_requirements: !ruby/object:Gem::Requirement
45
- none: false
46
41
  requirements:
47
42
  - - ! '>='
48
43
  - !ruby/object:Gem::Version
@@ -50,7 +45,6 @@ dependencies:
50
45
  - !ruby/object:Gem::Dependency
51
46
  name: getopt
52
47
  requirement: !ruby/object:Gem::Requirement
53
- none: false
54
48
  requirements:
55
49
  - - ! '>='
56
50
  - !ruby/object:Gem::Version
@@ -58,7 +52,6 @@ dependencies:
58
52
  type: :runtime
59
53
  prerelease: false
60
54
  version_requirements: !ruby/object:Gem::Requirement
61
- none: false
62
55
  requirements:
63
56
  - - ! '>='
64
57
  - !ruby/object:Gem::Version
@@ -66,7 +59,6 @@ dependencies:
66
59
  - !ruby/object:Gem::Dependency
67
60
  name: msgpack
68
61
  requirement: !ruby/object:Gem::Requirement
69
- none: false
70
62
  requirements:
71
63
  - - ! '>='
72
64
  - !ruby/object:Gem::Version
@@ -74,7 +66,6 @@ dependencies:
74
66
  type: :runtime
75
67
  prerelease: false
76
68
  version_requirements: !ruby/object:Gem::Requirement
77
- none: false
78
69
  requirements:
79
70
  - - ! '>='
80
71
  - !ruby/object:Gem::Version
@@ -82,7 +73,6 @@ dependencies:
82
73
  - !ruby/object:Gem::Dependency
83
74
  name: ruby-graphviz
84
75
  requirement: !ruby/object:Gem::Requirement
85
- none: false
86
76
  requirements:
87
77
  - - ! '>='
88
78
  - !ruby/object:Gem::Version
@@ -90,7 +80,6 @@ dependencies:
90
80
  type: :runtime
91
81
  prerelease: false
92
82
  version_requirements: !ruby/object:Gem::Requirement
93
- none: false
94
83
  requirements:
95
84
  - - ! '>='
96
85
  - !ruby/object:Gem::Version
@@ -98,7 +87,6 @@ dependencies:
98
87
  - !ruby/object:Gem::Dependency
99
88
  name: ruby2ruby
100
89
  requirement: !ruby/object:Gem::Requirement
101
- none: false
102
90
  requirements:
103
91
  - - ! '>='
104
92
  - !ruby/object:Gem::Version
@@ -106,7 +94,6 @@ dependencies:
106
94
  type: :runtime
107
95
  prerelease: false
108
96
  version_requirements: !ruby/object:Gem::Requirement
109
- none: false
110
97
  requirements:
111
98
  - - ! '>='
112
99
  - !ruby/object:Gem::Version
@@ -114,23 +101,20 @@ dependencies:
114
101
  - !ruby/object:Gem::Dependency
115
102
  name: ruby_parser
116
103
  requirement: !ruby/object:Gem::Requirement
117
- none: false
118
104
  requirements:
119
105
  - - ! '>='
120
106
  - !ruby/object:Gem::Version
121
- version: 3.0.2
107
+ version: 3.1.0
122
108
  type: :runtime
123
109
  prerelease: false
124
110
  version_requirements: !ruby/object:Gem::Requirement
125
- none: false
126
111
  requirements:
127
112
  - - ! '>='
128
113
  - !ruby/object:Gem::Version
129
- version: 3.0.2
114
+ version: 3.1.0
130
115
  - !ruby/object:Gem::Dependency
131
116
  name: superators19
132
117
  requirement: !ruby/object:Gem::Requirement
133
- none: false
134
118
  requirements:
135
119
  - - ! '>='
136
120
  - !ruby/object:Gem::Version
@@ -138,7 +122,6 @@ dependencies:
138
122
  type: :runtime
139
123
  prerelease: false
140
124
  version_requirements: !ruby/object:Gem::Requirement
141
- none: false
142
125
  requirements:
143
126
  - - ! '>='
144
127
  - !ruby/object:Gem::Version
@@ -146,7 +129,6 @@ dependencies:
146
129
  - !ruby/object:Gem::Dependency
147
130
  name: syntax
148
131
  requirement: !ruby/object:Gem::Requirement
149
- none: false
150
132
  requirements:
151
133
  - - ! '>='
152
134
  - !ruby/object:Gem::Version
@@ -154,7 +136,6 @@ dependencies:
154
136
  type: :runtime
155
137
  prerelease: false
156
138
  version_requirements: !ruby/object:Gem::Requirement
157
- none: false
158
139
  requirements:
159
140
  - - ! '>='
160
141
  - !ruby/object:Gem::Version
@@ -162,7 +143,6 @@ dependencies:
162
143
  - !ruby/object:Gem::Dependency
163
144
  name: uuid
164
145
  requirement: !ruby/object:Gem::Requirement
165
- none: false
166
146
  requirements:
167
147
  - - ! '>='
168
148
  - !ruby/object:Gem::Version
@@ -170,7 +150,6 @@ dependencies:
170
150
  type: :runtime
171
151
  prerelease: false
172
152
  version_requirements: !ruby/object:Gem::Requirement
173
- none: false
174
153
  requirements:
175
154
  - - ! '>='
176
155
  - !ruby/object:Gem::Version
@@ -178,7 +157,6 @@ dependencies:
178
157
  - !ruby/object:Gem::Dependency
179
158
  name: minitest
180
159
  requirement: !ruby/object:Gem::Requirement
181
- none: false
182
160
  requirements:
183
161
  - - ! '>='
184
162
  - !ruby/object:Gem::Version
@@ -186,7 +164,6 @@ dependencies:
186
164
  type: :development
187
165
  prerelease: false
188
166
  version_requirements: !ruby/object:Gem::Requirement
189
- none: false
190
167
  requirements:
191
168
  - - ! '>='
192
169
  - !ruby/object:Gem::Version
@@ -262,26 +239,25 @@ files:
262
239
  homepage: http://www.bloom-lang.org
263
240
  licenses:
264
241
  - BSD
242
+ metadata: {}
265
243
  post_install_message:
266
244
  rdoc_options: []
267
245
  require_paths:
268
246
  - lib
269
247
  required_ruby_version: !ruby/object:Gem::Requirement
270
- none: false
271
248
  requirements:
272
249
  - - ! '>='
273
250
  - !ruby/object:Gem::Version
274
251
  version: 1.8.7
275
252
  required_rubygems_version: !ruby/object:Gem::Requirement
276
- none: false
277
253
  requirements:
278
254
  - - ! '>='
279
255
  - !ruby/object:Gem::Version
280
256
  version: '0'
281
257
  requirements: []
282
258
  rubyforge_project: bloom-lang
283
- rubygems_version: 1.8.24
259
+ rubygems_version: 2.0.0
284
260
  signing_key:
285
- specification_version: 3
261
+ specification_version: 4
286
262
  summary: A prototype Bloom DSL for distributed programming.
287
263
  test_files: []