module CRDT.GCounter.Cv ( GCounter , increment , initial , query ) where import Data.Monoid ((<>)) import qualified Data.Vector as Vector import qualified Data.Vector.Mutable as VectorM import CRDT.GCounter.Cv.Internal -- | Increment counter increment :: Num a => Word -- ^ replica id -> GCounter a -> GCounter a increment replicaId (GCounter vec) = let i = fromIntegral replicaId vecResized = if i + 1 > length vec then vec <> Vector.replicate (i + 1 - length vec) 0 else vec vecUpdated = Vector.modify (\vm -> VectorM.modify vm (+1) i) vecResized in GCounter vecUpdated -- | Initial state initial :: GCounter a initial = GCounter Vector.empty -- | Get value from the state query :: Num a => GCounter a -> a query (GCounter v) = sum v