bud 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/budplot +97 -8
- data/bin/budvis +1 -2
- data/docs/cheat.md +1 -1
- data/lib/bud/aggs.rb +2 -1
- data/lib/bud/bud_meta.rb +8 -7
- data/lib/bud/collections.rb +36 -48
- data/lib/bud/graphs.rb +48 -21
- data/lib/bud/joins.rb +1 -1
- data/lib/bud/meta_algebra.rb +168 -0
- data/lib/bud/monkeypatch.rb +32 -5
- data/lib/bud/rewrite.rb +53 -14
- data/lib/bud/server.rb +25 -4
- data/lib/bud/state.rb +13 -14
- data/lib/bud/storage/dbm.rb +19 -8
- data/lib/bud/storage/tokyocabinet.rb +18 -8
- data/lib/bud/viz.rb +7 -5
- data/lib/bud/viz_util.rb +93 -11
- data/lib/bud.rb +30 -16
- metadata +4 -3
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
191
|
-
# those won't
|
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
|
205
|
+
return if [self, DepAnalysis, Stratification].include? klass
|
196
206
|
|
197
207
|
u = Unifier.new
|
198
|
-
ref_expander = NestedRefRewriter.new(klass
|
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
|
-
|
212
|
-
klass.module_eval
|
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
|
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
|
-
|
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] ?
|
678
|
-
(@port.nil? ?
|
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 |
|
773
|
-
|
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
|
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:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
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
|