Class: Meangirls::ORSet
Defined Under Namespace
Classes: Pair
Instance Attribute Summary collapse
-
#e ⇒ Object
Returns the value of attribute e.
Class Method Summary collapse
Instance Method Summary collapse
-
#<<(e) ⇒ Object
Inserts e into the set.
-
#==(other) ⇒ Object
Strict equality: all adds/removes match for every element.
-
#add(e, tag = Meangirls.tag) ⇒ Object
Inserts e into the set.
- #as_json ⇒ Object
- #bias ⇒ Object
-
#clone ⇒ Object
UGH defensive copying.
-
#delete(e, tag = nil) ⇒ Object
Deletes e from self by cancelling all known tags (or a specific tag if given.) Returns nil if no changes, e otherwise.
-
#initialize(hash = nil) ⇒ ORSet
constructor
A new instance of ORSet.
-
#merge(other) ⇒ Object
Merge with another OR-Set and return the merged copy.
-
#merge_internal!(element, pair) ⇒ Object
Updates self with new adds and removes for an element.
- #to_set ⇒ Object
- #type ⇒ Object
-
#uaeq(a, b) ⇒ Object
Unordered array equality TODO: slow.
Methods inherited from Set
#&, #+, #-, #===, #each, #empty?, #size, #to_a, #|
Methods inherited from CRDT
Constructor Details
#initialize(hash = nil) ⇒ ORSet
Returns a new instance of ORSet.
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/meangirls/or_set.rb', line 23 def initialize(hash = nil) @e = {} if hash raise ArgumentError, 'hash must contain e' unless hash['e'] hash['e'].each do |list| element, adds, removes = list merge_internal! element, Pair.new(adds, removes) end end end |
Instance Attribute Details
#e ⇒ Object
Returns the value of attribute e.
22 23 24 |
# File 'lib/meangirls/or_set.rb', line 22 def e @e end |
Class Method Details
.biases ⇒ Object
18 19 20 |
# File 'lib/meangirls/or_set.rb', line 18 def self.biases ['a'] end |
Instance Method Details
#<<(e) ⇒ Object
Inserts e into the set.
36 37 38 |
# File 'lib/meangirls/or_set.rb', line 36 def <<(e) add e end |
#==(other) ⇒ Object
Strict equality: all adds/removes match for every element. TODO: slow
42 43 44 45 46 47 48 49 |
# File 'lib/meangirls/or_set.rb', line 42 def ==(other) other.kind_of? self.class and (@e.keys | other.e.keys).all? do |e, pair| a = @e[e] and b = other.e[e] and uaeq(a.adds, b.adds) and uaeq(a.removes, b.removes) end end |
#add(e, tag = Meangirls.tag) ⇒ Object
Inserts e into the set. Tag will be randomly generated if not given.
52 53 54 55 56 |
# File 'lib/meangirls/or_set.rb', line 52 def add(e, tag = Meangirls.tag) pair = (@e[e] ||= Pair.new) pair.adds |= [tag] self end |
#as_json ⇒ Object
58 59 60 61 62 63 64 65 |
# File 'lib/meangirls/or_set.rb', line 58 def as_json { 'type' => type, 'e' => @e.map do |e, pair| [e, pair.adds, pair.removes] end } end |
#bias ⇒ Object
67 68 69 |
# File 'lib/meangirls/or_set.rb', line 67 def bias 'a' end |
#clone ⇒ Object
UGH defensive copying
72 73 74 75 76 77 78 79 |
# File 'lib/meangirls/or_set.rb', line 72 def clone c = super c.e = {} @e.each do |e, pair| c.merge_internal! e, pair.clone end c end |
#delete(e, tag = nil) ⇒ Object
Deletes e from self by cancelling all known tags (or a specific tag if given.) Returns nil if no changes, e otherwise.
83 84 85 86 87 88 89 |
# File 'lib/meangirls/or_set.rb', line 83 def delete(e, tag = nil) pair = @e[e] or return new = pair.adds - pair.removes return if new.empty? pair.removes += new e end |
#merge(other) ⇒ Object
Merge with another OR-Set and return the merged copy.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/meangirls/or_set.rb', line 92 def merge(other) unless other.kind_of? self.class raise ArgumentError, "other must be a #{self.class}" end copy = clone @e.each do |e, pair| copy.merge_internal! e, pair end other.e.each do |e, pair| copy.merge_internal! e, pair end copy end |
#merge_internal!(element, pair) ⇒ Object
Updates self with new adds and removes for an element.
108 109 110 111 112 113 114 115 |
# File 'lib/meangirls/or_set.rb', line 108 def merge_internal!(element, pair) if my = @e[element] my.adds |= pair.adds my.removes |= pair.removes else @e[element] = pair end end |
#to_set ⇒ Object
117 118 119 120 121 122 123 |
# File 'lib/meangirls/or_set.rb', line 117 def to_set s = Set.new @e.each do |element, pair| s << element unless (pair.adds - pair.removes).empty? end s end |
#type ⇒ Object
125 126 127 |
# File 'lib/meangirls/or_set.rb', line 125 def type 'or-set' end |
#uaeq(a, b) ⇒ Object
Unordered array equality TODO: slow
131 132 133 |
# File 'lib/meangirls/or_set.rb', line 131 def uaeq(a, b) (a - b).empty? and (b - a).empty? end |