module CRDT.Cv.GCounter
( GCounter (..)
, initial
, query
, increment
) where
import Data.IntMap.Strict (IntMap)
import qualified Data.IntMap.Strict as IntMap
import Data.Semigroup (Semigroup ((<>)))
import Data.Semilattice (Semilattice)
newtype GCounter a = GCounter (IntMap a)
deriving (Eq, Show)
instance Ord a => Semigroup (GCounter a) where
GCounter x <> GCounter y = GCounter $ IntMap.unionWith max x y
instance Ord a => Semilattice (GCounter a)
increment
:: Num a
=> Word
-> GCounter a
-> GCounter a
increment replicaId (GCounter imap) = GCounter (IntMap.insertWith (+) i 1 imap)
where
i = fromIntegral replicaId
initial :: GCounter a
initial = GCounter IntMap.empty
query :: Num a => GCounter a -> a
query (GCounter v) = sum v