This is a simple implementation of the Vector Clock algorithm for Erlang. It supports dynamic addition and removal of actors in the system at runtime.
It should also be noted that total ordering has been hacked on top of the regular VC implementation. Each clock carries a timestamp that is used in the evc:compare/2 function. Compare operates as follows: If A doesn't descend from B and B doesn't descend from A, compare timestamps instead. This compare function is suitable for plugging into, for example, lists:sort/2.
Actor A
VC=evc:new(),
% A experiences an internal eventNewVC=evc:increment(VC),
% A sends a message to BB! {NewVC, "I am a happy message!"}Actor B
VC=evc:new(),
receive
{VCFromA, _Message} ->
% B experiences internal event due to receiving a messageInternalVC=evc:increment(VC),
% Merge the two VCs to get the new VC for BNewVC=evc:merge(InternalVC, VCFromA),
% Now, the VC from A is "older" compared to the current VC in Btrue=evc:descends(NewVC, VCFromA)
endM=evc:merge(evc:increment(a, evc:new(a)), evc:increment(b, evc:new(b))), % M is {1, 1} - 1 event in actor A and 1 event in actor BA=evc:increment(a, M),
timer:sleep(10),
B=evc:increment(b, M), % A is {2, 1} and B is {1, 2}. Neither descends from either, however timestamp from B is newerB2=evc:increment(b, B), % B2 is a direct descendant of Btimer:sleep(10),
C=evc:increment(c, evc:new(c)), % C is completely unrelated to all the above clocks. Again, timestamp will be used.C2=evc:increment(c, C),
[A, B, B2, C, C2] =lists:sort(funevc:compare/2, [C2, B, A, C, B2]))