• No results found

Preliminaries We define the timestamp of operationo, denoted ts(o), as follows. If o is a put, thents(o) is the value of client’s variable ts when its assignment completes at line 36, Alg. 3. Else, ifo is a get, then ts(o) equals the value of ts when client executes line 57, Alg. 3 (i.e., when get returns). We further say that an operationo precedes operation o′, ifo completes beforeo′is invoked. Without loss of generality, we assume that all operations access the same keyk.

Lemma D.2.1 (Partial Order). Leto and o′be two get or put operations with timestampsts(o) and ts(o′), respectively, such that o precedes o′. Then ts(o) ≤ ts(o′), and if o′ is a put then ts(o) < ts(o′).

Proof. In the following, prefixo.RM DS denotes calls to RMDS within operation o (and similarly foro′). Leto′be a put (resp. get) operation.

Case 1 (o is a put): then o.RM DS.condUpdate(o.md) at line 46, Alg. 3, precedes (all possible calls to) o′.RM DS.read() at line 52, Alg. 3 (resp., line 34, Alg. 3). By linearizability of RMDS (and RMDS functionality in Alg. 1) and definition of operation timestamps, it follows thatts(o′) ≥ ts(o). Moreover, if o′ is a put, thents(o′) > ts(o) because ts(o′) is obtained from incrementing the timestampts returned by o′.RM DS.read() at line 34, Alg. 3, where ts ≥ ts(o).

Case 2 (o is a get): then since all possible calls to o′.RM DS.read() at line 52 (resp. 34) follow the latest call ofo.RM DS.read() in line 52, by Alg. 1 and by linearizability of RMDS, it follows thatts(o′) ≥ ts(o). If o′ is a put, thents(o′) > ts(o), similarly to Case 1.

Lemma D.2.2 (Unique puts). Ifo and o′are two put operations, thents(o) ̸= ts(o′).

Proof. By lines 34-36, Alg. 3, RMDS functionality (Alg. 1) and the fact that a given client does not invoke concurrent operations on the same key.

Lemma D.2.3 (Integrity). Letrd be a get(k) operation returning value v ̸= ⊥. Then there exists a single put operationwr of the form put(k, v) such that ts(rd) = ts(wr).

Proof. Sincerd returns v and has a timestamp ts(rd), rd receives v in response to get(k|ts(rd)) from some cloudCi. Suppose for the purpose of contradiction thatv is never written by a put. Then, by the collision resistance ofH(), the check at line 57 does not pass and rd does not returnv. Therefore, we conclude that some operation wr issues put (k|ts(rd)) to Ciin line 40. Hence,ts(wr) = ts(rd). Finally, by Lemma D.2.2 no other put has the same timestamp.

Proof. Letex be an execution of Algorithm 3. By Lemma D.2.3 the timestamp of a get either has been written by some put or the get returns⊥. With this in mind, we first construct ex′ fromex by completing all put operations of the form put (k, v), where v has been returned by some complete get operation. Then we construct a sequential permutationπ by ordering all operations inex′, except get operations that return⊥, according to their timestamps and by placing all get operations that did not return⊥ immediately after the put operation with the same timestamp. The get operations that did return⊥ are placed in the beginning of π.

Towards linearizability, we show that a getrd in π always returns the value v written by the latest preceding put which appears before it inπ, or the initial value of the register ⊥ if there is no such put. In the latter case, by constructionrd is ordered before any put in π. Otherwise,v ̸= ⊥ and by Lemma D.2.3 there is a put (k, v) operation, with the same timestamp, ts(rd). In this case, put (k, v) appears before rd in π, by construction. By Lemma D.2.2, other put operations inπ have a different timestamp and hence appear in π either before put (k, v) or afterrd.

It remains to show thatπ preserves real-time order. Consider two complete operations o ando′inex′ such thato precedes o′. By Lemma D.2.1,ts(o′) ≥ ts(o). If ts(o′) > ts(o) then o′ appears aftero in π by construction. Otherwise ts(o′) = ts(o) and by Lemma D.2.1 it follows thato′is a get. Ifo is a put, then o′ appears aftero since we placed each read after the put with the same timestamp. Otherwise, ifo is a get, then it appears before o′ as inex′.

Theorem D.2.5 (Availability). Hybris put calls are wait-free, whereas Hybris get calls are finite- write terminating.

Proof. The wait freedom of Hybris put operations follows from: a) the assumption of using 2f + 1 clouds out of which at most f may be faulty (and hence the wait statement at line 45, Alg. 3 is non-blocking), and b) wait-freedom of calls to RMDS (hence, calls to RMDS at lines 34 and 46, Alg. 3 return).

We prove finite-write termination of get by contradiction. Assume there is a finite number of writes to keyk in execution ex, yet that there is a get(k) operation rd by a correct client that never completes. LetW be the set of all put operations in ex, and let wr be the put operation with maximum timestamptsmaxinW that completes the call to RMDS at line 46, Alg. 3. We distinguish two cases: (i)rd invokes an infinite number of recursive get calls (in line 61, Alg 3), and (ii)rd never passes the check at line 57, Alg. 3.

In case (i), there is a recursive get call inrd, invoked after wr completes conditional update to RMDS. In this get call, the client does not execute line 61, Alg 3, by definition ofwr and specification ofRM DS.condUpdate in Alg. 1 (as there is no notify for a ts > tsmax). A contradiction.

In case (ii), notice that keyk|tsmaxis never garbage collected atf + 1 clouds that constitute cloudList at line 46, Alg. 3 in wr. Since rd does not terminate, it receives a notification at

line 59, Alg. 3 with timestamptsmaxand reiterates get. In this iteration of get, the timestamp ofrd is tsmax. AscloudList contains f + 1 clouds, including at least one correct cloud Ci, and asCiis eventually consistent,Cieventually returns valuev written by wr to a get call. This valuev passes the hash check at line 57, Alg. 3 and rd completes. A contradiction.