bud 0.0.3 → 0.0.4

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.
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