diff options
| author | Aviral Goel <goel.aviral@gmail.com> | 2016-12-17 16:31:29 -0500 |
|---|---|---|
| committer | Aviral Goel <goel.aviral@gmail.com> | 2016-12-17 16:31:29 -0500 |
| commit | 8956b27b29637a452d0603658f9646b324d904ed (patch) | |
| tree | 9df59595ff6712c1056a193df8d37a47aab8a475 /chapter | |
| parent | bd0ca41936a724619e31d6930b554bc12697768d (diff) | |
Added specification of counters, moved images to resources
Diffstat (limited to 'chapter')
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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/chapter/6/resources/partitioned-network.jpg b/chapter/6/resources/images/partitioned-network.jpg Binary files differindex 513fc13..513fc13 100644 --- a/chapter/6/resources/partitioned-network.jpg +++ b/chapter/6/resources/images/partitioned-network.jpg |
