Skip to content

Latest commit

 

History

History
52 lines (35 loc) · 1.89 KB

README.md

File metadata and controls

52 lines (35 loc) · 1.89 KB

crdt

Convergent and Commutative Replicated Data Types for Scala

CRDTs give you eventually consistent data structure for free. Merge copies of your data without fear!

This library is written in Scala 2.10 and uses type classes from Algebird.

PCounter

A PCounter is an increment only counter. That is, it maintains a distributed counter that can only be incremented. More concretely a PCounter keeps a map of Ids to counts, where Ids typically refer to different machines. There are operations increment the counter for a given Id and to get the total of the values across all Ids.

A PCounter can count any type A for which there is both a commutative Semigroup[A] and a Ordering[A]. A PCounter is itself a commutative Monoid.

import com.twitter.algebird.Semigroup
import scala.math.Ordering
import crdt.PCounter

// Create an empty counter
// Machines are identified by Strings. Counters are Ints
val counter = PCounter[String, Int]()

// Add some values
val updated = counter + ("a", 1) + ("b", 2) + ("c", 3)

// Get the total
updated.get // 1 + 2 + 3 = 6

// Increment the value associated with a machine
updated + ("a", 2)  // the total is now 3 + 2 + 3 = 8

As a PCounter is a Monoid you can merge PCounters together. Merging keeps the largest element associated with each machine.

import com.twitter.algebird.Operators._

val counter1 = PCounter[String, Int]() + ("a", 1)
val counter2 = PCounter[String, Int]() + ("a", 2)

val counter3 = counter1 + counter2
counter3.get // 2

If for some reason you want to see the elements associated with machines, values returns a Map[Id, A] from a PCounter[Id, A]:

val counter1 = PCounter[String, Int]() + ("a", 1)
counter1.values // Map[String,Int] = Map(a -> 1)