bud 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README +33 -16
- data/bin/budplot +42 -65
- data/bin/budtimelines +235 -0
- data/bin/budvis +24 -122
- data/bin/rebl +1 -0
- data/docs/README.md +21 -10
- data/docs/bfs.md +4 -6
- data/docs/c.html +251 -0
- data/docs/cheat.md +45 -30
- data/docs/deploy.md +26 -26
- data/docs/getstarted.md +6 -4
- data/docs/visualizations.md +43 -31
- data/examples/chat/chat.rb +4 -9
- data/examples/chat/chat_server.rb +1 -8
- data/examples/deploy/deploy_ip_port +1 -0
- data/examples/deploy/keys.rb +5 -0
- data/examples/deploy/tokenring-ec2.rb +9 -9
- data/examples/deploy/{tokenring-local.rb → tokenring-fork.rb} +3 -5
- data/examples/deploy/tokenring-thread.rb +15 -0
- data/examples/deploy/tokenring.rb +25 -17
- data/lib/bud/aggs.rb +87 -25
- data/lib/bud/bud_meta.rb +48 -31
- data/lib/bud/bust/bust.rb +16 -15
- data/lib/bud/collections.rb +207 -232
- data/lib/bud/depanalysis.rb +1 -0
- data/lib/bud/deploy/countatomicdelivery.rb +8 -20
- data/lib/bud/deploy/deployer.rb +16 -16
- data/lib/bud/deploy/ec2deploy.rb +34 -35
- data/lib/bud/deploy/forkdeploy.rb +90 -0
- data/lib/bud/deploy/threaddeploy.rb +38 -0
- data/lib/bud/graphs.rb +103 -199
- data/lib/bud/joins.rb +190 -41
- data/lib/bud/monkeypatch.rb +84 -0
- data/lib/bud/rebl.rb +8 -1
- data/lib/bud/rewrite.rb +152 -49
- data/lib/bud/server.rb +1 -0
- data/lib/bud/state.rb +24 -10
- data/lib/bud/storage/dbm.rb +170 -0
- data/lib/bud/storage/tokyocabinet.rb +5 -1
- data/lib/bud/stratify.rb +6 -7
- data/lib/bud/viz.rb +31 -17
- data/lib/bud/viz_util.rb +204 -0
- data/lib/bud.rb +271 -244
- data/lib/bud.rb.orig +806 -0
- metadata +43 -22
- data/docs/bfs.raw +0 -251
- data/docs/diffs +0 -181
- data/examples/basics/out +0 -1103
- data/examples/basics/out.new +0 -856
- 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
|
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
|
-
|
6
|
+
See LICENSE for licensing information.
|
6
7
|
|
7
|
-
Language cheatsheet in
|
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
|
-
-
|
15
|
-
|
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
|
-
-
|
18
|
-
|
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
|
-
|
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
|
-
|
24
|
-
|
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
|
29
|
-
|
30
|
-
"zktable"
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
23
|
-
|
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
|
-
|
52
|
-
write_index(inp, outp, priv,
|
53
|
-
|
54
|
-
|
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,
|
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']}/#{
|
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>
|
68
|
+
f.puts "<h2>Input Interfaces</h2>"
|
72
69
|
do_table(f, inp)
|
73
70
|
f.puts "</td><td>"
|
74
|
-
f.puts "<h2>
|
71
|
+
f.puts "<h2>Output Interfaces</h2>"
|
75
72
|
do_table(f, outp)
|
76
73
|
f.puts "</td><td>"
|
77
|
-
f.puts "<h2>
|
78
|
-
do_table(f, priv
|
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
|
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 |
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
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 "
|
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
|
-
|
115
|
-
|
116
|
-
|
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
|
-
|
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 '
|
3
|
+
require 'dbm'
|
4
4
|
require 'bud'
|
5
5
|
require 'bud/graphs'
|
6
|
-
|
6
|
+
require 'bud/viz_util'
|
7
7
|
|
8
|
-
|
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
|
-
|
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
|
-
|
78
|
-
|
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 :
|
134
|
-
puts ">
|
135
|
-
puts "This will create a series of svg files in
|
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 ">
|
139
|
-
puts "> open
|
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
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
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])
|