bud 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +17 -4
- data/README.md +5 -0
- data/docs/cheat.md +1 -1
- data/docs/getstarted.md +1 -1
- data/lib/bud.rb +52 -34
- data/lib/bud/aggs.rb +8 -11
- data/lib/bud/bud_meta.rb +18 -18
- data/lib/bud/collections.rb +14 -21
- data/lib/bud/executor/README.rescan +80 -0
- data/lib/bud/executor/elements.rb +25 -44
- data/lib/bud/executor/group.rb +80 -29
- data/lib/bud/executor/join.rb +73 -90
- data/lib/bud/monkeypatch.rb +1 -1
- data/lib/bud/rebl.rb +5 -2
- data/lib/bud/rewrite.rb +18 -14
- data/lib/bud/server.rb +1 -1
- data/lib/bud/source.rb +0 -45
- data/lib/bud/storage/dbm.rb +13 -9
- data/lib/bud/viz.rb +6 -8
- data/lib/bud/viz_util.rb +1 -0
- metadata +3 -18
data/lib/bud/monkeypatch.rb
CHANGED
data/lib/bud/rebl.rb
CHANGED
@@ -197,7 +197,7 @@ class LibRebl
|
|
197
197
|
attr_reader :ip, :port, :rebl_class_inst
|
198
198
|
@@builtin_tables = [:stdio, :periodics_tbl, :halt, :localtick,
|
199
199
|
:t_depends, :t_cycle, :t_provides, :t_rules,
|
200
|
-
:
|
200
|
+
:t_stratum, :t_underspecified,
|
201
201
|
:t_table_info, :t_table_schema, :rebl_breakpoint]
|
202
202
|
@@classid = 0
|
203
203
|
|
@@ -326,6 +326,9 @@ class LibRebl
|
|
326
326
|
@rebl_class_inst.tables.merge!(@old_inst.tables.reject do |k,v|
|
327
327
|
@@builtin_tables.include? k
|
328
328
|
end)
|
329
|
+
@rebl_class_inst.tables.each do |k,v|
|
330
|
+
v.invalidate_cache
|
331
|
+
end
|
329
332
|
@rebl_class_inst.channels.merge!(@old_inst.channels.reject do |k,v|
|
330
333
|
@@builtin_tables.include? k
|
331
334
|
end)
|
@@ -333,7 +336,7 @@ class LibRebl
|
|
333
336
|
@rebl_class_inst.zk_tables.merge! @old_inst.zk_tables
|
334
337
|
|
335
338
|
# Fix the bud instance pointers from copied tables.
|
336
|
-
@rebl_class_inst.tables.
|
339
|
+
@rebl_class_inst.tables.each_value do |v|
|
337
340
|
v.bud_instance = @rebl_class_inst
|
338
341
|
end
|
339
342
|
end
|
data/lib/bud/rewrite.rb
CHANGED
@@ -72,24 +72,27 @@ class RuleRewriter < Ruby2Ruby # :nodoc: all
|
|
72
72
|
# :defn block -- this is where we expect Bloom statements to appear
|
73
73
|
do_rule(exp)
|
74
74
|
elsif op == :notin
|
75
|
-
#
|
76
|
-
# See further explanation in the "else" section for
|
75
|
+
# Special case. In the rule "z <= x.notin(y)", z depends positively on x,
|
76
|
+
# but negatively on y. See further explanation in the "else" section for
|
77
|
+
# why this is a special case.
|
77
78
|
notintab = call_to_id(args[1]) # args expected to be of the form (:arglist (:call nil :y ...))
|
78
|
-
@tables[notintab.to_s] = true
|
79
|
+
@tables[notintab.to_s] = true # "true" denotes non-monotonic dependency
|
79
80
|
super
|
80
81
|
else
|
81
|
-
# Parse a call of the form
|
82
|
-
#
|
83
|
-
# a.b
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
82
|
+
# Parse a call of the form a.b.c.foo
|
83
|
+
#
|
84
|
+
# In the most general case, a.b is a nested module, a.b.c is a collection
|
85
|
+
# in that module, and a.b.c.foo is either a method or a field. If it is a
|
86
|
+
# method, and non-monotonic at that, we register a dependency between lhs
|
87
|
+
# and the table a.b.c. Note that notin is treated differently because in
|
88
|
+
# a.b.c.notin(d.e.f), we register a non-monotonic dependency of lhs on
|
89
|
+
# "d.e.f", not with "a.b.c"
|
87
90
|
ty, qn, _ = exp_id_type(recv, op, args) # qn = qualified name
|
88
91
|
if ty == :collection
|
89
92
|
(@tables[qn] = @nm if @collect) unless @tables[qn]
|
90
93
|
#elsif ty == :import .. do nothing
|
91
94
|
elsif ty == :not_coll_id
|
92
|
-
#
|
95
|
+
# Check if receiver is a collection, and further if the current exp
|
93
96
|
# represents a field lookup
|
94
97
|
op_is_field_name = false
|
95
98
|
if recv and recv.first == :call
|
@@ -99,17 +102,17 @@ class RuleRewriter < Ruby2Ruby # :nodoc: all
|
|
99
102
|
op_is_field_name = true if cols and cols.include?(op)
|
100
103
|
end
|
101
104
|
end
|
102
|
-
#
|
105
|
+
# For CALM analysis, mark deletion rules as non-monotonic
|
103
106
|
@nm = true if op == :-@
|
104
107
|
if recv
|
105
|
-
#
|
108
|
+
# Don't worry about monotone ops, table names, table.attr calls, or
|
106
109
|
# accessors of iterator variables
|
107
110
|
unless RuleRewriter.is_monotone(op) or op_is_field_name or
|
108
111
|
recv.first == :lvar or op.to_s.start_with?("__")
|
109
112
|
@nm = true
|
110
113
|
end
|
111
114
|
else
|
112
|
-
#
|
115
|
+
# Function called (implicit receiver = Bud instance) in a user-defined
|
113
116
|
# code block. Check if it is non-monotonic (like budtime, that
|
114
117
|
# produces a new value every time it is called)
|
115
118
|
@nm_funcs_called = true unless RuleRewriter.is_monotone(op)
|
@@ -126,7 +129,8 @@ class RuleRewriter < Ruby2Ruby # :nodoc: all
|
|
126
129
|
MONOTONE_WHITELIST.include?(op)
|
127
130
|
end
|
128
131
|
|
129
|
-
#
|
132
|
+
# Rewrite top-level rhs array literals to lambdas. During wiring, these are
|
133
|
+
# turned into coll_expr collections.
|
130
134
|
def lambda_rewrite(rhs)
|
131
135
|
# the <= case
|
132
136
|
if rhs[0] == :array
|
data/lib/bud/server.rb
CHANGED
@@ -30,7 +30,7 @@ class Bud::BudServer < EM::Connection #:nodoc: all
|
|
30
30
|
|
31
31
|
unless accepted.empty?
|
32
32
|
@bud.inbound[tbl_name] ||= []
|
33
|
-
@bud.inbound[tbl_name]
|
33
|
+
@bud.inbound[tbl_name].concat(accepted)
|
34
34
|
end
|
35
35
|
buf_leftover[tbl_name] = saved unless saved.empty?
|
36
36
|
end
|
data/lib/bud/source.rb
CHANGED
@@ -61,49 +61,4 @@ module Source
|
|
61
61
|
end
|
62
62
|
retval # array of lines
|
63
63
|
end
|
64
|
-
|
65
|
-
# Tok is string tokenizer that extracts a substring matching the
|
66
|
-
# supplied regex, and internally advances past the matched substring.
|
67
|
-
# Leading white space is ignored.
|
68
|
-
# tok = Tok.new("foo 123")
|
69
|
-
# x = tok =~ /\w+/ # => x == 'foo'
|
70
|
-
# y = tok =~ /\d+/ # => y = '123'
|
71
|
-
class Tok
|
72
|
-
attr_accessor :str, :group
|
73
|
-
def initialize(str)
|
74
|
-
@str = str
|
75
|
-
@group = nil
|
76
|
-
end
|
77
|
-
|
78
|
-
# match regex at beginning of string, and advance. Return matched token
|
79
|
-
def =~(regex)
|
80
|
-
s = @str
|
81
|
-
skiplen = 0
|
82
|
-
if s =~ /^\s*/
|
83
|
-
skiplen = $&.length
|
84
|
-
s = s[skiplen .. -1]
|
85
|
-
end
|
86
|
-
if (s =~ regex) == 0
|
87
|
-
# Regexp.last_match is local to this thread and method; squirrel
|
88
|
-
# it away for use in tok.[]
|
89
|
-
@group = Regexp.last_match
|
90
|
-
skiplen += $&.length
|
91
|
-
@str = @str[skiplen .. -1]
|
92
|
-
return $&
|
93
|
-
else
|
94
|
-
nil
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
# get the nth subgroup match
|
99
|
-
# t = Tok.new("a1122b"); t =~ /a(1+)(2+)b/ ; #=> t[0] = a1122b; t[1] = 11; t[2] = 22
|
100
|
-
def [](n)
|
101
|
-
@group ? @group[n] : nil
|
102
|
-
end
|
103
|
-
def pushBack(str)
|
104
|
-
@str = str + @str
|
105
|
-
end
|
106
|
-
|
107
|
-
def to_s; @str; end
|
108
|
-
end
|
109
64
|
end
|
data/lib/bud/storage/dbm.rb
CHANGED
@@ -126,14 +126,13 @@ module Bud
|
|
126
126
|
end
|
127
127
|
|
128
128
|
def merge_tuple_to_db(key, tuple)
|
129
|
-
val = val_cols.map{|c| tuple[cols.index(c)]}
|
130
129
|
key_s = MessagePack.pack(key)
|
131
|
-
val_s = MessagePack.pack(val)
|
132
130
|
if @dbm.has_key?(key_s)
|
133
131
|
old_tuple = self[key]
|
134
132
|
raise_pk_error(tuple, old_tuple) if tuple != old_tuple
|
135
133
|
else
|
136
|
-
|
134
|
+
val = val_cols.map{|c| tuple[cols.index(c)]}
|
135
|
+
@dbm[key_s] = MessagePack.pack(val)
|
137
136
|
end
|
138
137
|
end
|
139
138
|
|
@@ -141,10 +140,15 @@ module Bud
|
|
141
140
|
def tick_deltas
|
142
141
|
unless @delta.empty?
|
143
142
|
merge_to_db(@delta)
|
144
|
-
@tick_delta
|
143
|
+
@tick_delta.concat(@delta.values) if accumulate_tick_deltas
|
145
144
|
@delta.clear
|
146
145
|
end
|
147
146
|
unless @new_delta.empty?
|
147
|
+
# We allow @new_delta to contain duplicates but eliminate them here. We
|
148
|
+
# can't just allow duplicate delta tuples because that might cause
|
149
|
+
# spurious infinite delta processing loops.
|
150
|
+
@new_delta.reject! {|key| self[key] == @new_delta[key]}
|
151
|
+
|
148
152
|
@delta = @new_delta
|
149
153
|
@new_delta = {}
|
150
154
|
end
|
@@ -155,14 +159,15 @@ module Bud
|
|
155
159
|
def flush_deltas
|
156
160
|
unless @delta.empty?
|
157
161
|
merge_to_db(@delta)
|
158
|
-
@tick_delta
|
162
|
+
@tick_delta.concat(@delta.values) if accumulate_tick_deltas
|
159
163
|
@delta.clear
|
160
164
|
end
|
161
165
|
merge_to_db(@new_delta)
|
162
166
|
@new_delta = {}
|
163
167
|
end
|
164
168
|
|
165
|
-
# This is verbatim from BudTable. Need to DRY up. Should we be a subclass
|
169
|
+
# This is verbatim from BudTable. Need to DRY up. Should we be a subclass
|
170
|
+
# of BudTable?
|
166
171
|
public
|
167
172
|
def pending_delete(o)
|
168
173
|
if o.class <= Bud::PushElement
|
@@ -170,7 +175,7 @@ module Bud
|
|
170
175
|
elsif o.class <= Bud::BudCollection
|
171
176
|
o.pro.wire_to(self, :delete)
|
172
177
|
else
|
173
|
-
@to_delete
|
178
|
+
@to_delete.concat(o.map{|t| prep_tuple(t) unless t.nil?})
|
174
179
|
end
|
175
180
|
end
|
176
181
|
superator "<-" do |o|
|
@@ -184,7 +189,7 @@ module Bud
|
|
184
189
|
|
185
190
|
alias << insert
|
186
191
|
|
187
|
-
# Remove to_delete and then
|
192
|
+
# Remove to_delete and then move pending => delta.
|
188
193
|
def tick
|
189
194
|
deleted = nil
|
190
195
|
@to_delete.each do |tuple|
|
@@ -204,7 +209,6 @@ module Bud
|
|
204
209
|
@invalidated = !deleted.nil?
|
205
210
|
unless @pending.empty?
|
206
211
|
@delta = @pending
|
207
|
-
# merge_to_db(@pending)
|
208
212
|
@pending = {}
|
209
213
|
end
|
210
214
|
flush
|
data/lib/bud/viz.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'syntax/convertors/html'
|
3
|
-
require 'gchart'
|
4
1
|
require 'bud/state'
|
2
|
+
require 'set'
|
5
3
|
|
6
4
|
class VizOnline #:nodoc: all
|
7
5
|
attr_reader :logtab
|
6
|
+
|
7
|
+
META_TABLES = %w[t_cycle t_depends t_depends_tc t_provides t_rules
|
8
|
+
t_stratum t_table_info t_table_schema].to_set
|
9
|
+
|
8
10
|
def initialize(bud_instance)
|
9
11
|
@bud_instance = bud_instance
|
10
|
-
@meta_tables = {'t_rules' => 1, 't_depends' => 1, 't_table_info' => 1, 't_cycle' => 1, 't_stratum' => 1, 't_depends_tc' => 1, 't_table_schema' => 1, 't_provides' => 1}
|
11
12
|
@bud_instance.options[:dbm_dir] = "DBM_#{@bud_instance.class}_#{bud_instance.options[:tag]}_#{bud_instance.object_id}_#{bud_instance.port}"
|
12
13
|
@table_info = bud_instance.tables[:t_table_info]
|
13
14
|
@table_schema = bud_instance.tables[:t_table_schema]
|
@@ -26,17 +27,14 @@ class VizOnline #:nodoc: all
|
|
26
27
|
end
|
27
28
|
|
28
29
|
tmp_set.each do |t|
|
29
|
-
news = [:c_bud_time]
|
30
30
|
snd_alias = t[0].to_s + "_snd"
|
31
31
|
@table_schema << [t[0], :c_bud_time, 0]
|
32
32
|
t[1].each_with_index do |s, i|
|
33
|
-
news << s
|
34
33
|
@table_schema << [t[0], s, i+1]
|
35
34
|
if t[2] == "Bud::BudChannel"
|
36
35
|
@table_schema << [snd_alias, s, i+1]
|
37
36
|
end
|
38
37
|
end
|
39
|
-
lt = "#{t[0]}_vizlog".to_sym
|
40
38
|
if t[2] == "Bud::BudChannel"
|
41
39
|
lts = "#{snd_alias}_vizlog".to_sym
|
42
40
|
@table_info << [snd_alias, t[2]]
|
@@ -78,7 +76,7 @@ class VizOnline #:nodoc: all
|
|
78
76
|
@bud_instance.tables.each do |t|
|
79
77
|
tab = t[0]
|
80
78
|
next if tab == "the_big_log"
|
81
|
-
next if @
|
79
|
+
next if @bud_instance.budtime > 0 and META_TABLES.include? tab.to_s
|
82
80
|
# PAA: why did we previously exclude periodics?
|
83
81
|
add_rows(t[1], tab) #####unless t[1].class == Bud::BudPeriodic
|
84
82
|
if t[1].class == Bud::BudChannel
|
data/lib/bud/viz_util.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2012-
|
16
|
+
date: 2012-08-20 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: eventmachine
|
@@ -47,22 +47,6 @@ dependencies:
|
|
47
47
|
- - ! '>='
|
48
48
|
- !ruby/object:Gem::Version
|
49
49
|
version: '0'
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
|
-
name: gchart
|
52
|
-
requirement: !ruby/object:Gem::Requirement
|
53
|
-
none: false
|
54
|
-
requirements:
|
55
|
-
- - ! '>='
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version: '0'
|
58
|
-
type: :runtime
|
59
|
-
prerelease: false
|
60
|
-
version_requirements: !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
|
-
requirements:
|
63
|
-
- - ! '>='
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
version: '0'
|
66
50
|
- !ruby/object:Gem::Dependency
|
67
51
|
name: getopt
|
68
52
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,6 +210,7 @@ files:
|
|
226
210
|
- lib/bud/executor/elements.rb
|
227
211
|
- lib/bud/executor/group.rb
|
228
212
|
- lib/bud/executor/join.rb
|
213
|
+
- lib/bud/executor/README.rescan
|
229
214
|
- lib/bud/graphs.rb
|
230
215
|
- lib/bud/meta_algebra.rb
|
231
216
|
- lib/bud/metrics.rb
|