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/lib/bud/graphs.rb
CHANGED
@@ -1,32 +1,21 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
1
|
require 'rubygems'
|
2
|
+
require 'digest/md5'
|
3
3
|
require 'graphviz'
|
4
4
|
|
5
5
|
class GraphGen #:nodoc: all
|
6
|
+
attr_reader :nodes
|
6
7
|
|
7
|
-
def initialize(
|
8
|
-
#@graph = GraphViz.new(:G, :type => :digraph, :label => "", :ratio => 0.85 )
|
8
|
+
def initialize(tableinfo, cycle, name, budtime, collapse=false, cardinalities={})
|
9
9
|
@graph = GraphViz.new(:G, :type => :digraph, :label => "")
|
10
10
|
@graph.node[:fontname] = "Times-Roman"
|
11
11
|
@graph.node[:fontsize] = 18
|
12
12
|
@graph.edge[:fontname] = "Times-Roman"
|
13
13
|
@graph.edge[:fontsize] = 18
|
14
|
-
@tiers = []
|
15
14
|
@cards = cardinalities
|
16
15
|
@name = name
|
17
16
|
@collapse = collapse
|
18
|
-
@depanalysis = depanalysis
|
19
17
|
@budtime = budtime
|
20
|
-
@
|
21
|
-
@pics_dir = pics_dir
|
22
|
-
#@internals = {'count' => 1, 'localtick' => 1, 'stdio' => 1, 't_rules' => 1, 't_depends' => 1, 't_depends_tc' => 1, 't_provides' => 1, 't_cycle' => 1}
|
23
|
-
@internals = {'count' => 1, 'localtick' => 1, 'stdio' => 1} #, 't_rules' => 1, 't_depends' => 1, 't_depends_tc' => 1, 't_provides' => 1, 't_cycle' => 1}
|
24
|
-
|
25
|
-
# map: table -> stratum
|
26
|
-
@t2s = {}
|
27
|
-
mapping.each do |m|
|
28
|
-
@t2s[m[0]] = m[1].to_i
|
29
|
-
end
|
18
|
+
@internals = {'localtick' => 1, 'stdio' => 1}
|
30
19
|
|
31
20
|
# map: table -> type
|
32
21
|
@tabinf = {}
|
@@ -36,7 +25,7 @@ class GraphGen #:nodoc: all
|
|
36
25
|
|
37
26
|
@redcycle = {}
|
38
27
|
cycle.each do |c|
|
39
|
-
|
28
|
+
# assumption: !(c[2] and !c[3]), or stratification would have bombed out
|
40
29
|
if c[2] and c[3]
|
41
30
|
if !@redcycle[c[0]]
|
42
31
|
@redcycle[c[0]] = []
|
@@ -50,21 +39,6 @@ class GraphGen #:nodoc: all
|
|
50
39
|
@labels = {}
|
51
40
|
end
|
52
41
|
|
53
|
-
def safe_t2s(tab)
|
54
|
-
if @t2s[tab]
|
55
|
-
@t2s[tab]
|
56
|
-
else
|
57
|
-
words = tab.split(",")
|
58
|
-
maxs = 0
|
59
|
-
words.each do |w|
|
60
|
-
if @t2s[w] and @t2s[w] > maxs
|
61
|
-
maxs = @t2s[w]
|
62
|
-
end
|
63
|
-
end
|
64
|
-
return maxs
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
42
|
def name_bag(predicate, bag)
|
69
43
|
if bag[predicate]
|
70
44
|
return bag
|
@@ -84,12 +58,9 @@ class GraphGen #:nodoc: all
|
|
84
58
|
|
85
59
|
def name_of(predicate)
|
86
60
|
# consider doing this in bud
|
87
|
-
# PAA
|
88
61
|
if @redcycle[predicate] and @collapse
|
89
|
-
puts "collapse #{predicate}, redcycle #{@redcycle[predicate].inspect}"
|
90
62
|
via = @redcycle[predicate]
|
91
63
|
bag = name_bag(predicate, {})
|
92
|
-
#str = bag.key_cols.sort.join(", ")
|
93
64
|
str = bag.keys.sort.join(", ")
|
94
65
|
return str
|
95
66
|
else
|
@@ -98,14 +69,11 @@ class GraphGen #:nodoc: all
|
|
98
69
|
end
|
99
70
|
|
100
71
|
def process(depends)
|
101
|
-
|
102
72
|
# collapsing NEG/+ cycles.
|
103
73
|
# we want to create a function from any predicate to (cycle_name or bottom)
|
104
74
|
# bottom if the predicate is not in a NEG/+ cycle. otherwise,
|
105
75
|
# its name is "CYC" + concat(sort(predicate names))
|
106
|
-
|
107
76
|
depends.each do |d|
|
108
|
-
#puts "DEP: #{d.inspect}"
|
109
77
|
head = d[1]
|
110
78
|
body = d[3]
|
111
79
|
|
@@ -116,32 +84,30 @@ class GraphGen #:nodoc: all
|
|
116
84
|
|
117
85
|
head = name_of(head)
|
118
86
|
body = name_of(body)
|
119
|
-
addonce(head, (head != d[1]))
|
87
|
+
addonce(head, (head != d[1]), true)
|
120
88
|
addonce(body, (body != d[3]))
|
121
89
|
addedge(body, head, d[2], d[4], (head != d[1]), d[0])
|
122
90
|
end
|
123
91
|
end
|
124
92
|
|
125
|
-
def addonce(node, negcluster)
|
126
|
-
#puts "ADD NODE #{node}"
|
93
|
+
def addonce(node, negcluster, inhead=false)
|
127
94
|
if !@nodes[node]
|
128
95
|
@nodes[node] = @graph.add_node(node)
|
129
96
|
if @cards and @cards[node]
|
130
97
|
@nodes[node].label = node +"\n (#{@cards[node].to_s})"
|
131
|
-
puts "IMAGE IS #{@cards[node]}"
|
132
|
-
#@nodes[node].image = @cards[node]
|
133
|
-
end
|
134
|
-
|
135
|
-
if @vizlevel >= 3
|
136
|
-
@nodes[node].URL = "javascript:openWin(\"#{node}\", #{@budtime})"
|
137
|
-
else
|
138
|
-
@nodes[node].URL = "#{node}.html"
|
139
98
|
end
|
99
|
+
end
|
100
|
+
|
101
|
+
if @budtime == -1
|
102
|
+
@nodes[node].URL = "#{node}.html" if inhead
|
103
|
+
else
|
104
|
+
@nodes[node].URL = "javascript:openWin(\"#{node}\", #{@budtime})"
|
140
105
|
end
|
141
106
|
|
142
107
|
if negcluster
|
143
108
|
# cleaning
|
144
109
|
res = node
|
110
|
+
# pretty-printing issues
|
145
111
|
node.split(", ").each_with_index do |p, i|
|
146
112
|
if i == 0
|
147
113
|
res = p
|
@@ -151,12 +117,11 @@ class GraphGen #:nodoc: all
|
|
151
117
|
res = res + ", " + p
|
152
118
|
end
|
153
119
|
end
|
154
|
-
#@nodes[node].label = "<b>" + res + "</b>"
|
155
120
|
@nodes[node].label = res
|
156
121
|
@nodes[node].color = "red"
|
157
122
|
@nodes[node].shape = "octagon"
|
158
123
|
@nodes[node].penwidth = 3
|
159
|
-
@nodes[node].URL = "#{File.basename(@name)}
|
124
|
+
@nodes[node].URL = "#{File.basename(@name).gsub(".staging", "").gsub("collapsed", "expanded")}.svg"
|
160
125
|
elsif @tabinf[node] and (@tabinf[node] == "Bud::BudTable")
|
161
126
|
@nodes[node].shape = "rect"
|
162
127
|
end
|
@@ -180,11 +145,8 @@ class GraphGen #:nodoc: all
|
|
180
145
|
@edges[ekey].minlen = 1.5
|
181
146
|
end
|
182
147
|
@labels[ekey] = {}
|
183
|
-
|
184
148
|
end
|
185
149
|
|
186
|
-
#@edges[ekey].minlen = 5 if negcluster and body == head
|
187
|
-
|
188
150
|
if op == '<+'
|
189
151
|
@labels[ekey][' +/-'] = true
|
190
152
|
elsif op == "<~"
|
@@ -200,9 +162,8 @@ class GraphGen #:nodoc: all
|
|
200
162
|
end
|
201
163
|
end
|
202
164
|
|
203
|
-
def finish
|
165
|
+
def finish(depanalysis=nil, output=nil)
|
204
166
|
@labels.each_key do |k|
|
205
|
-
#@edges[k].label = @labels[k].key_cols.join(" ")
|
206
167
|
@edges[k].label = @labels[k].keys.join(" ")
|
207
168
|
end
|
208
169
|
|
@@ -221,28 +182,26 @@ class GraphGen #:nodoc: all
|
|
221
182
|
@nodes["T"].penwidth = 3
|
222
183
|
|
223
184
|
@tabinf.each_pair do |k, v|
|
224
|
-
|
225
185
|
unless @nodes[name_of(k.to_s)] or k.to_s =~ /_tbl/ or @internals[k.to_s] or (k.to_s =~ /^t_/ and @budtime != 0)
|
226
186
|
addonce(k.to_s, false)
|
227
187
|
end
|
228
188
|
if v == "Bud::BudPeriodic"
|
229
|
-
puts "adding edge S -> #{@nodes[k.to_s]}"
|
230
189
|
addedge("S", k.to_s, false, false, false)
|
231
190
|
end
|
232
191
|
end
|
233
192
|
|
234
|
-
unless
|
235
|
-
|
236
|
-
|
193
|
+
unless depanalysis.nil?
|
194
|
+
depanalysis.source.each {|s| addedge("S", s.pred, false, false, false)}
|
195
|
+
depanalysis.sink.each {|s| addedge(s.pred, "T", false, false, false)}
|
237
196
|
|
238
|
-
unless
|
197
|
+
unless depanalysis.underspecified.empty?
|
239
198
|
addonce("??", false)
|
240
199
|
@nodes["??"].color = "red"
|
241
200
|
@nodes["??"].shape = "diamond"
|
242
201
|
@nodes["??"].penwidth = 2
|
243
202
|
end
|
244
203
|
|
245
|
-
|
204
|
+
depanalysis.underspecified.each do |u|
|
246
205
|
if u.input
|
247
206
|
addedge(u.pred, "??", false, false, false)
|
248
207
|
else
|
@@ -251,155 +210,100 @@ class GraphGen #:nodoc: all
|
|
251
210
|
end
|
252
211
|
end
|
253
212
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
@graph.output(:svg => staging)
|
259
|
-
@graph.output(:dot => "#{fn}.dot")
|
260
|
-
@graph.output(:png => "#{fn}.png")
|
261
|
-
fin = File.open(staging, "r")
|
262
|
-
fout = File.open(fn, "w")
|
263
|
-
while line = fin.gets
|
264
|
-
fout.puts line.gsub("<title>G</title>", svg_javascript())
|
213
|
+
if output.nil?
|
214
|
+
@graph.output(:svg => @name)
|
215
|
+
else
|
216
|
+
@graph.output(output => @name)
|
265
217
|
end
|
266
|
-
fin.close
|
267
|
-
fout.close
|
268
|
-
File.delete(staging)
|
269
218
|
end
|
219
|
+
end
|
270
220
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
221
|
+
class SpaceTime
|
222
|
+
def initialize(input, links = false)
|
223
|
+
@input = input
|
224
|
+
@links = links
|
225
|
+
processes = input.map {|i| i[1]}
|
226
|
+
input.map{|i| processes << i[2]}
|
227
|
+
processes.uniq!
|
228
|
+
|
229
|
+
@queues = {}
|
230
|
+
|
231
|
+
@g = GraphViz.new(:G, :type => :digraph, :rankdir => "LR", :outputorder => "nodesfirst", :splines => "line")#, :clusterrank => "none")
|
232
|
+
@hdr = @g.subgraph("cluster_0")
|
233
|
+
|
234
|
+
@subs = {}
|
235
|
+
@head = {}
|
236
|
+
last = nil
|
237
|
+
processes.each_with_index do |p, i|
|
238
|
+
#@head[p] = @hdr.add_node("process #{p}(#{i})")#, :color => "white", :label => "")
|
239
|
+
@subs[p] = @g.subgraph("buster_#{i+1}")
|
240
|
+
@head[p] = @hdr.add_node("process #{p}(#{i})", :group => p)#, :color => "white", :label => "")
|
241
|
+
|
242
|
+
end
|
277
243
|
end
|
278
244
|
|
279
|
-
def
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
fout.puts c
|
298
|
-
rules[s[0]] = [s[1], s[3]]
|
299
|
-
fout.close
|
245
|
+
def msg_edge(f, t, l)
|
246
|
+
lbl = "#{f}#{t}#{l}"
|
247
|
+
if @edges[lbl]
|
248
|
+
prev = @edges[lbl]
|
249
|
+
@edges[lbl] = [prev[0], prev[1], prev[2], prev[3] + 1]
|
250
|
+
else
|
251
|
+
@edges[lbl] = [f, t, l, 1]
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def process
|
256
|
+
@edges = {}
|
257
|
+
queues = {}
|
258
|
+
@input.each do |i|
|
259
|
+
queues[i[1]] = [] unless queues[i[1]]
|
260
|
+
queues[i[2]] = [] unless queues[i[2]]
|
261
|
+
queues[i[1]] << i[3]
|
262
|
+
queues[i[2]] << i[4]
|
300
263
|
end
|
301
264
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
end
|
306
|
-
#code[v[0]] = "<br># RULE #{k}<br> " + code[v[0]] + "<br>" + v[1]
|
307
|
-
code[v[0]] = "\n# RULE #{k}\n " + code[v[0]] + "\n" + v[1]
|
265
|
+
squeues = {}
|
266
|
+
queues.each_pair do |k, v|
|
267
|
+
squeues[k] = v.sort{|a, b| a <=> b}
|
308
268
|
end
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
269
|
+
|
270
|
+
# create the nodes and the timeline edges first.
|
271
|
+
squeues.each do |k, v|
|
272
|
+
v.each_with_index do |item, i|
|
273
|
+
label = "#{k}-#{item}"
|
274
|
+
if @links
|
275
|
+
url = "DBM_#{k}_/tm_#{item}.svg"
|
276
|
+
#puts "URL is #{url}"
|
277
|
+
end
|
278
|
+
snd = @subs[k].add_node(label, {:label => item.to_s, :width => 0.1, :height => 0.1, :fontsize => 6, :pos => [1, i], :group => k, :URL => url})
|
279
|
+
|
280
|
+
unless @head[k].id == snd.id
|
281
|
+
@subs[k].add_edge(@head[k], snd, :weight => 2)
|
282
|
+
@head[k] = snd
|
317
283
|
end
|
318
284
|
end
|
319
|
-
fout.puts("</body></html>")
|
320
|
-
fout.close
|
321
285
|
end
|
322
|
-
end
|
323
|
-
|
324
286
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
}
|
335
|
-
|
336
|
-
pre.code span.attribute { color: #009900; }
|
337
|
-
pre.code span.char { color: #F00; }
|
338
|
-
pre.code span.class { color: #A020F0; font-weight: bold; }
|
339
|
-
pre.code span.comment { color: #0000FF; }
|
340
|
-
pre.code span.constant { color: #008B8B; }
|
341
|
-
pre.code span.escape { color: #6A5ACD; }
|
342
|
-
pre.code span.expr { color: #2222CC; }
|
343
|
-
pre.code span.global { color: #11AA44; }
|
344
|
-
pre.code span.ident { color: #000000; }
|
345
|
-
pre.code span.keyword { color: #A52A2A; font-weight: bold; }
|
346
|
-
pre.code span.method { color: #008B8B; }
|
347
|
-
pre.code span.module { color: #A020F0; font-weight: bold; }
|
348
|
-
pre.code span.number { color: #DD00DD; }
|
349
|
-
pre.code span.punct { color: #6A5ACD; }
|
350
|
-
pre.code span.regex { color: #DD00DD; }
|
351
|
-
pre.code span.string { color: #DD00DD; }
|
352
|
-
pre.code span.symbol { color: #008B8B; }
|
353
|
-
"
|
287
|
+
#@input.sort{|a, b| a[3] <=> b[3]}.each do |i|
|
288
|
+
@input.each do |i|
|
289
|
+
snd_loc = i[1]
|
290
|
+
rcv_loc = i[2]
|
291
|
+
snd_label = "#{snd_loc}-#{i[3]}"
|
292
|
+
rcv_label = "#{rcv_loc}-#{i[4]}"
|
293
|
+
#@g.add_edge(snd_label, rcv_label, :color => "red", :weight => 1, :label => i[5])
|
294
|
+
msg_edge(snd_label, rcv_label, i[5])
|
295
|
+
end
|
354
296
|
end
|
355
|
-
|
356
297
|
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
function openWin(target, time) {
|
368
|
-
win = window.open(target + \"_\" + time + \".html\", target, \"location=no,width=400,height=180,left=0,status=no\");
|
369
|
-
// hm, an associative array, how strange.
|
370
|
-
info[target] = 1
|
371
|
-
}
|
372
|
-
|
373
|
-
function advanceTo(time) {
|
374
|
-
arr = gup(\"wins\").split(\",\");
|
375
|
-
for (i=0; i < arr.length; i++) {
|
376
|
-
if (arr[i] != \"\") {
|
377
|
-
openWin(arr[i], time);
|
378
|
-
}
|
379
|
-
}
|
380
|
-
str = '';
|
381
|
-
// getting 'key_cols'
|
382
|
-
for (var i in info) {
|
383
|
-
str = str + ',' + i;
|
384
|
-
}
|
385
|
-
self.window.location.href = 'tm_' + time + '_expanded.svg?wins=' + str;
|
386
|
-
}
|
387
|
-
|
388
|
-
// off the netz
|
389
|
-
function gup( name )
|
390
|
-
{
|
391
|
-
name = name.replace(/[\[]/,\"\\\[\").replace(/[\]]/,\"\\\]\");
|
392
|
-
var regexS = \"[\\?&]\"+name+\"=([^&#]*)\";
|
393
|
-
var regex = new RegExp( regexS );
|
394
|
-
var results = regex.exec( window.location.href );
|
395
|
-
if( results == null )
|
396
|
-
return \"\";
|
397
|
-
else
|
398
|
-
return results[1];
|
399
|
-
}
|
400
|
-
|
401
|
-
]]>
|
402
|
-
</script>
|
403
|
-
"
|
298
|
+
def finish(file, fmt=nil)
|
299
|
+
@edges.each_pair do |k, v|
|
300
|
+
lbl = v[3] > 1 ? "#{v[2]}(#{v[3]})" : v[2]
|
301
|
+
@g.add_edge(v[0], v[1], :label => lbl, :color => "red", :weight => 1)
|
302
|
+
end
|
303
|
+
if fmt.nil?
|
304
|
+
@g.output(:svg => "#{file}.svg")
|
305
|
+
else
|
306
|
+
eval("@g.output(:#{fmt} => \"\#{file}.#{fmt}\")")
|
307
|
+
end
|
404
308
|
end
|
405
|
-
|
309
|
+
end
|