!iZ      !"#$%&'()*+,-./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 i j k l m n o p q r s t u v w x y z { | } ~  Safek crdt Grow-only setcrdtupdatecrdtinitializationcrdt lookup querySafekcrdtConstruct new valueSafe7]k crdt_A type that may be empty. If your type does not have a special empty value, just wrap it into , it is free.$Based on Control.Lens.Empty.AsEmpty.  Safekcrdt.If no key in the map then the result is empty.  SafekcrdtA 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  , Semilattice defines this laws:  commutativity x  y == y  x idempotency x  x == xcrdtJust (), specialized to .6Safekx'crdt XXX Internal !"#$%&' !"#$%&'Safek ,crdtGrow-only counter..crdtIncrement counter/crdt Initial state0crdtGet value from the state1crdtSee CvRDT.crdt replica id,-./0,-/0.Safe$k L5crdtnPositive-negative counter. Allows incrementing and decrementing. Nice example of combining of existing CvRDT (,' in this case) to create another CvRDT.9crdtGet value from the state:crdtDecrement counter;crdtIncrement counter<crdt Initial state=crdtSee CvRDT:crdt replica id;crdt replica id56789:;<5678<9:; Safe+k%1Acrdt5State-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 .AASafek%B None$3Kk+EcrdtGet sequential timestamps.ILaws: 1. t1 <- getTimes n t2 <- getTime t2 >= t1 + n getTimes 0 == getTimes 1IcrdtUnique process identifierMcrdtDUnix time in 10^{-7} seconds (100 ns), as in RFC 4122 and Swarm RON.Ecrdtnumber of needed timestampscrdt.Starting value of the range. So return value t means range [t .. t + n - 1].BCDEFGHIJKLMNOPIJDEFKLOMGHCPNB None $;=>?K]k/~bcrdt+ProcessSim inside Lamport clock simulation.ecrdt!Lamport clock simulation. Key is I3. Non-present value is equivalent to (0, initial).crdt)Increase time by pid and return new value abcdefghij defabcghij NoneH]k4zcrdtCompact version of | . For each 5, the corresponding sequence of vetices has the same Pid and sequentially growing  LocalTime", starting with the specified one.|crdt%TODO(cblp, 2018-02-06) Vector.UnboxedcrdtMReplace content with specified, applying changed found by the diff algorithm z{|}~ |}~{z Nonek5\None 7<FTVikJrcrdt: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 intent. PayloadInternal state of a replica.IntentUser's request to update.Operation (Op)*Operation to be applied to other replicas.For many types  operation and intent 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.  " op1 op2 .  op1 op2 ==>  op1 .  op2 ==  op2 .  op1 !Idempotency doesn't need to hold.crdt4Generate an update to the local and remote replicas.Returns - if the intended operation is not applicable.crdtPApply an update to the payload (downstream). An invalid update must be ignored.hTODO(Syrovetsky, 2017-12-05) There is no downstream precondition yet. We must make a test for it first.crdtlPartial order for causal semantics. Values of some type may be ordered and causally-ordered different ways.crdtx  y means that x must go before y and y can not go before x.crdt*Not comparable, i. e. (a "d b) "' (b "d a).crdtKMake op and apply it to the payload -- a common routine at the source node. None$FT]kRcrdtBLast write wins. Assuming timestamp is unique. This type is both  and CvRDT.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.crdtInitialize statecrdtdChange state as CvRDT operation. Current value is ignored, because new timestamp is always greater.crdt Query statecrdtSee CvRDTcrdt(Merge by choosing more recent timestamp.None;=kSfNoneFT]kSNone$<FHTkWcrdtid of previous vertex,  means the beginningatomid of this vertexcrdt means the beginningcrdt indices in  vectorcrdtUsing K as an identifier for verticescrdtIs added and is not removed.None$FTkX NoneFTkYiNone ;=>?FT]kZcrdt*Empty order, allowing arbitrary reordering !"!#$%&'()**+,-%./"0123456788 !9:0;<=>?@@A!#BCDEFFGH#IA!JKLM NO P Q R S T U V V W W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m l n o n p q r s t u v w x y z { | } ~        ! : " !##! :"8>?# " crdt-10.3-FsCntlodEVUHvKSyPWhwkH CRDT.Cv.Max CRDT.Cv.GSet Data.Empty Data.MultiMapData.SemilatticeCRDT.Cv.TwoPSetCRDT.Cv.GCounterCRDT.Cv.PNCounterCRDT.CvCRDT.LamportClockCRDT.LamportClock.Simulation CRDT.Cv.RGA CRDT.Cv.ORSetCRDT.CmCRDT.LWWCRDT.Cv.LwwElementSetCRDT.Cm.TwoPSet CRDT.Cm.RGA CRDT.Cm.ORSet CRDT.Cm.GSetCRDT.Cm.Counter Semigroup<> MacAddress CRDT.Cm.LWWLWWbaseData.SemigroupgetMaxMaxGSetaddinitiallookupqueryAsEmptyemptyisEmpty isNotEmpty $fAsEmptyChar$fAsEmptyMaybeMultiMapassocsdelete deleteManyinsertkeysSet singleton $fEqMultiMap$fShowMultiMap Semilatticemerge$fSemilatticeMaybe$fSemilatticeSet$fSemilatticeMaxTwoPSetmemberremoveisKnown$fSemilatticeTwoPSet$fSemigroupTwoPSet $fEqTwoPSet $fShowTwoPSetGCounter increment$fSemilatticeGCounter$fSemigroupGCounter $fEqGCounter$fShowGCounter PNCounterpositivenegative decrement$fSemilatticePNCounter$fSemigroupPNCounter $fEqPNCounter$fShowPNCounterCvRDT getMacAddress LamportClockClockgetTimesadvanceProcessgetPidPid LamportTime LocalTimegetRealLocalTimegetTimerunLamportClock$fShowLamportTime$fProcessStateT$fProcessReaderT $fClockStateT$fClockReaderT$fClockLamportClock$fProcessLamportClock$fEqPid$fOrdPid $fShowPid$fEqLamportTime$fOrdLamportTime$fApplicativeLamportClock$fFunctorLamportClock$fMonadLamportClock$fMonadIOLamportClock ProcessSim ProcessSimTLamportClockSimLamportClockSimTrunLamportClockSimrunLamportClockSimT runProcessSimrunProcessSimT$fMonadIOLamportClockSimT$fMonadFailLamportClockSimT$fMonadTransLamportClockSimT$fMonadIOProcessSimT$fClockProcessSimT$fProcessProcessSimT$fMonadTransProcessSimT$fApplicativeLamportClockSimT$fFunctorLamportClockSimT$fMonadLamportClockSimT$fMonadErrorLamportClockSimT$fApplicativeProcessSimT$fFunctorProcessSimT$fMonadProcessSimT$fMonadFailProcessSimT RgaPacked RgaStringRGAtoListtoStringfromList fromStringeditpackunpack $fMonoidRGA$fSemilatticeRGA$fSemigroupRGA$fEqRGA $fShowRGAORSet$fSemilatticeORSet$fSemigroupORSet $fEqORSet $fShowORSetCmRDTIntentPayloadmakeOpapply CausalOrdprecedes concurrentmakeAndApplyOpmakeAndApplyOpsvaluetime initializeassignadvanceFromLWW $fCmRDTLWW$fCausalOrdLWW$fSemilatticeLWW$fSemigroupLWW$fEqLWW $fShowLWW LwwElementSetLES$fSemilatticeLwwElementSet$fSemigroupLwwElementSet$fEqLwwElementSet$fShowLwwElementSetAddRemove$fCausalOrdTwoPSet$fCmRDTTwoPSet OpAddAfterOpRemove RgaIntentAddAfter RgaPayloadvertices vertexIxstoVectorload $fCmRDTRGA$fCausalOrdRGA$fEqRgaPayload$fShowRgaPayload$fShowRgaIntentTagelementsversionOpAdd $fShowTag$fCausalOrdORSet $fCmRDTORSet $fShowIntent$fEqTag$fOrdTag $fEqPayload $fShowPayload$fCausalOrdGSet $fCmRDTGSet$fEqGSet $fShowGSetCounter Increment Decrement$fCausalOrdCounter$fCmRDTCounter$fBoundedCounter $fEnumCounter $fEqCounter $fShowCounterGHC.BaseMaybeidgetMac decodeMacpreIncreaseTimeVertexIdNothing