úÎ?ç9lw      !"#$%&'()*+,-./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 ijklmnopqrstuvNoneDRwxywwxyw4None9:;IGet 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.)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.         SafeA 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 z , Semilattice defines this laws:  commutativity x { y == y { x idempotency x { x == xJust (), specialized to .6SafeDRSafeConstruct new valueSafe Grow-only set update!initialization !"# !" !" !"#Safe*$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 = |7. 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()*+%&'()%&()'%&'()*+None#:DR..Last write wins. Assuming timestamp is unique.2Initialize state3 Change state4 Query state6(Merge by choosing more recent timestamp. ./012345678./01234./01234./012345678 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 counter@Increment counterA Initial state :;<=>? replica id@ replica idABC:;<=>?@A:;<=A>?@:;<=>?@ABC None #:<=?DRF: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 . J up1 up2 ==>  (I up1 . I up2 $ s) ==  (I up2 . I up1 $ s) !Idempotency doesn't need to hold.GPrecondition for HB. Calculates if the operation is applicable to the current state.HLGenerate an update to the local and remote replicas. Doesn't have sense if G is false.May or may not use clock.ICApply an update to the payload. An invalid update must be ignored.}2TODO(cblp, 2017-09-29) import from lattices >= 1.6J*Not comparable, i. e. ¬(a "d b) "' ¬(b "d a).FGHI}JFHIGJFGHIJFGHI}J None9;<=DRQ*Empty order, allowing arbitrary reordering KLMNOP~QRSKLMNOPNOKLMPKLMNOP~QRS None9;<=DR\ query lookupYZ[\]^_YZ[\YZ[\YZ[\]^_ None #9;<=DRbcdef./01bc./01bcbcdefNone#<=DRp query lookup ijklmnopqrs IHijklmnop lmnijkopHIijklmnopqrs !"#$%&'()*+,-./012.345562.789:;<2=.>?@AB C C D E . F 6 2 G H I J K L M N O P Q R S S 2 T U V W X Y Z [ \ \ 2 ] ^ _ ` a b c c d e f g hi\jkkl2]mnopqrstuvw x yzcrdt-1.0-DAo34DUz97c2vc8iHGeiwY CRDT.Cv.Max LamportClockData.Semilattice Data.Observe CRDT.Cv.GSetCRDT.CvCRDT.Cv.GCounter CRDT.Cv.LWWCRDT.Cv.PNCounterCRDT.CmCRDT.Cm.Counter CRDT.Cm.GSet CRDT.Cm.LWW CRDT.Cm.TPSetLens.Micro.Extra Semigroup<>LWWbaseData.SemigroupgetMaxMaxProcessClock newTimestamp TimestampPidTimebarrierrunLamportClock runProcess$fClockReaderT $fEnumPid$fEqPid$fOrdPid $fShowPid $fEqTimestamp$fOrdTimestamp$fShowTimestamp SemilatticemergeObserveObservedobservepointquery$fSemilatticeMaxGSetaddinitial$fSemilatticeSetCvRDTGCounter increment$fSemilatticeGCounter$fSemigroupGCounter $fEqGCounter$fShowGCounter timestampvalueassign$fSemilatticeLWW$fSemigroupLWW$fOrdLWW$fEqLWW $fShowLWW PNCounterpositivenegative decrement$fSemilatticePNCounter$fSemigroupPNCounter $fEqPNCounter$fShowPNCounterCmRDTupdateAtSourcePreupdateAtSourceupdateDownstream concurrent CounterOp Increment DecrementCounter$fPartialOrdCounterOp$fObserveCounter $fCmRDTCounterCounterOpCounterOp $fShowCounter$fBoundedCounterOp$fEnumCounterOp $fEqCounterOp$fShowCounterOpAddlookup$fPartialOrdAdd $fObserveSet$fCmRDTSetAddAdd$fEqAdd $fShowAddAssign $fObserveLWW$fCmRDTLWWAssignLWW$fPartialOrdLWW $fEqAssign $fShowAssignTPSetOpRemoveTPSetpayload$fPartialOrdTPSetOp$fObserveTPSet$fCmRDTTPSetTPSetOpTPSetOp $fShowTPSet $fEqTPSetOp $fShowTPSetOp<<+= $fAtEnumMap $fIxedEnumMapGHC.Baseid comparableopToFunc