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); }
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(); }
public void ORSet_must_verify_MergeDisjointKeys() { var keys = ImmutableHashSet.CreateRange(new[] { "K3", "K4", "K5" }); var elements = new Dictionary <string, VersionVector> { { "K3", VersionVector.Create(_nodeA, 4L) }, { "K4", VersionVector.Create(new Dictionary <UniqueAddress, long> { { _nodeA, 3L }, { _nodeD, 8L } }.ToImmutableDictionary()) }, { "K5", VersionVector.Create(_nodeA, 2L) }, }.ToImmutableDictionary(); var vvector = VersionVector.Create(new Dictionary <UniqueAddress, long> { { _nodeA, 3L }, { _nodeD, 7L } }.ToImmutableDictionary()); var acc = new Dictionary <string, VersionVector> { { "K1", VersionVector.Create(_nodeA, 3L) } }.ToImmutableDictionary(); var expectedDots = new Dictionary <string, VersionVector> { { "K1", VersionVector.Create(_nodeA, 3L) }, { "K3", VersionVector.Create(_nodeA, 4L) }, { "K4", VersionVector.Create(_nodeD, 8L) }, // "a" -> 3 removed, optimized to include only those unseen }; ORSet <string> .MergeDisjointKeys(keys, elements, vvector, acc).Should().Equal(expectedDots); }
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"); }
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); }
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); }
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(); }
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"))); }
private static Props TestWriteAggregatorPropsWithDelta(ORSet <string> data, Delta delta, IWriteConsistency consistency, IImmutableDictionary <Address, IActorRef> probes, IImmutableList <Address> nodes, IImmutableSet <Address> unreachable, IActorRef replyTo, bool durable) => Actor.Props.Create(() => new TestWriteAggregator <ORSet <string> >(KeyB, data, delta, consistency, probes, nodes, unreachable, replyTo, durable));
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"); }
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"); }
public void ORSet_must_verify_SubtractDots() { var dot = VersionVector.Create(ImmutableDictionary.CreateRange(new Dictionary <UniqueAddress, long> { { _nodeA, 3L }, { _nodeB, 2L }, { _nodeD, 14L }, { _nodeG, 22L } })); var vvector = VersionVector.Create(ImmutableDictionary.CreateRange(new Dictionary <UniqueAddress, long> { { _nodeA, 4L }, { _nodeB, 1L }, { _nodeC, 1L }, { _nodeD, 14L }, { _nodeE, 5L }, { _nodeF, 2L } })); var expected = VersionVector.Create(ImmutableDictionary.CreateRange(new Dictionary <UniqueAddress, long> { { _nodeB, 2L }, { _nodeG, 22L } })); ORSet.SubtractDots(dot, vvector).Should().Be(expected); }
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"); }
public WriteAggregatorSpec(ITestOutputHelper output) : base(ConfigurationFactory.ParseString($@" akka.actor.provider = ""Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"" akka.remote.dot-netty.tcp.port = 0 akka.cluster.distributed-data.durable.lmdb {{ dir = ""target/WriteAggregatorSpec-{DateTime.UtcNow.Ticks}-ddata"" map-size = 10MiB }}"), "WriteAggregatorSpec", output) { _nodes = ImmutableList.CreateRange(new[] { _nodeA, _nodeB, _nodeC, _nodeD }); var cluster = Akka.Cluster.Cluster.Get(Sys); _fullState1 = ORSet <string> .Empty.Add(cluster, "a").Add(cluster, "b"); _fullState2 = _fullState1.ResetDelta().Add(cluster, "c"); _delta = new Delta(new DataEnvelope(_fullState2.Delta), 2L, 2L); _writeAll = new WriteAll(Dilated(TimeSpan.FromSeconds(3))); }
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)); }
public void ORSet_must_verify_MergeCommonKeys() { var commonKeys = ImmutableHashSet.CreateRange(new[] { "K1", "K2" }); var thisDot1 = VersionVector.Create(new Dictionary <UniqueAddress, long> { { _nodeA, 3L }, { _nodeD, 7L } }.ToImmutableDictionary()); var thisDot2 = VersionVector.Create(new Dictionary <UniqueAddress, long> { { _nodeB, 5L }, { _nodeC, 2L } }.ToImmutableDictionary()); var thisVVector = VersionVector.Create(new Dictionary <UniqueAddress, long> { { _nodeA, 3L }, { _nodeB, 5L }, { _nodeC, 2L }, { _nodeD, 7L } }.ToImmutableDictionary()); var thisSet = new ORSet <string>( elementsMap: new Dictionary <string, VersionVector> { { "K1", thisDot1 }, { "K2", thisDot2 } }.ToImmutableDictionary(), versionVector: thisVVector); var thatDot1 = VersionVector.Create(_nodeA, 3L); var thatDot2 = VersionVector.Create(_nodeB, 6L); var thatVVector = VersionVector.Create(new Dictionary <UniqueAddress, long> { { _nodeA, 3L }, { _nodeB, 6L }, { _nodeC, 1L }, { _nodeD, 8L } }.ToImmutableDictionary()); var thatSet = new ORSet <string>( elementsMap: new Dictionary <string, VersionVector> { { "K1", thatDot1 }, { "K2", thatDot2 } }.ToImmutableDictionary(), versionVector: thatVVector); var expectedDots = new Dictionary <string, VersionVector> { { "K1", VersionVector.Create(_nodeA, 3L) }, { "K2", VersionVector.Create(new Dictionary <UniqueAddress, long> { { _nodeB, 6L }, { _nodeC, 2L } }.ToImmutableDictionary()) } }; ORSet <string> .MergeCommonKeys(commonKeys, thisSet, thatSet).Should().Equal(expectedDots); }
public void Setup() { var newNodes = new List <UniqueAddress>(NumNodes); foreach (var i in Enumerable.Range(0, NumNodes)) { var address = new Address("akka.tcp", "Sys", "localhost", 2552 + i); var uniqueAddress = new UniqueAddress(address, i); newNodes.Add(uniqueAddress); } _nodes = newNodes.ToArray(); var newElements = new List <string>(NumNodes); foreach (var i in Enumerable.Range(0, NumElements)) { newElements.Add(i.ToString()); } _elements = newElements.ToArray(); _c1 = ORSet <String> .Empty; foreach (var node in _nodes) { _c1 = _c1.Add(node, _elements[0]); } // add some data that _c2 doesn't have _c2 = _c1; foreach (var node in _nodes.Skip(NumNodes / 2)) { _c2 = _c2.Add(node, _elements[1]); } _c3 = _c1; foreach (var node in _nodes.Take(NumNodes / 2)) { _c3 = _c3.Remove(node, _elements[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"); }
/// <summary> /// TBD /// </summary> /// <param name="cluster">TBD</param> /// <param name="crdt">TBD</param> public LocalORSet(Cluster.Cluster cluster, ORSet <T> crdt) : this(cluster.SelfUniqueAddress, crdt) { }
/// <summary> /// TBD /// </summary> /// <param name="currentNode">TBD</param> /// <param name="crdt">TBD</param> internal LocalORSet(UniqueAddress currentNode, ORSet <T> crdt) : this() { _currentNode = currentNode; _crdt = crdt; }
/// <summary> /// TBD /// </summary> /// <param name="set">TBD</param> public Surrogate(ORSet <T> set) { _set = set; }
/// <summary> /// Merges data from provided <see cref="ORSet{T}"/> into current CRDT, /// creating new immutable instance in a result. /// </summary> /// <param name="set">TBD</param> /// <returns>TBD</returns> public LocalORSet <T> Merge(ORSet <T> set) => new LocalORSet <T>(_currentNode, _crdt.Merge(set));
private ORDictionary <TKey, TValue> DryMerge(ORDictionary <TKey, TValue> other, ORSet <TKey> mergedKeys, IEnumerator <TKey> valueKeysEnumerator) { var mergedValues = ImmutableDictionary <TKey, TValue> .Empty.ToBuilder(); while (valueKeysEnumerator.MoveNext()) { var key = valueKeysEnumerator.Current; TValue value2; if (ValueMap.TryGetValue(key, out var value1)) { if (other.ValueMap.TryGetValue(key, out value2)) { var merged = value1.Merge(value2); mergedValues[key] = merged; } else { mergedValues[key] = value1; } } else { if (other.ValueMap.TryGetValue(key, out value2)) { mergedValues[key] = value2; } else { throw new IllegalStateException($"Missing value for {key}"); } } } return(new ORDictionary <TKey, TValue>(mergedKeys, mergedValues.ToImmutable())); }
internal ORDictionary(ORSet <TKey> keySet, IImmutableDictionary <TKey, TValue> valueMap, IDeltaOperation delta) { KeySet = keySet; ValueMap = valueMap; _syncRoot = delta; }
/// <summary> /// Creates an instance of an ORSet scoped to a current cluster. /// </summary> /// <typeparam name="T">TBD</typeparam> /// <param name="cluster">TBD</param> /// <param name="orset">TBD</param> /// <returns>TBD</returns> public static LocalORSet <T> ORSet <T>(this Cluster.Cluster cluster, ORSet <T> orset) => new LocalORSet <T>(cluster, orset);
static async Task Main(string[] args) { UniqueAddress[] _nodes; string[] _elements; // has data from all nodes ORSet <string> _c1 = ORSet <String> .Empty; // has additional items from all nodes ORSet <string> _c2 = ORSet <String> .Empty; // has removed items from all nodes ORSet <string> _c3 = ORSet <String> .Empty; var newNodes = new List <UniqueAddress>(NumNodes); foreach (var i in Enumerable.Range(0, NumNodes)) { var address = new Address("akka.tcp", "Sys", "localhost", 2552 + i); var uniqueAddress = new UniqueAddress(address, i); newNodes.Add(uniqueAddress); } _nodes = newNodes.ToArray(); var newElements = new List <string>(NumNodes); foreach (var i in Enumerable.Range(0, NumElements)) { newElements.Add(i.ToString()); } _elements = newElements.ToArray(); _c1 = ORSet <String> .Empty; foreach (var node in _nodes) { _c1 = _c1.Add(node, _elements[0]); } // add some data that _c2 doesn't have _c2 = _c1; foreach (var node in _nodes.Skip(NumNodes / 2)) { _c2 = _c2.Add(node, _elements[1]); } _c3 = _c1; foreach (var node in _nodes.Take(NumNodes / 2)) { _c3 = _c3.Remove(node, _elements[0]); } var init = ORSet <string> .Empty; foreach (var element in _elements) { foreach (var node in _nodes) { init = init.Add(node, element); } } _c1.Merge(init).Merge(_c2).Merge(_c3); await Task.Delay(5000); }
private ORSet <T> .AddDeltaOperation AddDelta <T>(ORSet <T> set) => (ORSet <T> .AddDeltaOperation)set.Delta;
protected override void OnChange(ORSet <int> crdt, object operation) => this.probe.Tell(crdt.Value);
/// <summary> /// Creates a new instance of the <see cref="ORDictionary{TKey,TValue}"/> class. /// </summary> /// <param name="keySet"></param> /// <param name="valueMap"></param> public ORDictionary(ORSet <TKey> keySet, IImmutableDictionary <TKey, TValue> valueMap) : this(keySet, valueMap, null) { }