aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAviral Goel <goel.aviral@gmail.com>2016-12-17 16:31:29 -0500
committerAviral Goel <goel.aviral@gmail.com>2016-12-17 16:31:29 -0500
commit8956b27b29637a452d0603658f9646b324d904ed (patch)
tree9df59595ff6712c1056a193df8d37a47aab8a475
parentbd0ca41936a724619e31d6930b554bc12697768d (diff)
Added specification of counters, moved images to resources
-rw-r--r--chapter/6/counters.md215
-rw-r--r--chapter/6/resources/code/counters/python/operation-based-increment-and-decrement-counter.py20
-rw-r--r--chapter/6/resources/code/counters/python/operation-based-increment-only-counter.py15
-rw-r--r--chapter/6/resources/code/counters/python/state-based-increment-and-decrement-counter-correct.py47
-rw-r--r--chapter/6/resources/code/counters/python/state-based-increment-and-decrement-counter-incorrect.py31
-rw-r--r--chapter/6/resources/code/counters/python/state-based-increment-only-counter-correct.py28
-rw-r--r--chapter/6/resources/code/counters/python/state-based-increment-only-counter-incorrect.py19
-rw-r--r--chapter/6/resources/images/counters/operation-based-increment-and-decrement-counter.png (renamed from chapter/6/images/counters/operation-based-increment-and-decrement-counter.png)bin259325 -> 259325 bytes
-rw-r--r--chapter/6/resources/images/counters/operation-based-increment-only-counter.png (renamed from chapter/6/images/counters/operation-based-increment-only-counter.png)bin236423 -> 236423 bytes
-rw-r--r--chapter/6/resources/images/counters/state-based-increment-and-decrement-counter-correct.png (renamed from chapter/6/images/counters/state-based-increment-and-decrement-counter-correct.png)bin250168 -> 250168 bytes
-rw-r--r--chapter/6/resources/images/counters/state-based-increment-and-decrement-counter-incorrect.png (renamed from chapter/6/images/counters/state-based-increment-and-decrement-counter-incorrect.png)bin247402 -> 247402 bytes
-rw-r--r--chapter/6/resources/images/counters/state-based-increment-only-counter-correct.png (renamed from chapter/6/images/counters/state-based-increment-only-counter-correct.png)bin240649 -> 240649 bytes
-rw-r--r--chapter/6/resources/images/counters/state-based-increment-only-counter-incorrect.png (renamed from chapter/6/images/counters/state-based-increment-only-counter-incorrect.png)bin241905 -> 241905 bytes
-rw-r--r--chapter/6/resources/images/partitioned-network.jpg (renamed from chapter/6/resources/partitioned-network.jpg)bin24303 -> 24303 bytes
14 files changed, 344 insertions, 31 deletions
diff --git a/chapter/6/counters.md b/chapter/6/counters.md
index c441e6e..523e717 100644
--- a/chapter/6/counters.md
+++ b/chapter/6/counters.md
@@ -17,6 +17,25 @@ This is straightforward to implement as there is only one update operation.
#### Specification
+```python
+
+class CmRDT:
+ pass
+
+class Counter(CmRDT):
+
+ def __init__(self): # constructor function
+ self._count = 0
+
+ def value(self): # query function
+ return self._count
+
+ def increment(self): # update function
+ self._count += 1
+ for replica in self.replicas():
+ self.transmit("increment", replica)
+
+```
#### Figure
@@ -31,6 +50,29 @@ Since the count always increases, modeling the state as count automatically make
#### Specification
+```python
+
+class CvRDT:
+ pass
+
+class Counter(CvRDT):
+
+ def __init__(self, count = 0): # constructor function
+ self._count = count
+
+ def value(self): # query function
+ return self._count
+
+ def increment(self): # update function
+ self._count += 1
+
+ def compare(self, other): # comparison function
+ return self.value() <= other.value()
+
+ def merge(self, other): # merge function
+ return Counter(max(self.value(), other.value()))
+
+```
#### Figure
@@ -41,6 +83,38 @@ Something is clearly amiss! When two replicas are incremented, they should toget
#### Specification
+```python
+
+class CvRDT:
+ pass
+
+class Counter(CvRDT):
+
+ def __init__(self, counts = None): # constructor function
+ if counts is None:
+ self._counts = [0] * length(self.replicas())
+ else:
+ self._counts = counts
+
+ def value(self): # query function
+ return sum(self._counts)
+
+ def counts(self): # query function
+ return list(self._counts) # return a clone
+
+ def increment(self): # update function
+ self._counts[self.replicaId()] += 1
+
+ def compare(self, other): # comparison function
+ return all(v1 <= v2 for (v1, v2) in
+ zip(self.counts(),
+ other.counts()))
+
+ def merge(self, other): # merge function
+ return Counter(map(max, zip(self.counts(),
+ other.counts())))
+
+```
#### Figure
@@ -59,6 +133,31 @@ Something is clearly amiss! When two replicas are incremented, they should toget
#### Specification
+```python
+
+class CmRDT:
+ pass
+
+class Counter(CmRDT):
+
+ def __init__(self): # constructor function
+ self._count = 0
+
+ def value(self): # query function
+ return self._count
+
+ def increment(self): # update function
+ self._count += 1
+ for replica in self.replicas():
+ self.transmit("increment", replica)
+
+ def decrement(self): # update function
+ self._count -= 1
+ for replica in self.replicas():
+ self.transmit("decrement", replica)
+
+```
+
#### Figure
![Operation based increment and decrement counter][operation-based-increment-and-decrement-counter]
@@ -67,7 +166,41 @@ Something is clearly amiss! When two replicas are incremented, they should toget
#### Specification
+```python
+
+class CvRDT:
+ pass
+
+class Counter(CvRDT):
+
+ def __init__(self, counts = None): # constructor function
+ if counts is None:
+ self._counts = [0] * length(self.replicas())
+ else:
+ self._counts = counts
+
+ def value(self): # query function
+ return sum(self._counts)
+
+ def counts(self): # query function
+ return list(self._counts) # return a clone
+ def increment(self): # update function
+ self._counts[self.replicaId()] += 1
+
+ def decrement(self): # update function
+ self._counts[self.replicaId()] -= 1
+
+ def compare(self, other): # comparison function
+ return all(v1 <= v2 for (v1, v2) in
+ zip(self.counts(),
+ other.counts()))
+
+ def merge(self, other): # merge function
+ return Counter(map(max, zip(self.counts(),
+ other.counts())))
+
+```
#### Figure
@@ -77,46 +210,66 @@ Something is clearly amiss! When two replicas are incremented, they should toget
#### Specification
+```python
+class CvRDT:
+ pass
-#### Figure
+class Counter(CvRDT):
-![State based increment and decrement counter (correct)][state-based-increment-and-decrement-counter-correct]
+ def __init__(self,
+ increments = None,
+ decrements = None): # constructor function
+ if increments is None:
+ self._increments = [0] * length(replicas())
+ else:
+ self._increments = increments
+ if decrements is None:
+ self._decrements = [0] * length(replicas())
+ else:
+ self._decrements = decrements
-## Non-negative Counter
+ def increments(self): # query function
+ return list(self._increments) # return a clone
+ def decrements(self): # query function
+ return list(self._decrements) # return a clone
+ def value(self): # query function
+ return (sum(self.increments()) -
+ sum(self.decrements()))
+ def increment(self): # update function
+ self._increments[self.replicaId()] += 1
+ def decrement(self): # update function
+ self._decrements[self.replicaId()] += 1
-### State based specification (CmRDT)
+ def compare(self, other): # comparison function
+ return (all(v1 <= v2 for (v1, v2) in
+ zip(self.increments(),
+ other.increments()))
+ and
+ all(v1 <= v2 for (v1, v2) in
+ zip(self.decrements(),
+ other.decrements())))
+
+ def merge(self, other): # merge function
+ return Counter(increments = map(max, zip(self.increments(),
+ other.increments())),
+ decrements = map(max, zip(self.decrements(),
+ other.decrements())))
-```javascript
-class
- counts = [0, 0, ..., 0]
-
- update increment()
- g <- getId()
- counts[g] <- counts[g] + 1
-
- // query function
- function value():
- sum = 0
- for count in counts:
- sum <- sum + count
- return sum
-
- function compare(other):
- for i in 0 : length(replicas()):
- if counts[i] > other.counts[i]:
- return False
- return True
-
```
-[operation-based-increment-only-counter]: images/counters/operation-based-increment-only-counter.png
-[state-based-increment-only-counter-incorrect]: images/counters/state-based-increment-only-counter-incorrect.png
-[state-based-increment-only-counter-correct]: images/counters/state-based-increment-only-counter-correct.png
-[operation-based-increment-and-decrement-counter]: images/counters/operation-based-increment-and-decrement-counter.png
-[state-based-increment-and-decrement-counter-incorrect]: images/counters/state-based-increment-and-decrement-counter-incorrect.png
-[state-based-increment-and-decrement-counter-correct]: images/counters/state-based-increment-and-decrement-counter-correct.png
+#### Figure
+
+![State based increment and decrement counter (correct)][state-based-increment-and-decrement-counter-correct]
+
+
+[operation-based-increment-only-counter]: resources/images/counters/operation-based-increment-only-counter.png
+[state-based-increment-only-counter-incorrect]: resources/images/counters/state-based-increment-only-counter-incorrect.png
+[state-based-increment-only-counter-correct]: resources/images/counters/state-based-increment-only-counter-correct.png
+[operation-based-increment-and-decrement-counter]: resources/images/counters/operation-based-increment-and-decrement-counter.png
+[state-based-increment-and-decrement-counter-incorrect]: resources/images/counters/state-based-increment-and-decrement-counter-incorrect.png
+[state-based-increment-and-decrement-counter-correct]: resources/images/counters/state-based-increment-and-decrement-counter-correct.png
diff --git a/chapter/6/resources/code/counters/python/operation-based-increment-and-decrement-counter.py b/chapter/6/resources/code/counters/python/operation-based-increment-and-decrement-counter.py
new file mode 100644
index 0000000..5182ab1
--- /dev/null
+++ b/chapter/6/resources/code/counters/python/operation-based-increment-and-decrement-counter.py
@@ -0,0 +1,20 @@
+class CmRDT:
+ pass
+
+class Counter(CmRDT):
+
+ def __init__(self): # constructor function
+ self._count = 0
+
+ def value(self): # query function
+ return self._count
+
+ def increment(self): # update function
+ self._count += 1
+ for replica in self.replicas():
+ self.transmit("increment", replica)
+
+ def decrement(self): # update function
+ self._count -= 1
+ for replica in self.replicas():
+ self.transmit("decrement", replica)
diff --git a/chapter/6/resources/code/counters/python/operation-based-increment-only-counter.py b/chapter/6/resources/code/counters/python/operation-based-increment-only-counter.py
new file mode 100644
index 0000000..b10cd98
--- /dev/null
+++ b/chapter/6/resources/code/counters/python/operation-based-increment-only-counter.py
@@ -0,0 +1,15 @@
+class CmRDT:
+ pass
+
+class Counter(CmRDT):
+
+ def __init__(self): # constructor function
+ self._count = 0
+
+ def value(self): # query function
+ return self._count
+
+ def increment(self): # update function
+ self._count += 1
+ for replica in self.replicas():
+ self.transmit("increment", replica)
diff --git a/chapter/6/resources/code/counters/python/state-based-increment-and-decrement-counter-correct.py b/chapter/6/resources/code/counters/python/state-based-increment-and-decrement-counter-correct.py
new file mode 100644
index 0000000..1ea726d
--- /dev/null
+++ b/chapter/6/resources/code/counters/python/state-based-increment-and-decrement-counter-correct.py
@@ -0,0 +1,47 @@
+class CvRDT:
+ pass
+
+class Counter(CvRDT):
+
+ def __init__(self,
+ increments = None,
+ decrements = None): # constructor function
+ if increments is None:
+ self._increments = [0] * length(replicas())
+ else:
+ self._increments = increments
+ if decrements is None:
+ self._decrements = [0] * length(replicas())
+ else:
+ self._decrements = decrements
+
+ def increments(self): # query function
+ return list(self._increments) # return a clone
+
+ def decrements(self): # query function
+ return list(self._decrements) # return a clone
+
+ def value(self): # query function
+ return (sum(self.increments()) -
+ sum(self.decrements()))
+
+ def increment(self): # update function
+ self._increments[self.replicaId()] += 1
+
+ def decrement(self): # update function
+ self._decrements[self.replicaId()] += 1
+
+ def compare(self, other): # comparison function
+ return (all(v1 <= v2 for (v1, v2) in
+ zip(self.increments(),
+ other.increments()))
+ and
+ all(v1 <= v2 for (v1, v2) in
+ zip(self.decrements(),
+ other.decrements())))
+
+ def merge(self, other): # merge function
+ return Counter(increments = map(max, zip(self.increments(),
+ other.increments())),
+ decrements = map(max, zip(self.decrements(),
+ other.decrements())))
diff --git a/chapter/6/resources/code/counters/python/state-based-increment-and-decrement-counter-incorrect.py b/chapter/6/resources/code/counters/python/state-based-increment-and-decrement-counter-incorrect.py
new file mode 100644
index 0000000..6f0cbde
--- /dev/null
+++ b/chapter/6/resources/code/counters/python/state-based-increment-and-decrement-counter-incorrect.py
@@ -0,0 +1,31 @@
+class CvRDT:
+ pass
+
+class Counter(CvRDT):
+
+ def __init__(self, counts = None): # constructor function
+ if counts is None:
+ self._counts = [0] * length(self.replicas())
+ else:
+ self._counts = counts
+
+ def value(self): # query function
+ return sum(self._counts)
+
+ def counts(self): # query function
+ return list(self._counts) # return a clone
+
+ def increment(self): # update function
+ self._counts[self.replicaId()] += 1
+
+ def decrement(self): # update function
+ self._counts[self.replicaId()] -= 1
+
+ def compare(self, other): # comparison function
+ return all(v1 <= v2 for (v1, v2) in
+ zip(self.counts(),
+ other.counts()))
+
+ def merge(self, other): # merge function
+ return Counter(map(max, zip(self.counts(),
+ other.counts())))
diff --git a/chapter/6/resources/code/counters/python/state-based-increment-only-counter-correct.py b/chapter/6/resources/code/counters/python/state-based-increment-only-counter-correct.py
new file mode 100644
index 0000000..a3d9069
--- /dev/null
+++ b/chapter/6/resources/code/counters/python/state-based-increment-only-counter-correct.py
@@ -0,0 +1,28 @@
+class CvRDT:
+ pass
+
+class Counter(CvRDT):
+
+ def __init__(self, counts = None): # constructor function
+ if counts is None:
+ self._counts = [0] * length(self.replicas())
+ else:
+ self._counts = counts
+
+ def value(self): # query function
+ return sum(self._counts)
+
+ def counts(self): # query function
+ return list(self._counts) # return a clone
+
+ def increment(self): # update function
+ self._counts[self.replicaId()] += 1
+
+ def compare(self, other): # comparison function
+ return all(v1 <= v2 for (v1, v2) in
+ zip(self.counts(),
+ other.counts()))
+
+ def merge(self, other): # merge function
+ return Counter(map(max, zip(self.counts(),
+ other.counts())))
diff --git a/chapter/6/resources/code/counters/python/state-based-increment-only-counter-incorrect.py b/chapter/6/resources/code/counters/python/state-based-increment-only-counter-incorrect.py
new file mode 100644
index 0000000..9971c65
--- /dev/null
+++ b/chapter/6/resources/code/counters/python/state-based-increment-only-counter-incorrect.py
@@ -0,0 +1,19 @@
+class CvRDT:
+ pass
+
+class Counter(CvRDT):
+
+ def __init__(self, count = 0): # constructor function
+ self._count = count
+
+ def value(self): # query function
+ return self._count
+
+ def increment(self): # update function
+ self._count += 1
+
+ def compare(self, other): # comparison function
+ return self.value() <= other.value()
+
+ def merge(self, other): # merge function
+ return Counter(max(self.value(), other.value()))
diff --git a/chapter/6/images/counters/operation-based-increment-and-decrement-counter.png b/chapter/6/resources/images/counters/operation-based-increment-and-decrement-counter.png
index f046c0b..f046c0b 100644
--- a/chapter/6/images/counters/operation-based-increment-and-decrement-counter.png
+++ b/chapter/6/resources/images/counters/operation-based-increment-and-decrement-counter.png
Binary files differ
diff --git a/chapter/6/images/counters/operation-based-increment-only-counter.png b/chapter/6/resources/images/counters/operation-based-increment-only-counter.png
index 398c562..398c562 100644
--- a/chapter/6/images/counters/operation-based-increment-only-counter.png
+++ b/chapter/6/resources/images/counters/operation-based-increment-only-counter.png
Binary files differ
diff --git a/chapter/6/images/counters/state-based-increment-and-decrement-counter-correct.png b/chapter/6/resources/images/counters/state-based-increment-and-decrement-counter-correct.png
index 0d6468b..0d6468b 100644
--- a/chapter/6/images/counters/state-based-increment-and-decrement-counter-correct.png
+++ b/chapter/6/resources/images/counters/state-based-increment-and-decrement-counter-correct.png
Binary files differ
diff --git a/chapter/6/images/counters/state-based-increment-and-decrement-counter-incorrect.png b/chapter/6/resources/images/counters/state-based-increment-and-decrement-counter-incorrect.png
index 3f7f1b9..3f7f1b9 100644
--- a/chapter/6/images/counters/state-based-increment-and-decrement-counter-incorrect.png
+++ b/chapter/6/resources/images/counters/state-based-increment-and-decrement-counter-incorrect.png
Binary files differ
diff --git a/chapter/6/images/counters/state-based-increment-only-counter-correct.png b/chapter/6/resources/images/counters/state-based-increment-only-counter-correct.png
index 4ca2843..4ca2843 100644
--- a/chapter/6/images/counters/state-based-increment-only-counter-correct.png
+++ b/chapter/6/resources/images/counters/state-based-increment-only-counter-correct.png
Binary files differ
diff --git a/chapter/6/images/counters/state-based-increment-only-counter-incorrect.png b/chapter/6/resources/images/counters/state-based-increment-only-counter-incorrect.png
index 3f95e59..3f95e59 100644
--- a/chapter/6/images/counters/state-based-increment-only-counter-incorrect.png
+++ b/chapter/6/resources/images/counters/state-based-increment-only-counter-incorrect.png
Binary files differ
diff --git a/chapter/6/resources/partitioned-network.jpg b/chapter/6/resources/images/partitioned-network.jpg
index 513fc13..513fc13 100644
--- a/chapter/6/resources/partitioned-network.jpg
+++ b/chapter/6/resources/images/partitioned-network.jpg
Binary files differ