15 Vector Time
Site identifiers
It is assumed that each site is uniquely identified with a site identifier. Let S be the set of site identifiers.
Vector times
Let ℕ be the set of natural numbers (i.e. non-negative integers). A vector time v is a map
v : S → ℕ
Definition: The vector time v∅ satisfies ∀s ∈ S, v∅(s) = 0.
Subset, intersection and union on vector times
Definition: For vector times v1,v2, v = v1 ↑ v2 denotes the vector time satisfying
∀s ∈ S, v(s) = max( v1(s), v2(s) )
Definition: For vector times v1,v2, v = v1 ↓ v2 denotes the vector time satisfying
∀s ∈ S, v(s) = min( v1(s), v2(s) )
Definition: For vector times v1,v2, we write v1 ≤ v2 if ∀ s ∈ S, v1(s) ≤ v2(s)
Note
- ∀v, v ↓ v = v
- ∀v, v ↑ v = v
- ∀v1,v2, v1 ↓ v2 = v2 ↓ v1
- ∀v1,v2, v1 ↑ v2 = v2 ↑ v1
- ∀v1,v2,v3, (v1 ↓ v2) ↓ v3 = v1 ↓ (v2 ↓ v3)
- ∀v1,v2,v3, (v1 ↑ v2) ↑ v3 = v1 ↑ (v2 ↑ v3)
- ∀v1,v2,v3, (v1 ↓ v2) ↑ v3 = (v1 ↑ v3) ↓ (v2 ↑ v3)
- ∀v1,v2,v3, (v1 ↑ v2) ↓ v3 = (v1 ↓ v3) ↑ (v2 ↓ v3)
- ∀v, v∅ ≤ v
- ∀v, (v∅ ↑ v) = v
- ∀v, (v∅ ↓ v) = v∅
- ∀v1,v2, (v1 ↓ v2) ≤ v1
- ∀v1,v2, v1 ≤ (v1 ↑ v2)
- ∀v, v ≤ v
- v1 ≤ v2 & v2 ≤ v1 ⇒ v1 = v2
- v1 ≤ v2 & v2 ≤ v3 ⇒ v1 ≤ v3
- v1 ≤ v & v2 ≤ v ⇒ (v1 ↑ v2) ≤ v
Identification of atomic operations
Each atomic operation is assumed to be generated at exactly one site. Each site independently assigns a zero based sequence number t to each atomic operation generated at that site.
Definition: Let op(s,t) denote the atomic operation generated at site s with sequence number t.
Extent of a vector time
Definition: The extent of vector time v is the set of atomic operations denoted by χ(v) satisfying
χ(v) = { op(s,t) | t < v(s) }
This definition relates to the whole purpose for vector times - for a given atomic operation O, we describe its execution context using the vector time v satisfying ec(O) = χ(v). This is a summary of the complete set of atomic operations that have been executed prior to O.
Note the following
- χ(v2) \ χ(v1) = { op(s,t) | v1(s) ≤ t < v2(s) }
- χ(v∅) = {}
- χ(v1 ↑ v2) = χ(v1) ∪ χ(v2)
- χ(v1 ↓ v2) = χ(v1) ∩ χ(v2)
- v1 ≤ v2 ⇔ χ(v1) ⊆ χ(v2)
Precedes relation on atomic operations
Definition: Let Ob be an atomic operation originally generated on site B. We write Oa → Ob if Oa was executed on B before Ob was generated on B.
Definition: Oa and Ob are concurrent (written Oa || Ob) if Oa ≠ Ob and neither Oa → Ob nor Ob → Oa.
Definition: The system enforces Causality Preservation if
Oa → Ob ⇒ Oa is executed before Ob on all sites
Proof:
Let Oc be generated on site C.
Ob → Oc so Ob was executed on site C before Oc was generated.
By causality preservation and Oa → Ob, we know that Oa is executed before Ob at all sites, and in particular at site C.
Therefore Oa was executed at site C before Oc was generated at site C, so we deduce Oa → Oc.
Execution context of an atomic operation
Definition: Vector time gc(O) denotes the generation context of atomic operation O such that χ(gc(O)) is the set of operations that had been executed prior to the original generation of O.
It follows from the definitions that
Oa → Ob ⇔ Oa ∈ χ(gc(Ob))
Definition: Vector time ec(O) denotes the execution context of atomic operation O such that χ(ec(O)) is the set of operations that have been performed prior to execution of O.
Claim: Causality preservation ⇒ gc(O) ≤ ec(O)
Proof:
⇔ Oa ∈ χ(gc(Ob))
⇒ Oa ∈ χ(ec(Ob))
It is assumed that a site generates operations in the context of previously generated operations at that site. Formally this means
t1 < t2 ⇔ op(s,t1) → op(s,t2)
Proof:
if Oa.t < Ob.t
⇒ contradiction to Oa || Ob
⇒ contradiction to Oa || Ob
Oa = Ob (because Oa.s = Ob.s and Oa.t = Ob.t)
⇒ contradiction (because Oa || Ob ⇒ Oa ≠ Ob)
Aggregate intersection and union on sets of vector times
Definition: For set of vector times V, v = ↓(V) denotes the vector time satisfying
∀s ∈ S, v(s) = min { v'(s) | v' ∈ V }
Definition: For set of vector times V, v = ↑ (V) denotes the vector time satisfying
∀s ∈ S, v(s) = max { v'(s) | v' ∈ V }
Causally valid vector times
Definition. Vector time v is causally valid if
O1 ∈ χ(v), O2 ∉ χ(v) ⇒ ¬ (O2 → O1)
or equivalently
O2 ∈ χ(v) and O1 → O2 ⇒ O1 ∈ χ(v)
Taking the negation, vector time v breaks causality if
∃operations O1,O2 st O1 ∉ χ(v) and O2 ∈ χ(v) and O1 → O2
Claim: Causality preservation ⇒ for every atomic operation, ec(O) is causally valid
Each site is assumed to have a linear sequence of operations that have been executed at that site called a history buffer. For a given site, let vh denote the vector time whose extent describes the current contents of the history buffer.
Let v be a causally valid vector time satisfying v ≤ vh. It can be proven that it is possible to transpose adjacent, concurrent operations within the history buffer to separate it into a prefix and suffix such that the set of operations in the prefix equals χ(v) and the suffix corresponds to χ(vh) \ χ(v). Furthermore no atomic operation in the suffix causally precedes an atomic operation in the prefix.
More specifically it won't be necessary to ever transpose a pair of contextually serialised operations [O1, O2] where O1 → O2.
Proof:
Let O1,O2 be operations with O2 ∈ χ(v) and O1 → O2
Need to show O1 ∈ χ(v)
O2 ∈ χ(v1) (because O2 ∈ χ(v) = χ(v1) ∩ χ(v2))
O2 ∈ χ(v2) (because O2 ∈ χ(v) = χ(v1) ∩ χ(v2))
O1 ∈ χ(v1) (because O2 ∈ χ(v1) and v1 is causally valid)
O1 ∈ χ(v2) (because O2 ∈ χ(v2) and v2 is causally valid)
O1 ∈ χ(v1) ∩ χ(v2) (because O1 ∈ χ(v1) and O1 ∈ χ(v2))
O1 ∈ χ(v) (because χ(v) = χ(v1) ∩ χ(v2))
Proof:
Let O1,O2be operations with O2 ∈ χ(v) and O1 → O2
Need to show O1 ∈ χ(v)
if O2 ∈ χ(v1)
O1 ∈ χ(v) (because χ(v1) ⊆ χ(v1) ∪ χ(v2) = χ(v))
O1 ∈ χ(v2) (because O2 ∈ χ(v2) and v2 is causally valid)
O1 ∈ χ(v) (because χ(v2) ⊆ χ(v1) ∪ χ(v2) = χ(v))
It follows therefore that
∀ v ∈ V, v is causally valid ⇒ ↓(V) and ↑(V) are causally valid
Formulation that allows more sites over time
Usually a vector time is defined with respect to a fixed number of sites in the system. In practice we need a definition that naturally allows for new sites to be added over time.
Definition: A vector time v is a set of (s,t) values where s is a site identifier and t is a positive integer, and the s values are never repeated. We write sites(v) for the set of s values in v. We write v(s) to retrieve t for given s. v(s) is defined to be zero for s ∉ sites(v)
It is straightforward to adjust the previous definitions to avoid reference to some fixed set of states S.
v1 ≤ v2 ⇔ ∀ s ∈ sites(v1), v1(s) ≤ v2(s)
For vector times v1,v2, v = v1 ↑ v2 denotes the vector time satisfying
sites(v) = sites(v1) ∪ sites(v2)
∀s ∈ sites(v), v(s) = max( v1(s), v2(s) )
For vector times v1,v2, v = v1 ↓ v2 denotes the vector time satisfying
sites(v) = sites(v1) ∩ sites(v2)
∀s ∈ sites(v), v(s) = min( v1(s), v2(s) )
Delta vector times
A delta vector time represents a change to a vector time which can be useful to reduce network bandwidth.
Definition: A delta vector time Δv = v2-v1 where v1 and v2 are vector times is defined as follows
Δv = { (s,t) ∈ v2 | t ≠ 1(s) } ∪ { (s,0) | s ∈ sites(1) \ sites(v2) }
and sites(Δv) = { s | (s,t) ∈ Δv }
We define v1+Δv as follows.
v1+ Δv = { (s,t) ∈ v1| s ∉ sites(Δv) } ∪ { (s,t) ∈ Δv | t > 0 }
Proof:
(⊆)
so (s,t) ∈ ( { (s,t) ∈ v1| s ∉ sites(v2-v1) } ∪ { (s,t) ∈ (v2-v1) | t > 0 } )
if (s,t) ∈ (v2-v1) and t > 0
s ∈ sites(v1) (because (s,t) ∈ v1)
t > 0 (because (s,t) ∈ v1)
(s,t) ∉ (v2-v1)
if s ∉ sites(v2)
s ∈ sites(v2-v1) ⇒ contradiction
Suppose v1(s) = t ≠ v2(s)
so s ∈ sites(v2-v1) ⇒ contradiction
so (s,t) ∈ v2
if t ≠ v1(s)
t > 0 (because (s,t) ∈ v2)
(s,t) ∈ v1 + (v2-v1)
so (s,t) ∈ v1
Suppose s ∈ sites(v2-v1)
⇒ contradiction
So (s,t) ∈ { (s,t) ∈ v1 | s ∉ sites(v2-v1) }
So (s,t) ∈ v1+( v2-v1)
We can define addition of delta vector times Δv = Δv1+ Δv2, satisfying (for any given vector time v)
(v + Δv1) + Δv2 = v + (Δv1+ Δv2)
Note that addition of delta vector times doesn’t commute.
It can be show that
Δv1+ Δv2 = Δv2∪ { (s,t) ∈ Δv1| s ∉ sites(Δv2) }
Vector time implementation
To facilitate fast look up of a vector time, a suitable implementation is a red-black tree. However a delta vector time has no need for fast look up, and therefore may be more efficiently stored using a variable size array of (s,t) pairs.
We can define an add method on a vector time in pseudo code as follows
v.add(s,t)
{
if (v.hasentry(s))
{
v.remove(s);
}
if (t > 0)
{
v.insert(s,t);
}
}
Applying a delta to a vector time simply involves calling add(s,t) for each (s,t) in the delta.
We can define an add method on a delta vector time in pseudo code as follows
Δv.add(s,t)
{
if (Δv.hasentry(s))
{
Δv.remove(s);
}
Δv.insert(s,t);
}
This may lead to a delta that has more (s,t) entries that it needs - because it doesn’t check for redundancy w.r.t the original vector time to which the delta applies.
References
[1]
Time, clocks, and the ordering of events in a distributed system
Communications of the ACM 21 (7): 558-565.
Leslie Lamport (1978).
TVectorTime.h in cxOT
Source: Ceda/cxOT/TVectorTime.h