Bartosz Sypytkowski
@horusiath
b.sypytkowski@gmail.com
http://bartoszsypytkowski.com
X = 1
X = 2
X = ?
Partition tolerance
Consistency
Availability
X = 2
X = 3
X = 1
X = 1
X = 2
X = 3
X = 1
X = 1
X = 2
X = 3
X = 2
X = 3
x • y = y • x
(x • y) • z = z • (y • z)
x • x = x
// empty value
empty → { }
// increment - every replica increments
// only its own replica entry
inc({ a: 1, b: 1 }) → { a: 2, b: 1 } // replica a ++
// merge - max number of all replicas
{ a: 2, b: 1 } ∪ { a: 1, b: 2 } → { a: 2, b: 2 }
// value - sum of all replicas
value({ a: 1, b: 2 }) → 3
Just compose 2 G-Counters:
Nothing to see here... just an ordinary set
// empty value - empty set
empty → {}
// add element
add({}, 123) → { 123 }
// merge - union sets
{ 123, 234 } ∪ { 234, 345 } → { 123, 234, 345 }
// value - just return a set
value({ 123, 234 }) → { 123, 234 }
// state of a G-Set on replicas A & B
A(X) → { 123, 234 }
B(X) → { 123, 234 }
// remove 123 on replica A
A(X) → { 234 }
B(X) → { 123, 234 }
// merge both replicas
A(X) ∪ B(X) → { 123, 234 } // WRONG!
Again... just compose 2 sets:
// empty value - 2 empty sets
empty → { add: {}, rem: {} }
// add element
X = add(empty, 123) → { add: { 123 }, rem: {} }
X = add(X, 234) → { add: { 123, 234 }, rem: {} }
// remove element
X = rem(X, 123) → { add: { 123, 234 }, rem: { 123 } }
// value - diff between add & rem
value(X) → { 234 }
// merge - union corresponding add/rem
X → { add: { 123, 234 }, rem: { 123 } }
Y → { add: { 123, 345 }, rem: {} }
X ∪ Y → { add: { 123, 234, 345 }, rem: { 123 } }
add: { A/1, B/2 }
rem: { }
Insert: C/3
Remove: C/4
Insert: C/5
add: { A/1, B/2, C/3 }
rem: { }
add: { A/1, B/2 }
rem: { C/4 }
add: { A/1, B/2, C/5 }
rem: { }
Value
Timestamp
LWW-Register
Key-Value pair
OR-Set
C:1
B:1 C:1
B:2 C:1
A:1 B:2 C:1
A:2 B:2 C:1
B:3 C:1
A:2 B:4 C:1
B:3 C:2
A:2 B:5 C:1
A:2 B:5 C:4
B:3 C:3
A:3 B:3 C:3
A:2 B:5 C:5
A:4 B:5 C:5
A
B
C
Less
Greater
Equal
Concurrent
a:1 b:0 c:0
a:2 b:1 c:2
a:1 b:0 c:0
a:1 b:0 c:0
a:4 b:1 c:2
a:3 b:0 c:0
a:4 b:1 c:2
a:3 b:2 c:2
A
B
set(x=1)
set(y=1)
Each record is identified by:
Prepare {X=1, ts:1, dep: [Y]}
Prepare {Y=1, ts:1, dep: [X]}
Prepared
Prepared
Commit {ts:1}
Commit {ts:1}
Committed
Committed
Get {X}
{X=1, ts:1, dep: [Y]}
{Y=1, ts:1, dep: [X]}
Get {Y}
Get {X}
{X=1, ts:1, dep: [Y]}
{Y=0, ts:0, dep: []}
Get {Y}
Mismatch
Get {Y, ts:1}
{Y=1, ts:1, dep: [X]}