bud 0.9.5 → 0.9.6
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.
- 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.
|