bud 0.0.7 → 0.0.8

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/lib/bud/viz.rb CHANGED
@@ -1,14 +1,13 @@
1
1
  require 'rubygems'
2
2
  require 'syntax/convertors/html'
3
3
  require 'gchart'
4
- require 'digest/md5'
5
4
  require 'bud/state'
6
5
 
7
6
  class VizOnline #:nodoc: all
8
7
  def initialize(bud_instance)
9
8
  @bud_instance = bud_instance
10
9
  return if bud_instance.class == Stratification or @bud_instance.class == DepAnalysis
11
- @meta_tables = {'t_rules' => 1, 't_depends' => 1, 't_table_info' => 1, 't_cycle' => 1, 't_stratum' => 1, 't_depends_tc' => 1, 't_table_schema' => 1}
10
+ @meta_tables = {'t_rules' => 1, 't_depends' => 1, 't_table_info' => 1, 't_cycle' => 1, 't_stratum' => 1, 't_depends_tc' => 1, 't_table_schema' => 1, 't_provides' => 1}
12
11
  @bud_instance.options[:dbm_dir] = "DBM_#{@bud_instance.class}_#{bud_instance.options[:tag]}_#{bud_instance.object_id}_#{bud_instance.port}"
13
12
  @table_info = bud_instance.tables[:t_table_info]
14
13
  @table_schema = bud_instance.tables[:t_table_schema]
@@ -57,13 +56,15 @@ class VizOnline #:nodoc: all
57
56
  if collection.class == Hash
58
57
  row = row[1]
59
58
  end
59
+ if collection.class == Bud::BudPeriodic
60
+ row = row[0]
61
+ end
60
62
  newrow = [tab, @bud_instance.budtime, row]
61
63
  begin
62
64
  @logtab << newrow
63
65
  rescue
64
- raise "ERROR! #{@logtab} << #{newrow}"
66
+ raise "ERROR! #{@logtab} << #{newrow.inspect} (etxt #{$!})"
65
67
  end
66
-
67
68
  end
68
69
  end
69
70
 
@@ -73,7 +74,8 @@ class VizOnline #:nodoc: all
73
74
  tab = t[0]
74
75
  next if tab == "the_big_log"
75
76
  next if @meta_tables[tab.to_s] and @bud_instance.budtime > 0
76
- add_rows(t[1], tab) unless t[1].class == Bud::BudPeriodic
77
+ # PAA: why did we previously exclude periodics?
78
+ add_rows(t[1], tab) #####unless t[1].class == Bud::BudPeriodic
77
79
  if t[1].class == Bud::BudChannel
78
80
  add_rows(t[1].pending, "#{tab}_snd")
79
81
  end
data/lib/bud/viz_util.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bud/graphs'
3
+ require 'bud/meta_algebra'
3
4
 
4
5
  module TraceCardinality
5
6
  state do
@@ -18,11 +19,12 @@ class VizHelper
18
19
  include Bud
19
20
  include TraceCardinality
20
21
 
21
- def initialize(tabinf, cycle, depends, rules, dir)
22
+ def initialize(tabinf, cycle, depends, rules, dir, provides)
22
23
  @t_tabinf = tabinf
23
24
  @t_cycle = cycle
24
25
  @t_depends = depends
25
26
  @t_rules = rules
27
+ @t_provides = provides
26
28
  @dir = dir
27
29
  super()
28
30
  end
@@ -59,21 +61,93 @@ end
59
61
 
60
62
 
61
63
  module VizUtil #:nodoc: all
62
- def graph_from_instance(bud_instance, viz_name, output_base, collapse=true, fmt=nil)
64
+ def self.ma_tables
65
+ # a craven, contemptible hack to grab the metatables.
66
+ estr = "class Foo\ninclude Bud\ninclude MetaAlgebra\ninclude MetaReports\nend"
67
+ eval(estr)
68
+ e = Foo.new
69
+ e.tables
70
+ end
71
+
72
+ def graph_from_instance(bud_instance, viz_name, output_base, collapse=true, fmt=nil, data=nil)
63
73
  tabinf = {}
64
74
  bud_instance.tables.each do |t|
65
75
  tab = t[0].to_s
66
76
  tabinf[tab] = t[1].class.to_s
67
77
  end
68
- write_graphs(tabinf, bud_instance.builtin_tables, bud_instance.t_cycle,
78
+
79
+ begins = get_paths(bud_instance)
80
+ bit = bud_instance.builtin_tables
81
+ VizUtil.ma_tables.each_pair{|k, v| bit[k] = v}
82
+
83
+ write_graphs(tabinf, bit, bud_instance.t_cycle,
69
84
  bud_instance.t_depends, bud_instance.t_rules, viz_name,
70
- output_base, fmt, collapse, bud_instance.meta_parser.depanalysis)
85
+ output_base, fmt, collapse, bud_instance.meta_parser.depanalysis, -1, nil,
86
+ get_labels(bud_instance), begins)
87
+ begins
88
+ end
89
+
90
+ def get_paths(bud_instance)
91
+ return {} unless bud_instance.respond_to? :a_preds
92
+ begins = {}
93
+ bud_instance.a_preds.each do |b|
94
+ begins[:start] ||= {}
95
+ begins[:start][b.path.split("|").last] = b.fullpath.split("|").last
96
+ begins[:finish] = {}
97
+ begins[:finish][b.fullpath.split("|").last] = true
98
+ end
99
+ begins
100
+ end
101
+
102
+ def get_labels(bud_instance)
103
+ return {} unless bud_instance.respond_to? :lps
104
+ # sort the paths. sort the paths to the same destination by length.
105
+ aps = {}
106
+ ap_interm = bud_instance.lps.sort do |a, b|
107
+ if a.to == b.to then
108
+ a.path.length <=> b.path.length
109
+ else
110
+ a <=> b
111
+ end
112
+ end
113
+ ap_interm.each do |a|
114
+ aps[a.to] ||= []
115
+ aps[a.to] << a.tag
116
+ end
117
+
118
+ # grab the lattice metadata
119
+ lub = {}
120
+ bud_instance.lub.each do |l|
121
+ lub[l.left] ||= {}
122
+ lub[l.left][l.right] = l.result
123
+ end
124
+
125
+ # b/c set union isn't working right
126
+ ap2 = {}
127
+ aps.each_pair do |k, v|
128
+ tmp = v.reduce({}) do |memo, i|
129
+ memo[:val] ||= :M
130
+ was = memo[:val]
131
+ if lub[memo[:val]][i]
132
+ if i == :N
133
+ memo[:val] = lub[i][memo[:val]]
134
+ else
135
+ memo[:val] = lub[memo[:val]][i]
136
+ end
137
+ else
138
+ puts "couldn't find #{memo[:val]} - #{i} in #{lub.inspect}"
139
+ end
140
+ memo
141
+ end
142
+ ap2[k] = [tmp, v]
143
+ end
144
+ ap2
71
145
  end
72
146
 
73
147
  def write_graphs(tabinf, builtin_tables, cycle, depends, rules, viz_name,
74
- output_base, fmt, collapse, depanalysis=nil, budtime=-1, card_info=nil)
148
+ output_base, fmt, collapse, depanalysis=nil, budtime=-1, card_info=nil, pathsto={}, begins = {})
75
149
  staging = "#{viz_name}.staging"
76
- gv = GraphGen.new(tabinf, builtin_tables, cycle, staging, budtime, collapse, card_info)
150
+ gv = GraphGen.new(tabinf, builtin_tables, cycle, staging, budtime, collapse, card_info, pathsto, begins)
77
151
  gv.process(depends)
78
152
  dump(rules, output_base, gv)
79
153
  gv.finish(depanalysis, fmt)
@@ -116,7 +190,6 @@ module VizUtil #:nodoc: all
116
190
  if !code[v[0]]
117
191
  code[v[0]] = ""
118
192
  end
119
- #code[v[0]] = "<br># RULE #{k}<br> " + code[v[0]] + "<br>" + v[1]
120
193
  code[v[0]] = "\n# RULE #{k}\n " + code[v[0]] + "\n" + v[1]
121
194
  end
122
195
  gv_obj.nodes.each_pair do |k, v|
@@ -213,7 +286,7 @@ END_JS
213
286
  end
214
287
 
215
288
  def get_meta2(dir)
216
- meta_tabs = {"t_table_info" => :tabinf, "t_table_schema" => :tabscm, "t_cycle" => :cycle, "t_depends" => :depends, "t_rules" => :rules}
289
+ meta_tabs = {"t_table_info" => :tabinf, "t_table_schema" => :tabscm, "t_cycle" => :cycle, "t_depends" => :depends, "t_rules" => :rules, "t_provides" => :provides}
217
290
  meta = {}
218
291
  data = []
219
292
 
@@ -227,7 +300,7 @@ END_JS
227
300
  tup = key[0]
228
301
  MessagePack.unpack(v).each {|val| tup << val}
229
302
  if meta_tabs[tab]
230
- raise "non-zero budtime. sure this is metadata?" if time != 0 and strict
303
+ raise "non-zero budtime.(tab=#{tab}, time=#{time}) sure this is metadata?" if time != 0 #and strict
231
304
  meta[meta_tabs[tab]] ||= []
232
305
  meta[meta_tabs[tab]] << tup
233
306
  #ret << tup
@@ -254,10 +327,19 @@ END_JS
254
327
  def start_table(dir, tab, time, schema)
255
328
  str = "#{dir}/#{tab}_#{time}.html"
256
329
  fout = File.new(str, "w")
257
-
258
330
  fout.puts "<html><title>#{tab} @ #{time}</title>"
259
331
  fout.puts "<table border=1>"
260
- fout.puts "<tr>" + schema.map{|s| "<th> #{s} </th>"}.join(" ") + "<tr>" unless schema.nil?
332
+ # issue with _snd schemas
333
+ if !schema.nil? and schema[0] == "c_bud_time"
334
+ fout.puts "<tr>"
335
+ if schema[1].length == 2 and schema[1][0].class == Array and schema[1][1].class == Array
336
+ fout.puts schema[1][0].map{|s| "<th> #{s} </th>"}.join(" ")
337
+ fout.puts schema[1][1].map{|s| "<th> #{s} </th>"}.join(" ")
338
+ else
339
+ fout.puts schema[1].map{|s| "<th> #{s} </th>"}.join(" ")
340
+ end
341
+ fout.puts "<tr>"
342
+ end
261
343
  fout.close
262
344
  return str
263
345
  end
data/lib/bud.rb CHANGED
@@ -20,6 +20,7 @@ require 'bud/deploy/threaddeploy'
20
20
  require 'bud/errors'
21
21
  require 'bud/joins'
22
22
  require 'bud/metrics'
23
+ require 'bud/meta_algebra'
23
24
  require 'bud/rtrace'
24
25
  require 'bud/server'
25
26
  require 'bud/state'
@@ -92,6 +93,15 @@ module Bud
92
93
  # * <tt>:metrics</tt> if true, dumps a hash of internal performance metrics
93
94
  # * controlling execution
94
95
  # * <tt>:tag</tt> a name for this instance, suitable for display during tracing and visualization
96
+ # * <tt>:channel_filter</tt> a code block that can be used to filter the
97
+ # network messages delivered to this Bud instance. At the start of each
98
+ # tick, the code block is invoked for every channel with any incoming
99
+ # messages; the code block is passed the name of the channel and an array
100
+ # containing the inbound messages. It should return a two-element array
101
+ # containing "accepted" and "postponed" messages, respectively. Accepted
102
+ # messages are delivered during this tick, and postponed messages are
103
+ # buffered and passed to the filter in subsequent ticks. Any messages that
104
+ # aren't in either array are dropped.
95
105
  # * storage configuration
96
106
  # * <tt>:dbm_dir</tt> filesystem directory to hold DBM-backed collections
97
107
  # * <tt>:dbm_truncate</tt> if true, DBM-backed collections are opened with +OTRUNC+
@@ -117,7 +127,7 @@ module Bud
117
127
  @inside_tick = false
118
128
  @tick_clock_time = nil
119
129
  @budtime = 0
120
- @inbound = []
130
+ @inbound = {}
121
131
  @done_bootstrap = false
122
132
  @joinstate = {} # joins are stateful, their state needs to be kept inside the Bud instance
123
133
  @instance_id = ILLEGAL_INSTANCE_ID # Assigned when we start running
@@ -187,15 +197,15 @@ module Bud
187
197
  # temp collections. Imported modules are rewritten during the import process;
188
198
  # we rewrite the main class associated with this Bud instance and any included
189
199
  # modules here. Note that we only rewrite each distinct Class once, and we
190
- # skip methods defined by the Bud (Ruby) module directly (since we can be sure
191
- # those won't reference Bloom modules).
200
+ # skip methods defined by the Bud (Ruby) module or the builtin Bloom programs
201
+ # (since we can be sure those won't need rewriting).
192
202
  def self.rewrite_local_methods(klass)
193
203
  @done_rewrite ||= {}
194
204
  return if @done_rewrite.has_key? klass.name
195
- return if klass.name == self.name # Skip methods defined in the Bud module
205
+ return if [self, DepAnalysis, Stratification].include? klass
196
206
 
197
207
  u = Unifier.new
198
- ref_expander = NestedRefRewriter.new(klass.bud_import_table)
208
+ ref_expander = NestedRefRewriter.new(klass)
199
209
  tmp_expander = TempExpander.new
200
210
  with_expander = WithExpander.new
201
211
  r2r = Ruby2Ruby.new
@@ -208,8 +218,8 @@ module Bud
208
218
  ast = with_expander.process(ast)
209
219
 
210
220
  if ref_expander.did_work or tmp_expander.did_work or with_expander.did_work
211
- new_source = r2r.process(ast)
212
- klass.module_eval new_source # Replace previous method def
221
+ new_src = r2r.process(ast)
222
+ klass.module_eval new_src # Replace previous method def
213
223
  end
214
224
 
215
225
  ref_expander.did_work = false
@@ -494,7 +504,7 @@ module Bud
494
504
  cb_id = nil
495
505
  schedule_and_wait do
496
506
  unless @tables.has_key? tbl_name
497
- raise Bud::Error, "no such table: #{tbl_name}"
507
+ raise Bud::Error, "no such collection: #{tbl_name}"
498
508
  end
499
509
 
500
510
  raise Bud::Error if @callbacks.has_key? @callback_id
@@ -650,7 +660,8 @@ module Bud
650
660
 
651
661
  def do_start_server
652
662
  @dsock = EventMachine::open_datagram_socket(@ip, @options[:port],
653
- BudServer, self)
663
+ BudServer, self,
664
+ @options[:channel_filter])
654
665
  @port = Socket.unpack_sockaddr_in(@dsock.get_sockname)[0]
655
666
  end
656
667
 
@@ -669,13 +680,13 @@ module Bud
669
680
  end
670
681
 
671
682
  def ip
672
- ip = options[:ext_ip] ? "#{@options[:ext_ip]}" : "#{@ip}"
683
+ options[:ext_ip] ? "#{@options[:ext_ip]}" : "#{@ip}"
673
684
  end
674
685
 
675
686
  def port
676
687
  return nil if @port.nil? and @options[:port] == 0 and not @options[:ext_port]
677
- return options[:ext_port] ? "#{@options[:ext_port]}" :
678
- (@port.nil? ? "#{@options[:port]}" : "#{@port}")
688
+ return @options[:ext_port] ? @options[:ext_port] :
689
+ (@port.nil? ? @options[:port] : @port)
679
690
  end
680
691
 
681
692
  # Returns the internal IP and port. See ip_port.
@@ -769,8 +780,10 @@ module Bud
769
780
  # directly into the storage of the appropriate local channel. The inbound
770
781
  # queue is cleared at the end of the tick.
771
782
  def receive_inbound
772
- @inbound.each do |msg|
773
- tables[msg[0].to_sym] << msg[1]
783
+ @inbound.each do |tbl_name, msg_buf|
784
+ msg_buf.each do |b|
785
+ tables[tbl_name] << b
786
+ end
774
787
  end
775
788
  end
776
789
 
@@ -840,7 +853,7 @@ module Bud
840
853
  unless new_e.class <= Bud::Error
841
854
  new_e = Bud::Error
842
855
  end
843
- raise new_e, "exception during Bud evaluation.\nException: #{e.inspect}.#{src_msg}"
856
+ raise new_e, "exception during Bud evaluation.\nException: #{e.inspect}\nLocation: #{e.backtrace.first}.#{src_msg}"
844
857
  end
845
858
  end
846
859
  @stratum_first_iter = false
@@ -870,7 +883,8 @@ module Bud
870
883
 
871
884
  def make_periodic_timer(name, period)
872
885
  EventMachine::PeriodicTimer.new(period) do
873
- @inbound << [name, [gen_id, Time.now]]
886
+ @inbound[name.to_sym] ||= []
887
+ @inbound[name.to_sym] << [gen_id, Time.now]
874
888
  tick_internal if @running_async
875
889
  end
876
890
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bud
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 7
10
- version: 0.0.7
9
+ - 8
10
+ version: 0.0.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - Peter Alvaro
@@ -274,6 +274,7 @@ files:
274
274
  - lib/bud/errors.rb
275
275
  - lib/bud/graphs.rb
276
276
  - lib/bud/joins.rb
277
+ - lib/bud/meta_algebra.rb
277
278
  - lib/bud/metrics.rb
278
279
  - lib/bud/monkeypatch.rb
279
280
  - lib/bud/rebl.rb