bud 0.9.5 → 0.9.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/History.txt +25 -1
- data/bin/budlabel +0 -0
- data/bin/budplot +11 -6
- data/bin/budtimelines +2 -2
- data/bin/budvis +7 -1
- data/docs/README.md +8 -8
- data/docs/cheat.md +2 -2
- data/lib/bud.rb +46 -26
- data/lib/bud/collections.rb +82 -45
- data/lib/bud/executor/elements.rb +2 -2
- data/lib/bud/executor/join.rb +31 -28
- data/lib/bud/graphs.rb +2 -2
- data/lib/bud/lattice-core.rb +52 -33
- data/lib/bud/lattice-lib.rb +28 -25
- data/lib/bud/monkeypatch.rb +1 -1
- data/lib/bud/rebl.rb +26 -8
- data/lib/bud/rewrite.rb +40 -20
- data/lib/bud/server.rb +3 -6
- data/lib/bud/source.rb +1 -16
- data/lib/bud/state.rb +1 -1
- data/lib/bud/viz.rb +10 -11
- data/lib/bud/viz_util.rb +8 -3
- metadata +7 -31
@@ -12,7 +12,7 @@ module Bud
|
|
12
12
|
class PushElement < BudCollection
|
13
13
|
attr_accessor :rescan, :invalidated
|
14
14
|
attr_accessor :elem_name
|
15
|
-
attr_reader :found_delta, :wired_by, :outputs
|
15
|
+
attr_reader :found_delta, :wired_by, :outputs, :pendings
|
16
16
|
|
17
17
|
def initialize(name_in, bud_instance, collection_name=nil, given_schema=nil, defer_schema=false, &blk)
|
18
18
|
super(name_in, bud_instance, given_schema, defer_schema)
|
@@ -130,7 +130,7 @@ module Bud
|
|
130
130
|
elsif ou.class <= Bud::LatticeWrapper
|
131
131
|
ou.insert(item, self)
|
132
132
|
else
|
133
|
-
raise Bud::Error, "
|
133
|
+
raise Bud::Error, "unexpected output target: #{ou.class}"
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
data/lib/bud/executor/join.rb
CHANGED
@@ -526,7 +526,8 @@ module Bud
|
|
526
526
|
@rhs_rcvd = false
|
527
527
|
@hash_tables = [{},{}]
|
528
528
|
if @lhs_keycols.nil? and blk.nil?
|
529
|
-
#
|
529
|
+
# Pointwise comparison. Could use zip, but it creates an array for each
|
530
|
+
# field pair.
|
530
531
|
blk = lambda {|lhs, rhs|
|
531
532
|
lhs.to_a == rhs.to_a
|
532
533
|
}
|
@@ -536,7 +537,7 @@ module Bud
|
|
536
537
|
|
537
538
|
def setup_preds(preds)
|
538
539
|
# This is simpler than PushSHJoin's setup_preds, because notin is a binary
|
539
|
-
# operator where both lhs and rhs are collections.
|
540
|
+
# operator where both lhs and rhs are collections. preds is an array of
|
540
541
|
# hash_pairs. For now assume that the attributes are in the same order as
|
541
542
|
# the tables.
|
542
543
|
@lhs_keycols, @rhs_keycols = preds.reduce([[], []]) do |memo, item|
|
@@ -548,10 +549,13 @@ module Bud
|
|
548
549
|
memo
|
549
550
|
end
|
550
551
|
end
|
552
|
+
|
551
553
|
def find_col(colspec, rel)
|
552
554
|
if colspec.is_a? Symbol
|
555
|
+
unless rel.respond_to? colspec
|
556
|
+
raise Bud::Error, "attribute :#{colspec} not found in #{rel.tabname}"
|
557
|
+
end
|
553
558
|
col_desc = rel.send(colspec)
|
554
|
-
raise Bud::Error, "unknown column #{colspec} in #{@rel.tabname}" if col_desc.nil?
|
555
559
|
elsif colspec.is_a? Array
|
556
560
|
col_desc = colspec
|
557
561
|
else
|
@@ -562,7 +566,7 @@ module Bud
|
|
562
566
|
|
563
567
|
def get_key(item, offset)
|
564
568
|
keycols = offset == 0 ? @lhs_keycols : @rhs_keycols
|
565
|
-
keycols.nil? ? $EMPTY : keycols
|
569
|
+
keycols.nil? ? $EMPTY : item.values_at(*keycols)
|
566
570
|
end
|
567
571
|
|
568
572
|
public
|
@@ -571,7 +575,16 @@ module Bud
|
|
571
575
|
end
|
572
576
|
|
573
577
|
def insert(item, source)
|
574
|
-
|
578
|
+
if source == @lhs && source == @rhs # Self join
|
579
|
+
do_insert(item, 0)
|
580
|
+
do_insert(item, 1)
|
581
|
+
else
|
582
|
+
offset = source == @lhs ? 0 : 1
|
583
|
+
do_insert(item, offset)
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
def do_insert(item, offset)
|
575
588
|
key = get_key(item, offset)
|
576
589
|
(@hash_tables[offset][key] ||= Set.new).add item
|
577
590
|
if @rhs_rcvd and offset == 0
|
@@ -597,7 +610,6 @@ module Bud
|
|
597
610
|
end
|
598
611
|
|
599
612
|
def process_match(lhs_item, rhs_values)
|
600
|
-
exclude = true
|
601
613
|
if rhs_values.nil?
|
602
614
|
# no corresponding rhs. Include in output
|
603
615
|
exclude = false
|
@@ -605,33 +617,24 @@ module Bud
|
|
605
617
|
# for any lhs * rhs pair, if block returns true, do not push lhs. lhs is pushed
|
606
618
|
# only if there is no match (anti-join)
|
607
619
|
exclude = rhs_values.any?{|rhs_item| @blk.call(lhs_item, rhs_item)}
|
620
|
+
else
|
621
|
+
exclude = true
|
608
622
|
end
|
609
|
-
unless exclude
|
610
|
-
push_out(lhs_item)
|
611
|
-
end
|
612
|
-
end
|
613
623
|
|
614
|
-
|
615
|
-
def push_out(item)
|
616
|
-
@outputs.each do |ou|
|
617
|
-
if ou.class <= Bud::PushElement
|
618
|
-
ou.insert(item, self)
|
619
|
-
elsif ou.class <= Bud::BudCollection
|
620
|
-
ou.do_insert(item, ou.new_delta)
|
621
|
-
else
|
622
|
-
raise Bud::Error, "expected either a PushElement or a BudCollection"
|
623
|
-
end
|
624
|
-
end
|
625
|
-
# for all the following, o is a BudCollection
|
626
|
-
@deletes.each{|o| o.pending_delete([item])}
|
627
|
-
@delete_keys.each{|o| o.pending_delete_keys([item])}
|
628
|
-
@pendings.each{|o| o.pending_merge([item])}
|
624
|
+
push_out(lhs_item, false) unless exclude
|
629
625
|
end
|
630
626
|
|
631
627
|
def invalidate_cache
|
632
|
-
|
633
|
-
|
634
|
-
@
|
628
|
+
raise Bud::Error if @rhs_rcvd # sanity check; should already be reset
|
629
|
+
|
630
|
+
if @lhs.rescan
|
631
|
+
puts "#{tabname} rel:#{@lhs.tabname} invalidated" if $BUD_DEBUG
|
632
|
+
@hash_tables[0] = {}
|
633
|
+
end
|
634
|
+
if @rhs.rescan
|
635
|
+
puts "#{tabname} rel:#{@rhs.tabname} invalidated" if $BUD_DEBUG
|
636
|
+
@hash_tables[1] = {}
|
637
|
+
end
|
635
638
|
end
|
636
639
|
|
637
640
|
def stratum_end
|
data/lib/bud/graphs.rb
CHANGED
@@ -167,7 +167,7 @@ class GraphGen #:nodoc: all
|
|
167
167
|
@edges[ekey].arrowsize = 2
|
168
168
|
|
169
169
|
@edges[ekey].color = (@nodes[body]["color"].source || "")
|
170
|
-
@edges[ekey].URL = "#{rule_id}.html" unless rule_id.nil?
|
170
|
+
@edges[ekey].URL = "#{rule_id}-#{head}.html" unless rule_id.nil?
|
171
171
|
if head =~ /_msg\z/
|
172
172
|
@edges[ekey].minlen = 2
|
173
173
|
else
|
@@ -303,7 +303,7 @@ class SpaceTime
|
|
303
303
|
params[:URL] = "DBM_#{k}/tm_#{item}.svg"
|
304
304
|
end
|
305
305
|
snd = @subs[k].add_nodes(label, params)
|
306
|
-
unless @head[k].
|
306
|
+
unless @head[k].object_id == snd.object_id
|
307
307
|
@subs[k].add_edges(@head[k], snd, :weight => 2)
|
308
308
|
@head[k] = snd
|
309
309
|
end
|
data/lib/bud/lattice-core.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'bud/executor/elements'
|
2
2
|
|
3
3
|
class Bud::Lattice
|
4
|
+
include Comparable
|
5
|
+
|
4
6
|
@@lattice_kinds = {}
|
5
7
|
@@global_morphs = Set.new
|
6
8
|
@@global_mfuncs = Set.new
|
@@ -76,7 +78,7 @@ class Bud::Lattice
|
|
76
78
|
end
|
77
79
|
|
78
80
|
def eql?(o)
|
79
|
-
|
81
|
+
self == o
|
80
82
|
end
|
81
83
|
|
82
84
|
# Ensure hashing and equality semantics are consistent.
|
@@ -84,6 +86,11 @@ class Bud::Lattice
|
|
84
86
|
reveal.hash
|
85
87
|
end
|
86
88
|
|
89
|
+
# Similarly, use reveal'ed value to implement Comparable.
|
90
|
+
def <=>(o)
|
91
|
+
reveal <=> o.reveal
|
92
|
+
end
|
93
|
+
|
87
94
|
# Return the state valued associated with a lattice instance. Note that this
|
88
95
|
# is non-monotonic when invoked from user code; it should be used with care by
|
89
96
|
# framework code.
|
@@ -107,8 +114,6 @@ end
|
|
107
114
|
|
108
115
|
# TODO:
|
109
116
|
# * merge logic for set-oriented collections
|
110
|
-
# * invalidation/rescan/non-monotonic stuff?
|
111
|
-
# * expressions on RHS ("CollExpr")
|
112
117
|
class Bud::LatticePushElement
|
113
118
|
attr_reader :wired_by, :outputs
|
114
119
|
attr_accessor :invalidated, :rescan
|
@@ -381,15 +386,15 @@ class Bud::PushApplyMethod < Bud::LatticePushElement
|
|
381
386
|
end
|
382
387
|
|
383
388
|
class Bud::LatticeWrapper
|
384
|
-
attr_reader :tabname, :wired_by, :
|
385
|
-
attr_accessor :accumulate_tick_deltas
|
389
|
+
attr_reader :tabname, :wired_by, :rescan_on_delta
|
390
|
+
attr_accessor :accumulate_tick_deltas, :bud_instance
|
386
391
|
|
387
392
|
def initialize(tabname, klass, bud_i)
|
388
393
|
@tabname = tabname
|
389
394
|
@klass = klass
|
390
395
|
@bud_instance = bud_i
|
391
396
|
@wired_by = []
|
392
|
-
@
|
397
|
+
@rescan_on_delta = Set.new
|
393
398
|
end
|
394
399
|
|
395
400
|
def qualified_tabname
|
@@ -400,6 +405,35 @@ class Bud::LatticeWrapper
|
|
400
405
|
false
|
401
406
|
end
|
402
407
|
|
408
|
+
def setup_wiring(input, kind)
|
409
|
+
if input.class <= Bud::LatticeWrapper
|
410
|
+
input.to_push_elem.wire_to(self, kind)
|
411
|
+
elsif (input.class <= Bud::LatticePushElement || input.class <= Bud::PushElement)
|
412
|
+
input.wire_to(self, kind)
|
413
|
+
elsif input.class <= Bud::BudCollection
|
414
|
+
input.pro.wire_to(self, kind)
|
415
|
+
elsif input.class <= Proc
|
416
|
+
tbl = register_coll_expr(input)
|
417
|
+
tbl.pro.wire_to(self, kind)
|
418
|
+
else
|
419
|
+
raise Bud::Error, "unrecognized wiring input: #{input}"
|
420
|
+
end
|
421
|
+
|
422
|
+
add_merge_target
|
423
|
+
end
|
424
|
+
|
425
|
+
def positive_predecessors
|
426
|
+
@wired_by.select {|e| e.outputs.include?(self) || e.pendings.include?(self)}
|
427
|
+
end
|
428
|
+
|
429
|
+
private
|
430
|
+
def register_coll_expr(expr)
|
431
|
+
name = "expr_#{expr.object_id}".to_sym
|
432
|
+
@bud_instance.coll_expr(name, expr, nil)
|
433
|
+
@bud_instance.send(name)
|
434
|
+
end
|
435
|
+
|
436
|
+
public
|
403
437
|
def current_value
|
404
438
|
@storage ||= @klass.new
|
405
439
|
@storage
|
@@ -436,30 +470,6 @@ class Bud::LatticeWrapper
|
|
436
470
|
rv
|
437
471
|
end
|
438
472
|
|
439
|
-
def setup_wiring(input, kind)
|
440
|
-
if input.class <= Bud::LatticeWrapper
|
441
|
-
input.to_push_elem.wire_to(self, kind)
|
442
|
-
elsif (input.class <= Bud::LatticePushElement || input.class <= Bud::PushElement)
|
443
|
-
input.wire_to(self, kind)
|
444
|
-
elsif input.class <= Bud::BudCollection
|
445
|
-
input.pro.wire_to(self, kind)
|
446
|
-
elsif input.class <= Proc
|
447
|
-
tbl = register_coll_expr(input)
|
448
|
-
tbl.pro.wire_to(self, kind)
|
449
|
-
else
|
450
|
-
raise Bud::Error, "unrecognized wiring input: #{input}"
|
451
|
-
end
|
452
|
-
|
453
|
-
add_merge_target
|
454
|
-
end
|
455
|
-
|
456
|
-
private
|
457
|
-
def register_coll_expr(expr)
|
458
|
-
name = "expr_#{expr.object_id}".to_sym
|
459
|
-
@bud_instance.coll_expr(name, expr, nil)
|
460
|
-
@bud_instance.send(name)
|
461
|
-
end
|
462
|
-
|
463
473
|
# Merge "i" into @new_delta
|
464
474
|
public
|
465
475
|
def insert(i, source)
|
@@ -520,8 +530,17 @@ class Bud::LatticeWrapper
|
|
520
530
|
end
|
521
531
|
|
522
532
|
def bootstrap
|
523
|
-
|
524
|
-
@pending
|
533
|
+
# Bootstrap blocks might install lattice values via either <= (@new_delta)
|
534
|
+
# or <+ (@pending).
|
535
|
+
if @new_delta
|
536
|
+
merge_to_storage(@new_delta)
|
537
|
+
@new_delta = nil
|
538
|
+
end
|
539
|
+
|
540
|
+
if @pending
|
541
|
+
merge_to_storage(@pending)
|
542
|
+
@pending = nil
|
543
|
+
end
|
525
544
|
end
|
526
545
|
|
527
546
|
def tick
|
@@ -537,7 +556,7 @@ class Bud::LatticeWrapper
|
|
537
556
|
m = do_merge(current_value, v)
|
538
557
|
if m != current_value
|
539
558
|
@storage = m
|
540
|
-
@
|
559
|
+
@rescan_on_delta.each do |e|
|
541
560
|
if e.kind_of? Bud::ScannerElement
|
542
561
|
e.force_rescan = true
|
543
562
|
else
|
data/lib/bud/lattice-lib.rb
CHANGED
@@ -1,69 +1,66 @@
|
|
1
1
|
require 'bud/lattice-core'
|
2
2
|
|
3
|
+
# Float::INFINITY only defined in MRI 1.9.2+
|
4
|
+
unless defined? Float::INFINITY
|
5
|
+
Float::INFINITY = 1.0/0.0
|
6
|
+
end
|
7
|
+
|
3
8
|
class Bud::MaxLattice < Bud::Lattice
|
4
9
|
wrapper_name :lmax
|
5
10
|
|
6
|
-
def initialize(i
|
7
|
-
|
8
|
-
reject_input(i)
|
9
|
-
end
|
11
|
+
def initialize(i=-Float::INFINITY)
|
12
|
+
reject_input(i) unless i.class <= Comparable
|
10
13
|
@v = i
|
11
14
|
end
|
12
15
|
|
13
16
|
def merge(i)
|
14
|
-
|
15
|
-
(@v.nil? || (i_val != nil && i_val > @v)) ? i : self
|
17
|
+
i.reveal > @v ? i : self
|
16
18
|
end
|
17
19
|
|
18
20
|
morph :gt do |k|
|
19
|
-
Bud::BoolLattice.new(!!(@v
|
21
|
+
Bud::BoolLattice.new(!!(@v > k))
|
20
22
|
end
|
21
23
|
|
22
24
|
morph :gt_eq do |k|
|
23
|
-
Bud::BoolLattice.new(!!(@v
|
25
|
+
Bud::BoolLattice.new(!!(@v >= k))
|
24
26
|
end
|
25
27
|
|
26
28
|
# XXX: support MaxLattice input?
|
27
29
|
morph :+ do |i|
|
28
|
-
#
|
29
|
-
return self if @v.nil?
|
30
|
+
# NB: since bottom of lmax is negative infinity, + is a no-op
|
30
31
|
reject_input(i, "+") unless i.class <= Numeric
|
31
32
|
self.class.new(@v + i)
|
32
33
|
end
|
33
34
|
|
34
35
|
morph :min_of do |i|
|
35
36
|
reject_input(i, "min_of") unless i.class <= Numeric
|
36
|
-
|
37
|
+
i < @v ? self.class.new(i) : self
|
37
38
|
end
|
38
39
|
|
39
40
|
def lt_eq(k)
|
40
|
-
Bud::BoolLattice.new(!!(@v
|
41
|
+
Bud::BoolLattice.new(!!(@v <= k))
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
44
45
|
class Bud::MinLattice < Bud::Lattice
|
45
46
|
wrapper_name :lmin
|
46
47
|
|
47
|
-
def initialize(i=
|
48
|
-
|
49
|
-
reject_input(i)
|
50
|
-
end
|
48
|
+
def initialize(i=Float::INFINITY)
|
49
|
+
reject_input(i) unless i.class <= Comparable
|
51
50
|
@v = i
|
52
51
|
end
|
53
52
|
|
54
53
|
def merge(i)
|
55
|
-
|
56
|
-
(@v.nil? || (i_val != nil && i_val < @v)) ? i : self
|
54
|
+
i.reveal < @v ? i : self
|
57
55
|
end
|
58
56
|
|
59
57
|
morph :lt do |k|
|
60
|
-
Bud::BoolLattice.new(!!(@v
|
58
|
+
Bud::BoolLattice.new(!!(@v < k))
|
61
59
|
end
|
62
60
|
|
63
61
|
# XXX: support MinLattice input
|
64
62
|
morph :+ do |i|
|
65
63
|
# Since bottom of lmin is infinity, + is a no-op
|
66
|
-
return self if @v.nil?
|
67
64
|
reject_input(i, "+") unless i.class <= Numeric
|
68
65
|
self.class.new(@v + i)
|
69
66
|
end
|
@@ -205,7 +202,8 @@ end
|
|
205
202
|
class Bud::SetLattice < Bud::Lattice
|
206
203
|
wrapper_name :lset
|
207
204
|
|
208
|
-
def initialize(i=
|
205
|
+
def initialize(i=Set.new)
|
206
|
+
reject_input(i) unless i.kind_of? Enumerable
|
209
207
|
reject_input(i) if i.any? {|e| e.kind_of? Bud::Lattice}
|
210
208
|
|
211
209
|
i = Set.new(i) unless i.kind_of? Set
|
@@ -216,6 +214,11 @@ class Bud::SetLattice < Bud::Lattice
|
|
216
214
|
wrap_unsafe(@v | i.reveal)
|
217
215
|
end
|
218
216
|
|
217
|
+
# Override default "inspect" implementation to produce slightly nicer output
|
218
|
+
def inspect
|
219
|
+
"<#{self.class.wrapper}: #{reveal.to_a.sort.inspect}>"
|
220
|
+
end
|
221
|
+
|
219
222
|
morph :intersect do |i|
|
220
223
|
wrap_unsafe(@v & i.reveal)
|
221
224
|
end
|
@@ -304,8 +307,8 @@ class Bud::PositiveSetLattice < Bud::SetLattice
|
|
304
307
|
end
|
305
308
|
|
306
309
|
monotone :pos_sum do
|
307
|
-
@sum = @v.reduce(:+) if @sum.nil?
|
308
|
-
|
310
|
+
@sum = @v.reduce(Bud::MaxLattice.new(0), :+) if @sum.nil?
|
311
|
+
@sum
|
309
312
|
end
|
310
313
|
end
|
311
314
|
|
@@ -361,7 +364,7 @@ class Bud::BagLattice < Bud::Lattice
|
|
361
364
|
end
|
362
365
|
|
363
366
|
monotone :size do
|
364
|
-
@size = @v.values.reduce(:+) if @size.nil?
|
365
|
-
|
367
|
+
@size = @v.values.reduce(Bud::MaxLattice.new(0), :+) if @size.nil?
|
368
|
+
@size
|
366
369
|
end
|
367
370
|
end
|
data/lib/bud/monkeypatch.rb
CHANGED
data/lib/bud/rebl.rb
CHANGED
@@ -4,7 +4,9 @@ require 'rubygems'
|
|
4
4
|
require 'bud'
|
5
5
|
require 'abbrev'
|
6
6
|
require 'tempfile'
|
7
|
-
|
7
|
+
|
8
|
+
TABLE_TYPES = ["table", "scratch", "channel", "loopback", "periodic",
|
9
|
+
"sync", "store", "interface", "interfaces"]
|
8
10
|
|
9
11
|
# The class to which rebl adds user-specified rules and declarations.
|
10
12
|
class ReblBase
|
@@ -93,10 +95,13 @@ class ReblShell
|
|
93
95
|
|
94
96
|
# One step of the rebl shell loop: processes one rebl shell line from stdin
|
95
97
|
# and returns. May raise an Exception.
|
96
|
-
def self.rebl_loop(lib,noreadline=false)
|
98
|
+
def self.rebl_loop(lib, noreadline=false)
|
97
99
|
begin
|
98
|
-
|
99
|
-
|
100
|
+
if noreadline
|
101
|
+
line = gets
|
102
|
+
else
|
103
|
+
line = Readline::readline('rebl> ')
|
104
|
+
end
|
100
105
|
do_exit if line.nil?
|
101
106
|
line.strip!
|
102
107
|
return if line.empty?
|
@@ -110,7 +115,7 @@ class ReblShell
|
|
110
115
|
else
|
111
116
|
puts "invalid command or ambiguous command prefix"
|
112
117
|
end
|
113
|
-
elsif
|
118
|
+
elsif is_collection? split_line[0]
|
114
119
|
# Collection
|
115
120
|
lib.add_collection(line)
|
116
121
|
else
|
@@ -186,6 +191,12 @@ class ReblShell
|
|
186
191
|
puts "\n" + @@exit_message
|
187
192
|
exit!
|
188
193
|
end
|
194
|
+
|
195
|
+
# Checks if a given string refers to a collection type (one of the builtin
|
196
|
+
# collection types or a wrapper_name for a lattice).
|
197
|
+
def self.is_collection?(c)
|
198
|
+
TABLE_TYPES.include?(c) || Bud::Lattice.lattice_kinds.has_key?(c.to_sym)
|
199
|
+
end
|
189
200
|
end
|
190
201
|
|
191
202
|
|
@@ -233,11 +244,14 @@ class LibRebl
|
|
233
244
|
def dump(c)
|
234
245
|
if c.nil?
|
235
246
|
puts "Error: dump must be passed a collection name"
|
236
|
-
elsif
|
237
|
-
puts "Error: non-existent collection \"#{c}\""
|
238
|
-
else
|
247
|
+
elsif @rebl_class_inst.tables.has_key? c.to_sym
|
239
248
|
tups = @rebl_class_inst.tables[c.to_sym].to_a.sort
|
240
249
|
puts(tups.empty? ? "(empty)" : tups.sort.map{|t| "#{t}"}.join("\n"))
|
250
|
+
elsif @rebl_class_inst.lattices.has_key? c.to_sym
|
251
|
+
val = @rebl_class_inst.lattices[c.to_sym].current_value
|
252
|
+
puts val.inspect
|
253
|
+
else
|
254
|
+
puts "Error: non-existent collection \"#{c}\""
|
241
255
|
end
|
242
256
|
end
|
243
257
|
|
@@ -334,11 +348,15 @@ class LibRebl
|
|
334
348
|
end)
|
335
349
|
@rebl_class_inst.dbm_tables.merge! @old_inst.dbm_tables
|
336
350
|
@rebl_class_inst.zk_tables.merge! @old_inst.zk_tables
|
351
|
+
@rebl_class_inst.lattices.merge! @old_inst.lattices
|
337
352
|
|
338
353
|
# Fix the bud instance pointers from copied tables.
|
339
354
|
@rebl_class_inst.tables.each_value do |v|
|
340
355
|
v.bud_instance = @rebl_class_inst
|
341
356
|
end
|
357
|
+
@rebl_class_inst.lattices.each_value do |v|
|
358
|
+
v.bud_instance = @rebl_class_inst
|
359
|
+
end
|
342
360
|
end
|
343
361
|
|
344
362
|
# Run lazily in background, shutting down old instance.
|