bud 0.9.2 → 0.9.3
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.
- 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
         |