예제 #1
0
def test_gcounter():
    """
     []
   /    \
 A[a:1] B[b:1]       +1, +1
   |     |  \
   |     |    \
   |    /      |
 AB[a:1, b:1]  |     merge
   |           |
 AB[a:2, b:1]  |      +1
   |           |
    \      B2[b:2]    +1
     \         |
      \       /
    ABB2[a:2, b:2]    merge
    """

    A = GCounter(client_id="a")
    B = GCounter(client_id="b")

    A.increment()
    assert A.payload == {"a": 1}

    B.increment()
    assert B.payload == {"b": 1}

    B2 = B.clone()
    assert B2.payload == {"b": 1}

    B2.increment()
    assert B2.payload == {"b": 2}

    AB = GCounter.merge(A, B)
    AB.client_id = "a"
    assert AB.payload == {"a": 1, "b": 1}

    AB.increment()
    assert AB.payload == {"a": 2, "b": 1}

    ABB2 = GCounter.merge(AB, B2)
    assert ABB2.payload == {"a": 2, "b": 2}
예제 #2
0
def test_gcounter():
    """
     []
   /    \
 A[a:1] B[b:1]       +1, +1
   |     |  \
   |     |    \
   |    /      |
 AB[a:1, b:1]  |     merge
   |           |
 AB[a:2, b:1]  |      +1
   |           |
    \      B2[b:2]    +1
     \         |
      \       /
    ABB2[a:2, b:2]    merge
    """

    A = GCounter(client_id="a")
    B = GCounter(client_id="b")

    A.increment()
    assert A.payload == {"a": 1}

    B.increment()
    assert B.payload == {"b": 1}

    B2 = B.clone()
    assert B2.payload == {"b": 1}

    B2.increment()
    assert B2.payload == {"b": 2}

    AB = GCounter.merge(A, B)
    AB.client_id = "a"
    assert AB.payload == {"a": 1, "b": 1}

    AB.increment()
    assert AB.payload == {"a": 2, "b": 1}

    ABB2 = GCounter.merge(AB, B2)
    assert ABB2.payload == {"a": 2, "b": 2}
예제 #3
0
 def __init__(self, client_id=None):
     self.P = GCounter()
     self.N = GCounter()
     self.client_id = client_id or random_client_id()
예제 #4
0
class PNCounter(StateCRDT):
    def __init__(self, client_id=None):
        self.P = GCounter()
        self.N = GCounter()
        self.client_id = client_id or random_client_id()

    #
    # State-based CRDT API
    #
    def get_payload(self):
        return {"P": self.P.payload, "N": self.N.payload}

    def set_payload(self, payload):
        self.P.payload = payload['P']
        self.N.payload = payload['N']

    payload = property(get_payload, set_payload)

    def get_client_id(self):
        return self._cid

    def set_client_id(self, client_id):
        self._cid = client_id
        self.P.client_id = client_id
        self.N.client_id = client_id

    client_id = property(get_client_id, set_client_id)

    def clone(self):
        new = super(PNCounter, self).clone()

        # Copy the client id
        new.client_id = self.client_id
        return new

    @property
    def value(self):
        return self.P.value - self.N.value

    @classmethod
    def merge(cls, X, Y):
        merged_P = GCounter.merge(X.P, Y.P)
        merged_N = GCounter.merge(X.N, Y.N)

        merged_payload = {
            "P": merged_P.payload,
            "N": merged_N.payload,
        }
        return PNCounter.from_payload(merged_payload)

    def compare(self, other):
        """
        (∀i ∈ [0, n − 1] : X.P [i] ≤ Y.P [i] ∧
        ∀i ∈ [0, n − 1] : X.N[i] ≤ Y.N[i]
        """
        P_compare = self.P.compare(other.P)
        N_compare = self.N.compare(other.N)

        return P_compare and N_compare

    #
    # Counter API
    #
    def increment(self):
        self.P.increment()

    def decrement(self):
        self.N.increment()

    def __cmp__(self, other):
        return self.value.__cmp__(other.value)
예제 #5
0
 def __init__(self, client_id=None):
     self.P = GCounter()
     self.N = GCounter()
     self.client_id = client_id or random_client_id()
예제 #6
0
class PNCounter(StateCRDT):
    def __init__(self, client_id=None):
        self.P = GCounter()
        self.N = GCounter()
        self.client_id = client_id or random_client_id()

    #
    # State-based CRDT API
    #
    def get_payload(self):
        return {
            "P": self.P.payload,
            "N": self.N.payload
            }

    def set_payload(self, payload):
        self.P.payload = payload['P']
        self.N.payload = payload['N']

    payload = property(get_payload, set_payload)

    def get_client_id(self):
        return self._cid

    def set_client_id(self, client_id):
        self._cid = client_id
        self.P.client_id = client_id
        self.N.client_id = client_id

    client_id = property(get_client_id, set_client_id)

    def clone(self):
        new = super(PNCounter, self).clone()

        # Copy the client id
        new.client_id = self.client_id
        return new

    @property
    def value(self):
        return self.P.value - self.N.value

    @classmethod
    def merge(cls, X, Y):
        merged_P = GCounter.merge(X.P, Y.P)
        merged_N = GCounter.merge(X.N, Y.N)

        merged_payload = {
            "P": merged_P.payload,
            "N": merged_N.payload,
            }
        return PNCounter.from_payload(merged_payload)

    def compare(self, other):
        """
        (∀i ∈ [0, n − 1] : X.P [i] ≤ Y.P [i] ∧
        ∀i ∈ [0, n − 1] : X.N[i] ≤ Y.N[i]
        """
        P_compare = self.P.compare(other.P)
        N_compare = self.N.compare(other.N)

        return P_compare and N_compare

    #
    # Counter API
    #
    def increment(self):
        self.P.increment()

    def decrement(self):
        self.N.increment()

    def __cmp__(self, other):
        return self.value.__cmp__(other.value)