bud 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +9 -0
- data/README +30 -0
- data/bin/budplot +134 -0
- data/bin/budvis +201 -0
- data/bin/rebl +4 -0
- data/docs/README.md +13 -0
- data/docs/bfs.md +379 -0
- data/docs/bfs.raw +251 -0
- data/docs/bfs_arch.png +0 -0
- data/docs/bloom-loop.png +0 -0
- data/docs/bust.md +83 -0
- data/docs/cheat.md +291 -0
- data/docs/deploy.md +96 -0
- data/docs/diffs +181 -0
- data/docs/getstarted.md +296 -0
- data/docs/intro.md +36 -0
- data/docs/modules.md +112 -0
- data/docs/operational.md +96 -0
- data/docs/rebl.md +99 -0
- data/docs/ruby_hooks.md +19 -0
- data/docs/visualizations.md +75 -0
- data/examples/README +1 -0
- data/examples/basics/hello.rb +12 -0
- data/examples/basics/out +1103 -0
- data/examples/basics/out.new +856 -0
- data/examples/basics/paths.rb +51 -0
- data/examples/bust/README.md +9 -0
- data/examples/bust/bustclient-example.rb +23 -0
- data/examples/bust/bustinspector.html +135 -0
- data/examples/bust/bustserver-example.rb +18 -0
- data/examples/chat/README.md +9 -0
- data/examples/chat/chat.rb +45 -0
- data/examples/chat/chat_protocol.rb +8 -0
- data/examples/chat/chat_server.rb +29 -0
- data/examples/deploy/tokenring-ec2.rb +26 -0
- data/examples/deploy/tokenring-local.rb +17 -0
- data/examples/deploy/tokenring.rb +39 -0
- data/lib/bud/aggs.rb +126 -0
- data/lib/bud/bud_meta.rb +185 -0
- data/lib/bud/bust/bust.rb +126 -0
- data/lib/bud/bust/client/idempotence.rb +10 -0
- data/lib/bud/bust/client/restclient.rb +49 -0
- data/lib/bud/collections.rb +937 -0
- data/lib/bud/depanalysis.rb +44 -0
- data/lib/bud/deploy/countatomicdelivery.rb +50 -0
- data/lib/bud/deploy/deployer.rb +67 -0
- data/lib/bud/deploy/ec2deploy.rb +200 -0
- data/lib/bud/deploy/localdeploy.rb +41 -0
- data/lib/bud/errors.rb +15 -0
- data/lib/bud/graphs.rb +405 -0
- data/lib/bud/joins.rb +300 -0
- data/lib/bud/rebl.rb +314 -0
- data/lib/bud/rewrite.rb +523 -0
- data/lib/bud/rtrace.rb +27 -0
- data/lib/bud/server.rb +43 -0
- data/lib/bud/state.rb +108 -0
- data/lib/bud/storage/tokyocabinet.rb +170 -0
- data/lib/bud/storage/zookeeper.rb +178 -0
- data/lib/bud/stratify.rb +83 -0
- data/lib/bud/viz.rb +65 -0
- data/lib/bud.rb +797 -0
- metadata +330 -0
data/LICENSE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Copyright (c) 2011, Regents of the University of California
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
o Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
7
|
+
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
8
|
+
o Neither the name of the University of California, Berkeley nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
9
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Bud
|
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.
|
4
|
+
|
5
|
+
Please see LICENSE for licensing information.
|
6
|
+
|
7
|
+
Language cheatsheet in doc/cheat.md
|
8
|
+
|
9
|
+
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
|
+
|
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.
|
16
|
+
|
17
|
+
- Compatibility: Bud only works with Ruby (MRI) 1.8. MRI 1.9, JRuby and other Ruby
|
18
|
+
implementations are currently not supported.
|
19
|
+
|
20
|
+
To install:
|
21
|
+
% gem install bud
|
22
|
+
|
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.
|
25
|
+
|
26
|
+
## Optional Dependencies
|
27
|
+
|
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.
|
data/bin/budplot
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bud'
|
4
|
+
require 'bud/bud_meta'
|
5
|
+
require 'bud/graphs'
|
6
|
+
require 'bud/depanalysis'
|
7
|
+
|
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}" }
|
17
|
+
|
18
|
+
da = d.meta_parser.depanalysis
|
19
|
+
|
20
|
+
#puts "MP info src=#{da.source.length}, snk=#{da.sink.length}, under=#{da.underspecified.length}"
|
21
|
+
|
22
|
+
#d.meta_parser.depanalysis.source.each do |s|
|
23
|
+
# puts "SRC: #{s}"
|
24
|
+
#end
|
25
|
+
|
26
|
+
interfaces = {}
|
27
|
+
d.t_provides.each do |name, is_input|
|
28
|
+
interfaces[name] = is_input
|
29
|
+
end
|
30
|
+
|
31
|
+
tabinf = {}
|
32
|
+
inp = []
|
33
|
+
outp = []
|
34
|
+
priv = []
|
35
|
+
d.tables.each do |t|
|
36
|
+
tab = t[0].to_s
|
37
|
+
tabinf[tab] = t[1].class.to_s
|
38
|
+
if interfaces[tab].nil?
|
39
|
+
unless tab =~ /^t_/ or tab == "stdio" or tab == "localtick"
|
40
|
+
priv << t
|
41
|
+
end
|
42
|
+
else
|
43
|
+
if interfaces[tab]
|
44
|
+
inp << t
|
45
|
+
else
|
46
|
+
outp << t
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
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
|
62
|
+
end
|
63
|
+
|
64
|
+
def write_index(inp, outp, priv, svg)
|
65
|
+
f = File.open("bud_doc/index.html", "w")
|
66
|
+
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/\" />"
|
68
|
+
|
69
|
+
f.puts "<table border='1' valign='top' width = '100%'><tr valign='top'>"
|
70
|
+
f.puts "<td valign='top'>"
|
71
|
+
f.puts "<h2> Input Interfaces </h2>"
|
72
|
+
do_table(f, inp)
|
73
|
+
f.puts "</td><td>"
|
74
|
+
f.puts "<h2> Output Interfaces </h2>"
|
75
|
+
do_table(f, outp)
|
76
|
+
f.puts "</td><td>"
|
77
|
+
f.puts "<h2> Private State </h2>"
|
78
|
+
do_table(f, priv, true)
|
79
|
+
f.puts "</td>"
|
80
|
+
f.puts "</tr></table>"
|
81
|
+
f.puts "</html>"
|
82
|
+
f.close
|
83
|
+
end
|
84
|
+
|
85
|
+
def do_table(f, info, type=false)
|
86
|
+
next if info.nil?
|
87
|
+
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 " (#{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
|
94
|
+
end
|
95
|
+
f.puts "</table>"
|
96
|
+
end
|
97
|
+
|
98
|
+
@shreddies = []
|
99
|
+
@provides = []
|
100
|
+
@demands = []
|
101
|
+
@tabinf = {}
|
102
|
+
@port = 12345
|
103
|
+
files = []
|
104
|
+
classes = []
|
105
|
+
|
106
|
+
if ARGV.length < 2
|
107
|
+
puts "len #{ARGV.length} USAGE:\nruby plotter.rb LIST_OF_FILES LIST_OF_MODULES"
|
108
|
+
exit
|
109
|
+
end
|
110
|
+
|
111
|
+
`mkdir bud_doc`
|
112
|
+
|
113
|
+
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]}\"")
|
125
|
+
else
|
126
|
+
puts "Work on #{ARGV[i]}"
|
127
|
+
#instant(ARGV[i])
|
128
|
+
modules << ARGV[i]
|
129
|
+
puts "OK"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
process(modules)
|
134
|
+
|
data/bin/budvis
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'tokyocabinet'
|
4
|
+
require 'bud'
|
5
|
+
require 'bud/graphs'
|
6
|
+
include TokyoCabinet
|
7
|
+
|
8
|
+
# prototype offline viz
|
9
|
+
|
10
|
+
BUD_TC_DIR = "#{ARGV[0]}/bud_"
|
11
|
+
|
12
|
+
|
13
|
+
class VizHelper
|
14
|
+
include Bud
|
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
|
24
|
+
@t_tabinf = tabinf
|
25
|
+
@t_cycle = cycle
|
26
|
+
@t_depends = depends
|
27
|
+
@dir = dir
|
28
|
+
@t_rules = rules
|
29
|
+
super()
|
30
|
+
end
|
31
|
+
|
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
|
+
def summarize(dir, schema)
|
38
|
+
table_io = {}
|
39
|
+
timeseries = {}
|
40
|
+
cardinalities.sort{|a, b| a[0] <=> b[0]}.each do |card|
|
41
|
+
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
|
+
end
|
47
|
+
full_info.each do |info|
|
48
|
+
write_table_content(table_io["#{info.table}_#{info.bud_time}"], info.row)
|
49
|
+
end
|
50
|
+
|
51
|
+
table_io.each_value do |tab|
|
52
|
+
end_table(tab)
|
53
|
+
end
|
54
|
+
|
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
|
+
# fix: nested loops
|
69
|
+
times.sort.each do |time|
|
70
|
+
card_info = {}
|
71
|
+
cardinalities.each do |card|
|
72
|
+
if card.bud_time == time.bud_time
|
73
|
+
card_info[card.table] = card.cnt
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
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
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
def start_table(dir, tab, time, schema)
|
87
|
+
str = "#{dir}/#{tab}_#{time}.html"
|
88
|
+
#fout = File.new("#{dir}/#{tab}_#{time}.html", "w")
|
89
|
+
fout = File.new(str, "w")
|
90
|
+
|
91
|
+
#fout.puts "<h1>#{tab} #{time_node_header()}</h1>"
|
92
|
+
fout.puts "<html><title>#{tab} @ #{time}</title>"
|
93
|
+
fout.puts "<table border=1>"
|
94
|
+
fout.puts "<tr>" + schema.map{|s| "<th> #{s} </th>"}.join(" ") + "<tr>"
|
95
|
+
fout.close
|
96
|
+
return str
|
97
|
+
end
|
98
|
+
|
99
|
+
def end_table(stream)
|
100
|
+
fp = File.open(stream, "a")
|
101
|
+
fp.puts "</table>"
|
102
|
+
fp.close
|
103
|
+
end
|
104
|
+
|
105
|
+
def write_table_content(fn, row)
|
106
|
+
stream = File.open(fn, "a")
|
107
|
+
stream.puts "<tr>"
|
108
|
+
stream.puts row.map{|c| "<td>#{c.to_s}</td>"}.join(" ")
|
109
|
+
stream.puts "</tr>"
|
110
|
+
stream.close
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
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
|
+
def usage
|
132
|
+
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"
|
136
|
+
puts "e.g."
|
137
|
+
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"
|
140
|
+
exit
|
141
|
+
end
|
142
|
+
|
143
|
+
# begin "main"
|
144
|
+
|
145
|
+
usage unless ARGV[0]
|
146
|
+
|
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
|
198
|
+
end
|
199
|
+
|
200
|
+
vh.tick
|
201
|
+
vh.summarize(ARGV[0], schminf)
|
data/bin/rebl
ADDED
data/docs/README.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#Bud: Bloom under development#
|
2
|
+
Welcome to the documentation for *Bud*, a prototype of Bloom under development.
|
3
|
+
|
4
|
+
The documents here are organized to be read in any order, but you might like to try the following:
|
5
|
+
|
6
|
+
* [intro.md](intro.md): A brief introduction to Bud and Bloom
|
7
|
+
* [getstarted.md](getstarted.md): A quickstart to teach you basic Bloom concepts, the use of `rebl` interactive terminal, and the embedding of Bloom code in Ruby via the `Bud` module.
|
8
|
+
* [operational.md](operational.md): an operational view of Bloom, to provide a more detailed model of how Bloom code is evaluated by Bud.
|
9
|
+
* [Bud RubyDoc](http://rubydoc.info/github/bloom-lang/bud/): RubyDoc on the language constructs and runtime hooks provided by the Bud module
|
10
|
+
* [cheat.md](cheat.md): A concise "cheat sheet" to remind you about Bloom syntax.
|
11
|
+
* [ruby_hooks.md](ruby_hooks.md): Bud module methods that allow you to interact with the Bud evaluator from other Ruby threads.
|
12
|
+
* [bud-sandbox](http://github.com/bloom-lang/bud-sandbox): a github repository including lots of useful libraries and examples.
|
13
|
+
* [bfs.md](bfs.md): A walkthrough of the Bloom distributed filesystem.
|