bud 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/README +33 -16
  2. data/bin/budplot +42 -65
  3. data/bin/budtimelines +235 -0
  4. data/bin/budvis +24 -122
  5. data/bin/rebl +1 -0
  6. data/docs/README.md +21 -10
  7. data/docs/bfs.md +4 -6
  8. data/docs/c.html +251 -0
  9. data/docs/cheat.md +45 -30
  10. data/docs/deploy.md +26 -26
  11. data/docs/getstarted.md +6 -4
  12. data/docs/visualizations.md +43 -31
  13. data/examples/chat/chat.rb +4 -9
  14. data/examples/chat/chat_server.rb +1 -8
  15. data/examples/deploy/deploy_ip_port +1 -0
  16. data/examples/deploy/keys.rb +5 -0
  17. data/examples/deploy/tokenring-ec2.rb +9 -9
  18. data/examples/deploy/{tokenring-local.rb → tokenring-fork.rb} +3 -5
  19. data/examples/deploy/tokenring-thread.rb +15 -0
  20. data/examples/deploy/tokenring.rb +25 -17
  21. data/lib/bud/aggs.rb +87 -25
  22. data/lib/bud/bud_meta.rb +48 -31
  23. data/lib/bud/bust/bust.rb +16 -15
  24. data/lib/bud/collections.rb +207 -232
  25. data/lib/bud/depanalysis.rb +1 -0
  26. data/lib/bud/deploy/countatomicdelivery.rb +8 -20
  27. data/lib/bud/deploy/deployer.rb +16 -16
  28. data/lib/bud/deploy/ec2deploy.rb +34 -35
  29. data/lib/bud/deploy/forkdeploy.rb +90 -0
  30. data/lib/bud/deploy/threaddeploy.rb +38 -0
  31. data/lib/bud/graphs.rb +103 -199
  32. data/lib/bud/joins.rb +190 -41
  33. data/lib/bud/monkeypatch.rb +84 -0
  34. data/lib/bud/rebl.rb +8 -1
  35. data/lib/bud/rewrite.rb +152 -49
  36. data/lib/bud/server.rb +1 -0
  37. data/lib/bud/state.rb +24 -10
  38. data/lib/bud/storage/dbm.rb +170 -0
  39. data/lib/bud/storage/tokyocabinet.rb +5 -1
  40. data/lib/bud/stratify.rb +6 -7
  41. data/lib/bud/viz.rb +31 -17
  42. data/lib/bud/viz_util.rb +204 -0
  43. data/lib/bud.rb +271 -244
  44. data/lib/bud.rb.orig +806 -0
  45. metadata +43 -22
  46. data/docs/bfs.raw +0 -251
  47. data/docs/diffs +0 -181
  48. data/examples/basics/out +0 -1103
  49. data/examples/basics/out.new +0 -856
  50. data/lib/bud/deploy/localdeploy.rb +0 -53
data/README CHANGED
@@ -1,30 +1,47 @@
1
1
  # Bud
2
2
 
3
- This is Bud, a.k.a. "Bloom Under Development". It is an initial cut at a Bloom DSL, using Ruby as a setting.
3
+ This is Bud, a.k.a. "Bloom Under Development". It is an initial cut at a Bloom
4
+ DSL, using Ruby as a setting.
4
5
 
5
- Please see LICENSE for licensing information.
6
+ See LICENSE for licensing information.
6
7
 
7
- Language cheatsheet in doc/cheat.md
8
+ Language cheatsheet in docs/cheat.md ; see the docs/ directory for other
9
+ documentation.
8
10
 
9
11
  Main deficiencies at this point are:
10
- - Inefficient evaluation: Programs are run using semi-naive evaluation strategies, but no further
11
- query optimization has been implemented, and little effort has been spent in
12
- tuning.
13
12
 
14
- - No Ruby constraints: Within Bloom programs the full power of Ruby is also available, including mutable state.
15
- This allows programmers to get outside the Bloom framework and lose cleanliness.
13
+ - Inefficient evaluation: Programs are run using semi-naive evaluation
14
+ strategies, but no further query optimization has been implemented, and little
15
+ effort has been spent in tuning.
16
16
 
17
- - Compatibility: Bud only works with Ruby (MRI) 1.8. MRI 1.9, JRuby and other Ruby
18
- implementations are currently not supported.
17
+ - No Ruby constraints: Within Bloom programs the full power of Ruby is also
18
+ available, including mutable state. This allows programmers to get outside
19
+ the Bloom framework and lose cleanliness.
19
20
 
20
- To install:
21
+ - Compatibility: Bud only works with Ruby (MRI) 1.8. MRI 1.9, JRuby and other
22
+ Ruby implementations are currently not supported.
23
+
24
+ ## Installation
25
+
26
+ To install the latest release:
21
27
  % gem install bud
22
28
 
23
- Simple example programs can be found in examples. A much larger set
24
- of example programs and libraries can be found in the bud-sandbox repo.
29
+ To build and install a new gem from the current development sources:
30
+ % gem build bud.gemspec ; gem install bud*.gem
31
+
32
+ Note that GraphViz must be installed.
33
+
34
+ Simple example programs can be found in examples. A much larger set of example
35
+ programs and libraries can be found in the bud-sandbox repository.
36
+
37
+ To run the unit tests:
38
+ % cd test; ruby ts_bud.rb
25
39
 
26
40
  ## Optional Dependencies
27
41
 
28
- The bud gem has a handful of mandatory dependencies. It also has one optional
29
- dependency: if you wish to use the Bud collections backed by Zookeeper (the
30
- "zktable" collection type), the "zookeeper" gem must be installed.
42
+ The bud gem has a handful of mandatory dependencies. It also has two optional
43
+ dependencies: if you wish to use Bud collections backed by Zookeeper or Tokyo
44
+ Cabinet (the "zktable" and "tctable" collection types, respectively), the
45
+ "zookeeper" and/or "tokyocabinet" gems must be installed. Note that before
46
+ installing the "tokyocabinet" gem, the Tokyo Cabinet libraries should be
47
+ installed first.
data/bin/budplot CHANGED
@@ -2,26 +2,30 @@
2
2
  require 'rubygems'
3
3
  require 'bud'
4
4
  require 'bud/bud_meta'
5
- require 'bud/graphs'
6
5
  require 'bud/depanalysis'
6
+ require 'bud/graphs'
7
+ require 'bud/viz_util'
7
8
 
8
- # args: N, files_n, classes_m
9
-
10
- def process(mods)
11
- classdef = "class FooBar\ninclude Bud\n" + mods.map{|m| "include #{m}"}.join("\n") + "\nend\n FooBar.new"
12
- puts "classdef #{classdef}"
13
- d = eval(classdef)
14
-
15
- d.t_rules.each {|s| puts "RULE: #{s.inspect}" }
16
- #d.t_depends.each {|s| puts "DEP: #{s.inspect}" }
9
+ include VizUtil
17
10
 
18
- da = d.meta_parser.depanalysis
11
+ def is_module?(m)
12
+ begin
13
+ return (eval("defined?(#{m})") == "constant")
14
+ rescue SyntaxError
15
+ return false
16
+ end
17
+ end
19
18
 
20
- #puts "MP info src=#{da.source.length}, snk=#{da.sink.length}, under=#{da.underspecified.length}"
19
+ def process(mods)
20
+ mods.each do |m|
21
+ unless is_module? m
22
+ puts "Error: unable to find definition for module \"#{m}\""
23
+ exit
24
+ end
25
+ end
21
26
 
22
- #d.meta_parser.depanalysis.source.each do |s|
23
- # puts "SRC: #{s}"
24
- #end
27
+ classdef = "class FooBar\ninclude Bud\n" + mods.map{|m| "include #{m}"}.join("\n") + "\nend\n FooBar.new"
28
+ d = eval(classdef)
25
29
 
26
30
  interfaces = {}
27
31
  d.t_provides.each do |name, is_input|
@@ -48,87 +52,60 @@ def process(mods)
48
52
  end
49
53
  end
50
54
 
51
- svg = "bud_doc/" + mods.join("_") + "_viz"
52
- write_index(inp, outp, priv, svg)
53
- gv = GraphGen.new(d.t_stratum, tabinf, d.t_cycle, svg, -1, 1, ".", true, d.meta_parser.depanalysis)
54
- gv.process(d.t_depends)
55
- gv.dump(d.t_rules)
56
- gv.finish
57
-
58
- gv2 = GraphGen.new(d.t_stratum, tabinf, d.t_cycle, svg, -1, 1, ".", false, d.meta_parser.depanalysis)
59
- gv2.process(d.t_depends)
60
- gv2.dump(d.t_rules)
61
- gv2.finish
55
+ viz_name = "bud_doc/" + mods.join("_") + "_viz"
56
+ write_index(inp, outp, priv, viz_name)
57
+ graph_from_instance(d, "#{viz_name}_collapsed", "bud_doc", true)
58
+ graph_from_instance(d, "#{viz_name}_expanded", "bud_doc", false)
62
59
  end
63
60
 
64
- def write_index(inp, outp, priv, svg)
61
+ def write_index(inp, outp, priv, viz_name)
65
62
  f = File.open("bud_doc/index.html", "w")
66
63
  f.puts "<html>"
67
- f.puts "<embed src=\"#{ENV['PWD']}/#{svg}_collapsed.svg\" width=\"100%\" height=\"60%\" type=\"image/svg+xml\" pluginspage=\"http://www.adobe.com/svg/viewer/install/\" />"
64
+ f.puts "<embed src=\"#{ENV['PWD']}/#{viz_name}_collapsed.svg\" width=\"100%\" height=\"60%\" type=\"image/svg+xml\" pluginspage=\"http://www.adobe.com/svg/viewer/install/\" />"
68
65
 
69
66
  f.puts "<table border='1' valign='top' width = '100%'><tr valign='top'>"
70
67
  f.puts "<td valign='top'>"
71
- f.puts "<h2> Input Interfaces </h2>"
68
+ f.puts "<h2>Input Interfaces</h2>"
72
69
  do_table(f, inp)
73
70
  f.puts "</td><td>"
74
- f.puts "<h2> Output Interfaces </h2>"
71
+ f.puts "<h2>Output Interfaces</h2>"
75
72
  do_table(f, outp)
76
73
  f.puts "</td><td>"
77
- f.puts "<h2> Private State </h2>"
78
- do_table(f, priv, true)
74
+ f.puts "<h2>Private State</h2>"
75
+ do_table(f, priv)
79
76
  f.puts "</td>"
80
77
  f.puts "</tr></table>"
81
78
  f.puts "</html>"
82
79
  f.close
83
80
  end
84
81
 
85
- def do_table(f, info, type=false)
86
- next if info.nil?
82
+ def do_table(f, info)
87
83
  f.puts "<table border='1'>"
88
- info.sort{|a, b| a[0].to_s <=> b[0].to_s}.each do |inf|
89
- #f.puts "<h3>#{inf[0]}</h3>"
90
- #f.puts "&nbsp; (#{inf[1].class.to_s.gsub('Bud::Bud', '')})<br>" if type
91
- unless inf[1].schema.nil?
92
- f.puts "<tr><td><b>#{inf[0]}</b></td>" + inf[1].schema.map{|i| "<td>#{i}</td>"}.join(" ") + "</tr>"
93
- end
84
+ info.sort{|a, b| a[0].to_s <=> b[0].to_s}.each do |tbl_name, tbl_impl|
85
+ next if tbl_impl.schema.nil?
86
+ key_s = tbl_impl.key_cols.join(", ")
87
+ key_s = "[]" if key_s == ""
88
+ val_s = tbl_impl.val_cols.join(", ")
89
+ f.puts "<tr><td><b>#{tbl_name}</b></td>"
90
+ f.puts "<td>#{key_s}</td><td>#{val_s}</td></tr>"
94
91
  end
95
92
  f.puts "</table>"
96
93
  end
97
94
 
98
- @shreddies = []
99
- @provides = []
100
- @demands = []
101
- @tabinf = {}
102
- @port = 12345
103
- files = []
104
- classes = []
105
-
106
95
  if ARGV.length < 2
107
- puts "len #{ARGV.length} USAGE:\nruby plotter.rb LIST_OF_FILES LIST_OF_MODULES"
96
+ puts "Usage: budplot LIST_OF_FILES LIST_OF_MODULES"
108
97
  exit
109
98
  end
110
99
 
111
100
  `mkdir bud_doc`
112
101
 
113
102
  modules = []
114
- (0..ARGV.length-1).each do |i|
115
- begin
116
- f = File.open(ARGV[i])
117
- mods = false
118
- rescue
119
- mods = true
120
- end
121
-
122
- unless mods
123
- puts "DO #{ARGV[i]}"
124
- eval ( "require \"#{ARGV[i]}\"")
103
+ ARGV.each do |arg|
104
+ if File.exists? arg
105
+ eval "require '#{arg}'"
125
106
  else
126
- puts "Work on #{ARGV[i]}"
127
- #instant(ARGV[i])
128
- modules << ARGV[i]
129
- puts "OK"
107
+ modules << arg
130
108
  end
131
109
  end
132
110
 
133
111
  process(modules)
134
-
data/bin/budtimelines ADDED
@@ -0,0 +1,235 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'dbm'
4
+ require 'bud'
5
+ require 'bud/graphs'
6
+ require 'bud/viz_util'
7
+ require 'getopt/std'
8
+
9
+ include VizUtil
10
+
11
+ module Depends
12
+ state do
13
+ table :depends, [:rid, :lhs, :op, :rhs, :nm]
14
+ end
15
+ end
16
+
17
+ class GlobalDepAnalyzer
18
+ include Bud
19
+ include Depends
20
+ # this module's purpose and mechanism are very similar
21
+ # to those of basic stratification. here, we are interested
22
+ # in NM paths that DO cross temporal edges.
23
+
24
+ state do
25
+ table :depends_tc, [:lhs, :rhs, :via, :nm]
26
+ end
27
+
28
+ bloom do
29
+ depends_tc <= depends{|d| [d.lhs, d.rhs, d.rhs, d.nm]}
30
+ depends_tc <= (depends * depends_tc).pairs(:rhs => :lhs) do |d, tc|
31
+ [d.lhs, tc.rhs, d.rhs, (d.nm or tc.nm)]
32
+ end
33
+ end
34
+ end
35
+
36
+ module TPSchema
37
+ state do
38
+ table :deltas, [:bud_time, :tab, :nm]
39
+ table :zerod_cards, [:bud_time, :table, :cnt]
40
+ table :nm_tab, [:table]
41
+ table :collapsible_base, [:start, :fin]
42
+ table :collapsible, [:start, :fin]
43
+ scratch :collapsible_tmp, [:start, :fin]
44
+ scratch :lcl_best_interval, [:start, :fin]
45
+ table :best_interval, [:start, :fin]
46
+ end
47
+ end
48
+
49
+ module DeltaLogic
50
+ include TPSchema
51
+ bloom do
52
+ zerod_cards <= cardinalities
53
+ zerod_cards <= (times * depends).pairs do |t, d|
54
+ unless cardinalities{|c| c[1] if c[0] == t.bud_time}.include? d[1]
55
+ [t.bud_time, d[1], 0]
56
+ end
57
+ end
58
+
59
+
60
+ nm_tab <= depends do |d|
61
+ [d[1]] if d[4]
62
+ end
63
+
64
+ deltas <= (zerod_cards * zerod_cards).pairs(:table => :table) do |c1, c2|
65
+ if c1.bud_time == c2.bud_time - 1 and c1.table == c2.table and c1.cnt != c2.cnt
66
+ if nm_tab.include? [c1.table]
67
+ [c2.bud_time, c1.table, true]
68
+ else
69
+ [c2.bud_time, c1.table, false]
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ module VanillaTraceProcessing
77
+ include TPSchema
78
+ include DeltaLogic
79
+
80
+ bloom do
81
+ collapsible_base <= times do |t|
82
+ unless deltas{|d| d.bud_time if d.nm}.include? t.bud_time
83
+ [t.bud_time-1, t.bud_time]
84
+ end
85
+ end
86
+
87
+ collapsible <= collapsible_base
88
+
89
+ collapsible <= (collapsible_base * collapsible).pairs(:fin => :start) do |b, c|
90
+ puts "another collapsible row; now #{b.inspect} - #{c.inspect}"
91
+ [b.start, c.fin]
92
+ end
93
+
94
+ best_interval <= collapsible do |c|
95
+ unless collapsible{|c1| c1.start == c.start and c1.fin > c.fin}.any? \
96
+ or collapsible{|c2| c2.fin == c.fin and c2.start < c.start}.any?
97
+ c
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ class SimpleTraceProcessor
104
+ include Bud
105
+ include TraceCardinality
106
+ include Depends
107
+ include VanillaTraceProcessing
108
+
109
+ end
110
+
111
+ def collapse(intervals, host, time)
112
+ return time unless @opts["C"]
113
+ # worth rethinking when the # of intervals/instance gets high
114
+ intervals[host].each do |i|
115
+ if time > i[0] and time < i[1]
116
+ return i[1]
117
+ end
118
+ end
119
+ return time
120
+ end
121
+
122
+ def usage
123
+ puts "USAGE:"
124
+ exit
125
+ end
126
+
127
+ usage unless ARGV[0]
128
+ usage if ARGV[0] == '--help'
129
+
130
+ @opts = Getopt::Std.getopts("CLo:")
131
+
132
+ snd_info = {}
133
+ rcv_info = {}
134
+ clean_arg = []
135
+ intervals = {}
136
+
137
+
138
+ da = GlobalDepAnalyzer.new
139
+
140
+ ARGV.each do |arg_raw|
141
+ elems = arg_raw.split("_")
142
+ arg = elems[1..3].join("_")
143
+ clean_arg << arg
144
+ snd_info[arg] = []
145
+ rcv_info[arg] = []
146
+
147
+ meta, data = get_meta2("#{arg_raw}/bud_")
148
+ tp = SimpleTraceProcessor.new
149
+
150
+ meta[:depends].each do |m|
151
+ tp.depends << m
152
+ da.depends << m
153
+ end
154
+
155
+ data.each do |d|
156
+ tp.full_info << d
157
+ if meta[:tabinf].map{|m| m[0] if m[1] == "Bud::BudChannel"}.include? d[1]
158
+ if d[1] =~ /_snd\z/
159
+ snd_info[arg] << d
160
+ else
161
+ rcv_info[arg] << d
162
+ end
163
+ elsif meta[:tabinf].map{|m| m[0] if m[1] == "Bud::BudPeriodic"}.include? d[1]
164
+ end
165
+ end
166
+
167
+ tp.tick
168
+
169
+
170
+ puts "entries in collapsible: #{tp.collapsible.length}"
171
+ puts "entries in base: #{tp.collapsible_base.length}"
172
+ puts "entries in deltas: #{tp.deltas.length}"
173
+
174
+ intervals[arg] = []
175
+ tp.best_interval.each do |n|
176
+ puts "BEST INTERVAL[#{arg}]: #{n.inspect}"
177
+ intervals[arg] << n
178
+ end
179
+ end
180
+
181
+ da.tick
182
+ nmreach = {}
183
+ da.depends_tc.each do |d|
184
+ nmreach[d[0]] = {} unless nmreach[d[0]]
185
+ nmreach[d[0]][d[1]] = d[3]
186
+ end
187
+
188
+ # our local intervals relations are too optimistic. to say that intervals[foo] = [2, 5]
189
+ # is merely to say that nothing NM happened locally btw 2 and 5. it is only safe to collapse
190
+ # 2 and 5 if during this interval, we could not have BOTH caused and perceived the results of
191
+ # a NM deduction. we can (again, conservatively) ensure that this is not the case by showing
192
+ # that from 2-5, there exist no messages A and B s.t. we sent A and received B in the interval 2..5
193
+ # and B <n A (where <n means is globally NM-derivable from).
194
+
195
+ # we can of course do better than this even with the data we have, but it is complicated and we'll
196
+ # get to it later.
197
+
198
+ plot_data = []
199
+ snd_info.each_pair do |k1, v1|
200
+ rcv_info.each_pair do |k2, v2|
201
+ v1.each do |lval|
202
+ v2.each do |rval|
203
+ unless k1 == k2
204
+ # erm, tuple equivalence?
205
+ l = lval[2].clone
206
+ r = rval[2].clone
207
+ l.shift
208
+ r.shift
209
+ if l.inspect == r.inspect
210
+ plot_data << [l.inspect, k1, k2, lval[0], rval[0], rval[1]]
211
+ end
212
+ else
213
+ if collapse(intervals, k1, lval[0]) == collapse(intervals, k2, rval[0]) and lval[0] < rval[0]
214
+ unless nmreach[rval[1]].nil?
215
+ if nmreach[rval[1]][lval[1].gsub(/_snd\z/, "")]
216
+ match = intervals[k1].find_all{|i| i[1] == collapse(intervals, k1, lval[0])}.first
217
+ intervals[k1].delete(match)
218
+ intervals[k1] << [match[0], lval[0]]
219
+ intervals[k1] << [lval[0]+1, match[1]]
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end
228
+
229
+ rpd = plot_data.map do |p|
230
+ [p[0], p[1], p[2], collapse(intervals, p[1], p[3]), collapse(intervals, p[2], p[4]), p[5]]
231
+ end
232
+
233
+ st = SpaceTime.new(rpd, @opts["L"])
234
+ st.process
235
+ st.finish("spacetime_trace_#{clean_arg.join('-')}", @opts["o"])
data/bin/budvis CHANGED
@@ -1,49 +1,33 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'rubygems'
3
- require 'tokyocabinet'
3
+ require 'dbm'
4
4
  require 'bud'
5
5
  require 'bud/graphs'
6
- include TokyoCabinet
6
+ require 'bud/viz_util'
7
7
 
8
- # prototype offline viz
9
-
10
- BUD_TC_DIR = "#{ARGV[0]}/bud_"
8
+ include VizUtil
11
9
 
10
+ BUD_DBM_DIR = "#{ARGV[0]}/bud_"
12
11
 
13
12
  class VizHelper
14
13
  include Bud
14
+ include TraceCardinality
15
15
 
16
- state do
17
- table :full_info, [:bud_time, :table, :row]
18
- scratch :cardinalities, [:bud_time, :table] => [:cnt]
19
- scratch :times, [:bud_time]
20
- end
21
-
22
- def initialize(strata, tabinf, cycle, depends, rules, dir)
23
- @t_strata = strata
16
+ def initialize(tabinf, cycle, depends, rules, dir)
24
17
  @t_tabinf = tabinf
25
18
  @t_cycle = cycle
26
19
  @t_depends = depends
27
- @dir = dir
28
20
  @t_rules = rules
21
+ @dir = dir
29
22
  super()
30
23
  end
31
24
 
32
- bloom :counting do
33
- cardinalities <= full_info.group([full_info.bud_time, full_info.table], count)
34
- times <= full_info.map{|f| [f.bud_time]}
35
- end
36
-
37
25
  def summarize(dir, schema)
38
26
  table_io = {}
39
- timeseries = {}
40
27
  cardinalities.sort{|a, b| a[0] <=> b[0]}.each do |card|
41
28
  table_io["#{card.table}_#{card.bud_time}"] = start_table(dir, card.table, card.bud_time, schema[card.table])
42
- unless timeseries[card.table]
43
- timeseries[card.table] = []
44
- end
45
- timeseries[card.table] << card.cnt
46
29
  end
30
+
47
31
  full_info.each do |info|
48
32
  write_table_content(table_io["#{info.table}_#{info.bud_time}"], info.row)
49
33
  end
@@ -52,19 +36,6 @@ class VizHelper
52
36
  end_table(tab)
53
37
  end
54
38
 
55
- ts2 = {}
56
- timeseries.each_pair do |k, v|
57
- fn = v
58
- puts "GOT #{fn}"
59
- #ts2[k] = "#{ENV['PWD']}/#{fn}"
60
- ts2[k] = v
61
- end
62
-
63
- sum = GraphGen.new(@t_strata, @t_tabinf, @t_cycle, "#{@dir}/summary", -1, 3, @dir, false, nil, ts2)
64
- sum.process(@t_depends)
65
- sum.dump(@t_rules)
66
- sum.finish
67
-
68
39
  # fix: nested loops
69
40
  times.sort.each do |time|
70
41
  card_info = {}
@@ -74,24 +45,18 @@ class VizHelper
74
45
  end
75
46
  end
76
47
 
77
- gv = GraphGen.new(@t_strata, @t_tabinf, @t_cycle, "#{@dir}/tm_#{time.bud_time}", time.bud_time, 3, @dir, false, nil, card_info)
78
- gv.process(@t_depends)
79
- gv.dump(@t_rules)
80
- gv.finish
81
-
48
+ d = "#{@dir}/tm_#{time.bud_time}"
49
+ write_graphs(@t_tabinf, @t_cycle, @t_depends, @t_rules, d, @dir, nil, false, nil, time.bud_time, card_info)
82
50
  end
83
-
84
51
  end
85
52
 
86
53
  def start_table(dir, tab, time, schema)
87
54
  str = "#{dir}/#{tab}_#{time}.html"
88
- #fout = File.new("#{dir}/#{tab}_#{time}.html", "w")
89
55
  fout = File.new(str, "w")
90
56
 
91
- #fout.puts "<h1>#{tab} #{time_node_header()}</h1>"
92
57
  fout.puts "<html><title>#{tab} @ #{time}</title>"
93
58
  fout.puts "<table border=1>"
94
- fout.puts "<tr>" + schema.map{|s| "<th> #{s} </th>"}.join(" ") + "<tr>"
59
+ fout.puts "<tr>" + schema.map{|s| "<th> #{s} </th>"}.join(" ") + "<tr>" unless schema.nil?
95
60
  fout.close
96
61
  return str
97
62
  end
@@ -111,91 +76,28 @@ class VizHelper
111
76
  end
112
77
  end
113
78
 
114
- def deserialize_table(tab, strict)
115
- # oy. meta only
116
- ret = []
117
- tab.each_pair do |k, v|
118
- #key = Marshal.load(k)
119
- key = MessagePack.unpack(k)
120
- time = key.shift
121
- raise "non-zero budtime. sure this is metadata?" if time != 0 and strict
122
- tup = key
123
- #Marshal.load(v).each{|v| tup << v }
124
- MessagePack.unpack(v).each{|val| tup << val }
125
- ret << tup
126
- end
127
- tab.close
128
- return ret
129
- end
130
-
131
79
  def usage
132
80
  puts "Usage:"
133
- puts "Running a Bud program with option :visualize => 3 will cause a TC directory TC_dir to be created (Class_ObjectId_Port)"
134
- puts "> ruby visualize.rb TC_dir"
135
- puts "This will create a series of svg files in TC_dir, the root of which will be named tm_0_expanded.svg. Open in a browser.\n"
81
+ puts "Running a Bud program with option :trace => true will cause a DBM directory DBM_dir to be created (Class_ObjectId_Port)"
82
+ puts "> budvis DBM_dir"
83
+ puts "This will create a series of svg files in DBM_dir, the root of which will be named tm_0.svg. Open in a browser.\n"
136
84
  puts "e.g."
137
85
  puts "> ruby test/tc_carts.rb"
138
- puts "> ruby visualize.rb BCS_2159661360_"
139
- puts "> open -a /Applications/Google\ Chrome.app/ BCS_2159661360_/tm_0_expanded.svg"
86
+ puts "> budvis DBM_BCS_2159661360_"
87
+ puts "> open DBM_BCS_2159661360_/tm_0.svg"
88
+ puts "\nWith the SVG file open in a browser, you may navigate forward and backward in time"
89
+ puts "by clicking the T and S nodes, respectively."
140
90
  exit
141
91
  end
142
92
 
143
- # begin "main"
144
-
145
93
  usage unless ARGV[0]
94
+ usage if ARGV[0] == '--help'
146
95
 
147
- @tables = {}
148
-
149
- Dir.new(BUD_TC_DIR).entries.each do |file|
150
- next if file =~ /^\./
151
- puts "FILE is #{file}"
152
- hdb = TokyoCabinet::HDB.new
153
- ret = hdb.open("#{BUD_TC_DIR}/#{file}", HDB::OREADER)
154
- raise "db not found" unless ret
155
- @tables[file] = hdb
156
- end
157
-
158
-
159
- # let's try to do a visualization
160
- strata = deserialize_table(@tables['t_stratum_vizlog.tch'], true)
161
- tabinf = deserialize_table(@tables['t_table_info_vizlog.tch'], true)
162
- tabscm = deserialize_table(@tables['t_table_schema_vizlog.tch'], true)
163
- cycle = deserialize_table(@tables['t_cycle_vizlog.tch'], true)
164
- depends = deserialize_table(@tables['t_depends_vizlog.tch'], true)
165
- rules = deserialize_table(@tables['t_rules_vizlog.tch'], true)
166
-
167
-
168
- schminf = {}
169
- tabscm.each do |ts|
170
- puts "TABSCM: #{ts.inspect}"
171
- tab = ts[0].to_s
172
- unless schminf[tab]
173
- schminf[tab] = []
174
- end
175
- schminf[tab][ts[2]] = ts[1]
176
- end
177
-
178
- gv = GraphGen.new(strata, tabinf, cycle, "OUTPUT", -1, 1, "plotter_out")
179
- gv.process(depends)
180
- gv.finish
181
-
182
-
183
- vh = VizHelper.new(strata, tabinf, cycle, depends, rules, ARGV[0])
184
-
185
- @tables.each_pair do |name, contents|
186
- name = name.gsub("_vizlog.tch", "")
187
- contents.each_pair do |k, v|
188
- key = MessagePack.unpack(k)
189
- time = key[0]
190
- row = key
191
- MessagePack.unpack(v).each{ |val| row << val }
192
- if name == "t_table_info.tch" or name == "t_table_schema.tch"
193
- #vh.full_info << [0, name, row]
194
- else
195
- vh.full_info << [time, name, row]
196
- end
197
- end
96
+ meta, data = get_meta2(BUD_DBM_DIR)
97
+ vh = VizHelper.new(meta[:tabinf], meta[:cycle], meta[:depends], meta[:rules], ARGV[0])
98
+ data.each do |d|
99
+ vh.full_info << d
198
100
  end
199
101
 
200
102
  vh.tick
201
- vh.summarize(ARGV[0], schminf)
103
+ vh.summarize(ARGV[0], meta[:schminf])
data/bin/rebl CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'rubygems'
2
3
  require 'bud/rebl'
3
4
 
4
5
  ReblShell::run