public void VersionVector_VectorCompareAndNext() { var a = new VersionVector(A, 4); Assert.AreEqual(VectorRelationship.Equal, a.VectorCompare(a)); var b = new VersionVector(B, 6); Assert.AreEqual(VectorRelationship.Conflict, a.VectorCompare(b)); Assert.AreEqual(VectorRelationship.Conflict, b.VectorCompare(a)); var cNext = a.Next(C); Assert.AreEqual(VectorRelationship.Equal, cNext.VectorCompare(cNext)); Assert.AreEqual(VectorRelationship.Greater, cNext.VectorCompare(a)); Assert.AreEqual(VectorRelationship.Conflict, cNext.VectorCompare(b)); var aNext = (cNext | a).Next(A); var bNext = (cNext | b).Next(B); Assert.AreEqual(VectorRelationship.Greater, aNext.VectorCompare(cNext)); Assert.AreEqual(VectorRelationship.Greater, aNext.VectorCompare(a)); Assert.AreEqual(VectorRelationship.Conflict, aNext.VectorCompare(b)); Assert.AreEqual(VectorRelationship.Less, cNext.VectorCompare(aNext)); Assert.AreEqual(VectorRelationship.Less, a.VectorCompare(aNext)); Assert.AreEqual(VectorRelationship.Conflict, b.VectorCompare(aNext)); Assert.AreEqual(VectorRelationship.Greater, bNext.VectorCompare(cNext)); Assert.AreEqual(VectorRelationship.Greater, bNext.VectorCompare(a)); Assert.AreEqual(VectorRelationship.Greater, bNext.VectorCompare(b)); Assert.AreEqual(VectorRelationship.Less, cNext.VectorCompare(bNext)); Assert.AreEqual(VectorRelationship.Less, a.VectorCompare(bNext)); Assert.AreEqual(VectorRelationship.Less, b.VectorCompare(bNext)); }
public void Parse_should_handle_multiple_events() { var vv = VersionVector.Parse("{(r,1),(s,3)}"); vv["r"].Should().Be(1); vv["s"].Should().Be(3); }
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 Parse_should_handle_single_event() { var vv = VersionVector.Parse("{(r,1)}"); vv["r"].Should().Be(1); vv["s"].Should().Be(0); }
public async Task <OkResult> Put(HttpRequestMessage req, string key, [FromBody] JToken value) { VersionVector context = GetContext(req); await _node.PutAsync(key, value, context); return(Ok()); }
public void Ids_should_return_set_of_identifiers() { var vv = new VersionVector(new[] { new CausalEvent("r", 1), new CausalEvent("s", 1) }); var ids = vv.Ids(); ids.Should().Contain(new[] { "r", "s" }); ids.Should().HaveCount(2); ids.Should().OnlyHaveUniqueItems(); }
private void CheckThunkFor(VersionVector vc1, VersionVector vc2, Action <VersionVector, VersionVector> thunk, int times) { var vcc1 = CopyVectorClock(vc1); var vcc2 = CopyVectorClock(vc2); for (var i = 0; i < times; i++) { thunk(vcc1, vcc2); } }
VersionVector GetContext(HttpRequestMessage request) { VersionVector vv = null; string headerValue = request.GetHeader("X-Context"); if (!string.IsNullOrEmpty(headerValue)) { vv = VersionVector.FromContextString(headerValue); } return(vv); }
public void ReplicatedDataSerializer_should_serialize_VersionVector() { CheckSerialization(VersionVector.Empty); CheckSerialization(VersionVector.Create(_address1, 1)); CheckSerialization(VersionVector.Empty.Increment(_address1).Increment(_address2)); var v1 = VersionVector.Empty.Increment(_address1).Increment(_address1); var v2 = VersionVector.Empty.Increment(_address2); CheckSameContent(v1.Merge(v2), v2.Merge(v1)); }
internal VersionVector CopyVectorClock(VersionVector vc) { var versions = ImmutableDictionary <UniqueAddress, long> .Empty; var enumerator = vc.VersionEnumerator; while (enumerator.MoveNext()) { var nodePair = enumerator.Current; versions = versions.SetItem(nodePair.Key, nodePair.Value); } return(VersionVector.Create(versions)); }
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 Setup() { var(vcBefore, nodes) = CreateVectorClockOfSize(ClockSize); _vcBefore = vcBefore; _nodes = nodes; _firstNode = nodes.First(); _lastNode = nodes.Last(); _middleNode = nodes[ClockSize / 2]; _vcBaseLast = vcBefore.Increment(_lastNode); _vcAfterLast = _vcBaseLast.Increment(_firstNode); _vcConcurrentLast = _vcBaseLast.Increment(_lastNode); _vcBaseMiddle = _vcBefore.Increment(_middleNode); _vcAfterMiddle = _vcBaseMiddle.Increment(_firstNode); _vcConcurrentMiddle = _vcBaseMiddle.Increment(_middleNode); }
public void Join_should_return_a_clock_that_describes_the_collective_causal_past() { var kernel = new DvvKernel(); var s1 = new Siblings { { new JObject(new JProperty("v", 1)), "((r,1),{})" }, { new JObject(new JProperty("v", 2)), "((r,2),{(s,2)})" } }; VersionVector vv = kernel.Join(s1); vv.Events.Should().Contain(new[] { new KeyValuePair <string, long>("r", 2), new KeyValuePair <string, long>("s", 2) }); }
public void VersionVector_ConstructorAndEquality() { var items = new [] { new VectorItem <int>(A, 4), new VectorItem <int>(B, 6), }; var a = new VersionVector(items); Assert.IsTrue(a.SequenceEqual(items)); var b = new VersionVector( new VectorItem <int>(A, 4), new VectorItem <int>(B, 6)); Assert.AreEqual(a, b); }
public void DataEnvelopes_with_identical_content_must_match() { var g1 = GCounter.Empty.Increment(node1, 1); var d1 = new DataEnvelope(g1); var d1a = new DataEnvelope(g1); var g2 = GCounter.Empty.Increment(node2, 2); var d2 = new DataEnvelope(g2); d1.Should().NotBe(d2); d1a.Should().Be(d1); d1a.GetHashCode().Should().Be(d1.GetHashCode()); // add some delta versions var d1b = d1.WithDeltaVersions(VersionVector.Create(node1, 1)); d1.Should().NotBe(d1b); d1.GetHashCode().Should().NotBe(d1b.GetHashCode()); // add identical delta version on different instance var d1b2 = d1.WithDeltaVersions(VersionVector.Create(node1, 1)); d1b2.Should().Be(d1b); d1b2.GetHashCode().Should().Be(d1b.GetHashCode()); // merge with another instance var d2b1 = d1b2.Merge(d2); d2b1.Should().NotBe(d1b2); d2b1.GetHashCode().Should().NotBe(d1b2.GetHashCode()); // prune var d3 = d2b1.WithPruning( ImmutableDictionary <UniqueAddress, IPruningState> .Empty.Add(node2, new PruningPerformed(obsoleteTime))); d3.Should().NotBe(d2b1); d3.GetHashCode().Should().NotBe(d2b1.GetHashCode()); // create identical instance var d3b = d2b1.WithPruning( ImmutableDictionary <UniqueAddress, IPruningState> .Empty.Add(node2, new PruningPerformed(obsoleteTime))); d3.Should().Be(d3b); d3.GetHashCode().Should().Be(d3b.GetHashCode()); }
public static Proto.Msg.VersionVector VersionVectorToProto(VersionVector versionVector) { var b = new Proto.Msg.VersionVector(); using (var enumerator = versionVector.VersionEnumerator) { while (enumerator.MoveNext()) { var current = enumerator.Current; b.Entries.Add(new Proto.Msg.VersionVector.Types.Entry() { Node = UniqueAddressToProto(current.Key), Version = current.Value }); } } return(b); }
public void Event_should_generate_a_new_clock_to_represent_a_new_version() { var kernel = new DvvKernel(); var context = new VersionVector(new[] { new CausalEvent("s", 2), new CausalEvent("r", 2), }); var s1 = new Siblings { { new JObject(new JProperty("v", 1)), "((r,1),{})" }, { new JObject(new JProperty("v", 2)), "((r,2),{(s,2)})" } }; DottedVersionVector dvv = kernel.Event(context, s1, "r"); dvv.ToString().Should().Be("((r,3),{(r,2),(s,2)})"); }
public async Task <IHttpActionResult> Get(HttpRequestMessage req, string key) { try { Siblings siblings = await _node.GetAsync(key); // Only return the values (strip-off the clocks) List <JToken> values = siblings.Select(s => s.Value).ToList(); HttpResponseMessage res = req.CreateResponse(values); VersionVector context = _node.Kernel.Join(siblings); res.Headers.Add("X-Context", context.ToContextString()); return(ResponseMessage(res)); } catch (KeyNotFoundException e) { return(NotFound()); } }
public void Discard_should_remove_obsolete_siblings() { var kernel = new DvvKernel(); var s1 = new Siblings { { new JObject(new JProperty("v", 1)), "((r,1),{})" }, { new JObject(new JProperty("v", 2)), "((r,2),{})" } }; // This is the context we'd receive representing ((r,3),{(r,1)}) : v3 var context = new VersionVector(new CausalEvent("r", 1)); Siblings siblings = kernel.Discard(s1, context); // Assert siblings.Should().HaveCount(1); siblings.Should().NotContain(x => x.Clock.Equals(DottedVersionVector.Parse("((r,1),{})"))); siblings.Should().Contain(x => x.Clock.Equals(DottedVersionVector.Parse("((r,2),{})"))); }
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 ToString_should_handle_multiple_events() { var vv = new VersionVector(new[] { new CausalEvent("r", 1), new CausalEvent("s", 1) }); vv.ToString().Should().Be("{(r,1),(s,1)}"); }
/// <summary> /// Wraps the value in a <see cref="Gossip.VecVersioned{T}"/> with the given version vector. /// </summary> public static VecVersioned <T> Version <T>(this T val, VersionVector version = null) => new VecVersioned <T> { Value = val, Version = version ?? new VersionVector() };
/// <summary> /// The <see cref="DataEnvelope"/> wraps a data entry and carries state of the pruning process for the entry. /// </summary> /// <param name="data">TBD</param> /// <param name="pruning">TBD</param> /// <param name="deltaVersions"></param> internal DataEnvelope(IReplicatedData data, ImmutableDictionary <UniqueAddress, IPruningState> pruning = null, VersionVector deltaVersions = null) { Data = data; Pruning = pruning ?? ImmutableDictionary <UniqueAddress, IPruningState> .Empty; DeltaVersions = deltaVersions ?? VersionVector.Empty; }
public void Indexer_should_return_zero_for_missing_id() { var vv = new VersionVector(new CausalEvent("r", 1)); vv["x"].Should().Be(0); }
public void Parse_should_return_empty_vv_when_value_is_null_or_whitespace(object value) { var vv = VersionVector.Parse((string)value); vv.Events.Should().HaveCount(0); }
public static Version <Actor, K, V> ToVersion <ConflictV, OrdActor, Actor, K, V>(this VersionVector <ConflictV, OrdActor, TLong, Actor, long, V> vector, K key) where OrdActor : struct, Ord <Actor> where ConflictV : struct, Conflict <V> => vector.Value.IsSome ? new VersionValueVector <ConflictV, OrdActor, Actor, K, V>(key, vector) : new VersionDeletedVector <ConflictV, OrdActor, Actor, K, V>(key, vector);
/// <summary> /// Register a write from any actor /// </summary> /// <param name="actor">Actor that did the write operation</param> /// <param name="value">Value that the actor wrote</param> /// <param name="vector">The vector of the actor</param> /// <returns></returns> public VersionVector <ConflictA, OrdActor, NumClock, Actor, Clock, A> Put(VersionVector <ConflictA, OrdActor, NumClock, Actor, Clock, A> version) => VectorClock.relation(Vector, version.Vector) switch {
public void Indexer_should_return_counter_for_id_regardless_of_case() { var vv = new VersionVector(new CausalEvent("r", 1)); vv["R"].Should().Be(1); }
internal DataEnvelope WithDeltaVersions(VersionVector deltaVersions) => new DataEnvelope(Data, Pruning, deltaVersions);
public void Parse_should_return_empty_vv_when_no_causal_events() { var vv = VersionVector.Parse("{}"); vv.Events.Should().HaveCount(0); }