public static bool HappensAfter(VectorClock first, VectorClock second) { // Create immutable other to protect from concurrent accesses ImmutableVectorClock immutableFirst = first.ToImmutable(); ImmutableVectorClock immutableSecond = second.ToImmutable(); // Get all possible ids ImmutableHashSet <string> firstIds = immutableFirst.Ids; ImmutableHashSet <string> secondIds = immutableSecond.Ids; HashSet <string> allIds = new HashSet <string>(firstIds); allIds.UnionWith(secondIds); // For all ids, at least one has to be greater than // other and none can be less bool oneGreater = false; foreach (string id in allIds) { int firstClock = immutableFirst[id]; int secondClock = immutableSecond[id]; if (firstClock > secondClock) { oneGreater = true; } else if (firstClock < secondClock) { return(false); } } return(oneGreater); }
public void Merge(VectorClock other) { // Create immutable other to protect from concurrent accesses ImmutableVectorClock immutableOther = other.ToImmutable(); ImmutableHashSet <string> secondIds = immutableOther.Ids; // Dont let concurrent updates while merging lock (this) { // Get all possible ids HashSet <string> allIds = new HashSet <string>(vc.Keys); allIds.UnionWith(secondIds); foreach (string id in allIds) { int otherClock = immutableOther[id]; // Add other value if not there or // update with max between both values vc.AddOrUpdate(id, otherClock, (key, prev) => Math.Max(prev, otherClock)); } // Invalidate immutable this immutableThis = null; } }
public void Increment(string serverId) { lock (this) { vc.AddOrUpdate(serverId, 1, (key, prev) => prev + 1); // Invalidate immutable this immutableThis = null; } }
private VectorClock BuildGrpcClock(CausalConsistency.ImmutableVectorClock vectorClock) { (IList <string> serverIds, IList <int> clocks) = CausalConsistency.VectorClocks.ToIdsAndClocksList(vectorClock); return(new VectorClock { ServerIds = { serverIds }, ServerClocks = { clocks } }); }
public override async Task <WriteResponse> Write(WriteRequest request, ServerCallContext context) { CausalConsistency.ImmutableVectorClock timestamp = await dispatcher.OnWrite(ParseWriteRequest(request)); return(new WriteResponse { Timestamp = BuildGrpcClock(timestamp) }); }
public override ImmutableVectorClock ToImmutable() { lock (this) { if (immutableThis == null) { immutableThis = ImmutableVectorClock.CopyOf(this); } } return(immutableThis); }
public static (IList <string>, IList <int>) ToIdsAndClocksList( ImmutableVectorClock vectorClock) { IList <string> serverIds = new List <string>(); IList <int> clocks = new List <int>(); foreach ((string serverId, int serverClock) in vectorClock.Clocks) { serverIds.Add(serverId); clocks.Add(serverClock); } return(serverIds, clocks); }
public static ImmutableVectorClock FromIdsAndClocksList( IList <string> serverIds, IList <int> serverClocks) { IList <KeyValuePair <string, int> > clocks = new List <KeyValuePair <string, int> >(); for (int i = 0; i < serverIds.Count; i++) { clocks.Add(new KeyValuePair <string, int>( serverIds[i], serverClocks[i] )); } return(ImmutableVectorClock.FromClocks(clocks)); }
public CausalConsistency.ImmutableVectorClock Write( string partitionId, string objectId, string value, CausalConsistency.ImmutableVectorClock timestamp) { WriteRequest request = new WriteRequest { PartitionId = partitionId, ObjectId = objectId, ObjectValue = value, Timestamp = BuildGrpcClock(timestamp) }; WriteResponse response = client.Write( request, deadline: DateTime.UtcNow.AddSeconds(60)); return(BuildVectorClock(response.Timestamp)); }
public CausalConsistency.ImmutableVectorClock Read( string partitionId, string objectId, out string value, CausalConsistency.ImmutableVectorClock timestamp) { ReadRequest request = new ReadRequest { PartitionId = partitionId, ObjectId = objectId, Timestamp = BuildGrpcClock(timestamp) }; ReadResponse response = client.Read( request, deadline: DateTime.UtcNow.AddSeconds(60)); value = !response.Missing ? response.ObjectValue : null; return(BuildVectorClock(response.Timestamp)); }
public async Task BroadcastWrite( string partitionId, Broadcast.MessageId messageId, string key, string value, CausalConsistency.ImmutableVectorClock replicaTimestamp, string writeServerId, long timeout) { await client.BroadcastWriteAsync( new BroadcastWriteRequest { PartitionId = partitionId, MessageId = BuildMessageId(messageId), Key = key, Value = value, ReplicaTimestamp = BuildClock(replicaTimestamp), WriteServerId = writeServerId }, deadline : DateTime.UtcNow.AddMilliseconds(timeout)); }
public static bool Equal(VectorClock first, VectorClock second) { // Create immutable other to protect from concurrent accesses ImmutableVectorClock immutableFirst = first.ToImmutable(); ImmutableVectorClock immutableSecond = second.ToImmutable(); // Get all possible ids ImmutableHashSet <string> firstIds = immutableFirst.Ids; ImmutableHashSet <string> secondIds = immutableSecond.Ids; if (firstIds.Count != secondIds.Count) { return(false); } foreach (string id in firstIds) { if (immutableFirst[id] != immutableSecond[id]) { return(false); } } return(true); }