예제 #1
0
        public void ORDictionary_must_be_able_to_update_ORSet_entry_with_Remove_then_Merge_then_Add()
        {
            var m1 = ORDictionary <string, ORSet <string> > .Empty
                     .SetItem(_node1, "a", ORSet.Create(_node1, "A"))
                     .SetItem(_node1, "b", ORSet.Create(_node1, "B01").Add(_node1, "B02").Add(_node1, "B03"));

            var m2 = ORDictionary <string, ORSet <string> > .Empty
                     .SetItem(_node2, "c", ORSet.Create(_node2, "C"));

            var merged1 = m1.Merge(m2);

            var m3 = merged1.Remove(_node1, "b");

            var merged2 = merged1.Merge(m3);

            Assert.Equal(ImmutableHashSet.Create("A"), merged2["a"].Elements);
            Assert.DoesNotContain("b", merged2.Entries.Keys);
            Assert.Equal(ImmutableHashSet.Create("C"), merged2["c"].Elements);

            var m4 = merged2.SetItem(_node1, "b", ORSet.Create(_node1, "B2"));
            var m5 = merged2.AddOrUpdate(_node2, "c", ORSet <string> .Empty, old => old.Add(_node2, "C2"))
                     .SetItem(_node2, "b", ORSet.Create(_node2, "B3"));

            var merged3 = m5.Merge(m4);

            Assert.Equal(ImmutableHashSet.Create("A"), merged3["a"].Elements);
            Assert.Equal(ImmutableHashSet.Create("B2", "B3"), merged3["b"].Elements);
            Assert.Equal(ImmutableHashSet.Create("C", "C2"), merged3["c"].Elements);
        }
        public void ReplicatedDataSerializer_should_serialize_ORDictionary_delta()
        {
            CheckSerialization(ORDictionary <string, GSet <string> > .Empty
                               .SetItem(_address1, "a", GSet.Create("A"))
                               .SetItem(_address2, "b", GSet.Create("B"))
                               .Delta);

            CheckSerialization(ORDictionary <string, GSet <string> > .Empty
                               .SetItem(_address1, "a", GSet.Create("A"))
                               .ResetDelta()
                               .Remove(_address2, "a")
                               .Delta);

            CheckSerialization(ORDictionary <string, GSet <string> > .Empty
                               .SetItem(_address1, "a", GSet.Create("A"))
                               .Remove(_address2, "a")
                               .Delta);

            CheckSerialization(ORDictionary <string, ORSet <string> > .Empty
                               .SetItem(_address1, "a", ORSet.Create(_address1, "A"))
                               .SetItem(_address2, "b", ORSet.Create(_address2, "B"))
                               .AddOrUpdate(_address1, "a", ORSet <string> .Empty, old => old.Add(_address1, "C"))
                               .Delta);

            CheckSerialization(ORDictionary <string, ORSet <string> > .Empty
                               .ResetDelta()
                               .AddOrUpdate(_address1, "a", ORSet <string> .Empty, old => old.Add(_address1, "C"))
                               .Delta);
        }
예제 #3
0
        public void ORDictionary_must_be_able_to_update_an_entry()
        {
            var m1 = ORDictionary <string, ORSet <string> > .Empty
                     .SetItem(_node1, "a", ORSet.Create(_node1, "A"))
                     .SetItem(_node1, "b", ORSet.Create(_node1, "B01").Add(_node1, "B02").Add(_node1, "B03"));

            var m2 = ORDictionary <string, ORSet <string> > .Empty
                     .SetItem(_node2, "c", ORSet.Create(_node2, "C"));

            var merged1 = m1.Merge(m2);

            var m3 = merged1.AddOrUpdate(_node1, "b", ORSet <string> .Empty, old => old.Clear(_node1).Add(_node1, "B2"));

            var merged2 = merged1.Merge(m3);

            merged2["a"].Elements.Should().BeEquivalentTo("A");
            merged2["b"].Elements.Should().BeEquivalentTo("B2");
            merged2["c"].Elements.Should().BeEquivalentTo("C");

            var m4      = merged1.AddOrUpdate(_node2, "b", ORSet <string> .Empty, old => old.Add(_node2, "B3"));
            var merged3 = m3.Merge(m4);

            merged3["a"].Elements.Should().BeEquivalentTo("A");
            merged3["b"].Elements.Should().BeEquivalentTo("B2", "B3");
            merged3["c"].Elements.Should().BeEquivalentTo("C");
        }
예제 #4
0
        public void ORDictionary_must_be_able_to_update_ORSet_entry_with_Remove_then_Add()
        {
            var m1 = ORDictionary <string, ORSet <string> > .Empty
                     .SetItem(_node1, "a", ORSet.Create(_node1, "A01"))
                     .AddOrUpdate(_node1, "a", ORSet <string> .Empty, old => old.Add(_node1, "A02"))
                     .AddOrUpdate(_node1, "a", ORSet <string> .Empty, old => old.Add(_node1, "A03"))
                     .SetItem(_node1, "b", ORSet.Create(_node1, "B01").Add(_node1, "B02").Add(_node1, "B03"));

            var m2 = ORDictionary <string, ORSet <string> > .Empty
                     .SetItem(_node2, "c", ORSet.Create(_node2, "C"));

            var merged1 = m1.Merge(m2);

            // note that remove + put work because the new VersionVector version is incremented
            // from a global counter

            var m3 = merged1.Remove(_node1, "b").SetItem(_node1, "b", ORSet.Create(_node1, "B2"));

            var merged2 = merged1.Merge(m3);

            Assert.Equal(ImmutableHashSet.Create("A01", "A02", "A03"), merged2["a"].Elements);
            Assert.Equal(ImmutableHashSet.Create("B2"), merged2["b"].Elements);
            Assert.Equal(ImmutableHashSet.Create("C"), merged2["c"].Elements);

            var m4      = merged1.AddOrUpdate(_node2, "b", ORSet <string> .Empty, old => old.Add(_node2, "B3"));
            var merged3 = m3.Merge(m4);

            Assert.Equal(ImmutableHashSet.Create("A01", "A02", "A03"), merged3["a"].Elements);
            Assert.Equal(ImmutableHashSet.Create("B2", "B3"), merged3["b"].Elements);
            Assert.Equal(ImmutableHashSet.Create("C"), merged3["c"].Elements);
        }
예제 #5
0
        public void ORSet_must_verify_removed_after_merge_2()
        {
            var a = ORSet.Create(_node1, "Z");
            var b = ORSet.Create(_node2, "Z");
            // replicate node3
            var c  = a;
            var a2 = a.Remove(_node1, "Z");
            // replicate b to node1, now node1 has node2's 'Z'
            var a3 = a2.Merge(b);

            a3.Elements.Should().BeEquivalentTo("Z");
            // Remove node2's 'Z'
            var b2 = b.Remove(_node2, "Z");
            // Replicate c to node2, now node2 has node1's old 'Z'
            var b3 = b2.Merge(c);

            b3.Elements.Should().BeEquivalentTo("Z");
            // Merge everytyhing

            a3.Merge(c).Merge(b3).Elements.Should().BeEmpty();
            a3.Merge(b3).Merge(c).Elements.Should().BeEmpty();
            c.Merge(a3).Merge(b3).Elements.Should().BeEmpty();
            c.Merge(b3).Merge(a3).Elements.Should().BeEmpty();
            b3.Merge(c).Merge(a3).Elements.Should().BeEmpty();
            b3.Merge(a3).Merge(c).Elements.Should().BeEmpty();
        }
예제 #6
0
        public void ORSet_must_verify_removed_after_merge()
        {
            // Add Z at node1 replica
            var a = ORSet.Create(_node1, "Z");
            // Replicate it to some node3, i.e. it has dot 'Z'->{node1 -> 1}
            var c = a;
            // Remove Z at node1 replica
            var a2 = a.Remove(_node1, "Z");
            // Add Z at node2, a new replica
            var b = ORSet.Create(_node2, "Z");
            // Replicate b to node1, so now node1 has a Z, the one with a Dot of
            // {node2 -> 1} and version vector of [{node1 -> 1}, {node2 -> 1}]
            var a3 = b.Merge(a2);

            a3.Elements.Should().BeEquivalentTo("Z");
            // Remove the 'Z' at node2 replica
            var b2 = b.Remove(_node2, "Z");

            // Both node3 (c) and node1 (a3) have a 'Z', but when they merge, there should be
            // no 'Z' as node3 (c)'s has been removed by node1 and node1 (a3)'s has been removed by
            // node2
            c.Elements.Should().BeEquivalentTo("Z");
            a3.Elements.Should().BeEquivalentTo("Z");
            b2.Elements.Should().BeEmpty();

            a3.Merge(c).Merge(b2).Elements.Should().BeEmpty();
            a3.Merge(b2).Merge(c).Elements.Should().BeEmpty();
            c.Merge(a3).Merge(b2).Elements.Should().BeEmpty();
            c.Merge(b2).Merge(a3).Elements.Should().BeEmpty();
            b2.Merge(c).Merge(a3).Elements.Should().BeEmpty();
            b2.Merge(a3).Merge(c).Elements.Should().BeEmpty();
        }
예제 #7
0
        public void A_ORDictionary_should_be_able_to_update_an_entry()
        {
            var m1 = ORDictionary <string, ORSet <string> > .Empty
                     .SetItem(_node1, "a", ORSet.Create(_node1, "A"))
                     .SetItem(_node1, "b", ORSet.Create(_node1, "B01").Add(_node1, "B02").Add(_node1, "B03"));

            var m2 = ORDictionary <string, ORSet <string> > .Empty
                     .SetItem(_node2, "c", ORSet.Create(_node2, "C"));

            var merged1 = m1.Merge(m2);

            var m3 = merged1.AddOrUpdate(_node1, "b", ORSet <string> .Empty, old => old.Clear(_node1).Add(_node1, "B2"));

            var merged2 = merged1.Merge(m3);

            Assert.Equal(ImmutableHashSet.Create("A"), merged2["a"].Elements);
            Assert.Equal(ImmutableHashSet.Create("B2"), merged2["b"].Elements);
            Assert.Equal(ImmutableHashSet.Create("C"), merged2["c"].Elements);

            var m4      = merged1.AddOrUpdate(_node2, "b", ORSet <string> .Empty, old => old.Add(_node2, "B3"));
            var merged3 = m3.Merge(m4);

            Assert.Equal(ImmutableHashSet.Create("A"), merged3["a"].Elements);
            Assert.Equal(ImmutableHashSet.Create("B2", "B3"), merged3["b"].Elements);
            Assert.Equal(ImmutableHashSet.Create("C"), merged3["c"].Elements);
        }
예제 #8
0
        public void ORDictionary_must_not_allow_SetItem_for_ORSet_elements_type()
        {
            var m = ORDictionary <string, ORSet <string> > .Empty
                    .SetItem(_node1, "a", ORSet.Create(_node1, "A"));

            Assert.Throws <ArgumentException>(() =>
                                              m.SetItem(_node1, "a", ORSet.Create(_node1, "B")));
        }
예제 #9
0
        public void ORSet_must_verify_disjoint_Merge()
        {
            var a1 = ORSet.Create(_node1, "bar");
            var b1 = ORSet.Create(_node2, "baz");
            var c  = a1.Merge(b1);
            var a2 = a1.Remove(_node1, "bar");
            var d  = a2.Merge(c);

            d.Elements.Should().BeEquivalentTo("baz");
        }
예제 #10
0
        public void ORDictionary_must_have_usual_anomalies_for_remove_with_update_scenario()
        {
            // please note that the current ORMultiMap has the same anomaly
            // because the condition of keeping global vvector is violated
            // by removal of the whole entry for the removed key "b" which results in removal of it's value's vvector
            var m1 = ORDictionary.Create(_node1, "a", ORSet.Create(_node1, "A")).SetItem(_node1, "b", ORSet.Create(_node1, "B"));
            var m2 = ORDictionary.Create(_node2, "c", ORSet.Create(_node2, "C"));

            // m1 - node1 gets the update from m2
            var merged1 = m1.Merge(m2);
            // m2 - node2 gets the update from m1
            var merged2 = m2.Merge(m1);

            // RACE CONDITION ahead!
            var m3 = merged1.ResetDelta().Remove(_node1, "b");
            // let's imagine that m3 (node1) update gets propagated here (full state or delta - doesn't matter)
            // and is in flight, but in the meantime, an element is being added somewhere else (m4 - node2)
            // and the update is propagated before the update from node1 is merged
            var m4 = merged2.ResetDelta().AddOrUpdate(_node2, "b", ORSet <string> .Empty, x => x.Add(_node2, "B2"));
            // and later merged on node1
            var merged3 = m3.Merge(m4);
            // and the other way round...
            var merged4 = m4.Merge(m3);

            // result -  the element "B" is kept on both sides...
            merged3.Entries["a"].Elements.Should().BeEquivalentTo("A");
            merged3.Entries["b"].Elements.Should().BeEquivalentTo("B", "B2");
            merged3.Entries["c"].Elements.Should().BeEquivalentTo("C");

            merged4.Entries["a"].Elements.Should().BeEquivalentTo("A");
            merged4.Entries["b"].Elements.Should().BeEquivalentTo("B", "B2");
            merged4.Entries["c"].Elements.Should().BeEquivalentTo("C");

            // but if the timing was slightly different, so that the update from node1
            // would get merged just before update on node2:
            var merged5 = m2.Merge(m3)
                          .ResetDelta()
                          .AddOrUpdate(_node2, "b", ORSet <string> .Empty, x => x.Add(_node2, "B2"));
            // the update propagated ... and merged on node1:
            var merged6 = m3.Merge(merged5);

            // then the outcome is different... because the vvector of value("b") was lost...
            merged5.Entries["a"].Elements.Should().BeEquivalentTo("A");
            // this time it's different...
            merged5.Entries["b"].Elements.Should().BeEquivalentTo("B2");
            merged5.Entries["c"].Elements.Should().BeEquivalentTo("C");

            merged6.Entries["a"].Elements.Should().BeEquivalentTo("A");
            // this time it's different...
            merged6.Entries["b"].Elements.Should().BeEquivalentTo("B2");
            merged6.Entries["c"].Elements.Should().BeEquivalentTo("C");
        }
예제 #11
0
        public void ORDictionary_must_not_have_anomalies_for_remove_with_update_scenario_and_deltas_7()
        {
            var m1 = ORDictionary.Create(_node1, "a", ORSet.Create(_node1, "A"))
                     .SetItem(_node1, "b", ORSet.Create(_node1, "B1"))
                     .Remove(_node1, "b");
            var m2 = ORDictionary.Create(_node1, "a", ORSet.Create(_node1, "A"))
                     .SetItem(_node1, "b", ORSet.Create(_node1, "B2"));
            var m2d = m2.ResetDelta().Remove(_node1, "b");
            var m2u = m2.ResetDelta()
                      .AddOrUpdate(_node1, "b", ORSet <string> .Empty, x => x.Add(_node1, "B3"))
                      .AddOrUpdate(_node2, "b", ORSet <string> .Empty, x => x.Add(_node2, "B4"));

            var merged1 = m1.Merge(m2d).MergeDelta(m2u.Delta);

            merged1.Entries["a"].Elements.Should().BeEquivalentTo("A");
            // note that B1 is lost as it was added and removed earlier in timeline than B2
            merged1.Entries["b"].Elements.Should().BeEquivalentTo("B2", "B3", "B4");
        }
예제 #12
0
        public void ReplicatedDataSerializer_should_serialize_ORSet()
        {
            CheckSerialization(ORSet <string> .Empty);
            CheckSerialization(ORSet.Create(_address1, "a"));
            CheckSerialization(ORSet.Create(_address1, "a").Add(_address2, "a"));
            CheckSerialization(ORSet.Create(_address1, "a").Remove(_address2, "a"));
            CheckSerialization(ORSet.Create(_address1, "a").Add(_address2, "b").Remove(_address1, "a"));
            CheckSerialization(ORSet.Create(_address1, 1).Add(_address2, 2));
            CheckSerialization(ORSet.Create(_address1, 1L).Add(_address2, 2L));
            CheckSerialization(ORSet.Create <object>(_address1, "a").Add(_address2, 2).Add(_address3, 3L).Add(_address3, _address3));

            var s1 = ORSet.Create(_address1, "a").Add(_address2, "b");
            var s2 = ORSet.Create(_address2, "b").Add(_address1, "a");

            CheckSameContent(s1.Merge(s2), s2.Merge(s1));

            var s3 = ORSet.Create <object>(_address1, "a").Add(_address2, 17).Remove(_address3, 17);
            var s4 = ORSet.Create <object>(_address2, 17).Remove(_address3, 17).Add(_address1, "a");

            CheckSameContent(s3.Merge(s4), s4.Merge(s3));
        }
예제 #13
0
        public void ORDictionary_must_not_have_anomalies_for_remove_with_update_scenario_and_deltas_6()
        {
            var m1 = ORDictionary.Create(_node1, "a", ORSet.Create(_node1, "A")).SetItem(_node1, "b", ORSet.Create(_node1, "B"));
            var m2 = ORDictionary.Create(_node2, "b", ORSet.Create(_node2, "B3"));

            var merged1 = m1.Merge(m2);

            var m3 = merged1.ResetDelta().Remove(_node1, "b");
            var m4 = merged1.ResetDelta().Remove(_node2, "b")
                     .AddOrUpdate(_node2, "b", ORSet <string> .Empty, x => x.Add(_node2, "B1"))
                     .AddOrUpdate(_node2, "b", ORSet <string> .Empty, x => x.Add(_node2, "B2"));

            var merged2 = m3.Merge(m4);

            merged2.Entries["a"].Elements.Should().BeEquivalentTo("A");
            // note that B is not included, because it was removed in both timelines
            merged2.Entries["b"].Elements.Should().BeEquivalentTo("B1", "B2");

            var merged3 = m3.MergeDelta(m4.Delta);

            merged3.Entries["a"].Elements.Should().BeEquivalentTo("A");
            // note that B is not included, because it was removed in both timelines
            merged3.Entries["b"].Elements.Should().BeEquivalentTo("B1", "B2");
        }