úÎA?;mi      !"#$%&'()*+,-./0123456789:;<=>?@A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h Safe9:;Get another unique timestampºTimestamps are assumed unique, totally ordered, and consistent with causal order; i.e., if assignment 1 happened-before assignment 2, the former s timestamp is less than the latter s.iKey is  R. Non-present value is equivalent to 0. TODO(cblp, 2017-09-28) Use bounded-intmap Unique process identifier &XXX Make sure all subsequent calls to 1 return timestamps greater than all prior calls.i j klm     i  j klmSafeA semilattice.EIt may be a join-semilattice, or meet-semilattice, it doesn't matter.#If it matters for you, use package lattices.In addition to n , Semilattice defines this laws:  commutativity x o y == y o x idempotency x o x == xJust ( ), specialized to .6SafeConstruct new valueSafe Grow-only setupdateinitializationSafe* 5State-based, or convergent (Cv) replicated data type.!Update is any function modifying state.GQuery function is not needed. State itself is exposed. In other words, query = p7. Some types may offer more convenient query functions.$Actually, a CvRDT is nothing more a .    Safe!Grow-only counter.#Increment counter$ Initial state%Get value from the state!"# replica id$%&'!"#$%!"$%#!"#$%&'Safe#*nPositive-negative counter. Allows incrementing and decrementing. Nice example of combining of existing CvRDT (!' in this case) to create another CvRDT..Get value from the state/Decrement counter0Increment counter1 Initial state *+,-./ replica id0 replica id123*+,-./01*+,-1./0*+,-./0123Safe #6:<=DR6:Operation-based, or commutative (Cm) replicated data type.Implementation;In Haskell, a CmRDT implementation consists of 3 types  a payload, an  operation (op ) and an update. PayloadInternal state of a replica. OperationUser's request to update.Update*Operation to be applied to other replicas.For many types  operation and update may be the same. But for i, for instance, this rule doesn't hold: user can request only value, and type attaches a timestamp to it.)Additional constraint  commutativity law(Concurrent updates are observed equally. " up1 up2 s . @ up1 up2 ==> observe (< up1 . < up2 $ s) == observe (< up2 . < up1 $ s) !Idempotency doesn't need to hold.:Precondition for ;B. Calculates if the operation is applicable to the current state.;LGenerate an update to the local and remote replicas. Doesn't have sense if : is false.May or may not use clock.<CApply an update to the payload. An invalid update must be ignored.='Extract user-visible value from payload>lPartial order for causal semantics. Values of some type may be ordered and causally-ordered different ways.@*Not comparable, i. e. ¬(a "d b) "' ¬(b "d a). 6789:;<=>?q@ 6978;<:=>?@ >?6789:;;<==@6 789:;;<==>?q@ Safe 9;<=DR[D*Empty order, allowing arbitrary reorderingABCDEABCABCABCDE Safe9;<=DRJKLMJKJKJKLM Safe#<=DR[PQRST<;PQRPQR;<PQRST Safe#:DRWChange state as CmRDT operationYBLast write wins. Assuming timestamp is unique. This type is both 6 and  .]Initialize state^dChange state as CvRDT operation. Current value is ignored, because new timestamp is always greater._ Query statec(Merge by choosing more recent timestamp.WXYZ[\]^_`abcde WXYZ\[]^_ YZ[\]^_WX WXYZ[\]^_`abcder !"#$%&'()*+,(-.//0,(12345567(80,9:;<=>?@ABCDEFG H I J K L M N O P * Q R S T U V Q W X Y Z [ \ \   ] ^ , _ ( ` a b c d e f g hijklm nopqcrdt-2.0-D6kcn8PF5NSJLK9JPTU5ku CRDT.Cv.Max LamportClockData.Semilattice CRDT.Cv.GSetCRDT.CvCRDT.Cv.GCounterCRDT.Cv.PNCounterCRDT.CmCRDT.Cm.Counter CRDT.Cm.GSet CRDT.Cm.TPSetCRDT.LWW Semigroup<> CRDT.Cm.LWWLWWbaseData.SemigroupgetMaxMaxProcessClock newTimestamp TimestampPidTimebarrierrunLamportClock runProcess$fClockReaderT$fEqPid$fOrdPid $fShowPid $fEqTimestamp$fOrdTimestamp$fShowTimestamp Semilatticemergepointquery$fSemilatticeMaxGSetaddinitial$fSemilatticeSetCvRDTGCounter increment$fSemilatticeGCounter$fSemigroupGCounter $fEqGCounter$fShowGCounter PNCounterpositivenegative decrement$fSemilatticePNCounter$fSemigroupPNCounter $fEqPNCounter$fShowPNCounterCmRDTOpPayloadViewupdateAtSourcePreupdateAtSourceupdateDownstreamview CausalOrdbefore concurrentCounter Increment Decrement$fCausalOrdCounter$fCmRDTCounter$fBoundedCounter $fEnumCounter $fEqCounter $fShowCounterAdd$fCausalOrdGSet $fCmRDTGSet$fEqGSet $fShowGSetTPSetRemove$fCausalOrdTPSet $fCmRDTTPSet $fEqTPSet $fShowTPSetAssignvalue timestampassign $fCmRDTLWW$fCausalOrdLWW$fSemilatticeLWW$fSemigroupLWW$fOrdLWW$fEqLWW $fShowLWW $fEqAssign $fShowAssign LamportTimeunPidpostIncrementAtlamportTimeFromListlamportTimeLookupGHC.Baseid comparable