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/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(mapping, tableinfo, cycle, name, budtime, vizlevel, pics_dir, collapse=false, depanalysis=nil, cardinalities={})
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
- @vizlevel = vizlevel
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
- puts "CYCLE: #{c.inspect}"
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)}_expanded.svg"
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 @depanalysis.nil?
235
- @depanalysis.source.each {|s| addedge("S", s.pred, false, false, false) }
236
- @depanalysis.sink.each {|s| addedge(s.pred, "T", false, false, false) }
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 @depanalysis.underspecified.empty?
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
- @depanalysis.underspecified.each do |u|
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
- suffix = @collapse ? "collapsed" : "expanded"
255
- fn = "#{@name}_#{suffix}.svg"
256
- puts "fn is #{fn}"
257
- staging = "#{fn}_staging"
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
- def output_base
272
- if @vizlevel >= 3
273
- @pics_dir
274
- else
275
- "bud_doc"
276
- end
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 dump(shredded_rules)
280
- return if shredded_rules.nil?
281
-
282
- fout = File.new("#{output_base}/style.css", "w")
283
- fout.puts css
284
- fout.close
285
-
286
- code = {}
287
- rules = {}
288
- convertor = Syntax::Convertors::HTML.for_syntax "ruby"
289
- shredded_rules.each do |s|
290
- #fout = File.new("#{output_base}/#{s[0]}.html", "w+")
291
- fout = File.new("#{output_base}/#{s[0]}.html", "w+")
292
- fout.puts header
293
- fout.puts "<h1>Rule #{s[0]}</h1><br>"
294
-
295
- c = convertor.convert(s[3])
296
- c.sub!(/^<pre>/, "<pre class=\"code\" style='font-size:20px'>\n")
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
- rules.each_pair do |k, v|
303
- if !code[v[0]]
304
- code[v[0]] = ""
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
- @nodes.each_pair do |k, v|
310
- fout = File.new("#{output_base}/#{k}.html", "w+")
311
- fout.puts header
312
- k.split(", ").each do |i|
313
- unless code[i].nil?
314
- c = convertor.convert(code[i])
315
- c.sub!(/^<pre>/, "<pre class=\"code\">\n")
316
- fout.puts c
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
- def header
326
- return "<html><meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/>\n<head><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" /></head><body>"
327
- end
328
-
329
- def css
330
- return "pre.code {
331
- padding: 1ex 1ex 1ex 1ex;
332
- border: 4px groove #CC0000;
333
- overflow-x: auto;
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
- end
358
-
359
- def svg_javascript
360
- return "
361
- <script type='text/javascript'>
362
- <![CDATA[
363
-
364
- var windows = new Array()
365
- var info = new Array()
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