/// <summary> /// Is this Reflexive, AntiSymetic, and Transitive? Compare two VectorClocks, /// the outcomes will be one of the following: -- Clock 1 is BEFORE clock 2 /// if there exists an i such that c1(i) <= c(2) and there does not exist a j /// such that c1(j) > c2(j). -- Clock 1 is CONCURRANT to clock 2 if there /// exists an i, j such that c1(i) < c2(i) and c1(j) > c2(j) -- Clock 1 is /// AFTER clock 2 otherwise /// </summary> /// <param name="v1">The first VectorClock</param> /// <param name="v2">The second VectorClock</param> /// <returns>Whether the change occured before, after or concurrently</returns> public static Occured Compare(VectorClock v1, VectorClock v2) { if (v1 == null || v2 == null) throw new ArgumentException("Can't compare null vector clocks!"); // We do two checks: v1 <= v2 and v2 <= v1 if both are true then bool v1Bigger = false; bool v2Bigger = false; int p1 = 0; int p2 = 0; while (p1 < v1.versions.Count && p2 < v2.versions.Count) { ClockEntry ver1 = v1.versions[p1]; ClockEntry ver2 = v2.versions[p2]; if (ver1.NodeId == ver2.NodeId) { if (ver1.Version > ver2.Version) v1Bigger = true; else if (ver2.Version > ver1.Version) v2Bigger = true; p1++; p2++; } else if (ver1.NodeId > ver2.NodeId) { // since ver1 is bigger that means it is missing a version that ver2 has v2Bigger = true; p2++; } else { // this means ver2 is bigger which means it is missing a version ver1 has v1Bigger = true; p1++; } } // Check for left overs if (p1 < v1.versions.Count) v1Bigger = true; else if (p2 < v2.versions.Count) v2Bigger = true; // This is the case where they are equal, return BEFORE arbitrarily if (!v1Bigger && !v2Bigger) return Occured.Before; // This is the case where v1 is a successor clock to v2 else if (v1Bigger && !v2Bigger) return Occured.After; // This is the case where v2 is a successor clock to v1 else if (!v1Bigger && v2Bigger) return Occured.Before; // This is the case where both clocks are parallel to one another else return Occured.Concurrently; }
public VectorClock Merge(VectorClock clock) { VectorClock newClock = new VectorClock(); int i = 0; int j = 0; while (i < this.versions.Count && j < clock.versions.Count) { ClockEntry v1 = this.versions[i]; ClockEntry v2 = clock.versions[j]; if (v1.NodeId == v2.NodeId) { newClock.versions.Add(new ClockEntry(v1.NodeId, (short)Math.Max(v1.Version, v2.Version))); i++; j++; } else if (v1.NodeId < v2.NodeId) { newClock.versions.Add(v1.Clone()); i++; } else { newClock.versions.Add(v2.Clone()); j++; } } // Okay now there may be leftovers on one or the other list remaining for (int k = i; k < this.versions.Count; k++) newClock.versions.Add(this.versions[k].Clone()); for (int k = j; k < clock.versions.Count; k++) newClock.versions.Add(clock.versions[k].Clone()); return newClock; }